1*795d594fSAndroid Build Coastguard Worker /* 2*795d594fSAndroid Build Coastguard Worker * Copyright (C) 2023 The Android Open Source Project 3*795d594fSAndroid Build Coastguard Worker * 4*795d594fSAndroid Build Coastguard Worker * Licensed under the Apache License, Version 2.0 (the "License"); 5*795d594fSAndroid Build Coastguard Worker * you may not use this file except in compliance with the License. 6*795d594fSAndroid Build Coastguard Worker * You may obtain a copy of the License at 7*795d594fSAndroid Build Coastguard Worker * 8*795d594fSAndroid Build Coastguard Worker * http://www.apache.org/licenses/LICENSE-2.0 9*795d594fSAndroid Build Coastguard Worker * 10*795d594fSAndroid Build Coastguard Worker * Unless required by applicable law or agreed to in writing, software 11*795d594fSAndroid Build Coastguard Worker * distributed under the License is distributed on an "AS IS" BASIS, 12*795d594fSAndroid Build Coastguard Worker * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13*795d594fSAndroid Build Coastguard Worker * See the License for the specific language governing permissions and 14*795d594fSAndroid Build Coastguard Worker * limitations under the License. 15*795d594fSAndroid Build Coastguard Worker */ 16*795d594fSAndroid Build Coastguard Worker 17*795d594fSAndroid Build Coastguard Worker #ifndef ART_COMPILER_OPTIMIZING_CODE_GENERATION_DATA_H_ 18*795d594fSAndroid Build Coastguard Worker #define ART_COMPILER_OPTIMIZING_CODE_GENERATION_DATA_H_ 19*795d594fSAndroid Build Coastguard Worker 20*795d594fSAndroid Build Coastguard Worker #include <memory> 21*795d594fSAndroid Build Coastguard Worker 22*795d594fSAndroid Build Coastguard Worker #include "arch/instruction_set.h" 23*795d594fSAndroid Build Coastguard Worker #include "base/scoped_arena_allocator.h" 24*795d594fSAndroid Build Coastguard Worker #include "base/scoped_arena_containers.h" 25*795d594fSAndroid Build Coastguard Worker #include "code_generator.h" 26*795d594fSAndroid Build Coastguard Worker #include "dex/proto_reference.h" 27*795d594fSAndroid Build Coastguard Worker #include "dex/string_reference.h" 28*795d594fSAndroid Build Coastguard Worker #include "dex/type_reference.h" 29*795d594fSAndroid Build Coastguard Worker #include "handle.h" 30*795d594fSAndroid Build Coastguard Worker #include "mirror/class.h" 31*795d594fSAndroid Build Coastguard Worker #include "mirror/method_type.h" 32*795d594fSAndroid Build Coastguard Worker #include "mirror/object.h" 33*795d594fSAndroid Build Coastguard Worker #include "mirror/string.h" 34*795d594fSAndroid Build Coastguard Worker #include "stack_map_stream.h" 35*795d594fSAndroid Build Coastguard Worker 36*795d594fSAndroid Build Coastguard Worker namespace art HIDDEN { 37*795d594fSAndroid Build Coastguard Worker 38*795d594fSAndroid Build Coastguard Worker class CodeGenerationData : public DeletableArenaObject<kArenaAllocCodeGenerator> { 39*795d594fSAndroid Build Coastguard Worker public: Create(ArenaStack * arena_stack,InstructionSet instruction_set)40*795d594fSAndroid Build Coastguard Worker static std::unique_ptr<CodeGenerationData> Create(ArenaStack* arena_stack, 41*795d594fSAndroid Build Coastguard Worker InstructionSet instruction_set) { 42*795d594fSAndroid Build Coastguard Worker ScopedArenaAllocator allocator(arena_stack); 43*795d594fSAndroid Build Coastguard Worker void* memory = allocator.Alloc<CodeGenerationData>(kArenaAllocCodeGenerator); 44*795d594fSAndroid Build Coastguard Worker return std::unique_ptr<CodeGenerationData>( 45*795d594fSAndroid Build Coastguard Worker ::new (memory) CodeGenerationData(std::move(allocator), instruction_set)); 46*795d594fSAndroid Build Coastguard Worker } 47*795d594fSAndroid Build Coastguard Worker GetScopedAllocator()48*795d594fSAndroid Build Coastguard Worker ScopedArenaAllocator* GetScopedAllocator() { 49*795d594fSAndroid Build Coastguard Worker return &allocator_; 50*795d594fSAndroid Build Coastguard Worker } 51*795d594fSAndroid Build Coastguard Worker AddSlowPath(SlowPathCode * slow_path)52*795d594fSAndroid Build Coastguard Worker void AddSlowPath(SlowPathCode* slow_path) { 53*795d594fSAndroid Build Coastguard Worker slow_paths_.emplace_back(std::unique_ptr<SlowPathCode>(slow_path)); 54*795d594fSAndroid Build Coastguard Worker } 55*795d594fSAndroid Build Coastguard Worker GetSlowPaths()56*795d594fSAndroid Build Coastguard Worker ArrayRef<const std::unique_ptr<SlowPathCode>> GetSlowPaths() const { 57*795d594fSAndroid Build Coastguard Worker return ArrayRef<const std::unique_ptr<SlowPathCode>>(slow_paths_); 58*795d594fSAndroid Build Coastguard Worker } 59*795d594fSAndroid Build Coastguard Worker GetStackMapStream()60*795d594fSAndroid Build Coastguard Worker StackMapStream* GetStackMapStream() { return &stack_map_stream_; } 61*795d594fSAndroid Build Coastguard Worker ReserveJitStringRoot(StringReference string_reference,Handle<mirror::String> string)62*795d594fSAndroid Build Coastguard Worker void ReserveJitStringRoot(StringReference string_reference, Handle<mirror::String> string) { 63*795d594fSAndroid Build Coastguard Worker jit_string_roots_.Overwrite(string_reference, 64*795d594fSAndroid Build Coastguard Worker reinterpret_cast64<uint64_t>(string.GetReference())); 65*795d594fSAndroid Build Coastguard Worker } 66*795d594fSAndroid Build Coastguard Worker GetJitStringRootIndex(StringReference string_reference)67*795d594fSAndroid Build Coastguard Worker uint64_t GetJitStringRootIndex(StringReference string_reference) const { 68*795d594fSAndroid Build Coastguard Worker return jit_string_roots_.Get(string_reference); 69*795d594fSAndroid Build Coastguard Worker } 70*795d594fSAndroid Build Coastguard Worker GetNumberOfJitStringRoots()71*795d594fSAndroid Build Coastguard Worker size_t GetNumberOfJitStringRoots() const { 72*795d594fSAndroid Build Coastguard Worker return jit_string_roots_.size(); 73*795d594fSAndroid Build Coastguard Worker } 74*795d594fSAndroid Build Coastguard Worker ReserveJitClassRoot(TypeReference type_reference,Handle<mirror::Class> klass)75*795d594fSAndroid Build Coastguard Worker void ReserveJitClassRoot(TypeReference type_reference, Handle<mirror::Class> klass) { 76*795d594fSAndroid Build Coastguard Worker jit_class_roots_.Overwrite(type_reference, reinterpret_cast64<uint64_t>(klass.GetReference())); 77*795d594fSAndroid Build Coastguard Worker } 78*795d594fSAndroid Build Coastguard Worker GetJitClassRootIndex(TypeReference type_reference)79*795d594fSAndroid Build Coastguard Worker uint64_t GetJitClassRootIndex(TypeReference type_reference) const { 80*795d594fSAndroid Build Coastguard Worker return jit_class_roots_.Get(type_reference); 81*795d594fSAndroid Build Coastguard Worker } 82*795d594fSAndroid Build Coastguard Worker GetNumberOfJitClassRoots()83*795d594fSAndroid Build Coastguard Worker size_t GetNumberOfJitClassRoots() const { 84*795d594fSAndroid Build Coastguard Worker return jit_class_roots_.size(); 85*795d594fSAndroid Build Coastguard Worker } 86*795d594fSAndroid Build Coastguard Worker ReserveJitMethodTypeRoot(ProtoReference proto_reference,Handle<mirror::MethodType> method_type)87*795d594fSAndroid Build Coastguard Worker void ReserveJitMethodTypeRoot(ProtoReference proto_reference, 88*795d594fSAndroid Build Coastguard Worker Handle<mirror::MethodType> method_type) { 89*795d594fSAndroid Build Coastguard Worker jit_method_type_roots_.Overwrite(proto_reference, 90*795d594fSAndroid Build Coastguard Worker reinterpret_cast64<uint64_t>(method_type.GetReference())); 91*795d594fSAndroid Build Coastguard Worker } 92*795d594fSAndroid Build Coastguard Worker GetJitMethodTypeRootIndex(ProtoReference proto_reference)93*795d594fSAndroid Build Coastguard Worker uint64_t GetJitMethodTypeRootIndex(ProtoReference proto_reference) const { 94*795d594fSAndroid Build Coastguard Worker return jit_method_type_roots_.Get(proto_reference); 95*795d594fSAndroid Build Coastguard Worker } 96*795d594fSAndroid Build Coastguard Worker GetNumberOfJitMethodTypeRoots()97*795d594fSAndroid Build Coastguard Worker size_t GetNumberOfJitMethodTypeRoots() const { 98*795d594fSAndroid Build Coastguard Worker return jit_method_type_roots_.size(); 99*795d594fSAndroid Build Coastguard Worker } 100*795d594fSAndroid Build Coastguard Worker GetNumberOfJitRoots()101*795d594fSAndroid Build Coastguard Worker size_t GetNumberOfJitRoots() const { 102*795d594fSAndroid Build Coastguard Worker return GetNumberOfJitStringRoots() + 103*795d594fSAndroid Build Coastguard Worker GetNumberOfJitClassRoots() + 104*795d594fSAndroid Build Coastguard Worker GetNumberOfJitMethodTypeRoots(); 105*795d594fSAndroid Build Coastguard Worker } 106*795d594fSAndroid Build Coastguard Worker 107*795d594fSAndroid Build Coastguard Worker void EmitJitRoots(/*out*/std::vector<Handle<mirror::Object>>* roots) 108*795d594fSAndroid Build Coastguard Worker REQUIRES_SHARED(Locks::mutator_lock_); 109*795d594fSAndroid Build Coastguard Worker 110*795d594fSAndroid Build Coastguard Worker private: CodeGenerationData(ScopedArenaAllocator && allocator,InstructionSet instruction_set)111*795d594fSAndroid Build Coastguard Worker CodeGenerationData(ScopedArenaAllocator&& allocator, InstructionSet instruction_set) 112*795d594fSAndroid Build Coastguard Worker : allocator_(std::move(allocator)), 113*795d594fSAndroid Build Coastguard Worker stack_map_stream_(&allocator_, instruction_set), 114*795d594fSAndroid Build Coastguard Worker slow_paths_(allocator_.Adapter(kArenaAllocCodeGenerator)), 115*795d594fSAndroid Build Coastguard Worker jit_string_roots_(StringReferenceValueComparator(), 116*795d594fSAndroid Build Coastguard Worker allocator_.Adapter(kArenaAllocCodeGenerator)), 117*795d594fSAndroid Build Coastguard Worker jit_class_roots_(TypeReferenceValueComparator(), 118*795d594fSAndroid Build Coastguard Worker allocator_.Adapter(kArenaAllocCodeGenerator)), 119*795d594fSAndroid Build Coastguard Worker jit_method_type_roots_(ProtoReferenceValueComparator(), 120*795d594fSAndroid Build Coastguard Worker allocator_.Adapter(kArenaAllocCodeGenerator)) { 121*795d594fSAndroid Build Coastguard Worker slow_paths_.reserve(kDefaultSlowPathsCapacity); 122*795d594fSAndroid Build Coastguard Worker } 123*795d594fSAndroid Build Coastguard Worker 124*795d594fSAndroid Build Coastguard Worker static constexpr size_t kDefaultSlowPathsCapacity = 8; 125*795d594fSAndroid Build Coastguard Worker 126*795d594fSAndroid Build Coastguard Worker ScopedArenaAllocator allocator_; 127*795d594fSAndroid Build Coastguard Worker StackMapStream stack_map_stream_; 128*795d594fSAndroid Build Coastguard Worker ScopedArenaVector<std::unique_ptr<SlowPathCode>> slow_paths_; 129*795d594fSAndroid Build Coastguard Worker 130*795d594fSAndroid Build Coastguard Worker // Maps a StringReference (dex_file, string_index) to the index in the literal table. 131*795d594fSAndroid Build Coastguard Worker // Entries are initially added with a pointer in the handle zone, and `EmitJitRoots` 132*795d594fSAndroid Build Coastguard Worker // will compute all the indices. 133*795d594fSAndroid Build Coastguard Worker ScopedArenaSafeMap<StringReference, uint64_t, StringReferenceValueComparator> jit_string_roots_; 134*795d594fSAndroid Build Coastguard Worker 135*795d594fSAndroid Build Coastguard Worker // Maps a ClassReference (dex_file, type_index) to the index in the literal table. 136*795d594fSAndroid Build Coastguard Worker // Entries are initially added with a pointer in the handle zone, and `EmitJitRoots` 137*795d594fSAndroid Build Coastguard Worker // will compute all the indices. 138*795d594fSAndroid Build Coastguard Worker ScopedArenaSafeMap<TypeReference, uint64_t, TypeReferenceValueComparator> jit_class_roots_; 139*795d594fSAndroid Build Coastguard Worker 140*795d594fSAndroid Build Coastguard Worker // Maps a ProtoReference (dex_file, proto_index) to the index in the literal table. 141*795d594fSAndroid Build Coastguard Worker // Entries are initially added with a pointer in the handle zone, and `EmitJitRoots` 142*795d594fSAndroid Build Coastguard Worker // will compute all the indices. 143*795d594fSAndroid Build Coastguard Worker ScopedArenaSafeMap<ProtoReference, uint64_t, ProtoReferenceValueComparator> 144*795d594fSAndroid Build Coastguard Worker jit_method_type_roots_; 145*795d594fSAndroid Build Coastguard Worker }; 146*795d594fSAndroid Build Coastguard Worker 147*795d594fSAndroid Build Coastguard Worker } // namespace art 148*795d594fSAndroid Build Coastguard Worker 149*795d594fSAndroid Build Coastguard Worker #endif // ART_COMPILER_OPTIMIZING_CODE_GENERATION_DATA_H_ 150