xref: /aosp_15_r20/art/compiler/optimizing/stack_map_stream.h (revision 795d594fd825385562da6b089ea9b2033f3abf5a)
1*795d594fSAndroid Build Coastguard Worker /*
2*795d594fSAndroid Build Coastguard Worker  * Copyright (C) 2014 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_STACK_MAP_STREAM_H_
18*795d594fSAndroid Build Coastguard Worker #define ART_COMPILER_OPTIMIZING_STACK_MAP_STREAM_H_
19*795d594fSAndroid Build Coastguard Worker 
20*795d594fSAndroid Build Coastguard Worker #include "base/allocator.h"
21*795d594fSAndroid Build Coastguard Worker #include "base/arena_bit_vector.h"
22*795d594fSAndroid Build Coastguard Worker #include "base/bit_table.h"
23*795d594fSAndroid Build Coastguard Worker #include "base/bit_vector-inl.h"
24*795d594fSAndroid Build Coastguard Worker #include "base/macros.h"
25*795d594fSAndroid Build Coastguard Worker #include "base/memory_region.h"
26*795d594fSAndroid Build Coastguard Worker #include "base/scoped_arena_containers.h"
27*795d594fSAndroid Build Coastguard Worker #include "base/value_object.h"
28*795d594fSAndroid Build Coastguard Worker #include "dex_register_location.h"
29*795d594fSAndroid Build Coastguard Worker #include "nodes.h"
30*795d594fSAndroid Build Coastguard Worker #include "oat/stack_map.h"
31*795d594fSAndroid Build Coastguard Worker 
32*795d594fSAndroid Build Coastguard Worker namespace art HIDDEN {
33*795d594fSAndroid Build Coastguard Worker 
34*795d594fSAndroid Build Coastguard Worker class CodeGenerator;
35*795d594fSAndroid Build Coastguard Worker 
36*795d594fSAndroid Build Coastguard Worker /**
37*795d594fSAndroid Build Coastguard Worker  * Collects and builds stack maps for a method. All the stack maps
38*795d594fSAndroid Build Coastguard Worker  * for a method are placed in a CodeInfo object.
39*795d594fSAndroid Build Coastguard Worker  */
40*795d594fSAndroid Build Coastguard Worker class StackMapStream : public DeletableArenaObject<kArenaAllocStackMapStream> {
41*795d594fSAndroid Build Coastguard Worker  public:
StackMapStream(ScopedArenaAllocator * allocator,InstructionSet instruction_set)42*795d594fSAndroid Build Coastguard Worker   explicit StackMapStream(ScopedArenaAllocator* allocator, InstructionSet instruction_set)
43*795d594fSAndroid Build Coastguard Worker       : allocator_(allocator),
44*795d594fSAndroid Build Coastguard Worker         instruction_set_(instruction_set),
45*795d594fSAndroid Build Coastguard Worker         stack_maps_(allocator),
46*795d594fSAndroid Build Coastguard Worker         register_masks_(allocator),
47*795d594fSAndroid Build Coastguard Worker         stack_masks_(allocator),
48*795d594fSAndroid Build Coastguard Worker         inline_infos_(allocator),
49*795d594fSAndroid Build Coastguard Worker         method_infos_(allocator),
50*795d594fSAndroid Build Coastguard Worker         dex_register_masks_(allocator),
51*795d594fSAndroid Build Coastguard Worker         dex_register_maps_(allocator),
52*795d594fSAndroid Build Coastguard Worker         dex_register_catalog_(allocator),
53*795d594fSAndroid Build Coastguard Worker         lazy_stack_masks_(allocator->Adapter(kArenaAllocStackMapStream)),
54*795d594fSAndroid Build Coastguard Worker         current_stack_map_(),
55*795d594fSAndroid Build Coastguard Worker         current_inline_infos_(allocator->Adapter(kArenaAllocStackMapStream)),
56*795d594fSAndroid Build Coastguard Worker         current_dex_registers_(allocator->Adapter(kArenaAllocStackMapStream)),
57*795d594fSAndroid Build Coastguard Worker         previous_dex_registers_(allocator->Adapter(kArenaAllocStackMapStream)),
58*795d594fSAndroid Build Coastguard Worker         dex_register_timestamp_(allocator->Adapter(kArenaAllocStackMapStream)),
59*795d594fSAndroid Build Coastguard Worker         expected_num_dex_registers_(0u),
60*795d594fSAndroid Build Coastguard Worker         temp_dex_register_mask_(allocator, 32, true, kArenaAllocStackMapStream),
61*795d594fSAndroid Build Coastguard Worker         temp_dex_register_map_(allocator->Adapter(kArenaAllocStackMapStream)) {
62*795d594fSAndroid Build Coastguard Worker   }
63*795d594fSAndroid Build Coastguard Worker 
64*795d594fSAndroid Build Coastguard Worker   void BeginMethod(size_t frame_size_in_bytes,
65*795d594fSAndroid Build Coastguard Worker                    size_t core_spill_mask,
66*795d594fSAndroid Build Coastguard Worker                    size_t fp_spill_mask,
67*795d594fSAndroid Build Coastguard Worker                    uint32_t num_dex_registers,
68*795d594fSAndroid Build Coastguard Worker                    bool baseline,
69*795d594fSAndroid Build Coastguard Worker                    bool debuggable,
70*795d594fSAndroid Build Coastguard Worker                    bool has_should_deoptimize_flag = false);
71*795d594fSAndroid Build Coastguard Worker   void EndMethod(size_t code_size);
72*795d594fSAndroid Build Coastguard Worker 
73*795d594fSAndroid Build Coastguard Worker   void BeginStackMapEntry(
74*795d594fSAndroid Build Coastguard Worker       uint32_t dex_pc,
75*795d594fSAndroid Build Coastguard Worker       uint32_t native_pc_offset,
76*795d594fSAndroid Build Coastguard Worker       uint32_t register_mask = 0,
77*795d594fSAndroid Build Coastguard Worker       BitVector* sp_mask = nullptr,
78*795d594fSAndroid Build Coastguard Worker       StackMap::Kind kind = StackMap::Kind::Default,
79*795d594fSAndroid Build Coastguard Worker       bool needs_vreg_info = true,
80*795d594fSAndroid Build Coastguard Worker       const std::vector<uint32_t>& dex_pc_list_for_catch_verification = std::vector<uint32_t>());
81*795d594fSAndroid Build Coastguard Worker 
82*795d594fSAndroid Build Coastguard Worker   void EndStackMapEntry();
83*795d594fSAndroid Build Coastguard Worker 
AddDexRegisterEntry(DexRegisterLocation::Kind kind,int32_t value)84*795d594fSAndroid Build Coastguard Worker   void AddDexRegisterEntry(DexRegisterLocation::Kind kind, int32_t value) {
85*795d594fSAndroid Build Coastguard Worker     current_dex_registers_.push_back(DexRegisterLocation(kind, value));
86*795d594fSAndroid Build Coastguard Worker   }
87*795d594fSAndroid Build Coastguard Worker 
88*795d594fSAndroid Build Coastguard Worker   void BeginInlineInfoEntry(ArtMethod* method,
89*795d594fSAndroid Build Coastguard Worker                             uint32_t dex_pc,
90*795d594fSAndroid Build Coastguard Worker                             uint32_t num_dex_registers,
91*795d594fSAndroid Build Coastguard Worker                             const DexFile* outer_dex_file = nullptr,
92*795d594fSAndroid Build Coastguard Worker                             const CodeGenerator* codegen = nullptr);
93*795d594fSAndroid Build Coastguard Worker   void EndInlineInfoEntry();
94*795d594fSAndroid Build Coastguard Worker 
GetNumberOfStackMaps()95*795d594fSAndroid Build Coastguard Worker   size_t GetNumberOfStackMaps() const {
96*795d594fSAndroid Build Coastguard Worker     return stack_maps_.size();
97*795d594fSAndroid Build Coastguard Worker   }
98*795d594fSAndroid Build Coastguard Worker 
99*795d594fSAndroid Build Coastguard Worker   uint32_t GetStackMapNativePcOffset(size_t i);
100*795d594fSAndroid Build Coastguard Worker   void SetStackMapNativePcOffset(size_t i, uint32_t native_pc_offset);
101*795d594fSAndroid Build Coastguard Worker 
102*795d594fSAndroid Build Coastguard Worker   // Encode all stack map data.
103*795d594fSAndroid Build Coastguard Worker   // The returned vector is allocated using the allocator passed to the StackMapStream.
104*795d594fSAndroid Build Coastguard Worker   ScopedArenaVector<uint8_t> Encode();
105*795d594fSAndroid Build Coastguard Worker 
106*795d594fSAndroid Build Coastguard Worker  private:
107*795d594fSAndroid Build Coastguard Worker   static constexpr uint32_t kNoValue = -1;
108*795d594fSAndroid Build Coastguard Worker 
109*795d594fSAndroid Build Coastguard Worker   void CreateDexRegisterMap();
110*795d594fSAndroid Build Coastguard Worker 
111*795d594fSAndroid Build Coastguard Worker   // Invokes the callback with pointer of each BitTableBuilder field.
112*795d594fSAndroid Build Coastguard Worker   template<typename Callback>
ForEachBitTable(Callback && callback)113*795d594fSAndroid Build Coastguard Worker   void ForEachBitTable(Callback&& callback) {
114*795d594fSAndroid Build Coastguard Worker     size_t index = 0;
115*795d594fSAndroid Build Coastguard Worker     callback(index++, &stack_maps_);
116*795d594fSAndroid Build Coastguard Worker     callback(index++, &register_masks_);
117*795d594fSAndroid Build Coastguard Worker     callback(index++, &stack_masks_);
118*795d594fSAndroid Build Coastguard Worker     callback(index++, &inline_infos_);
119*795d594fSAndroid Build Coastguard Worker     callback(index++, &method_infos_);
120*795d594fSAndroid Build Coastguard Worker     callback(index++, &dex_register_masks_);
121*795d594fSAndroid Build Coastguard Worker     callback(index++, &dex_register_maps_);
122*795d594fSAndroid Build Coastguard Worker     callback(index++, &dex_register_catalog_);
123*795d594fSAndroid Build Coastguard Worker     CHECK_EQ(index, CodeInfo::kNumBitTables);
124*795d594fSAndroid Build Coastguard Worker   }
125*795d594fSAndroid Build Coastguard Worker 
126*795d594fSAndroid Build Coastguard Worker   ScopedArenaAllocator* allocator_;
127*795d594fSAndroid Build Coastguard Worker   const InstructionSet instruction_set_;
128*795d594fSAndroid Build Coastguard Worker   uint32_t code_size_ = 0;
129*795d594fSAndroid Build Coastguard Worker   uint32_t packed_frame_size_ = 0;
130*795d594fSAndroid Build Coastguard Worker   uint32_t core_spill_mask_ = 0;
131*795d594fSAndroid Build Coastguard Worker   uint32_t fp_spill_mask_ = 0;
132*795d594fSAndroid Build Coastguard Worker   uint32_t num_dex_registers_ = 0;
133*795d594fSAndroid Build Coastguard Worker   bool baseline_ = false;
134*795d594fSAndroid Build Coastguard Worker   bool debuggable_ = false;
135*795d594fSAndroid Build Coastguard Worker   bool has_should_deoptimize_flag_ = false;
136*795d594fSAndroid Build Coastguard Worker   BitTableBuilder<StackMap> stack_maps_;
137*795d594fSAndroid Build Coastguard Worker   BitTableBuilder<RegisterMask> register_masks_;
138*795d594fSAndroid Build Coastguard Worker   BitmapTableBuilder stack_masks_;
139*795d594fSAndroid Build Coastguard Worker   BitTableBuilder<InlineInfo> inline_infos_;
140*795d594fSAndroid Build Coastguard Worker   BitTableBuilder<MethodInfo> method_infos_;
141*795d594fSAndroid Build Coastguard Worker   BitmapTableBuilder dex_register_masks_;
142*795d594fSAndroid Build Coastguard Worker   BitTableBuilder<DexRegisterMapInfo> dex_register_maps_;
143*795d594fSAndroid Build Coastguard Worker   BitTableBuilder<DexRegisterInfo> dex_register_catalog_;
144*795d594fSAndroid Build Coastguard Worker 
145*795d594fSAndroid Build Coastguard Worker   ScopedArenaVector<BitVector*> lazy_stack_masks_;
146*795d594fSAndroid Build Coastguard Worker 
147*795d594fSAndroid Build Coastguard Worker   // Variables which track the current state between Begin/End calls;
148*795d594fSAndroid Build Coastguard Worker   bool in_method_ = false;
149*795d594fSAndroid Build Coastguard Worker   bool in_stack_map_ = false;
150*795d594fSAndroid Build Coastguard Worker   bool in_inline_info_ = false;
151*795d594fSAndroid Build Coastguard Worker   BitTableBuilder<StackMap>::Entry current_stack_map_;
152*795d594fSAndroid Build Coastguard Worker   ScopedArenaVector<BitTableBuilder<InlineInfo>::Entry> current_inline_infos_;
153*795d594fSAndroid Build Coastguard Worker   ScopedArenaVector<DexRegisterLocation> current_dex_registers_;
154*795d594fSAndroid Build Coastguard Worker   ScopedArenaVector<DexRegisterLocation> previous_dex_registers_;
155*795d594fSAndroid Build Coastguard Worker   ScopedArenaVector<uint32_t> dex_register_timestamp_;  // Stack map index of last change.
156*795d594fSAndroid Build Coastguard Worker   size_t expected_num_dex_registers_;
157*795d594fSAndroid Build Coastguard Worker 
158*795d594fSAndroid Build Coastguard Worker   // Temporary variables used in CreateDexRegisterMap.
159*795d594fSAndroid Build Coastguard Worker   // They are here so that we can reuse the reserved memory.
160*795d594fSAndroid Build Coastguard Worker   ArenaBitVector temp_dex_register_mask_;
161*795d594fSAndroid Build Coastguard Worker   ScopedArenaVector<BitTableBuilder<DexRegisterMapInfo>::Entry> temp_dex_register_map_;
162*795d594fSAndroid Build Coastguard Worker 
163*795d594fSAndroid Build Coastguard Worker   // A set of lambda functions to be executed at the end to verify
164*795d594fSAndroid Build Coastguard Worker   // the encoded data. It is generally only used in debug builds.
165*795d594fSAndroid Build Coastguard Worker   std::vector<std::function<void(CodeInfo&)>> dchecks_;
166*795d594fSAndroid Build Coastguard Worker 
167*795d594fSAndroid Build Coastguard Worker   DISALLOW_COPY_AND_ASSIGN(StackMapStream);
168*795d594fSAndroid Build Coastguard Worker };
169*795d594fSAndroid Build Coastguard Worker 
170*795d594fSAndroid Build Coastguard Worker }  // namespace art
171*795d594fSAndroid Build Coastguard Worker 
172*795d594fSAndroid Build Coastguard Worker #endif  // ART_COMPILER_OPTIMIZING_STACK_MAP_STREAM_H_
173