1 /*
2  * Copyright (C) 2011 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_RUNTIME_STACK_H_
18 #define ART_RUNTIME_STACK_H_
19 
20 #include <stdint.h>
21 
22 #include <optional>
23 #include <string>
24 
25 #include "base/locks.h"
26 #include "base/macros.h"
27 #include "deoptimization_kind.h"
28 #include "oat/stack_map.h"
29 #include "obj_ptr.h"
30 #include "quick/quick_method_frame_info.h"
31 
32 namespace art HIDDEN {
33 
34 namespace mirror {
35 class Object;
36 }  // namespace mirror
37 
38 class ArtMethod;
39 class Context;
40 class HandleScope;
41 class OatQuickMethodHeader;
42 class ShadowFrame;
43 class Thread;
44 union JValue;
45 
46 // The kind of vreg being accessed in calls to Set/GetVReg.
47 enum VRegKind {
48   kReferenceVReg,
49   kIntVReg,
50   kFloatVReg,
51   kLongLoVReg,
52   kLongHiVReg,
53   kDoubleLoVReg,
54   kDoubleHiVReg,
55   kConstant,
56   kImpreciseConstant,
57   kUndefined,
58 };
59 std::ostream& operator<<(std::ostream& os, VRegKind rhs);
60 
61 /*
62  * Our current stack layout.
63  * The Dalvik registers come first, followed by the
64  * Method*, followed by other special temporaries if any, followed by
65  * regular compiler temporary. As of now we only have the Method* as
66  * as a special compiler temporary.
67  * A compiler temporary can be thought of as a virtual register that
68  * does not exist in the dex but holds intermediate values to help
69  * optimizations and code generation. A special compiler temporary is
70  * one whose location in frame is well known while non-special ones
71  * do not have a requirement on location in frame as long as code
72  * generator itself knows how to access them.
73  *
74  * TODO: Update this documentation?
75  *
76  *     +-------------------------------+
77  *     | IN[ins-1]                     |  {Note: resides in caller's frame}
78  *     |       .                       |
79  *     | IN[0]                         |
80  *     | caller's ArtMethod            |  ... ArtMethod*
81  *     +===============================+  {Note: start of callee's frame}
82  *     | core callee-save spill        |  {variable sized}
83  *     +-------------------------------+
84  *     | fp callee-save spill          |
85  *     +-------------------------------+
86  *     | filler word                   |  {For compatibility, if V[locals-1] used as wide
87  *     +-------------------------------+
88  *     | V[locals-1]                   |
89  *     | V[locals-2]                   |
90  *     |      .                        |
91  *     |      .                        |  ... (reg == 2)
92  *     | V[1]                          |  ... (reg == 1)
93  *     | V[0]                          |  ... (reg == 0) <---- "locals_start"
94  *     +-------------------------------+
95  *     | stack alignment padding       |  {0 to (kStackAlignWords-1) of padding}
96  *     +-------------------------------+
97  *     | Compiler temp region          |  ... (reg >= max_num_special_temps)
98  *     |      .                        |
99  *     |      .                        |
100  *     | V[max_num_special_temps + 1]  |
101  *     | V[max_num_special_temps + 0]  |
102  *     +-------------------------------+
103  *     | OUT[outs-1]                   |
104  *     | OUT[outs-2]                   |
105  *     |       .                       |
106  *     | OUT[0]                        |
107  *     | ArtMethod*                    |  ... (reg == num_total_code_regs == special_temp_value) <<== sp, 16-byte aligned
108  *     +===============================+
109  */
110 
111 class StackVisitor {
112  public:
113   // This enum defines a flag to control whether inlined frames are included
114   // when walking the stack.
115   enum class StackWalkKind {
116     kIncludeInlinedFrames,
117     kSkipInlinedFrames,
118   };
119 
120  protected:
121   EXPORT StackVisitor(Thread* thread,
122                       Context* context,
123                       StackWalkKind walk_kind,
124                       bool check_suspended = true);
125 
126   bool GetRegisterIfAccessible(uint32_t reg, DexRegisterLocation::Kind kind, uint32_t* val) const
127       REQUIRES_SHARED(Locks::mutator_lock_);
128 
129  public:
~StackVisitor()130   virtual ~StackVisitor() {}
131   StackVisitor(const StackVisitor&) = default;
132   StackVisitor(StackVisitor&&) = default;
133 
134   // Return 'true' if we should continue to visit more frames, 'false' to stop.
135   virtual bool VisitFrame() REQUIRES_SHARED(Locks::mutator_lock_) = 0;
136 
137   enum class EXPORT CountTransitions {
138     kYes,
139     kNo,
140   };
141 
142   template <CountTransitions kCount = CountTransitions::kYes>
143   EXPORT void WalkStack(bool include_transitions = false) REQUIRES_SHARED(Locks::mutator_lock_);
144 
145   // Convenience helper function to walk the stack with a lambda as a visitor.
146   template <CountTransitions kCountTransitions = CountTransitions::kYes,
147             typename T>
148   ALWAYS_INLINE static void WalkStack(const T& fn,
149                                       Thread* thread,
150                                       Context* context,
151                                       StackWalkKind walk_kind,
152                                       bool check_suspended = true,
153                                       bool include_transitions = false)
REQUIRES_SHARED(Locks::mutator_lock_)154       REQUIRES_SHARED(Locks::mutator_lock_) {
155     class LambdaStackVisitor : public StackVisitor {
156      public:
157       LambdaStackVisitor(const T& fn,
158                          Thread* thread,
159                          Context* context,
160                          StackWalkKind walk_kind,
161                          bool check_suspended = true)
162           : StackVisitor(thread, context, walk_kind, check_suspended), fn_(fn) {}
163 
164       bool VisitFrame() override REQUIRES_SHARED(Locks::mutator_lock_) {
165         return fn_(this);
166       }
167 
168      private:
169       T fn_;
170     };
171     LambdaStackVisitor visitor(fn, thread, context, walk_kind, check_suspended);
172     visitor.template WalkStack<kCountTransitions>(include_transitions);
173   }
174 
GetThread()175   Thread* GetThread() const {
176     return thread_;
177   }
178 
179   EXPORT ArtMethod* GetMethod() const REQUIRES_SHARED(Locks::mutator_lock_);
180 
181   // Sets this stack frame's method pointer. This requires a full lock of the MutatorLock. This
182   // doesn't work with inlined methods.
183   EXPORT void SetMethod(ArtMethod* method) REQUIRES(Locks::mutator_lock_);
184 
GetOuterMethod()185   ArtMethod* GetOuterMethod() const {
186     return *GetCurrentQuickFrame();
187   }
188 
IsShadowFrame()189   bool IsShadowFrame() const {
190     return cur_shadow_frame_ != nullptr;
191   }
192 
193   EXPORT uint32_t GetDexPc(bool abort_on_failure = true) const
194       REQUIRES_SHARED(Locks::mutator_lock_);
195 
196   // Returns a vector of the inlined dex pcs, in order from outermost to innermost but it replaces
197   // the innermost one with `handler_dex_pc`. In essence, (outermost dex pc, mid dex pc #1, ..., mid
198   // dex pc #n-1, `handler_dex_pc`).
199   std::vector<uint32_t> ComputeDexPcList(uint32_t handler_dex_pc) const
200       REQUIRES_SHARED(Locks::mutator_lock_);
201 
202   EXPORT ObjPtr<mirror::Object> GetThisObject() const REQUIRES_SHARED(Locks::mutator_lock_);
203 
204   EXPORT size_t GetNativePcOffset() const REQUIRES_SHARED(Locks::mutator_lock_);
205 
206   // Returns the height of the stack in the managed stack frames, including transitions.
GetFrameHeight()207   size_t GetFrameHeight() REQUIRES_SHARED(Locks::mutator_lock_) {
208     return GetNumFrames() - cur_depth_ - 1;
209   }
210 
211   // Returns a frame ID for JDWP use, starting from 1.
GetFrameId()212   size_t GetFrameId() REQUIRES_SHARED(Locks::mutator_lock_) {
213     return GetFrameHeight() + 1;
214   }
215 
GetNumFrames()216   size_t GetNumFrames() REQUIRES_SHARED(Locks::mutator_lock_) {
217     if (num_frames_ == 0) {
218       num_frames_ = ComputeNumFrames(thread_, walk_kind_);
219     }
220     return num_frames_;
221   }
222 
GetFrameDepth()223   size_t GetFrameDepth() const REQUIRES_SHARED(Locks::mutator_lock_) {
224     return cur_depth_;
225   }
226 
227   // Get the method and dex pc immediately after the one that's currently being visited.
228   bool GetNextMethodAndDexPc(ArtMethod** next_method, uint32_t* next_dex_pc)
229       REQUIRES_SHARED(Locks::mutator_lock_);
230 
231   EXPORT bool GetVReg(
232       ArtMethod* m,
233       uint16_t vreg,
234       VRegKind kind,
235       uint32_t* val,
236       std::optional<DexRegisterLocation> location = std::optional<DexRegisterLocation>(),
237       bool need_full_register_list = false) const REQUIRES_SHARED(Locks::mutator_lock_);
238 
239   EXPORT bool GetVRegPair(ArtMethod* m,
240                           uint16_t vreg,
241                           VRegKind kind_lo,
242                           VRegKind kind_hi,
243                           uint64_t* val) const REQUIRES_SHARED(Locks::mutator_lock_);
244 
245   // Values will be set in debugger shadow frames. Debugger will make sure deoptimization
246   // is triggered to make the values effective.
247   EXPORT bool SetVReg(ArtMethod* m, uint16_t vreg, uint32_t new_value, VRegKind kind)
248       REQUIRES_SHARED(Locks::mutator_lock_);
249 
250   // Values will be set in debugger shadow frames. Debugger will make sure deoptimization
251   // is triggered to make the values effective.
252   EXPORT bool SetVRegReference(ArtMethod* m, uint16_t vreg, ObjPtr<mirror::Object> new_value)
253       REQUIRES_SHARED(Locks::mutator_lock_);
254 
255   // Values will be set in debugger shadow frames. Debugger will make sure deoptimization
256   // is triggered to make the values effective.
257   EXPORT bool SetVRegPair(ArtMethod* m,
258                           uint16_t vreg,
259                           uint64_t new_value,
260                           VRegKind kind_lo,
261                           VRegKind kind_hi) REQUIRES_SHARED(Locks::mutator_lock_);
262 
263   uintptr_t* GetGPRAddress(uint32_t reg) const;
264 
265   uintptr_t GetReturnPc() const REQUIRES_SHARED(Locks::mutator_lock_);
266   uintptr_t GetReturnPcAddr() const REQUIRES_SHARED(Locks::mutator_lock_);
267 
268   void SetReturnPc(uintptr_t new_ret_pc) REQUIRES_SHARED(Locks::mutator_lock_);
269 
IsInInlinedFrame()270   bool IsInInlinedFrame() const {
271     return !current_inline_frames_.empty();
272   }
273 
InlineDepth()274   size_t InlineDepth() const { return current_inline_frames_.size(); }
275 
GetCurrentInlinedFrame()276   InlineInfo GetCurrentInlinedFrame() const {
277     return current_inline_frames_.back();
278   }
279 
GetCurrentInlinedFrames()280   const BitTableRange<InlineInfo>& GetCurrentInlinedFrames() const {
281     return current_inline_frames_;
282   }
283 
GetCurrentQuickFramePc()284   uintptr_t GetCurrentQuickFramePc() const {
285     return cur_quick_frame_pc_;
286   }
287 
GetCurrentQuickFrame()288   ArtMethod** GetCurrentQuickFrame() const {
289     return cur_quick_frame_;
290   }
291 
GetCurrentShadowFrame()292   ShadowFrame* GetCurrentShadowFrame() const {
293     return cur_shadow_frame_;
294   }
295 
296   std::string DescribeLocation() const REQUIRES_SHARED(Locks::mutator_lock_);
297 
298   EXPORT static size_t ComputeNumFrames(Thread* thread, StackWalkKind walk_kind)
299       REQUIRES_SHARED(Locks::mutator_lock_);
300 
301   static void DescribeStack(Thread* thread) REQUIRES_SHARED(Locks::mutator_lock_);
302 
GetCurrentOatQuickMethodHeader()303   const OatQuickMethodHeader* GetCurrentOatQuickMethodHeader() const {
304     return cur_oat_quick_method_header_;
305   }
306 
307   QuickMethodFrameInfo GetCurrentQuickFrameInfo() const REQUIRES_SHARED(Locks::mutator_lock_);
308 
SetShouldDeoptimizeFlag(DeoptimizeFlagValue value)309   void SetShouldDeoptimizeFlag(DeoptimizeFlagValue value) REQUIRES_SHARED(Locks::mutator_lock_) {
310     uint8_t* should_deoptimize_addr = GetShouldDeoptimizeFlagAddr();
311     *should_deoptimize_addr = *should_deoptimize_addr | static_cast<uint8_t>(value);
312   };
313 
UnsetShouldDeoptimizeFlag(DeoptimizeFlagValue value)314   void UnsetShouldDeoptimizeFlag(DeoptimizeFlagValue value) REQUIRES_SHARED(Locks::mutator_lock_) {
315     uint8_t* should_deoptimize_addr = GetShouldDeoptimizeFlagAddr();
316     *should_deoptimize_addr = *should_deoptimize_addr & ~static_cast<uint8_t>(value);
317   };
318 
GetShouldDeoptimizeFlag()319   uint8_t GetShouldDeoptimizeFlag() const REQUIRES_SHARED(Locks::mutator_lock_) {
320     return *GetShouldDeoptimizeFlagAddr();
321   }
322 
ShouldForceDeoptForRedefinition()323   bool ShouldForceDeoptForRedefinition() const REQUIRES_SHARED(Locks::mutator_lock_) {
324     uint8_t should_deopt_flag = GetShouldDeoptimizeFlag();
325     return (should_deopt_flag &
326             static_cast<uint8_t>(DeoptimizeFlagValue::kForceDeoptForRedefinition)) != 0;
327   }
328 
329   // Return the number of dex register in the map from the outermost frame to the number of inlined
330   // frames indicated by `depth`. If `depth` is 0, grab just the registers from the outermost level.
331   // If it is greater than 0, grab as many inline frames as `depth` indicates.
332   size_t GetNumberOfRegisters(CodeInfo* code_info, int depth) const;
333 
334  private:
335   // Private constructor known in the case that num_frames_ has already been computed.
336   EXPORT StackVisitor(Thread* thread,
337                       Context* context,
338                       StackWalkKind walk_kind,
339                       size_t num_frames,
340                       bool check_suspended = true) REQUIRES_SHARED(Locks::mutator_lock_);
341 
IsAccessibleRegister(uint32_t reg,bool is_float)342   bool IsAccessibleRegister(uint32_t reg, bool is_float) const {
343     return is_float ? IsAccessibleFPR(reg) : IsAccessibleGPR(reg);
344   }
GetRegister(uint32_t reg,bool is_float)345   uintptr_t GetRegister(uint32_t reg, bool is_float) const {
346     DCHECK(IsAccessibleRegister(reg, is_float));
347     return is_float ? GetFPR(reg) : GetGPR(reg);
348   }
349 
350   bool IsAccessibleGPR(uint32_t reg) const;
351   uintptr_t GetGPR(uint32_t reg) const;
352 
353   bool IsAccessibleFPR(uint32_t reg) const;
354   uintptr_t GetFPR(uint32_t reg) const;
355 
356   bool GetVRegFromDebuggerShadowFrame(uint16_t vreg, VRegKind kind, uint32_t* val) const
357       REQUIRES_SHARED(Locks::mutator_lock_);
358   bool GetVRegFromOptimizedCode(ArtMethod* m,
359                                 uint16_t vreg,
360                                 VRegKind kind,
361                                 uint32_t* val,
362                                 bool need_full_register_list = false) const
363       REQUIRES_SHARED(Locks::mutator_lock_);
364 
365   bool GetVRegPairFromDebuggerShadowFrame(uint16_t vreg,
366                                           VRegKind kind_lo,
367                                           VRegKind kind_hi,
368                                           uint64_t* val) const
369       REQUIRES_SHARED(Locks::mutator_lock_);
370   bool GetVRegPairFromOptimizedCode(ArtMethod* m,
371                                     uint16_t vreg,
372                                     VRegKind kind_lo,
373                                     VRegKind kind_hi,
374                                     uint64_t* val) const
375       REQUIRES_SHARED(Locks::mutator_lock_);
376   bool GetVRegFromOptimizedCode(DexRegisterLocation location, uint32_t* val) const
377       REQUIRES_SHARED(Locks::mutator_lock_);
378 
379   ShadowFrame* PrepareSetVReg(ArtMethod* m, uint16_t vreg, bool wide)
380       REQUIRES_SHARED(Locks::mutator_lock_);
381 
382   void ValidateFrame() const REQUIRES_SHARED(Locks::mutator_lock_);
383 
384   ALWAYS_INLINE CodeInfo* GetCurrentInlineInfo() const;
385   ALWAYS_INLINE StackMap* GetCurrentStackMap() const;
386 
387   Thread* const thread_;
388   const StackWalkKind walk_kind_;
389   ShadowFrame* cur_shadow_frame_;
390   ArtMethod** cur_quick_frame_;
391   uintptr_t cur_quick_frame_pc_;
392   const OatQuickMethodHeader* cur_oat_quick_method_header_;
393   // Lazily computed, number of frames in the stack.
394   size_t num_frames_;
395   // Depth of the frame we're currently at.
396   size_t cur_depth_;
397   // Current inlined frames of the method we are currently at.
398   // We keep poping frames from the end as we visit the frames.
399   BitTableRange<InlineInfo> current_inline_frames_;
400 
401   // Cache the most recently decoded inline info data.
402   // The 'current_inline_frames_' refers to this data, so we need to keep it alive anyway.
403   // Marked mutable since the cache fields are updated from const getters.
404   mutable std::pair<const OatQuickMethodHeader*, CodeInfo> cur_inline_info_;
405   mutable std::pair<uintptr_t, StackMap> cur_stack_map_;
406 
407   uint8_t* GetShouldDeoptimizeFlagAddr() const REQUIRES_SHARED(Locks::mutator_lock_);
408 
409  protected:
410   Context* const context_;
411   const bool check_suspended_;
412 };
413 
414 }  // namespace art
415 
416 #endif  // ART_RUNTIME_STACK_H_
417