blob: fd2fd155dab0dfd5819fad4ed4d6fb136d50922e [file] [log] [blame]
Elliott Hughes68e76522011-10-05 13:22:16 -07001/*
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_SRC_STACK_H_
18#define ART_SRC_STACK_H_
19
Ian Rogers6d4d9fc2011-11-30 16:24:48 -080020#include "dex_file.h"
Ian Rogers0399dde2012-06-06 17:09:28 -070021#include "heap.h"
jeffhao725a9572012-11-13 18:20:12 -080022#include "instrumentation.h"
Elliott Hughesbfe487b2011-10-26 15:48:55 -070023#include "jni.h"
Elliott Hughes68e76522011-10-05 13:22:16 -070024#include "macros.h"
Ian Rogers0399dde2012-06-06 17:09:28 -070025#include "oat/runtime/context.h"
Elliott Hughes68e76522011-10-05 13:22:16 -070026
27#include <stdint.h>
28
29namespace art {
30
Mathieu Chartier66f19252012-09-18 08:57:04 -070031class AbstractMethod;
Ian Rogers0399dde2012-06-06 17:09:28 -070032class Object;
33class ShadowFrame;
Elliott Hughes08fc03a2012-06-26 17:34:00 -070034class StackIndirectReferenceTable;
Ian Rogers00f7d0e2012-07-19 15:28:27 -070035class ScopedObjectAccess;
Elliott Hughes68e76522011-10-05 13:22:16 -070036class Thread;
37
Ian Rogers0399dde2012-06-06 17:09:28 -070038class ShadowFrame {
Elliott Hughes68e76522011-10-05 13:22:16 -070039 public:
Ian Rogers2fa6b2e2012-10-17 00:10:17 -070040 static ShadowFrame* Create(uint16_t num_refs, uint16_t num_vregs, ShadowFrame* link,
41 AbstractMethod* method, uint32_t dex_pc) {
42 size_t sz = sizeof(ShadowFrame) + (sizeof(Object*) * num_refs) + (sizeof(uint32_t) * num_vregs);
43 uint8_t* memory = new uint8_t[sz];
44 return new (memory) ShadowFrame(num_refs, num_vregs, link, method, dex_pc);
45 }
46 ~ShadowFrame() {}
47
Ian Rogers0399dde2012-06-06 17:09:28 -070048 uint32_t NumberOfReferences() const {
49 return number_of_references_;
50 }
Elliott Hughes68e76522011-10-05 13:22:16 -070051
Ian Rogers5438ad82012-10-15 17:22:44 -070052 void SetNumberOfReferences(uint16_t number_of_references) {
Ian Rogers0399dde2012-06-06 17:09:28 -070053 number_of_references_ = number_of_references;
54 }
55
Ian Rogers5438ad82012-10-15 17:22:44 -070056 void SetNumberOfVRegs(uint16_t number_of_vregs) {
57 number_of_vregs_ = number_of_vregs;
58 }
59
Ian Rogers0399dde2012-06-06 17:09:28 -070060 uint32_t GetDexPC() const {
61 return dex_pc_;
62 }
63
64 void SetDexPC(uint32_t dex_pc) {
65 dex_pc_ = dex_pc;
66 }
67
Ian Rogers0399dde2012-06-06 17:09:28 -070068 ShadowFrame* GetLink() const {
69 return link_;
70 }
71
72 void SetLink(ShadowFrame* frame) {
73 DCHECK_NE(this, frame);
74 link_ = frame;
75 }
76
77 Object* GetReference(size_t i) const {
78 DCHECK_LT(i, number_of_references_);
79 return references_[i];
80 }
81
82 void SetReference(size_t i, Object* object) {
83 DCHECK_LT(i, number_of_references_);
84 references_[i] = object;
85 }
Elliott Hughes91bf6cd2012-02-14 17:27:48 -080086
Ian Rogers2fa6b2e2012-10-17 00:10:17 -070087 int32_t GetVReg(size_t i) const {
88 DCHECK_LT(i, number_of_vregs_);
89 const int8_t* vregs = reinterpret_cast<const int8_t*>(this) + VRegsOffset();
90 return reinterpret_cast<const int32_t*>(vregs)[i];
91 }
92
93 float GetVRegFloat(size_t i) const {
94 DCHECK_LT(i, number_of_vregs_);
95 const int8_t* vregs = reinterpret_cast<const int8_t*>(this) + VRegsOffset();
96 return reinterpret_cast<const float*>(vregs)[i];
97 }
98
99 int64_t GetVRegLong(size_t i) const {
100 const int8_t* vregs = reinterpret_cast<const int8_t*>(this) + VRegsOffset();
101 const int32_t* low_half = &reinterpret_cast<const int32_t*>(vregs)[i];
102 return *reinterpret_cast<const int64_t*>(low_half);
103 }
104
105 double GetVRegDouble(size_t i) const {
106 const int8_t* vregs = reinterpret_cast<const int8_t*>(this) + VRegsOffset();
107 const int32_t* low_half = &reinterpret_cast<const int32_t*>(vregs)[i];
108 return *reinterpret_cast<const double*>(low_half);
109 }
110
111 void SetVReg(size_t i, int32_t val) {
112 DCHECK_LT(i, number_of_vregs_);
113 int8_t* vregs = reinterpret_cast<int8_t*>(this) + VRegsOffset();
114 reinterpret_cast<int32_t*>(vregs)[i] = val;
115 }
116
117 void SetVRegFloat(size_t i, float val) {
118 DCHECK_LT(i, number_of_vregs_);
119 int8_t* vregs = reinterpret_cast<int8_t*>(this) + VRegsOffset();
120 reinterpret_cast<float*>(vregs)[i] = val;
121 }
122
123 void SetVRegLong(size_t i, int64_t val) {
124 int8_t* vregs = reinterpret_cast<int8_t*>(this) + VRegsOffset();
125 int32_t* low_half = &reinterpret_cast<int32_t*>(vregs)[i];
126 *reinterpret_cast<int64_t*>(low_half) = val;
127 }
128
129 void SetVRegDouble(size_t i, double val) {
130 int8_t* vregs = reinterpret_cast<int8_t*>(this) + VRegsOffset();
131 int32_t* low_half = &reinterpret_cast<int32_t*>(vregs)[i];
132 *reinterpret_cast<double*>(low_half) = val;
133 }
134
135 void SetReferenceAndVReg(size_t i, Object* val) {
136 SetReference(i, val);
137 SetVReg(i, reinterpret_cast<int32_t>(val));
138 }
139
Mathieu Chartier66f19252012-09-18 08:57:04 -0700140 AbstractMethod* GetMethod() const {
Ian Rogers0399dde2012-06-06 17:09:28 -0700141 DCHECK_NE(method_, static_cast<void*>(NULL));
142 return method_;
Elliott Hughes68e76522011-10-05 13:22:16 -0700143 }
144
Mathieu Chartier66f19252012-09-18 08:57:04 -0700145 void SetMethod(AbstractMethod* method) {
Ian Rogers0399dde2012-06-06 17:09:28 -0700146 DCHECK_NE(method, static_cast<void*>(NULL));
147 method_ = method;
Elliott Hughes68e76522011-10-05 13:22:16 -0700148 }
149
Ian Rogers0399dde2012-06-06 17:09:28 -0700150 bool Contains(Object** shadow_frame_entry) const {
151 return ((&references_[0] <= shadow_frame_entry) &&
152 (shadow_frame_entry <= (&references_[number_of_references_ - 1])));
Elliott Hughes68e76522011-10-05 13:22:16 -0700153 }
154
Mathieu Chartier6f1c9492012-10-15 12:08:41 -0700155 template <typename Visitor>
156 void VisitRoots(const Visitor& visitor) {
Ian Rogers0399dde2012-06-06 17:09:28 -0700157 size_t num_refs = NumberOfReferences();
158 for (size_t j = 0; j < num_refs; j++) {
159 Object* object = GetReference(j);
160 if (object != NULL) {
Mathieu Chartier6f1c9492012-10-15 12:08:41 -0700161 visitor(object, j);
Ian Rogers0399dde2012-06-06 17:09:28 -0700162 }
163 }
Elliott Hughes68e76522011-10-05 13:22:16 -0700164 }
165
Ian Rogers0399dde2012-06-06 17:09:28 -0700166 static size_t LinkOffset() {
167 return OFFSETOF_MEMBER(ShadowFrame, link_);
168 }
169
Ian Rogers0399dde2012-06-06 17:09:28 -0700170 static size_t MethodOffset() {
171 return OFFSETOF_MEMBER(ShadowFrame, method_);
172 }
173
Ian Rogers0399dde2012-06-06 17:09:28 -0700174 static size_t DexPCOffset() {
175 return OFFSETOF_MEMBER(ShadowFrame, dex_pc_);
176 }
177
Ian Rogers0399dde2012-06-06 17:09:28 -0700178 static size_t NumberOfReferencesOffset() {
179 return OFFSETOF_MEMBER(ShadowFrame, number_of_references_);
180 }
181
Ian Rogers5438ad82012-10-15 17:22:44 -0700182 static size_t NumberOfVRegsOffset() {
183 return OFFSETOF_MEMBER(ShadowFrame, number_of_vregs_);
184 }
185
Ian Rogers0399dde2012-06-06 17:09:28 -0700186 static size_t ReferencesOffset() {
187 return OFFSETOF_MEMBER(ShadowFrame, references_);
188 }
Elliott Hughes68e76522011-10-05 13:22:16 -0700189
Ian Rogers2fa6b2e2012-10-17 00:10:17 -0700190 size_t VRegsOffset() const {
Ian Rogers5438ad82012-10-15 17:22:44 -0700191 return ReferencesOffset() + (sizeof(Object*) * NumberOfReferences());
192 }
193
Elliott Hughes68e76522011-10-05 13:22:16 -0700194 private:
Ian Rogers2fa6b2e2012-10-17 00:10:17 -0700195 ShadowFrame(uint16_t num_refs, uint16_t num_vregs, ShadowFrame* link, AbstractMethod* method,
196 uint32_t dex_pc)
197 : number_of_references_ (num_refs), number_of_vregs_(num_vregs), link_(link),
198 method_(method), dex_pc_(dex_pc) {
199 for (size_t i = 0; i < num_refs; ++i) {
200 SetReference(i, NULL);
201 }
202 for (size_t i = 0; i < num_vregs; ++i) {
203 SetVReg(i, 0);
204 }
205 }
Elliott Hughes68e76522011-10-05 13:22:16 -0700206
Ian Rogers2fa6b2e2012-10-17 00:10:17 -0700207 // TODO: make the majority of these fields const.
Ian Rogers5438ad82012-10-15 17:22:44 -0700208 uint16_t number_of_references_;
209 uint16_t number_of_vregs_;
210 // Link to previous shadow frame or NULL.
Ian Rogers0399dde2012-06-06 17:09:28 -0700211 ShadowFrame* link_;
Mathieu Chartier66f19252012-09-18 08:57:04 -0700212 AbstractMethod* method_;
Ian Rogers0399dde2012-06-06 17:09:28 -0700213 uint32_t dex_pc_;
Ian Rogers2fa6b2e2012-10-17 00:10:17 -0700214 Object* references_[0];
Elliott Hughes68e76522011-10-05 13:22:16 -0700215
Ian Rogers0399dde2012-06-06 17:09:28 -0700216 DISALLOW_IMPLICIT_CONSTRUCTORS(ShadowFrame);
Elliott Hughes68e76522011-10-05 13:22:16 -0700217};
218
Ian Rogers0399dde2012-06-06 17:09:28 -0700219// The managed stack is used to record fragments of managed code stacks. Managed code stacks
220// may either be shadow frames or lists of frames using fixed frame sizes. Transition records are
221// necessary for transitions between code using different frame layouts and transitions into native
222// code.
223class PACKED ManagedStack {
224 public:
Ian Rogersca190662012-06-26 15:45:57 -0700225 ManagedStack()
226 : link_(NULL), top_shadow_frame_(NULL), top_quick_frame_(NULL), top_quick_frame_pc_(0) {}
Ian Rogers81d425b2012-09-27 16:03:43 -0700227
228 void PushManagedStackFragment(ManagedStack* fragment) {
229 // Copy this top fragment into given fragment.
230 memcpy(fragment, this, sizeof(ManagedStack));
231 // Clear this fragment, which has become the top.
232 memset(this, 0, sizeof(ManagedStack));
233 // Link our top fragment onto the given fragment.
234 link_ = fragment;
235 }
236
237 void PopManagedStackFragment(const ManagedStack& fragment) {
238 DCHECK(&fragment == link_);
239 // Copy this given fragment back to the top.
240 memcpy(this, &fragment, sizeof(ManagedStack));
241 }
Ian Rogers0399dde2012-06-06 17:09:28 -0700242
243 ManagedStack* GetLink() const {
244 return link_;
245 }
246
Mathieu Chartier66f19252012-09-18 08:57:04 -0700247 AbstractMethod** GetTopQuickFrame() const {
Ian Rogers0399dde2012-06-06 17:09:28 -0700248 return top_quick_frame_;
249 }
250
Mathieu Chartier66f19252012-09-18 08:57:04 -0700251 void SetTopQuickFrame(AbstractMethod** top) {
Ian Rogers0399dde2012-06-06 17:09:28 -0700252 top_quick_frame_ = top;
253 }
254
255 uintptr_t GetTopQuickFramePc() const {
256 return top_quick_frame_pc_;
257 }
258
259 void SetTopQuickFramePc(uintptr_t pc) {
260 top_quick_frame_pc_ = pc;
261 }
262
263 static size_t TopQuickFrameOffset() {
264 return OFFSETOF_MEMBER(ManagedStack, top_quick_frame_);
265 }
266
267 static size_t TopQuickFramePcOffset() {
268 return OFFSETOF_MEMBER(ManagedStack, top_quick_frame_pc_);
269 }
270
271 ShadowFrame* PushShadowFrame(ShadowFrame* new_top_frame) {
272 ShadowFrame* old_frame = top_shadow_frame_;
273 top_shadow_frame_ = new_top_frame;
274 new_top_frame->SetLink(old_frame);
275 return old_frame;
276 }
277
278 ShadowFrame* PopShadowFrame() {
279 CHECK(top_shadow_frame_ != NULL);
280 ShadowFrame* frame = top_shadow_frame_;
281 top_shadow_frame_ = frame->GetLink();
282 return frame;
283 }
284
285 ShadowFrame* GetTopShadowFrame() const {
286 return top_shadow_frame_;
287 }
288
289 static size_t TopShadowFrameOffset() {
290 return OFFSETOF_MEMBER(ManagedStack, top_shadow_frame_);
291 }
292
293 size_t NumShadowFrameReferences() const;
294
295 bool ShadowFramesContain(Object** shadow_frame_entry) const;
296
297 private:
298 ManagedStack* link_;
299 ShadowFrame* top_shadow_frame_;
Mathieu Chartier66f19252012-09-18 08:57:04 -0700300 AbstractMethod** top_quick_frame_;
Ian Rogers0399dde2012-06-06 17:09:28 -0700301 uintptr_t top_quick_frame_pc_;
302};
303
304class StackVisitor {
305 protected:
jeffhao725a9572012-11-13 18:20:12 -0800306 StackVisitor(const ManagedStack* stack, const std::vector<InstrumentationStackFrame>* instrumentation_stack,
Elliott Hughes08fc03a2012-06-26 17:34:00 -0700307 Context* context)
Ian Rogersb726dcb2012-09-05 08:57:23 -0700308 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_)
jeffhao725a9572012-11-13 18:20:12 -0800309 : stack_start_(stack), instrumentation_stack_(instrumentation_stack), cur_shadow_frame_(NULL),
Ian Rogersca190662012-06-26 15:45:57 -0700310 cur_quick_frame_(NULL), cur_quick_frame_pc_(0), num_frames_(0), cur_depth_(0),
311 context_(context) {}
Ian Rogers0399dde2012-06-06 17:09:28 -0700312
313 public:
314 virtual ~StackVisitor() {}
315
316 // Return 'true' if we should continue to visit more frames, 'false' to stop.
Ian Rogersb726dcb2012-09-05 08:57:23 -0700317 virtual bool VisitFrame() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) = 0;
Ian Rogers0399dde2012-06-06 17:09:28 -0700318
Ian Rogers00f7d0e2012-07-19 15:28:27 -0700319 void WalkStack(bool include_transitions = false)
Ian Rogersb726dcb2012-09-05 08:57:23 -0700320 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
Ian Rogers0399dde2012-06-06 17:09:28 -0700321
Mathieu Chartier66f19252012-09-18 08:57:04 -0700322 AbstractMethod* GetMethod() const {
Ian Rogers0399dde2012-06-06 17:09:28 -0700323 if (cur_shadow_frame_ != NULL) {
324 return cur_shadow_frame_->GetMethod();
325 } else if (cur_quick_frame_ != NULL) {
326 return *cur_quick_frame_;
327 } else {
328 return NULL;
329 }
330 }
331
332 bool IsShadowFrame() const {
333 return cur_shadow_frame_ != NULL;
334 }
335
Ian Rogers0c7abda2012-09-19 13:33:42 -0700336 uint32_t GetDexPc() const SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
337
338 size_t GetNativePcOffset() const SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
339
Ian Rogers0399dde2012-06-06 17:09:28 -0700340 uintptr_t LoadCalleeSave(int num, size_t frame_size) const {
341 // Callee saves are held at the top of the frame
Mathieu Chartier66f19252012-09-18 08:57:04 -0700342 AbstractMethod* method = GetMethod();
Ian Rogers0399dde2012-06-06 17:09:28 -0700343 DCHECK(method != NULL);
344 byte* save_addr =
345 reinterpret_cast<byte*>(cur_quick_frame_) + frame_size - ((num + 1) * kPointerSize);
346#if defined(__i386__)
347 save_addr -= kPointerSize; // account for return address
348#endif
349 return *reinterpret_cast<uintptr_t*>(save_addr);
350 }
351
Elliott Hughes08fc03a2012-06-26 17:34:00 -0700352 // Returns the height of the stack in the managed stack frames, including transitions.
Ian Rogersb726dcb2012-09-05 08:57:23 -0700353 size_t GetFrameHeight() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
Ian Rogers0399dde2012-06-06 17:09:28 -0700354 return GetNumFrames() - cur_depth_;
355 }
356
Elliott Hughes08fc03a2012-06-26 17:34:00 -0700357 // Returns a frame ID for JDWP use, starting from 1.
Ian Rogersb726dcb2012-09-05 08:57:23 -0700358 size_t GetFrameId() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
Ian Rogers0399dde2012-06-06 17:09:28 -0700359 return GetFrameHeight() + 1;
360 }
361
Ian Rogersb726dcb2012-09-05 08:57:23 -0700362 size_t GetNumFrames() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
Ian Rogers0399dde2012-06-06 17:09:28 -0700363 if (num_frames_ == 0) {
364 num_frames_ = ComputeNumFrames();
365 }
366 return num_frames_;
367 }
368
Mathieu Chartier66f19252012-09-18 08:57:04 -0700369 uint32_t GetVReg(AbstractMethod* m, int vreg) const SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
Ian Rogers0399dde2012-06-06 17:09:28 -0700370
Mathieu Chartier66f19252012-09-18 08:57:04 -0700371 void SetVReg(AbstractMethod* m, int vreg, uint32_t new_value)
Ian Rogersb726dcb2012-09-05 08:57:23 -0700372 SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
Ian Rogers0399dde2012-06-06 17:09:28 -0700373
374 uintptr_t GetGPR(uint32_t reg) const;
375
Mathieu Chartier66f19252012-09-18 08:57:04 -0700376 uint32_t GetVReg(AbstractMethod** cur_quick_frame, const DexFile::CodeItem* code_item,
Ian Rogers0ec569a2012-07-01 16:43:46 -0700377 uint32_t core_spills, uint32_t fp_spills, size_t frame_size, int vreg) const {
Ian Rogers0399dde2012-06-06 17:09:28 -0700378 int offset = GetVRegOffset(code_item, core_spills, fp_spills, frame_size, vreg);
Ian Rogers0ec569a2012-07-01 16:43:46 -0700379 DCHECK_EQ(cur_quick_frame, GetCurrentQuickFrame());
380 byte* vreg_addr = reinterpret_cast<byte*>(cur_quick_frame) + offset;
Ian Rogers0399dde2012-06-06 17:09:28 -0700381 return *reinterpret_cast<uint32_t*>(vreg_addr);
382 }
383
384 uintptr_t GetReturnPc() const;
385
386 void SetReturnPc(uintptr_t new_ret_pc);
387
388 /*
389 * Return sp-relative offset for a Dalvik virtual register, compiler
390 * spill or Method* in bytes using Method*.
391 * Note that (reg >= 0) refers to a Dalvik register, (reg == -2)
392 * denotes Method* and (reg <= -3) denotes a compiler temp.
393 *
394 * +------------------------+
395 * | IN[ins-1] | {Note: resides in caller's frame}
396 * | . |
397 * | IN[0] |
398 * | caller's Method* |
399 * +========================+ {Note: start of callee's frame}
400 * | core callee-save spill | {variable sized}
401 * +------------------------+
402 * | fp callee-save spill |
403 * +------------------------+
404 * | filler word | {For compatibility, if V[locals-1] used as wide
405 * +------------------------+
406 * | V[locals-1] |
407 * | V[locals-2] |
408 * | . |
409 * | . | ... (reg == 2)
410 * | V[1] | ... (reg == 1)
411 * | V[0] | ... (reg == 0) <---- "locals_start"
412 * +------------------------+
413 * | Compiler temps | ... (reg == -2)
414 * | | ... (reg == -3)
415 * | | ... (reg == -4)
416 * +------------------------+
417 * | stack alignment padding| {0 to (kStackAlignWords-1) of padding}
418 * +------------------------+
419 * | OUT[outs-1] |
420 * | OUT[outs-2] |
421 * | . |
422 * | OUT[0] |
423 * | curMethod* | ... (reg == -1) <<== sp, 16-byte aligned
424 * +========================+
425 */
426 static int GetVRegOffset(const DexFile::CodeItem* code_item,
Ian Rogersb23a7722012-10-09 16:54:26 -0700427 uint32_t core_spills, uint32_t fp_spills,
428 size_t frame_size, int reg) {
Ian Rogers0399dde2012-06-06 17:09:28 -0700429 DCHECK_EQ(frame_size & (kStackAlignment - 1), 0U);
430 int num_spills = __builtin_popcount(core_spills) + __builtin_popcount(fp_spills) + 1; // Filler.
431 int num_ins = code_item->ins_size_;
432 int num_regs = code_item->registers_size_ - num_ins;
433 int locals_start = frame_size - ((num_spills + num_regs) * sizeof(uint32_t));
434 if (reg == -2) {
435 return 0; // Method*
436 } else if (reg <= -3) {
437 return locals_start - ((reg + 1) * sizeof(uint32_t)); // Compiler temp.
438 } else if (reg < num_regs) {
439 return locals_start + (reg * sizeof(uint32_t)); // Dalvik local reg.
440 } else {
441 return frame_size + ((reg - num_regs) * sizeof(uint32_t)) + sizeof(uint32_t); // Dalvik in.
442 }
443 }
444
445 uintptr_t GetCurrentQuickFramePc() const {
446 return cur_quick_frame_pc_;
447 }
448
Mathieu Chartier66f19252012-09-18 08:57:04 -0700449 AbstractMethod** GetCurrentQuickFrame() const {
Ian Rogers0399dde2012-06-06 17:09:28 -0700450 return cur_quick_frame_;
451 }
452
453 ShadowFrame* GetCurrentShadowFrame() const {
454 return cur_shadow_frame_;
455 }
456
Elliott Hughes08fc03a2012-06-26 17:34:00 -0700457 StackIndirectReferenceTable* GetCurrentSirt() const {
Mathieu Chartier66f19252012-09-18 08:57:04 -0700458 AbstractMethod** sp = GetCurrentQuickFrame();
Elliott Hughes08fc03a2012-06-26 17:34:00 -0700459 ++sp; // Skip Method*; SIRT comes next;
460 return reinterpret_cast<StackIndirectReferenceTable*>(sp);
461 }
462
Ian Rogers0399dde2012-06-06 17:09:28 -0700463 private:
Ian Rogersb726dcb2012-09-05 08:57:23 -0700464 size_t ComputeNumFrames() const SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
Ian Rogers0399dde2012-06-06 17:09:28 -0700465
jeffhao725a9572012-11-13 18:20:12 -0800466 InstrumentationStackFrame GetInstrumentationStackFrame(uint32_t depth) const {
467 return instrumentation_stack_->at(instrumentation_stack_->size() - depth - 1);
Ian Rogers0399dde2012-06-06 17:09:28 -0700468 }
469
Ian Rogersb726dcb2012-09-05 08:57:23 -0700470 void SanityCheckFrame() const SHARED_LOCKS_REQUIRED(Locks::mutator_lock_);
Ian Rogers0399dde2012-06-06 17:09:28 -0700471
472 const ManagedStack* const stack_start_;
jeffhao725a9572012-11-13 18:20:12 -0800473 const std::vector<InstrumentationStackFrame>* const instrumentation_stack_;
Ian Rogers0399dde2012-06-06 17:09:28 -0700474 ShadowFrame* cur_shadow_frame_;
Mathieu Chartier66f19252012-09-18 08:57:04 -0700475 AbstractMethod** cur_quick_frame_;
Ian Rogers0399dde2012-06-06 17:09:28 -0700476 uintptr_t cur_quick_frame_pc_;
477 // Lazily computed, number of frames in the stack.
478 size_t num_frames_;
479 // Depth of the frame we're currently at.
480 size_t cur_depth_;
481 protected:
482 Context* const context_;
483};
484
Elliott Hughes68e76522011-10-05 13:22:16 -0700485} // namespace art
486
487#endif // ART_SRC_STACK_H_