blob: 4163d6f82e379dd3efe256c23d4a378f110fbe78 [file] [log] [blame]
Ben Murdoch3ef787d2012-04-12 10:51:47 +01001// Copyright 2012 the V8 project authors. All rights reserved.
Ben Murdochb8a8cc12014-11-26 15:28:44 +00002// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
Steve Blocka7e24c12009-10-30 11:49:00 +00004
5#ifndef V8_FRAMES_H_
6#define V8_FRAMES_H_
7
Ben Murdochb8a8cc12014-11-26 15:28:44 +00008#include "src/allocation.h"
9#include "src/handles.h"
10#include "src/safepoint-table.h"
Ben Murdochb8e0da22011-05-16 14:20:40 +010011
Steve Blocka7e24c12009-10-30 11:49:00 +000012namespace v8 {
13namespace internal {
14
Ben Murdochb8a8cc12014-11-26 15:28:44 +000015#if V8_TARGET_ARCH_ARM64
16typedef uint64_t RegList;
17#else
Steve Blocka7e24c12009-10-30 11:49:00 +000018typedef uint32_t RegList;
Ben Murdochb8a8cc12014-11-26 15:28:44 +000019#endif
Steve Blocka7e24c12009-10-30 11:49:00 +000020
21// Get the number of registers in a given register list.
22int NumRegs(RegList list);
23
Ben Murdochb8a8cc12014-11-26 15:28:44 +000024void SetUpJSCallerSavedCodeData();
25
Steve Blocka7e24c12009-10-30 11:49:00 +000026// Return the code of the n-th saved register available to JavaScript.
27int JSCallerSavedCode(int n);
28
29
30// Forward declarations.
Ben Murdochb8a8cc12014-11-26 15:28:44 +000031class ExternalCallbackScope;
32class StackFrameIteratorBase;
Steve Blocka7e24c12009-10-30 11:49:00 +000033class ThreadLocalTop;
Steve Block44f0eee2011-05-26 01:26:41 +010034class Isolate;
Steve Blocka7e24c12009-10-30 11:49:00 +000035
Ben Murdoch3ef787d2012-04-12 10:51:47 +010036class InnerPointerToCodeCache {
Kristian Monsen80d68ea2010-09-08 11:05:35 +010037 public:
Ben Murdoch3ef787d2012-04-12 10:51:47 +010038 struct InnerPointerToCodeCacheEntry {
39 Address inner_pointer;
Kristian Monsen80d68ea2010-09-08 11:05:35 +010040 Code* code;
Ben Murdochb8e0da22011-05-16 14:20:40 +010041 SafepointEntry safepoint_entry;
Kristian Monsen80d68ea2010-09-08 11:05:35 +010042 };
43
Ben Murdoch3ef787d2012-04-12 10:51:47 +010044 explicit InnerPointerToCodeCache(Isolate* isolate) : isolate_(isolate) {
Steve Block44f0eee2011-05-26 01:26:41 +010045 Flush();
Kristian Monsen80d68ea2010-09-08 11:05:35 +010046 }
47
Ben Murdoch3ef787d2012-04-12 10:51:47 +010048 Code* GcSafeFindCodeForInnerPointer(Address inner_pointer);
49 Code* GcSafeCastToCode(HeapObject* object, Address inner_pointer);
Kristian Monsen80d68ea2010-09-08 11:05:35 +010050
Steve Block44f0eee2011-05-26 01:26:41 +010051 void Flush() {
Kristian Monsen80d68ea2010-09-08 11:05:35 +010052 memset(&cache_[0], 0, sizeof(cache_));
53 }
54
Ben Murdoch3ef787d2012-04-12 10:51:47 +010055 InnerPointerToCodeCacheEntry* GetCacheEntry(Address inner_pointer);
Kristian Monsen80d68ea2010-09-08 11:05:35 +010056
57 private:
Ben Murdoch3ef787d2012-04-12 10:51:47 +010058 InnerPointerToCodeCacheEntry* cache(int index) { return &cache_[index]; }
Steve Block44f0eee2011-05-26 01:26:41 +010059
60 Isolate* isolate_;
61
Ben Murdoch3ef787d2012-04-12 10:51:47 +010062 static const int kInnerPointerToCodeCacheSize = 1024;
63 InnerPointerToCodeCacheEntry cache_[kInnerPointerToCodeCacheSize];
Steve Block44f0eee2011-05-26 01:26:41 +010064
Ben Murdoch3ef787d2012-04-12 10:51:47 +010065 DISALLOW_COPY_AND_ASSIGN(InnerPointerToCodeCache);
Kristian Monsen80d68ea2010-09-08 11:05:35 +010066};
67
68
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000069// Every try-block pushes the context register.
70class TryBlockConstant : public AllStatic {
71 public:
72 static const int kElementCount = 1;
73};
74
75
Ben Murdochb8a8cc12014-11-26 15:28:44 +000076class StackHandlerConstants : public AllStatic {
77 public:
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000078 static const int kNextOffset = 0 * kPointerSize;
Ben Murdochb8a8cc12014-11-26 15:28:44 +000079
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000080 static const int kSize = kNextOffset + kPointerSize;
Ben Murdochb8a8cc12014-11-26 15:28:44 +000081 static const int kSlotCount = kSize >> kPointerSizeLog2;
82};
83
84
Steve Blocka7e24c12009-10-30 11:49:00 +000085class StackHandler BASE_EMBEDDED {
86 public:
Steve Blocka7e24c12009-10-30 11:49:00 +000087 // Get the address of this stack handler.
88 inline Address address() const;
89
90 // Get the next stack handler in the chain.
91 inline StackHandler* next() const;
92
Steve Blocka7e24c12009-10-30 11:49:00 +000093 // Conversion support.
94 static inline StackHandler* FromAddress(Address address);
95
Steve Blocka7e24c12009-10-30 11:49:00 +000096 private:
Steve Blocka7e24c12009-10-30 11:49:00 +000097 DISALLOW_IMPLICIT_CONSTRUCTORS(StackHandler);
98};
99
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000100#define STACK_FRAME_TYPE_LIST(V) \
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000101 V(ENTRY, EntryFrame) \
102 V(ENTRY_CONSTRUCT, EntryConstructFrame) \
103 V(EXIT, ExitFrame) \
104 V(JAVA_SCRIPT, JavaScriptFrame) \
105 V(OPTIMIZED, OptimizedFrame) \
Ben Murdochda12d292016-06-02 14:46:10 +0100106 V(WASM, WasmFrame) \
107 V(WASM_TO_JS, WasmToJsFrame) \
108 V(JS_TO_WASM, JsToWasmFrame) \
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000109 V(INTERPRETED, InterpretedFrame) \
110 V(STUB, StubFrame) \
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000111 V(STUB_FAILURE_TRAMPOLINE, StubFailureTrampolineFrame) \
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000112 V(INTERNAL, InternalFrame) \
113 V(CONSTRUCT, ConstructFrame) \
114 V(ARGUMENTS_ADAPTOR, ArgumentsAdaptorFrame)
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000115
Ben Murdoch097c5b22016-05-18 11:27:45 +0100116// Every pointer in a frame has a slot id. On 32-bit platforms, doubles consume
117// two slots.
118//
119// Stack slot indices >= 0 access the callee stack with slot 0 corresponding to
120// the callee's saved return address and 1 corresponding to the saved frame
121// pointer. Some frames have additional information stored in the fixed header,
122// for example JSFunctions store the function context and marker in the fixed
123// header, with slot index 2 corresponding to the current function context and 3
124// corresponding to the frame marker/JSFunction.
125//
126// slot JS frame
127// +-----------------+--------------------------------
128// -n-1 | parameter 0 | ^
129// |- - - - - - - - -| |
130// -n | | Caller
131// ... | ... | frame slots
132// -2 | parameter n-1 | (slot < 0)
133// |- - - - - - - - -| |
134// -1 | parameter n | v
135// -----+-----------------+--------------------------------
136// 0 | return addr | ^ ^
137// |- - - - - - - - -| | |
138// 1 | saved frame ptr | Fixed |
139// |- - - - - - - - -| Header <-- frame ptr |
140// 2 | [Constant Pool] | | |
141// |- - - - - - - - -| | |
Ben Murdochda12d292016-06-02 14:46:10 +0100142// 2+cp |Context/Frm. Type| v if a constant pool |
143// |-----------------+---- is used, cp = 1, |
144// 3+cp | | ^ otherwise, cp = 0 |
145// |- - - - - - - - -| | |
146// 4+cp | | | Callee
147// |- - - - - - - - -| | frame slots
148// ... | | Frame slots (slot >= 0)
149// |- - - - - - - - -| | |
150// | | v |
151// -----+-----------------+----- <-- stack ptr -------------
152//
153class CommonFrameConstants : public AllStatic {
154 public:
155 static const int kCallerFPOffset = 0 * kPointerSize;
156 static const int kCallerPCOffset = kCallerFPOffset + 1 * kFPOnStackSize;
157 static const int kCallerSPOffset = kCallerPCOffset + 1 * kPCOnStackSize;
158
159 // Fixed part of the frame consists of return address, caller fp,
160 // constant pool (if FLAG_enable_embedded_constant_pool), context, and
161 // function. StandardFrame::IterateExpressions assumes that kLastObjectOffset
162 // is the last object pointer.
163 static const int kFixedFrameSizeAboveFp = kPCOnStackSize + kFPOnStackSize;
164 static const int kFixedSlotCountAboveFp =
165 kFixedFrameSizeAboveFp / kPointerSize;
166 static const int kCPSlotSize =
167 FLAG_enable_embedded_constant_pool ? kPointerSize : 0;
168 static const int kCPSlotCount = kCPSlotSize / kPointerSize;
169 static const int kConstantPoolOffset = kCPSlotSize ? -1 * kPointerSize : 0;
170 static const int kContextOrFrameTypeSize = kPointerSize;
171 static const int kContextOrFrameTypeOffset =
172 -(kCPSlotSize + kContextOrFrameTypeSize);
173};
174
175// StandardFrames are used for interpreted, full-codegen and optimized
176// JavaScript frames. They always have a context below the saved fp/constant
177// pool and below that the JSFunction of the executing function.
178//
179// slot JS frame
180// +-----------------+--------------------------------
181// -n-1 | parameter 0 | ^
182// |- - - - - - - - -| |
183// -n | | Caller
184// ... | ... | frame slots
185// -2 | parameter n-1 | (slot < 0)
186// |- - - - - - - - -| |
187// -1 | parameter n | v
188// -----+-----------------+--------------------------------
189// 0 | return addr | ^ ^
190// |- - - - - - - - -| | |
191// 1 | saved frame ptr | Fixed |
192// |- - - - - - - - -| Header <-- frame ptr |
193// 2 | [Constant Pool] | | |
194// |- - - - - - - - -| | |
Ben Murdoch097c5b22016-05-18 11:27:45 +0100195// 2+cp | Context | | if a constant pool |
196// |- - - - - - - - -| | is used, cp = 1, |
Ben Murdochda12d292016-06-02 14:46:10 +0100197// 3+cp | JSFunction | v otherwise, cp = 0 |
Ben Murdoch097c5b22016-05-18 11:27:45 +0100198// +-----------------+---- |
199// 4+cp | | ^ Callee
200// |- - - - - - - - -| | frame slots
201// ... | | Frame slots (slot >= 0)
202// |- - - - - - - - -| | |
203// | | v |
204// -----+-----------------+----- <-- stack ptr -------------
205//
Ben Murdochda12d292016-06-02 14:46:10 +0100206class StandardFrameConstants : public CommonFrameConstants {
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000207 public:
Ben Murdochda12d292016-06-02 14:46:10 +0100208 static const int kFixedFrameSizeFromFp = 2 * kPointerSize + kCPSlotSize;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000209 static const int kFixedFrameSize =
210 kFixedFrameSizeAboveFp + kFixedFrameSizeFromFp;
Ben Murdochda12d292016-06-02 14:46:10 +0100211 static const int kFixedSlotCountFromFp = kFixedFrameSizeFromFp / kPointerSize;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000212 static const int kFixedSlotCount = kFixedFrameSize / kPointerSize;
Ben Murdochda12d292016-06-02 14:46:10 +0100213 static const int kContextOffset = kContextOrFrameTypeOffset;
214 static const int kFunctionOffset = -2 * kPointerSize - kCPSlotSize;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000215 static const int kExpressionsOffset = -3 * kPointerSize - kCPSlotSize;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000216 static const int kLastObjectOffset = kContextOffset;
217};
218
Ben Murdochda12d292016-06-02 14:46:10 +0100219// TypedFrames have a SMI type maker value below the saved FP/constant pool to
220// distinguish them from StandardFrames, which have a context in that position
221// instead.
222//
223// slot JS frame
224// +-----------------+--------------------------------
225// -n-1 | parameter 0 | ^
226// |- - - - - - - - -| |
227// -n | | Caller
228// ... | ... | frame slots
229// -2 | parameter n-1 | (slot < 0)
230// |- - - - - - - - -| |
231// -1 | parameter n | v
232// -----+-----------------+--------------------------------
233// 0 | return addr | ^ ^
234// |- - - - - - - - -| | |
235// 1 | saved frame ptr | Fixed |
236// |- - - - - - - - -| Header <-- frame ptr |
237// 2 | [Constant Pool] | | |
238// |- - - - - - - - -| | |
239// 2+cp |Frame Type Marker| v if a constant pool |
240// |-----------------+---- is used, cp = 1, |
241// 3+cp | | ^ otherwise, cp = 0 |
242// |- - - - - - - - -| | |
243// 4+cp | | | Callee
244// |- - - - - - - - -| | frame slots
245// ... | | Frame slots (slot >= 0)
246// |- - - - - - - - -| | |
247// | | v |
248// -----+-----------------+----- <-- stack ptr -------------
249//
250class TypedFrameConstants : public CommonFrameConstants {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000251 public:
Ben Murdochda12d292016-06-02 14:46:10 +0100252 static const int kFrameTypeSize = kContextOrFrameTypeSize;
253 static const int kFrameTypeOffset = kContextOrFrameTypeOffset;
254 static const int kFixedFrameSizeFromFp = kCPSlotSize + kFrameTypeSize;
255 static const int kFixedSlotCountFromFp = kFixedFrameSizeFromFp / kPointerSize;
256 static const int kFixedFrameSize =
257 StandardFrameConstants::kFixedFrameSizeAboveFp + kFixedFrameSizeFromFp;
258 static const int kFixedSlotCount = kFixedFrameSize / kPointerSize;
259 static const int kFirstPushedFrameValueOffset =
260 -StandardFrameConstants::kCPSlotSize - kFrameTypeSize - kPointerSize;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000261};
262
Ben Murdochda12d292016-06-02 14:46:10 +0100263#define TYPED_FRAME_PUSHED_VALUE_OFFSET(x) \
264 (TypedFrameConstants::kFirstPushedFrameValueOffset - (x)*kPointerSize)
265#define TYPED_FRAME_SIZE(count) \
266 (TypedFrameConstants::kFixedFrameSize + (count)*kPointerSize)
267#define TYPED_FRAME_SIZE_FROM_SP(count) \
268 (TypedFrameConstants::kFixedFrameSizeFromFp + (count)*kPointerSize)
269#define DEFINE_TYPED_FRAME_SIZES(count) \
270 static const int kFixedFrameSize = TYPED_FRAME_SIZE(count); \
271 static const int kFixedSlotCount = kFixedFrameSize / kPointerSize; \
272 static const int kFixedFrameSizeFromFp = TYPED_FRAME_SIZE_FROM_SP(count); \
273 static const int kFixedSlotCountFromFp = kFixedFrameSizeFromFp / kPointerSize
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000274
Ben Murdochda12d292016-06-02 14:46:10 +0100275class ArgumentsAdaptorFrameConstants : public TypedFrameConstants {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000276 public:
277 // FP-relative.
Ben Murdochda12d292016-06-02 14:46:10 +0100278 static const int kFunctionOffset = TYPED_FRAME_PUSHED_VALUE_OFFSET(0);
279 static const int kLengthOffset = TYPED_FRAME_PUSHED_VALUE_OFFSET(1);
280 DEFINE_TYPED_FRAME_SIZES(2);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000281};
282
Ben Murdochda12d292016-06-02 14:46:10 +0100283class InternalFrameConstants : public TypedFrameConstants {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000284 public:
285 // FP-relative.
Ben Murdochda12d292016-06-02 14:46:10 +0100286 static const int kCodeOffset = TYPED_FRAME_PUSHED_VALUE_OFFSET(0);
287 DEFINE_TYPED_FRAME_SIZES(1);
288};
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000289
Ben Murdochda12d292016-06-02 14:46:10 +0100290class FrameDropperFrameConstants : public InternalFrameConstants {
291 public:
292 // FP-relative.
293 static const int kFunctionOffset = TYPED_FRAME_PUSHED_VALUE_OFFSET(1);
294 DEFINE_TYPED_FRAME_SIZES(2);
295};
296
297class ConstructFrameConstants : public TypedFrameConstants {
298 public:
299 // FP-relative.
300 static const int kContextOffset = TYPED_FRAME_PUSHED_VALUE_OFFSET(0);
301 static const int kAllocationSiteOffset = TYPED_FRAME_PUSHED_VALUE_OFFSET(1);
302 static const int kLengthOffset = TYPED_FRAME_PUSHED_VALUE_OFFSET(2);
303 static const int kImplicitReceiverOffset = TYPED_FRAME_PUSHED_VALUE_OFFSET(3);
304 DEFINE_TYPED_FRAME_SIZES(4);
305};
306
307class StubFailureTrampolineFrameConstants : public InternalFrameConstants {
308 public:
309 static const int kArgumentsArgumentsOffset =
310 TYPED_FRAME_PUSHED_VALUE_OFFSET(0);
311 static const int kArgumentsLengthOffset = TYPED_FRAME_PUSHED_VALUE_OFFSET(1);
312 static const int kArgumentsPointerOffset = TYPED_FRAME_PUSHED_VALUE_OFFSET(2);
313 static const int kFixedHeaderBottomOffset = kArgumentsPointerOffset;
314 DEFINE_TYPED_FRAME_SIZES(3);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000315};
316
317
318class InterpreterFrameConstants : public AllStatic {
319 public:
320 // Fixed frame includes new.target and bytecode offset.
321 static const int kFixedFrameSize =
Ben Murdoch097c5b22016-05-18 11:27:45 +0100322 StandardFrameConstants::kFixedFrameSize + 3 * kPointerSize;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000323 static const int kFixedFrameSizeFromFp =
Ben Murdoch097c5b22016-05-18 11:27:45 +0100324 StandardFrameConstants::kFixedFrameSizeFromFp + 3 * kPointerSize;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000325
326 // FP-relative.
Ben Murdochc5610432016-08-08 18:44:38 +0100327 static const int kLastParamFromFp = StandardFrameConstants::kCallerSPOffset;
Ben Murdoch097c5b22016-05-18 11:27:45 +0100328 static const int kNewTargetFromFp =
329 -StandardFrameConstants::kFixedFrameSizeFromFp - 1 * kPointerSize;
330 static const int kBytecodeArrayFromFp =
331 -StandardFrameConstants::kFixedFrameSizeFromFp - 2 * kPointerSize;
332 static const int kBytecodeOffsetFromFp =
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000333 -StandardFrameConstants::kFixedFrameSizeFromFp - 3 * kPointerSize;
Ben Murdochc5610432016-08-08 18:44:38 +0100334 static const int kRegisterFileFromFp =
Ben Murdoch097c5b22016-05-18 11:27:45 +0100335 -StandardFrameConstants::kFixedFrameSizeFromFp - 4 * kPointerSize;
336
Ben Murdochc5610432016-08-08 18:44:38 +0100337 static const int kExpressionsOffset = kRegisterFileFromFp;
Ben Murdoch097c5b22016-05-18 11:27:45 +0100338
339 // Expression index for {StandardFrame::GetExpressionAddress}.
340 static const int kBytecodeArrayExpressionIndex = -2;
341 static const int kBytecodeOffsetExpressionIndex = -1;
342 static const int kRegisterFileExpressionIndex = 0;
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000343};
Steve Blocka7e24c12009-10-30 11:49:00 +0000344
Ben Murdoch097c5b22016-05-18 11:27:45 +0100345inline static int FPOffsetToFrameSlot(int frame_offset) {
346 return StandardFrameConstants::kFixedSlotCountAboveFp - 1 -
347 frame_offset / kPointerSize;
348}
349
350inline static int FrameSlotToFPOffset(int slot) {
351 return (StandardFrameConstants::kFixedSlotCountAboveFp - 1 - slot) *
352 kPointerSize;
353}
Steve Blocka7e24c12009-10-30 11:49:00 +0000354
355// Abstract base class for all stack frames.
356class StackFrame BASE_EMBEDDED {
357 public:
358#define DECLARE_TYPE(type, ignore) type,
359 enum Type {
360 NONE = 0,
361 STACK_FRAME_TYPE_LIST(DECLARE_TYPE)
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100362 NUMBER_OF_TYPES,
363 // Used by FrameScope to indicate that the stack frame is constructed
364 // manually and the FrameScope does not need to emit code.
365 MANUAL
Steve Blocka7e24c12009-10-30 11:49:00 +0000366 };
367#undef DECLARE_TYPE
368
369 // Opaque data type for identifying stack frames. Used extensively
370 // by the debugger.
Iain Merrick75681382010-08-19 15:07:18 +0100371 // ID_MIN_VALUE and ID_MAX_VALUE are specified to ensure that enumeration type
372 // has correct value range (see Issue 830 for more details).
373 enum Id {
374 ID_MIN_VALUE = kMinInt,
375 ID_MAX_VALUE = kMaxInt,
376 NO_ID = 0
377 };
Steve Blocka7e24c12009-10-30 11:49:00 +0000378
Steve Block053d10c2011-06-13 19:13:29 +0100379 // Used to mark the outermost JS entry frame.
380 enum JsFrameMarker {
381 INNER_JSENTRY_FRAME = 0,
382 OUTERMOST_JSENTRY_FRAME = 1
383 };
384
Kristian Monsen0d5e1162010-09-30 15:31:59 +0100385 struct State {
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000386 State() : sp(NULL), fp(NULL), pc_address(NULL),
387 constant_pool_address(NULL) { }
Kristian Monsen0d5e1162010-09-30 15:31:59 +0100388 Address sp;
389 Address fp;
390 Address* pc_address;
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000391 Address* constant_pool_address;
Kristian Monsen0d5e1162010-09-30 15:31:59 +0100392 };
393
Ben Murdoch8b112d22011-06-08 16:22:53 +0100394 // Copy constructor; it breaks the connection to host iterator
395 // (as an iterator usually lives on stack).
Steve Block6ded16b2010-05-10 14:33:55 +0100396 StackFrame(const StackFrame& original) {
397 this->state_ = original.state_;
398 this->iterator_ = NULL;
Ben Murdoch8b112d22011-06-08 16:22:53 +0100399 this->isolate_ = original.isolate_;
Steve Block6ded16b2010-05-10 14:33:55 +0100400 }
401
Steve Blocka7e24c12009-10-30 11:49:00 +0000402 // Type testers.
403 bool is_entry() const { return type() == ENTRY; }
404 bool is_entry_construct() const { return type() == ENTRY_CONSTRUCT; }
405 bool is_exit() const { return type() == EXIT; }
Ben Murdochb0fe1622011-05-05 13:52:32 +0100406 bool is_optimized() const { return type() == OPTIMIZED; }
Ben Murdoch097c5b22016-05-18 11:27:45 +0100407 bool is_interpreted() const { return type() == INTERPRETED; }
Ben Murdochda12d292016-06-02 14:46:10 +0100408 bool is_wasm() const { return type() == WASM; }
409 bool is_wasm_to_js() const { return type() == WASM_TO_JS; }
410 bool is_js_to_wasm() const { return type() == JS_TO_WASM; }
Steve Blocka7e24c12009-10-30 11:49:00 +0000411 bool is_arguments_adaptor() const { return type() == ARGUMENTS_ADAPTOR; }
412 bool is_internal() const { return type() == INTERNAL; }
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000413 bool is_stub_failure_trampoline() const {
414 return type() == STUB_FAILURE_TRAMPOLINE;
415 }
Steve Blocka7e24c12009-10-30 11:49:00 +0000416 bool is_construct() const { return type() == CONSTRUCT; }
417 virtual bool is_standard() const { return false; }
418
Ben Murdochb0fe1622011-05-05 13:52:32 +0100419 bool is_java_script() const {
420 Type type = this->type();
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000421 return (type == JAVA_SCRIPT) || (type == OPTIMIZED) ||
422 (type == INTERPRETED);
Ben Murdochb0fe1622011-05-05 13:52:32 +0100423 }
424
Steve Blocka7e24c12009-10-30 11:49:00 +0000425 // Accessors.
426 Address sp() const { return state_.sp; }
427 Address fp() const { return state_.fp; }
428 Address caller_sp() const { return GetCallerStackPointer(); }
429
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000430 // If this frame is optimized and was dynamically aligned return its old
431 // unaligned frame pointer. When the frame is deoptimized its FP will shift
432 // up one word and become unaligned.
433 Address UnpaddedFP() const;
434
Steve Blocka7e24c12009-10-30 11:49:00 +0000435 Address pc() const { return *pc_address(); }
436 void set_pc(Address pc) { *pc_address() = pc; }
437
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000438 Address constant_pool() const { return *constant_pool_address(); }
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000439 void set_constant_pool(Address constant_pool) {
440 *constant_pool_address() = constant_pool;
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000441 }
442
Steve Block6ded16b2010-05-10 14:33:55 +0100443 virtual void SetCallerFp(Address caller_fp) = 0;
444
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000445 // Manually changes value of fp in this object.
446 void UpdateFp(Address fp) { state_.fp = fp; }
447
Steve Blocka7e24c12009-10-30 11:49:00 +0000448 Address* pc_address() const { return state_.pc_address; }
449
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000450 Address* constant_pool_address() const {
451 return state_.constant_pool_address;
452 }
453
Steve Blocka7e24c12009-10-30 11:49:00 +0000454 // Get the id of this stack frame.
455 Id id() const { return static_cast<Id>(OffsetFrom(caller_sp())); }
456
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000457 // Get the top handler from the current stack iterator.
458 inline StackHandler* top_handler() const;
Steve Blocka7e24c12009-10-30 11:49:00 +0000459
460 // Get the type of this frame.
461 virtual Type type() const = 0;
462
463 // Get the code associated with this frame.
Iain Merrick75681382010-08-19 15:07:18 +0100464 // This method could be called during marking phase of GC.
465 virtual Code* unchecked_code() const = 0;
466
467 // Get the code associated with this frame.
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100468 inline Code* LookupCode() const;
Kristian Monsen80d68ea2010-09-08 11:05:35 +0100469
470 // Get the code object that contains the given pc.
Steve Block44f0eee2011-05-26 01:26:41 +0100471 static inline Code* GetContainingCode(Isolate* isolate, Address pc);
Steve Blocka7e24c12009-10-30 11:49:00 +0000472
Ben Murdochb0fe1622011-05-05 13:52:32 +0100473 // Get the code object containing the given pc and fill in the
474 // safepoint entry and the number of stack slots. The pc must be at
475 // a safepoint.
Ben Murdoch8b112d22011-06-08 16:22:53 +0100476 static Code* GetSafepointData(Isolate* isolate,
477 Address pc,
Ben Murdochb8e0da22011-05-16 14:20:40 +0100478 SafepointEntry* safepoint_entry,
Ben Murdochb0fe1622011-05-05 13:52:32 +0100479 unsigned* stack_slots);
480
Kristian Monsen80d68ea2010-09-08 11:05:35 +0100481 virtual void Iterate(ObjectVisitor* v) const = 0;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000482 static void IteratePc(ObjectVisitor* v, Address* pc_address,
483 Address* constant_pool_address, Code* holder);
Steve Blocka7e24c12009-10-30 11:49:00 +0000484
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100485 // Sets a callback function for return-address rewriting profilers
486 // to resolve the location of a return address to the location of the
487 // profiler's stashed return address.
488 static void SetReturnAddressLocationResolver(
489 ReturnAddressLocationResolver resolver);
Steve Blocka7e24c12009-10-30 11:49:00 +0000490
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000491 // Resolves pc_address through the resolution address function if one is set.
492 static inline Address* ResolveReturnAddressLocation(Address* pc_address);
493
Steve Blocka7e24c12009-10-30 11:49:00 +0000494 // Printing support.
495 enum PrintMode { OVERVIEW, DETAILS };
496 virtual void Print(StringStream* accumulator,
497 PrintMode mode,
498 int index) const { }
499
Ben Murdoch8b112d22011-06-08 16:22:53 +0100500 Isolate* isolate() const { return isolate_; }
501
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000502 protected:
503 inline explicit StackFrame(StackFrameIteratorBase* iterator);
504 virtual ~StackFrame() { }
505
Steve Blocka7e24c12009-10-30 11:49:00 +0000506 // Compute the stack pointer for the calling frame.
507 virtual Address GetCallerStackPointer() const = 0;
508
509 // Printing support.
510 static void PrintIndex(StringStream* accumulator,
511 PrintMode mode,
512 int index);
513
Steve Blocka7e24c12009-10-30 11:49:00 +0000514 // Compute the stack frame type for the given state.
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000515 static Type ComputeType(const StackFrameIteratorBase* iterator, State* state);
516
517#ifdef DEBUG
518 bool can_access_heap_objects() const;
519#endif
Steve Blocka7e24c12009-10-30 11:49:00 +0000520
521 private:
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000522 const StackFrameIteratorBase* iterator_;
Ben Murdoch8b112d22011-06-08 16:22:53 +0100523 Isolate* isolate_;
Steve Blocka7e24c12009-10-30 11:49:00 +0000524 State state_;
525
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000526 static ReturnAddressLocationResolver return_address_location_resolver_;
527
Steve Blocka7e24c12009-10-30 11:49:00 +0000528 // Fill in the state of the calling frame.
529 virtual void ComputeCallerState(State* state) const = 0;
530
531 // Get the type and the state of the calling frame.
532 virtual Type GetCallerState(State* state) const;
533
Ben Murdoch8b112d22011-06-08 16:22:53 +0100534 static const intptr_t kIsolateTag = 1;
535
Steve Blocka7e24c12009-10-30 11:49:00 +0000536 friend class StackFrameIterator;
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000537 friend class StackFrameIteratorBase;
Steve Blocka7e24c12009-10-30 11:49:00 +0000538 friend class StackHandlerIterator;
539 friend class SafeStackFrameIterator;
540
Steve Block6ded16b2010-05-10 14:33:55 +0100541 private:
542 void operator=(const StackFrame& original);
Steve Blocka7e24c12009-10-30 11:49:00 +0000543};
544
545
546// Entry frames are used to enter JavaScript execution from C.
547class EntryFrame: public StackFrame {
548 public:
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000549 Type type() const override { return ENTRY; }
Steve Blocka7e24c12009-10-30 11:49:00 +0000550
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000551 Code* unchecked_code() const override;
Steve Blocka7e24c12009-10-30 11:49:00 +0000552
553 // Garbage collection support.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000554 void Iterate(ObjectVisitor* v) const override;
Steve Blocka7e24c12009-10-30 11:49:00 +0000555
556 static EntryFrame* cast(StackFrame* frame) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000557 DCHECK(frame->is_entry());
Steve Blocka7e24c12009-10-30 11:49:00 +0000558 return static_cast<EntryFrame*>(frame);
559 }
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000560 void SetCallerFp(Address caller_fp) override;
Steve Blocka7e24c12009-10-30 11:49:00 +0000561
562 protected:
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000563 inline explicit EntryFrame(StackFrameIteratorBase* iterator);
Steve Blocka7e24c12009-10-30 11:49:00 +0000564
565 // The caller stack pointer for entry frames is always zero. The
566 // real information about the caller frame is available through the
567 // link to the top exit frame.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000568 Address GetCallerStackPointer() const override { return 0; }
Steve Blocka7e24c12009-10-30 11:49:00 +0000569
570 private:
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000571 void ComputeCallerState(State* state) const override;
572 Type GetCallerState(State* state) const override;
Steve Blocka7e24c12009-10-30 11:49:00 +0000573
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000574 friend class StackFrameIteratorBase;
Steve Blocka7e24c12009-10-30 11:49:00 +0000575};
576
577
578class EntryConstructFrame: public EntryFrame {
579 public:
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000580 Type type() const override { return ENTRY_CONSTRUCT; }
Steve Blocka7e24c12009-10-30 11:49:00 +0000581
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000582 Code* unchecked_code() const override;
Steve Blocka7e24c12009-10-30 11:49:00 +0000583
584 static EntryConstructFrame* cast(StackFrame* frame) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000585 DCHECK(frame->is_entry_construct());
Steve Blocka7e24c12009-10-30 11:49:00 +0000586 return static_cast<EntryConstructFrame*>(frame);
587 }
588
589 protected:
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000590 inline explicit EntryConstructFrame(StackFrameIteratorBase* iterator);
Steve Blocka7e24c12009-10-30 11:49:00 +0000591
592 private:
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000593 friend class StackFrameIteratorBase;
Steve Blocka7e24c12009-10-30 11:49:00 +0000594};
595
596
597// Exit frames are used to exit JavaScript execution and go to C.
598class ExitFrame: public StackFrame {
599 public:
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000600 Type type() const override { return EXIT; }
Steve Blocka7e24c12009-10-30 11:49:00 +0000601
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000602 Code* unchecked_code() const override;
Steve Blocka7e24c12009-10-30 11:49:00 +0000603
Steve Blockd0582a62009-12-15 09:54:21 +0000604 Object*& code_slot() const;
605
Steve Blocka7e24c12009-10-30 11:49:00 +0000606 // Garbage collection support.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000607 void Iterate(ObjectVisitor* v) const override;
Steve Blocka7e24c12009-10-30 11:49:00 +0000608
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000609 void SetCallerFp(Address caller_fp) override;
Steve Block6ded16b2010-05-10 14:33:55 +0100610
Steve Blocka7e24c12009-10-30 11:49:00 +0000611 static ExitFrame* cast(StackFrame* frame) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000612 DCHECK(frame->is_exit());
Steve Blocka7e24c12009-10-30 11:49:00 +0000613 return static_cast<ExitFrame*>(frame);
614 }
615
616 // Compute the state and type of an exit frame given a frame
617 // pointer. Used when constructing the first stack frame seen by an
618 // iterator and the frames following entry frames.
619 static Type GetStateForFramePointer(Address fp, State* state);
Kristian Monsen0d5e1162010-09-30 15:31:59 +0100620 static Address ComputeStackPointer(Address fp);
621 static void FillState(Address fp, Address sp, State* state);
Steve Blocka7e24c12009-10-30 11:49:00 +0000622
623 protected:
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000624 inline explicit ExitFrame(StackFrameIteratorBase* iterator);
Steve Blocka7e24c12009-10-30 11:49:00 +0000625
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000626 Address GetCallerStackPointer() const override;
Steve Blocka7e24c12009-10-30 11:49:00 +0000627
628 private:
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000629 void ComputeCallerState(State* state) const override;
Steve Blocka7e24c12009-10-30 11:49:00 +0000630
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000631 friend class StackFrameIteratorBase;
Steve Blocka7e24c12009-10-30 11:49:00 +0000632};
633
Ben Murdochc5610432016-08-08 18:44:38 +0100634class JavaScriptFrame;
Steve Blocka7e24c12009-10-30 11:49:00 +0000635
Ben Murdochc5610432016-08-08 18:44:38 +0100636class FrameSummary BASE_EMBEDDED {
637 public:
638 // Mode for JavaScriptFrame::Summarize. Exact summary is required to produce
639 // an exact stack trace. It will trigger an assertion failure if that is not
640 // possible, e.g., because of missing deoptimization information. The
641 // approximate mode should produce a summary even without deoptimization
642 // information, but it might miss frames.
643 enum Mode { kExactSummary, kApproximateSummary };
644
645 FrameSummary(Object* receiver, JSFunction* function,
646 AbstractCode* abstract_code, int code_offset,
647 bool is_constructor, Mode mode = kExactSummary);
648
649 static FrameSummary GetFirst(JavaScriptFrame* frame);
650
651 Handle<Object> receiver() { return receiver_; }
652 Handle<JSFunction> function() { return function_; }
653 Handle<AbstractCode> abstract_code() { return abstract_code_; }
654 int code_offset() { return code_offset_; }
655 bool is_constructor() { return is_constructor_; }
656
657 void Print();
658
659 private:
660 Handle<Object> receiver_;
661 Handle<JSFunction> function_;
662 Handle<AbstractCode> abstract_code_;
663 int code_offset_;
664 bool is_constructor_;
665};
666
667class StandardFrame : public StackFrame {
Steve Blocka7e24c12009-10-30 11:49:00 +0000668 public:
669 // Testers.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000670 bool is_standard() const override { return true; }
Steve Blocka7e24c12009-10-30 11:49:00 +0000671
672 // Accessors.
673 inline Object* context() const;
674
675 // Access the expressions in the stack frame including locals.
676 inline Object* GetExpression(int index) const;
677 inline void SetExpression(int index, Object* value);
678 int ComputeExpressionsCount() const;
679
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000680 void SetCallerFp(Address caller_fp) override;
Steve Block6ded16b2010-05-10 14:33:55 +0100681
Steve Blocka7e24c12009-10-30 11:49:00 +0000682 static StandardFrame* cast(StackFrame* frame) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000683 DCHECK(frame->is_standard());
Steve Blocka7e24c12009-10-30 11:49:00 +0000684 return static_cast<StandardFrame*>(frame);
685 }
686
687 protected:
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000688 inline explicit StandardFrame(StackFrameIteratorBase* iterator);
Steve Blocka7e24c12009-10-30 11:49:00 +0000689
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000690 void ComputeCallerState(State* state) const override;
Steve Blocka7e24c12009-10-30 11:49:00 +0000691
692 // Accessors.
693 inline Address caller_fp() const;
694 inline Address caller_pc() const;
695
696 // Computes the address of the PC field in the standard frame given
697 // by the provided frame pointer.
698 static inline Address ComputePCAddress(Address fp);
699
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000700 // Computes the address of the constant pool field in the standard
701 // frame given by the provided frame pointer.
702 static inline Address ComputeConstantPoolAddress(Address fp);
703
Steve Blocka7e24c12009-10-30 11:49:00 +0000704 // Iterate over expression stack including stack handlers, locals,
705 // and parts of the fixed part including context and code fields.
706 void IterateExpressions(ObjectVisitor* v) const;
707
708 // Returns the address of the n'th expression stack element.
Ben Murdoch097c5b22016-05-18 11:27:45 +0100709 virtual Address GetExpressionAddress(int n) const;
Steve Blocka7e24c12009-10-30 11:49:00 +0000710
Steve Blocka7e24c12009-10-30 11:49:00 +0000711 // Determines if the standard frame for the given frame pointer is
712 // an arguments adaptor frame.
713 static inline bool IsArgumentsAdaptorFrame(Address fp);
714
715 // Determines if the standard frame for the given frame pointer is a
716 // construct frame.
717 static inline bool IsConstructFrame(Address fp);
718
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000719 // Used by OptimizedFrames and StubFrames.
720 void IterateCompiledFrame(ObjectVisitor* v) const;
721
Steve Blocka7e24c12009-10-30 11:49:00 +0000722 private:
723 friend class StackFrame;
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000724 friend class SafeStackFrameIterator;
Steve Blocka7e24c12009-10-30 11:49:00 +0000725};
726
Ben Murdochda12d292016-06-02 14:46:10 +0100727class JavaScriptFrame : public StandardFrame {
Steve Blocka7e24c12009-10-30 11:49:00 +0000728 public:
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000729 Type type() const override { return JAVA_SCRIPT; }
Steve Blocka7e24c12009-10-30 11:49:00 +0000730
Ben Murdochc5610432016-08-08 18:44:38 +0100731 // Build a list with summaries for this frame including all inlined frames.
732 virtual void Summarize(
733 List<FrameSummary>* frames,
734 FrameSummary::Mode mode = FrameSummary::kExactSummary) const;
735
Steve Blocka7e24c12009-10-30 11:49:00 +0000736 // Accessors.
Ben Murdochc5610432016-08-08 18:44:38 +0100737 virtual JSFunction* function() const;
738 virtual Object* receiver() const;
739
Steve Blocka7e24c12009-10-30 11:49:00 +0000740 inline void set_receiver(Object* value);
741
742 // Access the parameters.
Ben Murdoch8b112d22011-06-08 16:22:53 +0100743 inline Address GetParameterSlot(int index) const;
744 inline Object* GetParameter(int index) const;
745 inline int ComputeParametersCount() const {
746 return GetNumberOfIncomingArguments();
747 }
Steve Blocka7e24c12009-10-30 11:49:00 +0000748
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000749 // Access the operand stack.
750 inline Address GetOperandSlot(int index) const;
751 inline Object* GetOperand(int index) const;
752 inline int ComputeOperandsCount() const;
753
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000754 // Generator support to preserve operand stack.
755 void SaveOperandStack(FixedArray* store) const;
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000756
757 // Debugger access.
758 void SetParameterValue(int index, Object* value) const;
759
Steve Blocka7e24c12009-10-30 11:49:00 +0000760 // Check if this frame is a constructor frame invoked through 'new'.
761 bool IsConstructor() const;
762
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000763 // Determines whether this frame includes inlined activations. To get details
764 // about the inlined frames use {GetFunctions} and {Summarize}.
765 bool HasInlinedFrames() const;
766
Steve Blocka7e24c12009-10-30 11:49:00 +0000767 // Check if this frame has "adapted" arguments in the sense that the
768 // actual passed arguments are available in an arguments adaptor
769 // frame below it on the stack.
770 inline bool has_adapted_arguments() const;
Ben Murdoch3fb3ca82011-12-02 17:19:32 +0000771 int GetArgumentsLength() const;
Steve Blocka7e24c12009-10-30 11:49:00 +0000772
773 // Garbage collection support.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000774 void Iterate(ObjectVisitor* v) const override;
Steve Blocka7e24c12009-10-30 11:49:00 +0000775
776 // Printing support.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000777 void Print(StringStream* accumulator, PrintMode mode,
778 int index) const override;
Steve Blocka7e24c12009-10-30 11:49:00 +0000779
780 // Determine the code for the frame.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000781 Code* unchecked_code() const override;
Ben Murdoch3fb3ca82011-12-02 17:19:32 +0000782
Ben Murdochb0fe1622011-05-05 13:52:32 +0100783 // Return a list with JSFunctions of this frame.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000784 virtual void GetFunctions(List<JSFunction*>* functions) const;
Ben Murdochb0fe1622011-05-05 13:52:32 +0100785
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000786 // Lookup exception handler for current {pc}, returns -1 if none found. Also
Ben Murdoch097c5b22016-05-18 11:27:45 +0100787 // returns data associated with the handler site specific to the frame type:
788 // - JavaScriptFrame : Data is the stack depth at entry of the try-block.
789 // - OptimizedFrame : Data is the stack slot count of the entire frame.
790 // - InterpretedFrame: Data is the register index holding the context.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000791 virtual int LookupExceptionHandlerInTable(
Ben Murdoch097c5b22016-05-18 11:27:45 +0100792 int* data, HandlerTable::CatchPrediction* prediction);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000793
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000794 // Architecture-specific register description.
795 static Register fp_register();
796 static Register context_register();
797 static Register constant_pool_pointer_register();
798
Steve Blocka7e24c12009-10-30 11:49:00 +0000799 static JavaScriptFrame* cast(StackFrame* frame) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000800 DCHECK(frame->is_java_script());
Steve Blocka7e24c12009-10-30 11:49:00 +0000801 return static_cast<JavaScriptFrame*>(frame);
802 }
803
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000804 static void PrintFunctionAndOffset(JSFunction* function, Code* code,
805 Address pc, FILE* file,
806 bool print_line_number);
807
808 static void PrintTop(Isolate* isolate, FILE* file, bool print_args,
809 bool print_line_number);
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100810
Steve Blocka7e24c12009-10-30 11:49:00 +0000811 protected:
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000812 inline explicit JavaScriptFrame(StackFrameIteratorBase* iterator);
Steve Blocka7e24c12009-10-30 11:49:00 +0000813
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000814 Address GetCallerStackPointer() const override;
Steve Blocka7e24c12009-10-30 11:49:00 +0000815
Ben Murdoch8b112d22011-06-08 16:22:53 +0100816 virtual int GetNumberOfIncomingArguments() const;
817
Ben Murdochb0fe1622011-05-05 13:52:32 +0100818 // Garbage collection support. Iterates over incoming arguments,
819 // receiver, and any callee-saved registers.
820 void IterateArguments(ObjectVisitor* v) const;
821
Steve Blocka7e24c12009-10-30 11:49:00 +0000822 private:
Steve Blocka7e24c12009-10-30 11:49:00 +0000823 inline Object* function_slot_object() const;
824
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000825 friend class StackFrameIteratorBase;
826};
827
828
829class StubFrame : public StandardFrame {
830 public:
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000831 Type type() const override { return STUB; }
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000832
833 // GC support.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000834 void Iterate(ObjectVisitor* v) const override;
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000835
836 // Determine the code for the frame.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000837 Code* unchecked_code() const override;
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000838
839 protected:
840 inline explicit StubFrame(StackFrameIteratorBase* iterator);
841
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000842 Address GetCallerStackPointer() const override;
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000843
844 virtual int GetNumberOfIncomingArguments() const;
845
846 friend class StackFrameIteratorBase;
Steve Blocka7e24c12009-10-30 11:49:00 +0000847};
848
849
Ben Murdochb0fe1622011-05-05 13:52:32 +0100850class OptimizedFrame : public JavaScriptFrame {
851 public:
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000852 Type type() const override { return OPTIMIZED; }
Ben Murdochb0fe1622011-05-05 13:52:32 +0100853
854 // GC support.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000855 void Iterate(ObjectVisitor* v) const override;
Ben Murdoch3fb3ca82011-12-02 17:19:32 +0000856
Ben Murdochb0fe1622011-05-05 13:52:32 +0100857 // Return a list with JSFunctions of this frame.
858 // The functions are ordered bottom-to-top (i.e. functions.last()
859 // is the top-most activation)
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000860 void GetFunctions(List<JSFunction*>* functions) const override;
Ben Murdochb0fe1622011-05-05 13:52:32 +0100861
Ben Murdochc5610432016-08-08 18:44:38 +0100862 void Summarize(
863 List<FrameSummary>* frames,
864 FrameSummary::Mode mode = FrameSummary::kExactSummary) const override;
Ben Murdochb0fe1622011-05-05 13:52:32 +0100865
Ben Murdoch097c5b22016-05-18 11:27:45 +0100866 // Lookup exception handler for current {pc}, returns -1 if none found.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000867 int LookupExceptionHandlerInTable(
Ben Murdoch097c5b22016-05-18 11:27:45 +0100868 int* data, HandlerTable::CatchPrediction* prediction) override;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000869
870 DeoptimizationInputData* GetDeoptimizationData(int* deopt_index) const;
871
872 static int StackSlotOffsetRelativeToFp(int slot_index);
Ben Murdochb0fe1622011-05-05 13:52:32 +0100873
874 protected:
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000875 inline explicit OptimizedFrame(StackFrameIteratorBase* iterator);
Ben Murdochb0fe1622011-05-05 13:52:32 +0100876
877 private:
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000878 friend class StackFrameIteratorBase;
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000879
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000880 Object* StackSlotAt(int index) const;
881};
882
883
884class InterpretedFrame : public JavaScriptFrame {
Ben Murdoch097c5b22016-05-18 11:27:45 +0100885 public:
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000886 Type type() const override { return INTERPRETED; }
887
Ben Murdoch097c5b22016-05-18 11:27:45 +0100888 // Lookup exception handler for current {pc}, returns -1 if none found.
889 int LookupExceptionHandlerInTable(
890 int* data, HandlerTable::CatchPrediction* prediction) override;
891
892 // Returns the current offset into the bytecode stream.
893 int GetBytecodeOffset() const;
894
895 // Updates the current offset into the bytecode stream, mainly used for stack
896 // unwinding to continue execution at a different bytecode offset.
897 void PatchBytecodeOffset(int new_offset);
898
899 // Returns the frame's current bytecode array.
Ben Murdochc5610432016-08-08 18:44:38 +0100900 BytecodeArray* GetBytecodeArray() const;
Ben Murdoch097c5b22016-05-18 11:27:45 +0100901
902 // Updates the frame's BytecodeArray with |bytecode_array|. Used by the
903 // debugger to swap execution onto a BytecodeArray patched with breakpoints.
Ben Murdochc5610432016-08-08 18:44:38 +0100904 void PatchBytecodeArray(BytecodeArray* bytecode_array);
Ben Murdoch097c5b22016-05-18 11:27:45 +0100905
906 // Access to the interpreter register file for this frame.
Ben Murdochc5610432016-08-08 18:44:38 +0100907 Object* ReadInterpreterRegister(int register_index) const;
908 void WriteInterpreterRegister(int register_index, Object* value);
Ben Murdoch097c5b22016-05-18 11:27:45 +0100909
910 // Build a list with summaries for this frame including all inlined frames.
Ben Murdochc5610432016-08-08 18:44:38 +0100911 void Summarize(
912 List<FrameSummary>* frames,
913 FrameSummary::Mode mode = FrameSummary::kExactSummary) const override;
Ben Murdoch097c5b22016-05-18 11:27:45 +0100914
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000915 protected:
916 inline explicit InterpretedFrame(StackFrameIteratorBase* iterator);
917
Ben Murdoch097c5b22016-05-18 11:27:45 +0100918 Address GetExpressionAddress(int n) const override;
919
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000920 private:
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000921 friend class StackFrameIteratorBase;
Ben Murdochb0fe1622011-05-05 13:52:32 +0100922};
923
924
Steve Blocka7e24c12009-10-30 11:49:00 +0000925// Arguments adaptor frames are automatically inserted below
926// JavaScript frames when the actual number of parameters does not
927// match the formal number of parameters.
928class ArgumentsAdaptorFrame: public JavaScriptFrame {
929 public:
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000930 Type type() const override { return ARGUMENTS_ADAPTOR; }
Steve Blocka7e24c12009-10-30 11:49:00 +0000931
932 // Determine the code for the frame.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000933 Code* unchecked_code() const override;
Steve Blocka7e24c12009-10-30 11:49:00 +0000934
935 static ArgumentsAdaptorFrame* cast(StackFrame* frame) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000936 DCHECK(frame->is_arguments_adaptor());
Steve Blocka7e24c12009-10-30 11:49:00 +0000937 return static_cast<ArgumentsAdaptorFrame*>(frame);
938 }
939
940 // Printing support.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000941 void Print(StringStream* accumulator, PrintMode mode,
942 int index) const override;
Ben Murdoch589d6972011-11-30 16:04:58 +0000943
Ben Murdoch097c5b22016-05-18 11:27:45 +0100944 static int GetLength(Address fp);
945
Steve Blocka7e24c12009-10-30 11:49:00 +0000946 protected:
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000947 inline explicit ArgumentsAdaptorFrame(StackFrameIteratorBase* iterator);
Steve Blocka7e24c12009-10-30 11:49:00 +0000948
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000949 int GetNumberOfIncomingArguments() const override;
Ben Murdoch8b112d22011-06-08 16:22:53 +0100950
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000951 Address GetCallerStackPointer() const override;
Steve Blocka7e24c12009-10-30 11:49:00 +0000952
953 private:
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000954 friend class StackFrameIteratorBase;
Steve Blocka7e24c12009-10-30 11:49:00 +0000955};
956
Ben Murdochda12d292016-06-02 14:46:10 +0100957class WasmFrame : public StandardFrame {
958 public:
959 Type type() const override { return WASM; }
960
961 // GC support.
962 void Iterate(ObjectVisitor* v) const override;
963
964 // Printing support.
965 void Print(StringStream* accumulator, PrintMode mode,
966 int index) const override;
967
968 // Determine the code for the frame.
969 Code* unchecked_code() const override;
970
Ben Murdochc5610432016-08-08 18:44:38 +0100971 Object* wasm_obj();
972 uint32_t function_index();
973
974 Object* function_name();
975
Ben Murdochda12d292016-06-02 14:46:10 +0100976 static WasmFrame* cast(StackFrame* frame) {
977 DCHECK(frame->is_wasm());
978 return static_cast<WasmFrame*>(frame);
979 }
980
981 protected:
982 inline explicit WasmFrame(StackFrameIteratorBase* iterator);
983
984 Address GetCallerStackPointer() const override;
985
986 private:
987 friend class StackFrameIteratorBase;
988};
989
990class WasmToJsFrame : public StubFrame {
991 public:
992 Type type() const override { return WASM_TO_JS; }
993
994 protected:
995 inline explicit WasmToJsFrame(StackFrameIteratorBase* iterator);
996
997 private:
998 friend class StackFrameIteratorBase;
999};
1000
1001class JsToWasmFrame : public StubFrame {
1002 public:
1003 Type type() const override { return JS_TO_WASM; }
1004
1005 protected:
1006 inline explicit JsToWasmFrame(StackFrameIteratorBase* iterator);
1007
1008 private:
1009 friend class StackFrameIteratorBase;
1010};
Steve Blocka7e24c12009-10-30 11:49:00 +00001011
1012class InternalFrame: public StandardFrame {
1013 public:
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001014 Type type() const override { return INTERNAL; }
Steve Blocka7e24c12009-10-30 11:49:00 +00001015
1016 // Garbage collection support.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001017 void Iterate(ObjectVisitor* v) const override;
Steve Blocka7e24c12009-10-30 11:49:00 +00001018
1019 // Determine the code for the frame.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001020 Code* unchecked_code() const override;
Steve Blocka7e24c12009-10-30 11:49:00 +00001021
1022 static InternalFrame* cast(StackFrame* frame) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001023 DCHECK(frame->is_internal());
Steve Blocka7e24c12009-10-30 11:49:00 +00001024 return static_cast<InternalFrame*>(frame);
1025 }
1026
1027 protected:
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001028 inline explicit InternalFrame(StackFrameIteratorBase* iterator);
Steve Blocka7e24c12009-10-30 11:49:00 +00001029
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001030 Address GetCallerStackPointer() const override;
Steve Blocka7e24c12009-10-30 11:49:00 +00001031
1032 private:
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001033 friend class StackFrameIteratorBase;
1034};
1035
1036
1037class StubFailureTrampolineFrame: public StandardFrame {
1038 public:
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001039 Type type() const override { return STUB_FAILURE_TRAMPOLINE; }
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001040
1041 // Get the code associated with this frame.
1042 // This method could be called during marking phase of GC.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001043 Code* unchecked_code() const override;
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001044
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001045 void Iterate(ObjectVisitor* v) const override;
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001046
1047 // Architecture-specific register description.
1048 static Register fp_register();
1049 static Register context_register();
1050 static Register constant_pool_pointer_register();
1051
1052 protected:
1053 inline explicit StubFailureTrampolineFrame(
1054 StackFrameIteratorBase* iterator);
1055
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001056 Address GetCallerStackPointer() const override;
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001057
1058 private:
1059 friend class StackFrameIteratorBase;
Steve Blocka7e24c12009-10-30 11:49:00 +00001060};
1061
1062
1063// Construct frames are special trampoline frames introduced to handle
1064// function invocations through 'new'.
1065class ConstructFrame: public InternalFrame {
1066 public:
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001067 Type type() const override { return CONSTRUCT; }
Steve Blocka7e24c12009-10-30 11:49:00 +00001068
1069 static ConstructFrame* cast(StackFrame* frame) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001070 DCHECK(frame->is_construct());
Steve Blocka7e24c12009-10-30 11:49:00 +00001071 return static_cast<ConstructFrame*>(frame);
1072 }
1073
1074 protected:
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001075 inline explicit ConstructFrame(StackFrameIteratorBase* iterator);
Steve Blocka7e24c12009-10-30 11:49:00 +00001076
1077 private:
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001078 friend class StackFrameIteratorBase;
Steve Blocka7e24c12009-10-30 11:49:00 +00001079};
1080
1081
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001082class StackFrameIteratorBase BASE_EMBEDDED {
Steve Blocka7e24c12009-10-30 11:49:00 +00001083 public:
Ben Murdoch8b112d22011-06-08 16:22:53 +01001084 Isolate* isolate() const { return isolate_; }
1085
Steve Blocka7e24c12009-10-30 11:49:00 +00001086 bool done() const { return frame_ == NULL; }
Steve Blocka7e24c12009-10-30 11:49:00 +00001087
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001088 protected:
1089 // An iterator that iterates over a given thread's stack.
1090 StackFrameIteratorBase(Isolate* isolate, bool can_access_heap_objects);
Steve Blocka7e24c12009-10-30 11:49:00 +00001091
Ben Murdoch8b112d22011-06-08 16:22:53 +01001092 Isolate* isolate_;
Steve Blocka7e24c12009-10-30 11:49:00 +00001093#define DECLARE_SINGLETON(ignore, type) type type##_;
1094 STACK_FRAME_TYPE_LIST(DECLARE_SINGLETON)
1095#undef DECLARE_SINGLETON
1096 StackFrame* frame_;
1097 StackHandler* handler_;
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001098 const bool can_access_heap_objects_;
Steve Blocka7e24c12009-10-30 11:49:00 +00001099
1100 StackHandler* handler() const {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001101 DCHECK(!done());
Steve Blocka7e24c12009-10-30 11:49:00 +00001102 return handler_;
1103 }
1104
1105 // Get the type-specific frame singleton in a given state.
1106 StackFrame* SingletonFor(StackFrame::Type type, StackFrame::State* state);
1107 // A helper function, can return a NULL pointer.
1108 StackFrame* SingletonFor(StackFrame::Type type);
1109
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001110 private:
Steve Blocka7e24c12009-10-30 11:49:00 +00001111 friend class StackFrame;
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001112 DISALLOW_COPY_AND_ASSIGN(StackFrameIteratorBase);
1113};
1114
1115
1116class StackFrameIterator: public StackFrameIteratorBase {
1117 public:
1118 // An iterator that iterates over the isolate's current thread's stack,
1119 explicit StackFrameIterator(Isolate* isolate);
1120 // An iterator that iterates over a given thread's stack.
1121 StackFrameIterator(Isolate* isolate, ThreadLocalTop* t);
1122
1123 StackFrame* frame() const {
1124 DCHECK(!done());
1125 return frame_;
1126 }
1127 void Advance();
1128
1129 private:
1130 // Go back to the first frame.
1131 void Reset(ThreadLocalTop* top);
1132
Steve Blocka7e24c12009-10-30 11:49:00 +00001133 DISALLOW_COPY_AND_ASSIGN(StackFrameIterator);
1134};
1135
Steve Blocka7e24c12009-10-30 11:49:00 +00001136// Iterator that supports iterating through all JavaScript frames.
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001137class JavaScriptFrameIterator BASE_EMBEDDED {
Steve Blocka7e24c12009-10-30 11:49:00 +00001138 public:
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001139 inline explicit JavaScriptFrameIterator(Isolate* isolate);
1140 inline JavaScriptFrameIterator(Isolate* isolate, ThreadLocalTop* top);
Steve Blocka7e24c12009-10-30 11:49:00 +00001141 // Skip frames until the frame with the given id is reached.
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001142 JavaScriptFrameIterator(Isolate* isolate, StackFrame::Id id);
Steve Block44f0eee2011-05-26 01:26:41 +01001143
Steve Blocka7e24c12009-10-30 11:49:00 +00001144 inline JavaScriptFrame* frame() const;
1145
1146 bool done() const { return iterator_.done(); }
1147 void Advance();
1148
1149 // Advance to the frame holding the arguments for the current
1150 // frame. This only affects the current frame if it has adapted
1151 // arguments.
1152 void AdvanceToArgumentsFrame();
1153
Steve Blocka7e24c12009-10-30 11:49:00 +00001154 private:
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001155 StackFrameIterator iterator_;
Steve Blocka7e24c12009-10-30 11:49:00 +00001156};
1157
Ben Murdochc5610432016-08-08 18:44:38 +01001158// NOTE: The stack trace frame iterator is an iterator that only traverse proper
1159// JavaScript frames that have proper JavaScript functions and WASM frames.
1160// This excludes the problematic functions in runtime.js.
1161class StackTraceFrameIterator BASE_EMBEDDED {
Steve Blocka7e24c12009-10-30 11:49:00 +00001162 public:
Ben Murdoch8b112d22011-06-08 16:22:53 +01001163 explicit StackTraceFrameIterator(Isolate* isolate);
Ben Murdochc5610432016-08-08 18:44:38 +01001164 bool done() const { return iterator_.done(); }
Steve Blocka7e24c12009-10-30 11:49:00 +00001165 void Advance();
Leon Clarke4515c472010-02-03 11:58:03 +00001166
Ben Murdochc5610432016-08-08 18:44:38 +01001167 inline StandardFrame* frame() const;
1168
1169 inline bool is_javascript() const;
1170 inline bool is_wasm() const;
1171 inline JavaScriptFrame* javascript_frame() const;
1172 inline WasmFrame* wasm_frame() const;
1173
Leon Clarke4515c472010-02-03 11:58:03 +00001174 private:
Ben Murdochc5610432016-08-08 18:44:38 +01001175 StackFrameIterator iterator_;
1176 bool IsValidFrame(StackFrame* frame) const;
Steve Blocka7e24c12009-10-30 11:49:00 +00001177};
1178
1179
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001180class SafeStackFrameIterator: public StackFrameIteratorBase {
Steve Blocka7e24c12009-10-30 11:49:00 +00001181 public:
Steve Block44f0eee2011-05-26 01:26:41 +01001182 SafeStackFrameIterator(Isolate* isolate,
1183 Address fp, Address sp,
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001184 Address js_entry_sp);
Steve Blocka7e24c12009-10-30 11:49:00 +00001185
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001186 inline StackFrame* frame() const;
Steve Blocka7e24c12009-10-30 11:49:00 +00001187 void Advance();
Steve Blocka7e24c12009-10-30 11:49:00 +00001188
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001189 StackFrame::Type top_frame_type() const { return top_frame_type_; }
Leon Clarked91b9f72010-01-27 17:25:45 +00001190
1191 private:
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001192 void AdvanceOneFrame();
Kristian Monsen0d5e1162010-09-30 15:31:59 +01001193
Steve Blocka7e24c12009-10-30 11:49:00 +00001194 bool IsValidStackAddress(Address addr) const {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001195 return low_bound_ <= addr && addr <= high_bound_;
Steve Blocka7e24c12009-10-30 11:49:00 +00001196 }
Steve Blocka7e24c12009-10-30 11:49:00 +00001197 bool IsValidFrame(StackFrame* frame) const;
1198 bool IsValidCaller(StackFrame* frame);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001199 bool IsValidExitFrame(Address fp) const;
1200 bool IsValidTop(ThreadLocalTop* top) const;
Steve Blocka7e24c12009-10-30 11:49:00 +00001201
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001202 const Address low_bound_;
1203 const Address high_bound_;
1204 StackFrame::Type top_frame_type_;
1205 ExternalCallbackScope* external_callback_scope_;
Steve Blocka7e24c12009-10-30 11:49:00 +00001206};
Steve Blocka7e24c12009-10-30 11:49:00 +00001207
1208
1209class StackFrameLocator BASE_EMBEDDED {
1210 public:
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001211 explicit StackFrameLocator(Isolate* isolate) : iterator_(isolate) {}
1212
Steve Blocka7e24c12009-10-30 11:49:00 +00001213 // Find the nth JavaScript frame on the stack. The caller must
1214 // guarantee that such a frame exists.
1215 JavaScriptFrame* FindJavaScriptFrame(int n);
1216
1217 private:
1218 StackFrameIterator iterator_;
1219};
1220
1221
Steve Block6ded16b2010-05-10 14:33:55 +01001222// Reads all frames on the current stack and copies them into the current
1223// zone memory.
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001224Vector<StackFrame*> CreateStackMap(Isolate* isolate, Zone* zone);
Steve Block6ded16b2010-05-10 14:33:55 +01001225
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001226} // namespace internal
1227} // namespace v8
Steve Blocka7e24c12009-10-30 11:49:00 +00001228
1229#endif // V8_FRAMES_H_