xref: /aosp_15_r20/art/compiler/optimizing/code_generation_data.h (revision 795d594fd825385562da6b089ea9b2033f3abf5a)
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