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/string_reference.h" 27 #include "dex/type_reference.h" 28 #include "handle.h" 29 #include "mirror/class.h" 30 #include "mirror/object.h" 31 #include "mirror/string.h" 32 #include "stack_map_stream.h" 33 34 namespace art HIDDEN { 35 36 class CodeGenerationData : public DeletableArenaObject<kArenaAllocCodeGenerator> { 37 public: Create(ArenaStack * arena_stack,InstructionSet instruction_set)38 static std::unique_ptr<CodeGenerationData> Create(ArenaStack* arena_stack, 39 InstructionSet instruction_set) { 40 ScopedArenaAllocator allocator(arena_stack); 41 void* memory = allocator.Alloc<CodeGenerationData>(kArenaAllocCodeGenerator); 42 return std::unique_ptr<CodeGenerationData>( 43 ::new (memory) CodeGenerationData(std::move(allocator), instruction_set)); 44 } 45 GetScopedAllocator()46 ScopedArenaAllocator* GetScopedAllocator() { 47 return &allocator_; 48 } 49 AddSlowPath(SlowPathCode * slow_path)50 void AddSlowPath(SlowPathCode* slow_path) { 51 slow_paths_.emplace_back(std::unique_ptr<SlowPathCode>(slow_path)); 52 } 53 GetSlowPaths()54 ArrayRef<const std::unique_ptr<SlowPathCode>> GetSlowPaths() const { 55 return ArrayRef<const std::unique_ptr<SlowPathCode>>(slow_paths_); 56 } 57 GetStackMapStream()58 StackMapStream* GetStackMapStream() { return &stack_map_stream_; } 59 ReserveJitStringRoot(StringReference string_reference,Handle<mirror::String> string)60 void ReserveJitStringRoot(StringReference string_reference, Handle<mirror::String> string) { 61 jit_string_roots_.Overwrite(string_reference, 62 reinterpret_cast64<uint64_t>(string.GetReference())); 63 } 64 GetJitStringRootIndex(StringReference string_reference)65 uint64_t GetJitStringRootIndex(StringReference string_reference) const { 66 return jit_string_roots_.Get(string_reference); 67 } 68 GetNumberOfJitStringRoots()69 size_t GetNumberOfJitStringRoots() const { 70 return jit_string_roots_.size(); 71 } 72 ReserveJitClassRoot(TypeReference type_reference,Handle<mirror::Class> klass)73 void ReserveJitClassRoot(TypeReference type_reference, Handle<mirror::Class> klass) { 74 jit_class_roots_.Overwrite(type_reference, reinterpret_cast64<uint64_t>(klass.GetReference())); 75 } 76 GetJitClassRootIndex(TypeReference type_reference)77 uint64_t GetJitClassRootIndex(TypeReference type_reference) const { 78 return jit_class_roots_.Get(type_reference); 79 } 80 GetNumberOfJitClassRoots()81 size_t GetNumberOfJitClassRoots() const { 82 return jit_class_roots_.size(); 83 } 84 GetNumberOfJitRoots()85 size_t GetNumberOfJitRoots() const { 86 return GetNumberOfJitStringRoots() + GetNumberOfJitClassRoots(); 87 } 88 89 void EmitJitRoots(/*out*/std::vector<Handle<mirror::Object>>* roots) 90 REQUIRES_SHARED(Locks::mutator_lock_); 91 92 private: CodeGenerationData(ScopedArenaAllocator && allocator,InstructionSet instruction_set)93 CodeGenerationData(ScopedArenaAllocator&& allocator, InstructionSet instruction_set) 94 : allocator_(std::move(allocator)), 95 stack_map_stream_(&allocator_, instruction_set), 96 slow_paths_(allocator_.Adapter(kArenaAllocCodeGenerator)), 97 jit_string_roots_(StringReferenceValueComparator(), 98 allocator_.Adapter(kArenaAllocCodeGenerator)), 99 jit_class_roots_(TypeReferenceValueComparator(), 100 allocator_.Adapter(kArenaAllocCodeGenerator)) { 101 slow_paths_.reserve(kDefaultSlowPathsCapacity); 102 } 103 104 static constexpr size_t kDefaultSlowPathsCapacity = 8; 105 106 ScopedArenaAllocator allocator_; 107 StackMapStream stack_map_stream_; 108 ScopedArenaVector<std::unique_ptr<SlowPathCode>> slow_paths_; 109 110 // Maps a StringReference (dex_file, string_index) to the index in the literal table. 111 // Entries are initially added with a pointer in the handle zone, and `EmitJitRoots` 112 // will compute all the indices. 113 ScopedArenaSafeMap<StringReference, uint64_t, StringReferenceValueComparator> jit_string_roots_; 114 115 // Maps a ClassReference (dex_file, type_index) to the index in the literal table. 116 // Entries are initially added with a pointer in the handle zone, and `EmitJitRoots` 117 // will compute all the indices. 118 ScopedArenaSafeMap<TypeReference, uint64_t, TypeReferenceValueComparator> jit_class_roots_; 119 }; 120 121 } // namespace art 122 123 #endif // ART_COMPILER_OPTIMIZING_CODE_GENERATION_DATA_H_ 124