blob: a1e438c6943494684ced2512f82f4ea78f598cfe [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) \
Ben Murdoch61f157c2016-09-16 13:49:30 +0100114 V(ARGUMENTS_ADAPTOR, ArgumentsAdaptorFrame) \
115 V(BUILTIN, BuiltinFrame)
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000116
Ben Murdoch097c5b22016-05-18 11:27:45 +0100117// Every pointer in a frame has a slot id. On 32-bit platforms, doubles consume
118// two slots.
119//
120// Stack slot indices >= 0 access the callee stack with slot 0 corresponding to
121// the callee's saved return address and 1 corresponding to the saved frame
122// pointer. Some frames have additional information stored in the fixed header,
123// for example JSFunctions store the function context and marker in the fixed
124// header, with slot index 2 corresponding to the current function context and 3
125// corresponding to the frame marker/JSFunction.
126//
127// slot JS frame
128// +-----------------+--------------------------------
129// -n-1 | parameter 0 | ^
130// |- - - - - - - - -| |
131// -n | | Caller
132// ... | ... | frame slots
133// -2 | parameter n-1 | (slot < 0)
134// |- - - - - - - - -| |
135// -1 | parameter n | v
136// -----+-----------------+--------------------------------
137// 0 | return addr | ^ ^
138// |- - - - - - - - -| | |
139// 1 | saved frame ptr | Fixed |
140// |- - - - - - - - -| Header <-- frame ptr |
141// 2 | [Constant Pool] | | |
142// |- - - - - - - - -| | |
Ben Murdochda12d292016-06-02 14:46:10 +0100143// 2+cp |Context/Frm. Type| v if a constant pool |
144// |-----------------+---- is used, cp = 1, |
145// 3+cp | | ^ otherwise, cp = 0 |
146// |- - - - - - - - -| | |
147// 4+cp | | | Callee
148// |- - - - - - - - -| | frame slots
149// ... | | Frame slots (slot >= 0)
150// |- - - - - - - - -| | |
151// | | v |
152// -----+-----------------+----- <-- stack ptr -------------
153//
154class CommonFrameConstants : public AllStatic {
155 public:
156 static const int kCallerFPOffset = 0 * kPointerSize;
157 static const int kCallerPCOffset = kCallerFPOffset + 1 * kFPOnStackSize;
158 static const int kCallerSPOffset = kCallerPCOffset + 1 * kPCOnStackSize;
159
160 // Fixed part of the frame consists of return address, caller fp,
161 // constant pool (if FLAG_enable_embedded_constant_pool), context, and
162 // function. StandardFrame::IterateExpressions assumes that kLastObjectOffset
163 // is the last object pointer.
164 static const int kFixedFrameSizeAboveFp = kPCOnStackSize + kFPOnStackSize;
165 static const int kFixedSlotCountAboveFp =
166 kFixedFrameSizeAboveFp / kPointerSize;
167 static const int kCPSlotSize =
168 FLAG_enable_embedded_constant_pool ? kPointerSize : 0;
169 static const int kCPSlotCount = kCPSlotSize / kPointerSize;
170 static const int kConstantPoolOffset = kCPSlotSize ? -1 * kPointerSize : 0;
171 static const int kContextOrFrameTypeSize = kPointerSize;
172 static const int kContextOrFrameTypeOffset =
173 -(kCPSlotSize + kContextOrFrameTypeSize);
174};
175
176// StandardFrames are used for interpreted, full-codegen and optimized
177// JavaScript frames. They always have a context below the saved fp/constant
178// pool and below that the JSFunction of the executing function.
179//
180// slot JS frame
181// +-----------------+--------------------------------
182// -n-1 | parameter 0 | ^
183// |- - - - - - - - -| |
184// -n | | Caller
185// ... | ... | frame slots
186// -2 | parameter n-1 | (slot < 0)
187// |- - - - - - - - -| |
188// -1 | parameter n | v
189// -----+-----------------+--------------------------------
190// 0 | return addr | ^ ^
191// |- - - - - - - - -| | |
192// 1 | saved frame ptr | Fixed |
193// |- - - - - - - - -| Header <-- frame ptr |
194// 2 | [Constant Pool] | | |
195// |- - - - - - - - -| | |
Ben Murdoch097c5b22016-05-18 11:27:45 +0100196// 2+cp | Context | | if a constant pool |
197// |- - - - - - - - -| | is used, cp = 1, |
Ben Murdochda12d292016-06-02 14:46:10 +0100198// 3+cp | JSFunction | v otherwise, cp = 0 |
Ben Murdoch097c5b22016-05-18 11:27:45 +0100199// +-----------------+---- |
200// 4+cp | | ^ Callee
201// |- - - - - - - - -| | frame slots
202// ... | | Frame slots (slot >= 0)
203// |- - - - - - - - -| | |
204// | | v |
205// -----+-----------------+----- <-- stack ptr -------------
206//
Ben Murdochda12d292016-06-02 14:46:10 +0100207class StandardFrameConstants : public CommonFrameConstants {
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000208 public:
Ben Murdochda12d292016-06-02 14:46:10 +0100209 static const int kFixedFrameSizeFromFp = 2 * kPointerSize + kCPSlotSize;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000210 static const int kFixedFrameSize =
211 kFixedFrameSizeAboveFp + kFixedFrameSizeFromFp;
Ben Murdochda12d292016-06-02 14:46:10 +0100212 static const int kFixedSlotCountFromFp = kFixedFrameSizeFromFp / kPointerSize;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000213 static const int kFixedSlotCount = kFixedFrameSize / kPointerSize;
Ben Murdochda12d292016-06-02 14:46:10 +0100214 static const int kContextOffset = kContextOrFrameTypeOffset;
215 static const int kFunctionOffset = -2 * kPointerSize - kCPSlotSize;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000216 static const int kExpressionsOffset = -3 * kPointerSize - kCPSlotSize;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000217 static const int kLastObjectOffset = kContextOffset;
218};
219
Ben Murdochda12d292016-06-02 14:46:10 +0100220// TypedFrames have a SMI type maker value below the saved FP/constant pool to
221// distinguish them from StandardFrames, which have a context in that position
222// instead.
223//
224// slot JS frame
225// +-----------------+--------------------------------
226// -n-1 | parameter 0 | ^
227// |- - - - - - - - -| |
228// -n | | Caller
229// ... | ... | frame slots
230// -2 | parameter n-1 | (slot < 0)
231// |- - - - - - - - -| |
232// -1 | parameter n | v
233// -----+-----------------+--------------------------------
234// 0 | return addr | ^ ^
235// |- - - - - - - - -| | |
236// 1 | saved frame ptr | Fixed |
237// |- - - - - - - - -| Header <-- frame ptr |
238// 2 | [Constant Pool] | | |
239// |- - - - - - - - -| | |
240// 2+cp |Frame Type Marker| v if a constant pool |
241// |-----------------+---- is used, cp = 1, |
242// 3+cp | | ^ otherwise, cp = 0 |
243// |- - - - - - - - -| | |
244// 4+cp | | | Callee
245// |- - - - - - - - -| | frame slots
246// ... | | Frame slots (slot >= 0)
247// |- - - - - - - - -| | |
248// | | v |
249// -----+-----------------+----- <-- stack ptr -------------
250//
251class TypedFrameConstants : public CommonFrameConstants {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000252 public:
Ben Murdochda12d292016-06-02 14:46:10 +0100253 static const int kFrameTypeSize = kContextOrFrameTypeSize;
254 static const int kFrameTypeOffset = kContextOrFrameTypeOffset;
255 static const int kFixedFrameSizeFromFp = kCPSlotSize + kFrameTypeSize;
256 static const int kFixedSlotCountFromFp = kFixedFrameSizeFromFp / kPointerSize;
257 static const int kFixedFrameSize =
258 StandardFrameConstants::kFixedFrameSizeAboveFp + kFixedFrameSizeFromFp;
259 static const int kFixedSlotCount = kFixedFrameSize / kPointerSize;
260 static const int kFirstPushedFrameValueOffset =
261 -StandardFrameConstants::kCPSlotSize - kFrameTypeSize - kPointerSize;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000262};
263
Ben Murdochda12d292016-06-02 14:46:10 +0100264#define TYPED_FRAME_PUSHED_VALUE_OFFSET(x) \
265 (TypedFrameConstants::kFirstPushedFrameValueOffset - (x)*kPointerSize)
266#define TYPED_FRAME_SIZE(count) \
267 (TypedFrameConstants::kFixedFrameSize + (count)*kPointerSize)
268#define TYPED_FRAME_SIZE_FROM_SP(count) \
269 (TypedFrameConstants::kFixedFrameSizeFromFp + (count)*kPointerSize)
270#define DEFINE_TYPED_FRAME_SIZES(count) \
271 static const int kFixedFrameSize = TYPED_FRAME_SIZE(count); \
272 static const int kFixedSlotCount = kFixedFrameSize / kPointerSize; \
273 static const int kFixedFrameSizeFromFp = TYPED_FRAME_SIZE_FROM_SP(count); \
274 static const int kFixedSlotCountFromFp = kFixedFrameSizeFromFp / kPointerSize
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000275
Ben Murdochda12d292016-06-02 14:46:10 +0100276class ArgumentsAdaptorFrameConstants : public TypedFrameConstants {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000277 public:
278 // FP-relative.
Ben Murdochda12d292016-06-02 14:46:10 +0100279 static const int kFunctionOffset = TYPED_FRAME_PUSHED_VALUE_OFFSET(0);
280 static const int kLengthOffset = TYPED_FRAME_PUSHED_VALUE_OFFSET(1);
281 DEFINE_TYPED_FRAME_SIZES(2);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000282};
283
Ben Murdoch61f157c2016-09-16 13:49:30 +0100284class BuiltinFrameConstants : public TypedFrameConstants {
285 public:
286 // FP-relative.
287 static const int kFunctionOffset = TYPED_FRAME_PUSHED_VALUE_OFFSET(0);
288 static const int kLengthOffset = TYPED_FRAME_PUSHED_VALUE_OFFSET(1);
289 DEFINE_TYPED_FRAME_SIZES(2);
290};
291
Ben Murdochda12d292016-06-02 14:46:10 +0100292class InternalFrameConstants : public TypedFrameConstants {
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000293 public:
294 // FP-relative.
Ben Murdochda12d292016-06-02 14:46:10 +0100295 static const int kCodeOffset = TYPED_FRAME_PUSHED_VALUE_OFFSET(0);
296 DEFINE_TYPED_FRAME_SIZES(1);
297};
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000298
Ben Murdochda12d292016-06-02 14:46:10 +0100299class FrameDropperFrameConstants : public InternalFrameConstants {
300 public:
301 // FP-relative.
302 static const int kFunctionOffset = TYPED_FRAME_PUSHED_VALUE_OFFSET(1);
303 DEFINE_TYPED_FRAME_SIZES(2);
304};
305
306class ConstructFrameConstants : public TypedFrameConstants {
307 public:
308 // FP-relative.
309 static const int kContextOffset = TYPED_FRAME_PUSHED_VALUE_OFFSET(0);
310 static const int kAllocationSiteOffset = TYPED_FRAME_PUSHED_VALUE_OFFSET(1);
311 static const int kLengthOffset = TYPED_FRAME_PUSHED_VALUE_OFFSET(2);
312 static const int kImplicitReceiverOffset = TYPED_FRAME_PUSHED_VALUE_OFFSET(3);
313 DEFINE_TYPED_FRAME_SIZES(4);
314};
315
316class StubFailureTrampolineFrameConstants : public InternalFrameConstants {
317 public:
318 static const int kArgumentsArgumentsOffset =
319 TYPED_FRAME_PUSHED_VALUE_OFFSET(0);
320 static const int kArgumentsLengthOffset = TYPED_FRAME_PUSHED_VALUE_OFFSET(1);
321 static const int kArgumentsPointerOffset = TYPED_FRAME_PUSHED_VALUE_OFFSET(2);
322 static const int kFixedHeaderBottomOffset = kArgumentsPointerOffset;
323 DEFINE_TYPED_FRAME_SIZES(3);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000324};
325
326
327class InterpreterFrameConstants : public AllStatic {
328 public:
329 // Fixed frame includes new.target and bytecode offset.
330 static const int kFixedFrameSize =
Ben Murdoch097c5b22016-05-18 11:27:45 +0100331 StandardFrameConstants::kFixedFrameSize + 3 * kPointerSize;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000332 static const int kFixedFrameSizeFromFp =
Ben Murdoch097c5b22016-05-18 11:27:45 +0100333 StandardFrameConstants::kFixedFrameSizeFromFp + 3 * kPointerSize;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000334
335 // FP-relative.
Ben Murdochc5610432016-08-08 18:44:38 +0100336 static const int kLastParamFromFp = StandardFrameConstants::kCallerSPOffset;
Ben Murdoch61f157c2016-09-16 13:49:30 +0100337 static const int kCallerPCOffsetFromFp =
338 StandardFrameConstants::kCallerPCOffset;
Ben Murdoch097c5b22016-05-18 11:27:45 +0100339 static const int kNewTargetFromFp =
340 -StandardFrameConstants::kFixedFrameSizeFromFp - 1 * kPointerSize;
341 static const int kBytecodeArrayFromFp =
342 -StandardFrameConstants::kFixedFrameSizeFromFp - 2 * kPointerSize;
343 static const int kBytecodeOffsetFromFp =
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000344 -StandardFrameConstants::kFixedFrameSizeFromFp - 3 * kPointerSize;
Ben Murdochc5610432016-08-08 18:44:38 +0100345 static const int kRegisterFileFromFp =
Ben Murdoch097c5b22016-05-18 11:27:45 +0100346 -StandardFrameConstants::kFixedFrameSizeFromFp - 4 * kPointerSize;
347
Ben Murdochc5610432016-08-08 18:44:38 +0100348 static const int kExpressionsOffset = kRegisterFileFromFp;
Ben Murdoch097c5b22016-05-18 11:27:45 +0100349
350 // Expression index for {StandardFrame::GetExpressionAddress}.
351 static const int kBytecodeArrayExpressionIndex = -2;
352 static const int kBytecodeOffsetExpressionIndex = -1;
353 static const int kRegisterFileExpressionIndex = 0;
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000354};
Steve Blocka7e24c12009-10-30 11:49:00 +0000355
Ben Murdoch097c5b22016-05-18 11:27:45 +0100356inline static int FPOffsetToFrameSlot(int frame_offset) {
357 return StandardFrameConstants::kFixedSlotCountAboveFp - 1 -
358 frame_offset / kPointerSize;
359}
360
361inline static int FrameSlotToFPOffset(int slot) {
362 return (StandardFrameConstants::kFixedSlotCountAboveFp - 1 - slot) *
363 kPointerSize;
364}
Steve Blocka7e24c12009-10-30 11:49:00 +0000365
366// Abstract base class for all stack frames.
367class StackFrame BASE_EMBEDDED {
368 public:
369#define DECLARE_TYPE(type, ignore) type,
370 enum Type {
371 NONE = 0,
372 STACK_FRAME_TYPE_LIST(DECLARE_TYPE)
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100373 NUMBER_OF_TYPES,
374 // Used by FrameScope to indicate that the stack frame is constructed
375 // manually and the FrameScope does not need to emit code.
376 MANUAL
Steve Blocka7e24c12009-10-30 11:49:00 +0000377 };
378#undef DECLARE_TYPE
379
380 // Opaque data type for identifying stack frames. Used extensively
381 // by the debugger.
Iain Merrick75681382010-08-19 15:07:18 +0100382 // ID_MIN_VALUE and ID_MAX_VALUE are specified to ensure that enumeration type
383 // has correct value range (see Issue 830 for more details).
384 enum Id {
385 ID_MIN_VALUE = kMinInt,
386 ID_MAX_VALUE = kMaxInt,
387 NO_ID = 0
388 };
Steve Blocka7e24c12009-10-30 11:49:00 +0000389
Steve Block053d10c2011-06-13 19:13:29 +0100390 // Used to mark the outermost JS entry frame.
391 enum JsFrameMarker {
392 INNER_JSENTRY_FRAME = 0,
393 OUTERMOST_JSENTRY_FRAME = 1
394 };
395
Kristian Monsen0d5e1162010-09-30 15:31:59 +0100396 struct State {
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000397 State() : sp(NULL), fp(NULL), pc_address(NULL),
398 constant_pool_address(NULL) { }
Kristian Monsen0d5e1162010-09-30 15:31:59 +0100399 Address sp;
400 Address fp;
401 Address* pc_address;
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000402 Address* constant_pool_address;
Kristian Monsen0d5e1162010-09-30 15:31:59 +0100403 };
404
Ben Murdoch8b112d22011-06-08 16:22:53 +0100405 // Copy constructor; it breaks the connection to host iterator
406 // (as an iterator usually lives on stack).
Steve Block6ded16b2010-05-10 14:33:55 +0100407 StackFrame(const StackFrame& original) {
408 this->state_ = original.state_;
409 this->iterator_ = NULL;
Ben Murdoch8b112d22011-06-08 16:22:53 +0100410 this->isolate_ = original.isolate_;
Steve Block6ded16b2010-05-10 14:33:55 +0100411 }
412
Steve Blocka7e24c12009-10-30 11:49:00 +0000413 // Type testers.
414 bool is_entry() const { return type() == ENTRY; }
415 bool is_entry_construct() const { return type() == ENTRY_CONSTRUCT; }
416 bool is_exit() const { return type() == EXIT; }
Ben Murdochb0fe1622011-05-05 13:52:32 +0100417 bool is_optimized() const { return type() == OPTIMIZED; }
Ben Murdoch097c5b22016-05-18 11:27:45 +0100418 bool is_interpreted() const { return type() == INTERPRETED; }
Ben Murdochda12d292016-06-02 14:46:10 +0100419 bool is_wasm() const { return type() == WASM; }
420 bool is_wasm_to_js() const { return type() == WASM_TO_JS; }
421 bool is_js_to_wasm() const { return type() == JS_TO_WASM; }
Steve Blocka7e24c12009-10-30 11:49:00 +0000422 bool is_arguments_adaptor() const { return type() == ARGUMENTS_ADAPTOR; }
Ben Murdoch61f157c2016-09-16 13:49:30 +0100423 bool is_builtin() const { return type() == BUILTIN; }
Steve Blocka7e24c12009-10-30 11:49:00 +0000424 bool is_internal() const { return type() == INTERNAL; }
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000425 bool is_stub_failure_trampoline() const {
426 return type() == STUB_FAILURE_TRAMPOLINE;
427 }
Steve Blocka7e24c12009-10-30 11:49:00 +0000428 bool is_construct() const { return type() == CONSTRUCT; }
429 virtual bool is_standard() const { return false; }
430
Ben Murdochb0fe1622011-05-05 13:52:32 +0100431 bool is_java_script() const {
432 Type type = this->type();
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000433 return (type == JAVA_SCRIPT) || (type == OPTIMIZED) ||
Ben Murdoch61f157c2016-09-16 13:49:30 +0100434 (type == INTERPRETED) || (type == BUILTIN);
Ben Murdochb0fe1622011-05-05 13:52:32 +0100435 }
436
Steve Blocka7e24c12009-10-30 11:49:00 +0000437 // Accessors.
438 Address sp() const { return state_.sp; }
439 Address fp() const { return state_.fp; }
440 Address caller_sp() const { return GetCallerStackPointer(); }
441
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000442 // If this frame is optimized and was dynamically aligned return its old
443 // unaligned frame pointer. When the frame is deoptimized its FP will shift
444 // up one word and become unaligned.
445 Address UnpaddedFP() const;
446
Steve Blocka7e24c12009-10-30 11:49:00 +0000447 Address pc() const { return *pc_address(); }
448 void set_pc(Address pc) { *pc_address() = pc; }
449
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000450 Address constant_pool() const { return *constant_pool_address(); }
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000451 void set_constant_pool(Address constant_pool) {
452 *constant_pool_address() = constant_pool;
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000453 }
454
Steve Block6ded16b2010-05-10 14:33:55 +0100455 virtual void SetCallerFp(Address caller_fp) = 0;
456
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000457 // Manually changes value of fp in this object.
458 void UpdateFp(Address fp) { state_.fp = fp; }
459
Steve Blocka7e24c12009-10-30 11:49:00 +0000460 Address* pc_address() const { return state_.pc_address; }
461
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000462 Address* constant_pool_address() const {
463 return state_.constant_pool_address;
464 }
465
Steve Blocka7e24c12009-10-30 11:49:00 +0000466 // Get the id of this stack frame.
467 Id id() const { return static_cast<Id>(OffsetFrom(caller_sp())); }
468
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000469 // Get the top handler from the current stack iterator.
470 inline StackHandler* top_handler() const;
Steve Blocka7e24c12009-10-30 11:49:00 +0000471
472 // Get the type of this frame.
473 virtual Type type() const = 0;
474
475 // Get the code associated with this frame.
Iain Merrick75681382010-08-19 15:07:18 +0100476 // This method could be called during marking phase of GC.
477 virtual Code* unchecked_code() const = 0;
478
479 // Get the code associated with this frame.
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100480 inline Code* LookupCode() const;
Kristian Monsen80d68ea2010-09-08 11:05:35 +0100481
482 // Get the code object that contains the given pc.
Steve Block44f0eee2011-05-26 01:26:41 +0100483 static inline Code* GetContainingCode(Isolate* isolate, Address pc);
Steve Blocka7e24c12009-10-30 11:49:00 +0000484
Ben Murdochb0fe1622011-05-05 13:52:32 +0100485 // Get the code object containing the given pc and fill in the
486 // safepoint entry and the number of stack slots. The pc must be at
487 // a safepoint.
Ben Murdoch8b112d22011-06-08 16:22:53 +0100488 static Code* GetSafepointData(Isolate* isolate,
489 Address pc,
Ben Murdochb8e0da22011-05-16 14:20:40 +0100490 SafepointEntry* safepoint_entry,
Ben Murdochb0fe1622011-05-05 13:52:32 +0100491 unsigned* stack_slots);
492
Kristian Monsen80d68ea2010-09-08 11:05:35 +0100493 virtual void Iterate(ObjectVisitor* v) const = 0;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000494 static void IteratePc(ObjectVisitor* v, Address* pc_address,
495 Address* constant_pool_address, Code* holder);
Steve Blocka7e24c12009-10-30 11:49:00 +0000496
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100497 // Sets a callback function for return-address rewriting profilers
498 // to resolve the location of a return address to the location of the
499 // profiler's stashed return address.
500 static void SetReturnAddressLocationResolver(
501 ReturnAddressLocationResolver resolver);
Steve Blocka7e24c12009-10-30 11:49:00 +0000502
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000503 // Resolves pc_address through the resolution address function if one is set.
504 static inline Address* ResolveReturnAddressLocation(Address* pc_address);
505
Steve Blocka7e24c12009-10-30 11:49:00 +0000506 // Printing support.
507 enum PrintMode { OVERVIEW, DETAILS };
508 virtual void Print(StringStream* accumulator,
509 PrintMode mode,
510 int index) const { }
511
Ben Murdoch8b112d22011-06-08 16:22:53 +0100512 Isolate* isolate() const { return isolate_; }
513
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000514 protected:
515 inline explicit StackFrame(StackFrameIteratorBase* iterator);
516 virtual ~StackFrame() { }
517
Steve Blocka7e24c12009-10-30 11:49:00 +0000518 // Compute the stack pointer for the calling frame.
519 virtual Address GetCallerStackPointer() const = 0;
520
521 // Printing support.
522 static void PrintIndex(StringStream* accumulator,
523 PrintMode mode,
524 int index);
525
Steve Blocka7e24c12009-10-30 11:49:00 +0000526 // Compute the stack frame type for the given state.
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000527 static Type ComputeType(const StackFrameIteratorBase* iterator, State* state);
528
529#ifdef DEBUG
530 bool can_access_heap_objects() const;
531#endif
Steve Blocka7e24c12009-10-30 11:49:00 +0000532
533 private:
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000534 const StackFrameIteratorBase* iterator_;
Ben Murdoch8b112d22011-06-08 16:22:53 +0100535 Isolate* isolate_;
Steve Blocka7e24c12009-10-30 11:49:00 +0000536 State state_;
537
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000538 static ReturnAddressLocationResolver return_address_location_resolver_;
539
Steve Blocka7e24c12009-10-30 11:49:00 +0000540 // Fill in the state of the calling frame.
541 virtual void ComputeCallerState(State* state) const = 0;
542
543 // Get the type and the state of the calling frame.
544 virtual Type GetCallerState(State* state) const;
545
Ben Murdoch8b112d22011-06-08 16:22:53 +0100546 static const intptr_t kIsolateTag = 1;
547
Steve Blocka7e24c12009-10-30 11:49:00 +0000548 friend class StackFrameIterator;
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000549 friend class StackFrameIteratorBase;
Steve Blocka7e24c12009-10-30 11:49:00 +0000550 friend class StackHandlerIterator;
551 friend class SafeStackFrameIterator;
552
Steve Block6ded16b2010-05-10 14:33:55 +0100553 private:
554 void operator=(const StackFrame& original);
Steve Blocka7e24c12009-10-30 11:49:00 +0000555};
556
557
558// Entry frames are used to enter JavaScript execution from C.
559class EntryFrame: public StackFrame {
560 public:
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000561 Type type() const override { return ENTRY; }
Steve Blocka7e24c12009-10-30 11:49:00 +0000562
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000563 Code* unchecked_code() const override;
Steve Blocka7e24c12009-10-30 11:49:00 +0000564
565 // Garbage collection support.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000566 void Iterate(ObjectVisitor* v) const override;
Steve Blocka7e24c12009-10-30 11:49:00 +0000567
568 static EntryFrame* cast(StackFrame* frame) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000569 DCHECK(frame->is_entry());
Steve Blocka7e24c12009-10-30 11:49:00 +0000570 return static_cast<EntryFrame*>(frame);
571 }
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000572 void SetCallerFp(Address caller_fp) override;
Steve Blocka7e24c12009-10-30 11:49:00 +0000573
574 protected:
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000575 inline explicit EntryFrame(StackFrameIteratorBase* iterator);
Steve Blocka7e24c12009-10-30 11:49:00 +0000576
577 // The caller stack pointer for entry frames is always zero. The
578 // real information about the caller frame is available through the
579 // link to the top exit frame.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000580 Address GetCallerStackPointer() const override { return 0; }
Steve Blocka7e24c12009-10-30 11:49:00 +0000581
582 private:
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000583 void ComputeCallerState(State* state) const override;
584 Type GetCallerState(State* state) const override;
Steve Blocka7e24c12009-10-30 11:49:00 +0000585
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000586 friend class StackFrameIteratorBase;
Steve Blocka7e24c12009-10-30 11:49:00 +0000587};
588
589
590class EntryConstructFrame: public EntryFrame {
591 public:
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000592 Type type() const override { return ENTRY_CONSTRUCT; }
Steve Blocka7e24c12009-10-30 11:49:00 +0000593
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000594 Code* unchecked_code() const override;
Steve Blocka7e24c12009-10-30 11:49:00 +0000595
596 static EntryConstructFrame* cast(StackFrame* frame) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000597 DCHECK(frame->is_entry_construct());
Steve Blocka7e24c12009-10-30 11:49:00 +0000598 return static_cast<EntryConstructFrame*>(frame);
599 }
600
601 protected:
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000602 inline explicit EntryConstructFrame(StackFrameIteratorBase* iterator);
Steve Blocka7e24c12009-10-30 11:49:00 +0000603
604 private:
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000605 friend class StackFrameIteratorBase;
Steve Blocka7e24c12009-10-30 11:49:00 +0000606};
607
608
609// Exit frames are used to exit JavaScript execution and go to C.
610class ExitFrame: public StackFrame {
611 public:
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000612 Type type() const override { return EXIT; }
Steve Blocka7e24c12009-10-30 11:49:00 +0000613
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000614 Code* unchecked_code() const override;
Steve Blocka7e24c12009-10-30 11:49:00 +0000615
Steve Blockd0582a62009-12-15 09:54:21 +0000616 Object*& code_slot() const;
617
Steve Blocka7e24c12009-10-30 11:49:00 +0000618 // Garbage collection support.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000619 void Iterate(ObjectVisitor* v) const override;
Steve Blocka7e24c12009-10-30 11:49:00 +0000620
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000621 void SetCallerFp(Address caller_fp) override;
Steve Block6ded16b2010-05-10 14:33:55 +0100622
Steve Blocka7e24c12009-10-30 11:49:00 +0000623 static ExitFrame* cast(StackFrame* frame) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000624 DCHECK(frame->is_exit());
Steve Blocka7e24c12009-10-30 11:49:00 +0000625 return static_cast<ExitFrame*>(frame);
626 }
627
628 // Compute the state and type of an exit frame given a frame
629 // pointer. Used when constructing the first stack frame seen by an
630 // iterator and the frames following entry frames.
631 static Type GetStateForFramePointer(Address fp, State* state);
Kristian Monsen0d5e1162010-09-30 15:31:59 +0100632 static Address ComputeStackPointer(Address fp);
633 static void FillState(Address fp, Address sp, State* state);
Steve Blocka7e24c12009-10-30 11:49:00 +0000634
635 protected:
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000636 inline explicit ExitFrame(StackFrameIteratorBase* iterator);
Steve Blocka7e24c12009-10-30 11:49:00 +0000637
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000638 Address GetCallerStackPointer() const override;
Steve Blocka7e24c12009-10-30 11:49:00 +0000639
640 private:
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000641 void ComputeCallerState(State* state) const override;
Steve Blocka7e24c12009-10-30 11:49:00 +0000642
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000643 friend class StackFrameIteratorBase;
Steve Blocka7e24c12009-10-30 11:49:00 +0000644};
645
Ben Murdochc5610432016-08-08 18:44:38 +0100646class JavaScriptFrame;
Steve Blocka7e24c12009-10-30 11:49:00 +0000647
Ben Murdochc5610432016-08-08 18:44:38 +0100648class FrameSummary BASE_EMBEDDED {
649 public:
650 // Mode for JavaScriptFrame::Summarize. Exact summary is required to produce
651 // an exact stack trace. It will trigger an assertion failure if that is not
652 // possible, e.g., because of missing deoptimization information. The
653 // approximate mode should produce a summary even without deoptimization
654 // information, but it might miss frames.
655 enum Mode { kExactSummary, kApproximateSummary };
656
657 FrameSummary(Object* receiver, JSFunction* function,
658 AbstractCode* abstract_code, int code_offset,
659 bool is_constructor, Mode mode = kExactSummary);
660
661 static FrameSummary GetFirst(JavaScriptFrame* frame);
662
663 Handle<Object> receiver() { return receiver_; }
664 Handle<JSFunction> function() { return function_; }
665 Handle<AbstractCode> abstract_code() { return abstract_code_; }
666 int code_offset() { return code_offset_; }
667 bool is_constructor() { return is_constructor_; }
668
669 void Print();
670
671 private:
672 Handle<Object> receiver_;
673 Handle<JSFunction> function_;
674 Handle<AbstractCode> abstract_code_;
675 int code_offset_;
676 bool is_constructor_;
677};
678
679class StandardFrame : public StackFrame {
Steve Blocka7e24c12009-10-30 11:49:00 +0000680 public:
681 // Testers.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000682 bool is_standard() const override { return true; }
Steve Blocka7e24c12009-10-30 11:49:00 +0000683
684 // Accessors.
685 inline Object* context() const;
686
687 // Access the expressions in the stack frame including locals.
688 inline Object* GetExpression(int index) const;
689 inline void SetExpression(int index, Object* value);
690 int ComputeExpressionsCount() const;
691
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000692 void SetCallerFp(Address caller_fp) override;
Steve Block6ded16b2010-05-10 14:33:55 +0100693
Steve Blocka7e24c12009-10-30 11:49:00 +0000694 static StandardFrame* cast(StackFrame* frame) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000695 DCHECK(frame->is_standard());
Steve Blocka7e24c12009-10-30 11:49:00 +0000696 return static_cast<StandardFrame*>(frame);
697 }
698
699 protected:
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000700 inline explicit StandardFrame(StackFrameIteratorBase* iterator);
Steve Blocka7e24c12009-10-30 11:49:00 +0000701
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000702 void ComputeCallerState(State* state) const override;
Steve Blocka7e24c12009-10-30 11:49:00 +0000703
704 // Accessors.
705 inline Address caller_fp() const;
706 inline Address caller_pc() const;
707
708 // Computes the address of the PC field in the standard frame given
709 // by the provided frame pointer.
710 static inline Address ComputePCAddress(Address fp);
711
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000712 // Computes the address of the constant pool field in the standard
713 // frame given by the provided frame pointer.
714 static inline Address ComputeConstantPoolAddress(Address fp);
715
Steve Blocka7e24c12009-10-30 11:49:00 +0000716 // Iterate over expression stack including stack handlers, locals,
717 // and parts of the fixed part including context and code fields.
718 void IterateExpressions(ObjectVisitor* v) const;
719
720 // Returns the address of the n'th expression stack element.
Ben Murdoch097c5b22016-05-18 11:27:45 +0100721 virtual Address GetExpressionAddress(int n) const;
Steve Blocka7e24c12009-10-30 11:49:00 +0000722
Steve Blocka7e24c12009-10-30 11:49:00 +0000723 // Determines if the standard frame for the given frame pointer is
724 // an arguments adaptor frame.
725 static inline bool IsArgumentsAdaptorFrame(Address fp);
726
727 // Determines if the standard frame for the given frame pointer is a
728 // construct frame.
729 static inline bool IsConstructFrame(Address fp);
730
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000731 // Used by OptimizedFrames and StubFrames.
732 void IterateCompiledFrame(ObjectVisitor* v) const;
733
Steve Blocka7e24c12009-10-30 11:49:00 +0000734 private:
735 friend class StackFrame;
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000736 friend class SafeStackFrameIterator;
Steve Blocka7e24c12009-10-30 11:49:00 +0000737};
738
Ben Murdochda12d292016-06-02 14:46:10 +0100739class JavaScriptFrame : public StandardFrame {
Steve Blocka7e24c12009-10-30 11:49:00 +0000740 public:
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000741 Type type() const override { return JAVA_SCRIPT; }
Steve Blocka7e24c12009-10-30 11:49:00 +0000742
Ben Murdochc5610432016-08-08 18:44:38 +0100743 // Build a list with summaries for this frame including all inlined frames.
744 virtual void Summarize(
745 List<FrameSummary>* frames,
746 FrameSummary::Mode mode = FrameSummary::kExactSummary) const;
747
Steve Blocka7e24c12009-10-30 11:49:00 +0000748 // Accessors.
Ben Murdochc5610432016-08-08 18:44:38 +0100749 virtual JSFunction* function() const;
750 virtual Object* receiver() const;
751
Steve Blocka7e24c12009-10-30 11:49:00 +0000752 inline void set_receiver(Object* value);
753
754 // Access the parameters.
Ben Murdoch8b112d22011-06-08 16:22:53 +0100755 inline Address GetParameterSlot(int index) const;
756 inline Object* GetParameter(int index) const;
757 inline int ComputeParametersCount() const {
758 return GetNumberOfIncomingArguments();
759 }
Steve Blocka7e24c12009-10-30 11:49:00 +0000760
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000761 // Access the operand stack.
762 inline Address GetOperandSlot(int index) const;
763 inline Object* GetOperand(int index) const;
764 inline int ComputeOperandsCount() const;
765
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000766 // Generator support to preserve operand stack.
767 void SaveOperandStack(FixedArray* store) const;
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000768
769 // Debugger access.
770 void SetParameterValue(int index, Object* value) const;
771
Steve Blocka7e24c12009-10-30 11:49:00 +0000772 // Check if this frame is a constructor frame invoked through 'new'.
773 bool IsConstructor() const;
774
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000775 // Determines whether this frame includes inlined activations. To get details
776 // about the inlined frames use {GetFunctions} and {Summarize}.
777 bool HasInlinedFrames() const;
778
Steve Blocka7e24c12009-10-30 11:49:00 +0000779 // Check if this frame has "adapted" arguments in the sense that the
780 // actual passed arguments are available in an arguments adaptor
781 // frame below it on the stack.
782 inline bool has_adapted_arguments() const;
Ben Murdoch3fb3ca82011-12-02 17:19:32 +0000783 int GetArgumentsLength() const;
Steve Blocka7e24c12009-10-30 11:49:00 +0000784
785 // Garbage collection support.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000786 void Iterate(ObjectVisitor* v) const override;
Steve Blocka7e24c12009-10-30 11:49:00 +0000787
788 // Printing support.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000789 void Print(StringStream* accumulator, PrintMode mode,
790 int index) const override;
Steve Blocka7e24c12009-10-30 11:49:00 +0000791
792 // Determine the code for the frame.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000793 Code* unchecked_code() const override;
Ben Murdoch3fb3ca82011-12-02 17:19:32 +0000794
Ben Murdochb0fe1622011-05-05 13:52:32 +0100795 // Return a list with JSFunctions of this frame.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000796 virtual void GetFunctions(List<JSFunction*>* functions) const;
Ben Murdochb0fe1622011-05-05 13:52:32 +0100797
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000798 // Lookup exception handler for current {pc}, returns -1 if none found. Also
Ben Murdoch097c5b22016-05-18 11:27:45 +0100799 // returns data associated with the handler site specific to the frame type:
800 // - JavaScriptFrame : Data is the stack depth at entry of the try-block.
801 // - OptimizedFrame : Data is the stack slot count of the entire frame.
802 // - InterpretedFrame: Data is the register index holding the context.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000803 virtual int LookupExceptionHandlerInTable(
Ben Murdoch097c5b22016-05-18 11:27:45 +0100804 int* data, HandlerTable::CatchPrediction* prediction);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000805
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000806 // Architecture-specific register description.
807 static Register fp_register();
808 static Register context_register();
809 static Register constant_pool_pointer_register();
810
Steve Blocka7e24c12009-10-30 11:49:00 +0000811 static JavaScriptFrame* cast(StackFrame* frame) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000812 DCHECK(frame->is_java_script());
Steve Blocka7e24c12009-10-30 11:49:00 +0000813 return static_cast<JavaScriptFrame*>(frame);
814 }
815
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000816 static void PrintFunctionAndOffset(JSFunction* function, Code* code,
817 Address pc, FILE* file,
818 bool print_line_number);
819
820 static void PrintTop(Isolate* isolate, FILE* file, bool print_args,
821 bool print_line_number);
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100822
Steve Blocka7e24c12009-10-30 11:49:00 +0000823 protected:
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000824 inline explicit JavaScriptFrame(StackFrameIteratorBase* iterator);
Steve Blocka7e24c12009-10-30 11:49:00 +0000825
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000826 Address GetCallerStackPointer() const override;
Steve Blocka7e24c12009-10-30 11:49:00 +0000827
Ben Murdoch8b112d22011-06-08 16:22:53 +0100828 virtual int GetNumberOfIncomingArguments() const;
829
Ben Murdochb0fe1622011-05-05 13:52:32 +0100830 // Garbage collection support. Iterates over incoming arguments,
831 // receiver, and any callee-saved registers.
832 void IterateArguments(ObjectVisitor* v) const;
833
Steve Blocka7e24c12009-10-30 11:49:00 +0000834 private:
Steve Blocka7e24c12009-10-30 11:49:00 +0000835 inline Object* function_slot_object() const;
836
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000837 friend class StackFrameIteratorBase;
838};
839
840
841class StubFrame : public StandardFrame {
842 public:
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000843 Type type() const override { return STUB; }
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000844
845 // GC support.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000846 void Iterate(ObjectVisitor* v) const override;
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000847
848 // Determine the code for the frame.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000849 Code* unchecked_code() const override;
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000850
851 protected:
852 inline explicit StubFrame(StackFrameIteratorBase* iterator);
853
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000854 Address GetCallerStackPointer() const override;
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000855
856 virtual int GetNumberOfIncomingArguments() const;
857
858 friend class StackFrameIteratorBase;
Steve Blocka7e24c12009-10-30 11:49:00 +0000859};
860
861
Ben Murdochb0fe1622011-05-05 13:52:32 +0100862class OptimizedFrame : public JavaScriptFrame {
863 public:
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000864 Type type() const override { return OPTIMIZED; }
Ben Murdochb0fe1622011-05-05 13:52:32 +0100865
866 // GC support.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000867 void Iterate(ObjectVisitor* v) const override;
Ben Murdoch3fb3ca82011-12-02 17:19:32 +0000868
Ben Murdochb0fe1622011-05-05 13:52:32 +0100869 // Return a list with JSFunctions of this frame.
870 // The functions are ordered bottom-to-top (i.e. functions.last()
871 // is the top-most activation)
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000872 void GetFunctions(List<JSFunction*>* functions) const override;
Ben Murdochb0fe1622011-05-05 13:52:32 +0100873
Ben Murdochc5610432016-08-08 18:44:38 +0100874 void Summarize(
875 List<FrameSummary>* frames,
876 FrameSummary::Mode mode = FrameSummary::kExactSummary) const override;
Ben Murdochb0fe1622011-05-05 13:52:32 +0100877
Ben Murdoch097c5b22016-05-18 11:27:45 +0100878 // Lookup exception handler for current {pc}, returns -1 if none found.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000879 int LookupExceptionHandlerInTable(
Ben Murdoch097c5b22016-05-18 11:27:45 +0100880 int* data, HandlerTable::CatchPrediction* prediction) override;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000881
882 DeoptimizationInputData* GetDeoptimizationData(int* deopt_index) const;
883
884 static int StackSlotOffsetRelativeToFp(int slot_index);
Ben Murdochb0fe1622011-05-05 13:52:32 +0100885
886 protected:
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000887 inline explicit OptimizedFrame(StackFrameIteratorBase* iterator);
Ben Murdochb0fe1622011-05-05 13:52:32 +0100888
889 private:
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000890 friend class StackFrameIteratorBase;
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000891
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000892 Object* StackSlotAt(int index) const;
893};
894
895
896class InterpretedFrame : public JavaScriptFrame {
Ben Murdoch097c5b22016-05-18 11:27:45 +0100897 public:
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000898 Type type() const override { return INTERPRETED; }
899
Ben Murdoch097c5b22016-05-18 11:27:45 +0100900 // Lookup exception handler for current {pc}, returns -1 if none found.
901 int LookupExceptionHandlerInTable(
902 int* data, HandlerTable::CatchPrediction* prediction) override;
903
904 // Returns the current offset into the bytecode stream.
905 int GetBytecodeOffset() const;
906
907 // Updates the current offset into the bytecode stream, mainly used for stack
908 // unwinding to continue execution at a different bytecode offset.
909 void PatchBytecodeOffset(int new_offset);
910
911 // Returns the frame's current bytecode array.
Ben Murdochc5610432016-08-08 18:44:38 +0100912 BytecodeArray* GetBytecodeArray() const;
Ben Murdoch097c5b22016-05-18 11:27:45 +0100913
914 // Updates the frame's BytecodeArray with |bytecode_array|. Used by the
915 // debugger to swap execution onto a BytecodeArray patched with breakpoints.
Ben Murdochc5610432016-08-08 18:44:38 +0100916 void PatchBytecodeArray(BytecodeArray* bytecode_array);
Ben Murdoch097c5b22016-05-18 11:27:45 +0100917
918 // Access to the interpreter register file for this frame.
Ben Murdochc5610432016-08-08 18:44:38 +0100919 Object* ReadInterpreterRegister(int register_index) const;
920 void WriteInterpreterRegister(int register_index, Object* value);
Ben Murdoch097c5b22016-05-18 11:27:45 +0100921
922 // Build a list with summaries for this frame including all inlined frames.
Ben Murdochc5610432016-08-08 18:44:38 +0100923 void Summarize(
924 List<FrameSummary>* frames,
925 FrameSummary::Mode mode = FrameSummary::kExactSummary) const override;
Ben Murdoch097c5b22016-05-18 11:27:45 +0100926
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000927 protected:
928 inline explicit InterpretedFrame(StackFrameIteratorBase* iterator);
929
Ben Murdoch097c5b22016-05-18 11:27:45 +0100930 Address GetExpressionAddress(int n) const override;
931
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000932 private:
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000933 friend class StackFrameIteratorBase;
Ben Murdochb0fe1622011-05-05 13:52:32 +0100934};
935
936
Steve Blocka7e24c12009-10-30 11:49:00 +0000937// Arguments adaptor frames are automatically inserted below
938// JavaScript frames when the actual number of parameters does not
939// match the formal number of parameters.
940class ArgumentsAdaptorFrame: public JavaScriptFrame {
941 public:
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000942 Type type() const override { return ARGUMENTS_ADAPTOR; }
Steve Blocka7e24c12009-10-30 11:49:00 +0000943
944 // Determine the code for the frame.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000945 Code* unchecked_code() const override;
Steve Blocka7e24c12009-10-30 11:49:00 +0000946
947 static ArgumentsAdaptorFrame* cast(StackFrame* frame) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000948 DCHECK(frame->is_arguments_adaptor());
Steve Blocka7e24c12009-10-30 11:49:00 +0000949 return static_cast<ArgumentsAdaptorFrame*>(frame);
950 }
951
952 // Printing support.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000953 void Print(StringStream* accumulator, PrintMode mode,
954 int index) const override;
Ben Murdoch589d6972011-11-30 16:04:58 +0000955
Ben Murdoch097c5b22016-05-18 11:27:45 +0100956 static int GetLength(Address fp);
957
Steve Blocka7e24c12009-10-30 11:49:00 +0000958 protected:
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000959 inline explicit ArgumentsAdaptorFrame(StackFrameIteratorBase* iterator);
Steve Blocka7e24c12009-10-30 11:49:00 +0000960
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000961 int GetNumberOfIncomingArguments() const override;
Ben Murdoch8b112d22011-06-08 16:22:53 +0100962
Ben Murdoch61f157c2016-09-16 13:49:30 +0100963 private:
964 friend class StackFrameIteratorBase;
965};
966
967// Builtin frames are built for builtins with JavaScript linkage, such as
968// various standard library functions (i.e. Math.asin, Math.floor, etc.).
969class BuiltinFrame final : public JavaScriptFrame {
970 public:
971 Type type() const final { return BUILTIN; }
972
973 static BuiltinFrame* cast(StackFrame* frame) {
974 DCHECK(frame->is_builtin());
975 return static_cast<BuiltinFrame*>(frame);
976 }
977
978 // Printing support.
979 void Print(StringStream* accumulator, PrintMode mode, int index) const final;
980
981 protected:
982 inline explicit BuiltinFrame(StackFrameIteratorBase* iterator);
983
984 int GetNumberOfIncomingArguments() const final;
Steve Blocka7e24c12009-10-30 11:49:00 +0000985
986 private:
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000987 friend class StackFrameIteratorBase;
Steve Blocka7e24c12009-10-30 11:49:00 +0000988};
989
Ben Murdochda12d292016-06-02 14:46:10 +0100990class WasmFrame : public StandardFrame {
991 public:
992 Type type() const override { return WASM; }
993
994 // GC support.
995 void Iterate(ObjectVisitor* v) const override;
996
997 // Printing support.
998 void Print(StringStream* accumulator, PrintMode mode,
999 int index) const override;
1000
1001 // Determine the code for the frame.
1002 Code* unchecked_code() const override;
1003
Ben Murdochc5610432016-08-08 18:44:38 +01001004 Object* wasm_obj();
1005 uint32_t function_index();
1006
Ben Murdochda12d292016-06-02 14:46:10 +01001007 static WasmFrame* cast(StackFrame* frame) {
1008 DCHECK(frame->is_wasm());
1009 return static_cast<WasmFrame*>(frame);
1010 }
1011
1012 protected:
1013 inline explicit WasmFrame(StackFrameIteratorBase* iterator);
1014
1015 Address GetCallerStackPointer() const override;
1016
1017 private:
1018 friend class StackFrameIteratorBase;
1019};
1020
1021class WasmToJsFrame : public StubFrame {
1022 public:
1023 Type type() const override { return WASM_TO_JS; }
1024
1025 protected:
1026 inline explicit WasmToJsFrame(StackFrameIteratorBase* iterator);
1027
1028 private:
1029 friend class StackFrameIteratorBase;
1030};
1031
1032class JsToWasmFrame : public StubFrame {
1033 public:
1034 Type type() const override { return JS_TO_WASM; }
1035
1036 protected:
1037 inline explicit JsToWasmFrame(StackFrameIteratorBase* iterator);
1038
1039 private:
1040 friend class StackFrameIteratorBase;
1041};
Steve Blocka7e24c12009-10-30 11:49:00 +00001042
1043class InternalFrame: public StandardFrame {
1044 public:
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001045 Type type() const override { return INTERNAL; }
Steve Blocka7e24c12009-10-30 11:49:00 +00001046
1047 // Garbage collection support.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001048 void Iterate(ObjectVisitor* v) const override;
Steve Blocka7e24c12009-10-30 11:49:00 +00001049
1050 // Determine the code for the frame.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001051 Code* unchecked_code() const override;
Steve Blocka7e24c12009-10-30 11:49:00 +00001052
1053 static InternalFrame* cast(StackFrame* frame) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001054 DCHECK(frame->is_internal());
Steve Blocka7e24c12009-10-30 11:49:00 +00001055 return static_cast<InternalFrame*>(frame);
1056 }
1057
1058 protected:
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001059 inline explicit InternalFrame(StackFrameIteratorBase* iterator);
Steve Blocka7e24c12009-10-30 11:49:00 +00001060
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001061 Address GetCallerStackPointer() const override;
Steve Blocka7e24c12009-10-30 11:49:00 +00001062
1063 private:
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001064 friend class StackFrameIteratorBase;
1065};
1066
1067
1068class StubFailureTrampolineFrame: public StandardFrame {
1069 public:
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001070 Type type() const override { return STUB_FAILURE_TRAMPOLINE; }
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001071
1072 // Get the code associated with this frame.
1073 // This method could be called during marking phase of GC.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001074 Code* unchecked_code() const override;
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001075
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001076 void Iterate(ObjectVisitor* v) const override;
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001077
1078 // Architecture-specific register description.
1079 static Register fp_register();
1080 static Register context_register();
1081 static Register constant_pool_pointer_register();
1082
1083 protected:
1084 inline explicit StubFailureTrampolineFrame(
1085 StackFrameIteratorBase* iterator);
1086
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001087 Address GetCallerStackPointer() const override;
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001088
1089 private:
1090 friend class StackFrameIteratorBase;
Steve Blocka7e24c12009-10-30 11:49:00 +00001091};
1092
1093
1094// Construct frames are special trampoline frames introduced to handle
1095// function invocations through 'new'.
1096class ConstructFrame: public InternalFrame {
1097 public:
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001098 Type type() const override { return CONSTRUCT; }
Steve Blocka7e24c12009-10-30 11:49:00 +00001099
1100 static ConstructFrame* cast(StackFrame* frame) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001101 DCHECK(frame->is_construct());
Steve Blocka7e24c12009-10-30 11:49:00 +00001102 return static_cast<ConstructFrame*>(frame);
1103 }
1104
1105 protected:
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001106 inline explicit ConstructFrame(StackFrameIteratorBase* iterator);
Steve Blocka7e24c12009-10-30 11:49:00 +00001107
1108 private:
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001109 friend class StackFrameIteratorBase;
Steve Blocka7e24c12009-10-30 11:49:00 +00001110};
1111
1112
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001113class StackFrameIteratorBase BASE_EMBEDDED {
Steve Blocka7e24c12009-10-30 11:49:00 +00001114 public:
Ben Murdoch8b112d22011-06-08 16:22:53 +01001115 Isolate* isolate() const { return isolate_; }
1116
Steve Blocka7e24c12009-10-30 11:49:00 +00001117 bool done() const { return frame_ == NULL; }
Steve Blocka7e24c12009-10-30 11:49:00 +00001118
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001119 protected:
1120 // An iterator that iterates over a given thread's stack.
1121 StackFrameIteratorBase(Isolate* isolate, bool can_access_heap_objects);
Steve Blocka7e24c12009-10-30 11:49:00 +00001122
Ben Murdoch8b112d22011-06-08 16:22:53 +01001123 Isolate* isolate_;
Steve Blocka7e24c12009-10-30 11:49:00 +00001124#define DECLARE_SINGLETON(ignore, type) type type##_;
1125 STACK_FRAME_TYPE_LIST(DECLARE_SINGLETON)
1126#undef DECLARE_SINGLETON
1127 StackFrame* frame_;
1128 StackHandler* handler_;
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001129 const bool can_access_heap_objects_;
Steve Blocka7e24c12009-10-30 11:49:00 +00001130
1131 StackHandler* handler() const {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001132 DCHECK(!done());
Steve Blocka7e24c12009-10-30 11:49:00 +00001133 return handler_;
1134 }
1135
1136 // Get the type-specific frame singleton in a given state.
1137 StackFrame* SingletonFor(StackFrame::Type type, StackFrame::State* state);
1138 // A helper function, can return a NULL pointer.
1139 StackFrame* SingletonFor(StackFrame::Type type);
1140
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001141 private:
Steve Blocka7e24c12009-10-30 11:49:00 +00001142 friend class StackFrame;
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001143 DISALLOW_COPY_AND_ASSIGN(StackFrameIteratorBase);
1144};
1145
1146
1147class StackFrameIterator: public StackFrameIteratorBase {
1148 public:
1149 // An iterator that iterates over the isolate's current thread's stack,
1150 explicit StackFrameIterator(Isolate* isolate);
1151 // An iterator that iterates over a given thread's stack.
1152 StackFrameIterator(Isolate* isolate, ThreadLocalTop* t);
1153
1154 StackFrame* frame() const {
1155 DCHECK(!done());
1156 return frame_;
1157 }
1158 void Advance();
1159
1160 private:
1161 // Go back to the first frame.
1162 void Reset(ThreadLocalTop* top);
1163
Steve Blocka7e24c12009-10-30 11:49:00 +00001164 DISALLOW_COPY_AND_ASSIGN(StackFrameIterator);
1165};
1166
Steve Blocka7e24c12009-10-30 11:49:00 +00001167// Iterator that supports iterating through all JavaScript frames.
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001168class JavaScriptFrameIterator BASE_EMBEDDED {
Steve Blocka7e24c12009-10-30 11:49:00 +00001169 public:
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001170 inline explicit JavaScriptFrameIterator(Isolate* isolate);
1171 inline JavaScriptFrameIterator(Isolate* isolate, ThreadLocalTop* top);
Steve Blocka7e24c12009-10-30 11:49:00 +00001172 // Skip frames until the frame with the given id is reached.
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001173 JavaScriptFrameIterator(Isolate* isolate, StackFrame::Id id);
Steve Block44f0eee2011-05-26 01:26:41 +01001174
Steve Blocka7e24c12009-10-30 11:49:00 +00001175 inline JavaScriptFrame* frame() const;
1176
1177 bool done() const { return iterator_.done(); }
1178 void Advance();
1179
1180 // Advance to the frame holding the arguments for the current
1181 // frame. This only affects the current frame if it has adapted
1182 // arguments.
1183 void AdvanceToArgumentsFrame();
1184
Steve Blocka7e24c12009-10-30 11:49:00 +00001185 private:
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001186 StackFrameIterator iterator_;
Steve Blocka7e24c12009-10-30 11:49:00 +00001187};
1188
Ben Murdochc5610432016-08-08 18:44:38 +01001189// NOTE: The stack trace frame iterator is an iterator that only traverse proper
1190// JavaScript frames that have proper JavaScript functions and WASM frames.
1191// This excludes the problematic functions in runtime.js.
1192class StackTraceFrameIterator BASE_EMBEDDED {
Steve Blocka7e24c12009-10-30 11:49:00 +00001193 public:
Ben Murdoch8b112d22011-06-08 16:22:53 +01001194 explicit StackTraceFrameIterator(Isolate* isolate);
Ben Murdochc5610432016-08-08 18:44:38 +01001195 bool done() const { return iterator_.done(); }
Steve Blocka7e24c12009-10-30 11:49:00 +00001196 void Advance();
Leon Clarke4515c472010-02-03 11:58:03 +00001197
Ben Murdochc5610432016-08-08 18:44:38 +01001198 inline StandardFrame* frame() const;
1199
1200 inline bool is_javascript() const;
1201 inline bool is_wasm() const;
1202 inline JavaScriptFrame* javascript_frame() const;
1203 inline WasmFrame* wasm_frame() const;
1204
Leon Clarke4515c472010-02-03 11:58:03 +00001205 private:
Ben Murdochc5610432016-08-08 18:44:38 +01001206 StackFrameIterator iterator_;
1207 bool IsValidFrame(StackFrame* frame) const;
Steve Blocka7e24c12009-10-30 11:49:00 +00001208};
1209
1210
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001211class SafeStackFrameIterator: public StackFrameIteratorBase {
Steve Blocka7e24c12009-10-30 11:49:00 +00001212 public:
Steve Block44f0eee2011-05-26 01:26:41 +01001213 SafeStackFrameIterator(Isolate* isolate,
1214 Address fp, Address sp,
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001215 Address js_entry_sp);
Steve Blocka7e24c12009-10-30 11:49:00 +00001216
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001217 inline StackFrame* frame() const;
Steve Blocka7e24c12009-10-30 11:49:00 +00001218 void Advance();
Steve Blocka7e24c12009-10-30 11:49:00 +00001219
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001220 StackFrame::Type top_frame_type() const { return top_frame_type_; }
Leon Clarked91b9f72010-01-27 17:25:45 +00001221
1222 private:
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001223 void AdvanceOneFrame();
Kristian Monsen0d5e1162010-09-30 15:31:59 +01001224
Steve Blocka7e24c12009-10-30 11:49:00 +00001225 bool IsValidStackAddress(Address addr) const {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001226 return low_bound_ <= addr && addr <= high_bound_;
Steve Blocka7e24c12009-10-30 11:49:00 +00001227 }
Steve Blocka7e24c12009-10-30 11:49:00 +00001228 bool IsValidFrame(StackFrame* frame) const;
1229 bool IsValidCaller(StackFrame* frame);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001230 bool IsValidExitFrame(Address fp) const;
1231 bool IsValidTop(ThreadLocalTop* top) const;
Steve Blocka7e24c12009-10-30 11:49:00 +00001232
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001233 const Address low_bound_;
1234 const Address high_bound_;
1235 StackFrame::Type top_frame_type_;
1236 ExternalCallbackScope* external_callback_scope_;
Steve Blocka7e24c12009-10-30 11:49:00 +00001237};
Steve Blocka7e24c12009-10-30 11:49:00 +00001238
1239
1240class StackFrameLocator BASE_EMBEDDED {
1241 public:
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001242 explicit StackFrameLocator(Isolate* isolate) : iterator_(isolate) {}
1243
Steve Blocka7e24c12009-10-30 11:49:00 +00001244 // Find the nth JavaScript frame on the stack. The caller must
1245 // guarantee that such a frame exists.
1246 JavaScriptFrame* FindJavaScriptFrame(int n);
1247
1248 private:
1249 StackFrameIterator iterator_;
1250};
1251
1252
Steve Block6ded16b2010-05-10 14:33:55 +01001253// Reads all frames on the current stack and copies them into the current
1254// zone memory.
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001255Vector<StackFrame*> CreateStackMap(Isolate* isolate, Zone* zone);
Steve Block6ded16b2010-05-10 14:33:55 +01001256
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001257} // namespace internal
1258} // namespace v8
Steve Blocka7e24c12009-10-30 11:49:00 +00001259
1260#endif // V8_FRAMES_H_