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