blob: f33eb167414af18081c82864dde237c3f5a46c2e [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
100
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000101#define STACK_FRAME_TYPE_LIST(V) \
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000102 V(ENTRY, EntryFrame) \
103 V(ENTRY_CONSTRUCT, EntryConstructFrame) \
104 V(EXIT, ExitFrame) \
105 V(JAVA_SCRIPT, JavaScriptFrame) \
106 V(OPTIMIZED, OptimizedFrame) \
107 V(INTERPRETED, InterpretedFrame) \
108 V(STUB, StubFrame) \
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000109 V(STUB_FAILURE_TRAMPOLINE, StubFailureTrampolineFrame) \
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000110 V(INTERNAL, InternalFrame) \
111 V(CONSTRUCT, ConstructFrame) \
112 V(ARGUMENTS_ADAPTOR, ArgumentsAdaptorFrame)
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000113
Ben Murdoch097c5b22016-05-18 11:27:45 +0100114// Every pointer in a frame has a slot id. On 32-bit platforms, doubles consume
115// two slots.
116//
117// Stack slot indices >= 0 access the callee stack with slot 0 corresponding to
118// the callee's saved return address and 1 corresponding to the saved frame
119// pointer. Some frames have additional information stored in the fixed header,
120// for example JSFunctions store the function context and marker in the fixed
121// header, with slot index 2 corresponding to the current function context and 3
122// corresponding to the frame marker/JSFunction.
123//
124// slot JS frame
125// +-----------------+--------------------------------
126// -n-1 | parameter 0 | ^
127// |- - - - - - - - -| |
128// -n | | Caller
129// ... | ... | frame slots
130// -2 | parameter n-1 | (slot < 0)
131// |- - - - - - - - -| |
132// -1 | parameter n | v
133// -----+-----------------+--------------------------------
134// 0 | return addr | ^ ^
135// |- - - - - - - - -| | |
136// 1 | saved frame ptr | Fixed |
137// |- - - - - - - - -| Header <-- frame ptr |
138// 2 | [Constant Pool] | | |
139// |- - - - - - - - -| | |
140// 2+cp | Context | | if a constant pool |
141// |- - - - - - - - -| | is used, cp = 1, |
142// 3+cp |JSFunction/Marker| v otherwise, cp = 0 |
143// +-----------------+---- |
144// 4+cp | | ^ Callee
145// |- - - - - - - - -| | frame slots
146// ... | | Frame slots (slot >= 0)
147// |- - - - - - - - -| | |
148// | | v |
149// -----+-----------------+----- <-- stack ptr -------------
150//
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000151
152class StandardFrameConstants : public AllStatic {
153 public:
154 // Fixed part of the frame consists of return address, caller fp,
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000155 // constant pool (if FLAG_enable_embedded_constant_pool), context, and
156 // function. StandardFrame::IterateExpressions assumes that kLastObjectOffset
157 // is the last object pointer.
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000158 static const int kCPSlotSize =
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000159 FLAG_enable_embedded_constant_pool ? kPointerSize : 0;
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000160 static const int kFixedFrameSizeFromFp = 2 * kPointerSize + kCPSlotSize;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000161 static const int kFixedFrameSizeAboveFp = kPCOnStackSize + kFPOnStackSize;
162 static const int kFixedFrameSize =
163 kFixedFrameSizeAboveFp + kFixedFrameSizeFromFp;
164 static const int kFixedSlotCountAboveFp =
165 kFixedFrameSizeAboveFp / kPointerSize;
166 static const int kFixedSlotCount = kFixedFrameSize / kPointerSize;
167 static const int kCPSlotCount = kCPSlotSize / kPointerSize;
168 static const int kExpressionsOffset = -3 * kPointerSize - kCPSlotSize;
169 static const int kMarkerOffset = -2 * kPointerSize - kCPSlotSize;
170 static const int kContextOffset = -1 * kPointerSize - kCPSlotSize;
171 static const int kConstantPoolOffset = kCPSlotSize ? -1 * kPointerSize : 0;
172 static const int kCallerFPOffset = 0 * kPointerSize;
173 static const int kCallerPCOffset = +1 * kFPOnStackSize;
174 static const int kCallerSPOffset = kCallerPCOffset + 1 * kPCOnStackSize;
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000175
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000176 static const int kLastObjectOffset = kContextOffset;
177};
178
179
180class ArgumentsAdaptorFrameConstants : public AllStatic {
181 public:
182 // FP-relative.
183 static const int kLengthOffset = StandardFrameConstants::kExpressionsOffset;
184
185 static const int kFrameSize =
186 StandardFrameConstants::kFixedFrameSize + kPointerSize;
187};
188
189
190class InternalFrameConstants : public AllStatic {
191 public:
192 // FP-relative.
193 static const int kCodeOffset = StandardFrameConstants::kExpressionsOffset;
194};
195
196
197class ConstructFrameConstants : public AllStatic {
198 public:
199 // FP-relative.
200 static const int kImplicitReceiverOffset =
201 StandardFrameConstants::kExpressionsOffset - 3 * kPointerSize;
202 static const int kLengthOffset =
203 StandardFrameConstants::kExpressionsOffset - 2 * kPointerSize;
204 static const int kAllocationSiteOffset =
205 StandardFrameConstants::kExpressionsOffset - 1 * kPointerSize;
206 static const int kCodeOffset =
207 StandardFrameConstants::kExpressionsOffset - 0 * kPointerSize;
208
209 static const int kFrameSize =
210 StandardFrameConstants::kFixedFrameSize + 4 * kPointerSize;
211};
212
213
214class InterpreterFrameConstants : public AllStatic {
215 public:
216 // Fixed frame includes new.target and bytecode offset.
217 static const int kFixedFrameSize =
Ben Murdoch097c5b22016-05-18 11:27:45 +0100218 StandardFrameConstants::kFixedFrameSize + 3 * kPointerSize;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000219 static const int kFixedFrameSizeFromFp =
Ben Murdoch097c5b22016-05-18 11:27:45 +0100220 StandardFrameConstants::kFixedFrameSizeFromFp + 3 * kPointerSize;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000221
222 // FP-relative.
Ben Murdoch097c5b22016-05-18 11:27:45 +0100223 static const int kNewTargetFromFp =
224 -StandardFrameConstants::kFixedFrameSizeFromFp - 1 * kPointerSize;
225 static const int kBytecodeArrayFromFp =
226 -StandardFrameConstants::kFixedFrameSizeFromFp - 2 * kPointerSize;
227 static const int kBytecodeOffsetFromFp =
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000228 -StandardFrameConstants::kFixedFrameSizeFromFp - 3 * kPointerSize;
Ben Murdoch097c5b22016-05-18 11:27:45 +0100229 static const int kRegisterFilePointerFromFp =
230 -StandardFrameConstants::kFixedFrameSizeFromFp - 4 * kPointerSize;
231
232 static const int kExpressionsOffset = kRegisterFilePointerFromFp;
233
234 // Expression index for {StandardFrame::GetExpressionAddress}.
235 static const int kBytecodeArrayExpressionIndex = -2;
236 static const int kBytecodeOffsetExpressionIndex = -1;
237 static const int kRegisterFileExpressionIndex = 0;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000238
239 // Register file pointer relative.
240 static const int kLastParamFromRegisterPointer =
Ben Murdoch097c5b22016-05-18 11:27:45 +0100241 StandardFrameConstants::kFixedFrameSize + 4 * kPointerSize;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000242
243 static const int kBytecodeOffsetFromRegisterPointer = 1 * kPointerSize;
Ben Murdoch097c5b22016-05-18 11:27:45 +0100244 static const int kBytecodeArrayFromRegisterPointer = 2 * kPointerSize;
245 static const int kNewTargetFromRegisterPointer = 3 * kPointerSize;
246 static const int kFunctionFromRegisterPointer = 4 * kPointerSize;
247 static const int kContextFromRegisterPointer = 5 * kPointerSize;
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000248};
Steve Blocka7e24c12009-10-30 11:49:00 +0000249
Ben Murdoch097c5b22016-05-18 11:27:45 +0100250inline static int FPOffsetToFrameSlot(int frame_offset) {
251 return StandardFrameConstants::kFixedSlotCountAboveFp - 1 -
252 frame_offset / kPointerSize;
253}
254
255inline static int FrameSlotToFPOffset(int slot) {
256 return (StandardFrameConstants::kFixedSlotCountAboveFp - 1 - slot) *
257 kPointerSize;
258}
Steve Blocka7e24c12009-10-30 11:49:00 +0000259
260// Abstract base class for all stack frames.
261class StackFrame BASE_EMBEDDED {
262 public:
263#define DECLARE_TYPE(type, ignore) type,
264 enum Type {
265 NONE = 0,
266 STACK_FRAME_TYPE_LIST(DECLARE_TYPE)
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100267 NUMBER_OF_TYPES,
268 // Used by FrameScope to indicate that the stack frame is constructed
269 // manually and the FrameScope does not need to emit code.
270 MANUAL
Steve Blocka7e24c12009-10-30 11:49:00 +0000271 };
272#undef DECLARE_TYPE
273
274 // Opaque data type for identifying stack frames. Used extensively
275 // by the debugger.
Iain Merrick75681382010-08-19 15:07:18 +0100276 // ID_MIN_VALUE and ID_MAX_VALUE are specified to ensure that enumeration type
277 // has correct value range (see Issue 830 for more details).
278 enum Id {
279 ID_MIN_VALUE = kMinInt,
280 ID_MAX_VALUE = kMaxInt,
281 NO_ID = 0
282 };
Steve Blocka7e24c12009-10-30 11:49:00 +0000283
Steve Block053d10c2011-06-13 19:13:29 +0100284 // Used to mark the outermost JS entry frame.
285 enum JsFrameMarker {
286 INNER_JSENTRY_FRAME = 0,
287 OUTERMOST_JSENTRY_FRAME = 1
288 };
289
Kristian Monsen0d5e1162010-09-30 15:31:59 +0100290 struct State {
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000291 State() : sp(NULL), fp(NULL), pc_address(NULL),
292 constant_pool_address(NULL) { }
Kristian Monsen0d5e1162010-09-30 15:31:59 +0100293 Address sp;
294 Address fp;
295 Address* pc_address;
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000296 Address* constant_pool_address;
Kristian Monsen0d5e1162010-09-30 15:31:59 +0100297 };
298
Ben Murdoch8b112d22011-06-08 16:22:53 +0100299 // Copy constructor; it breaks the connection to host iterator
300 // (as an iterator usually lives on stack).
Steve Block6ded16b2010-05-10 14:33:55 +0100301 StackFrame(const StackFrame& original) {
302 this->state_ = original.state_;
303 this->iterator_ = NULL;
Ben Murdoch8b112d22011-06-08 16:22:53 +0100304 this->isolate_ = original.isolate_;
Steve Block6ded16b2010-05-10 14:33:55 +0100305 }
306
Steve Blocka7e24c12009-10-30 11:49:00 +0000307 // Type testers.
308 bool is_entry() const { return type() == ENTRY; }
309 bool is_entry_construct() const { return type() == ENTRY_CONSTRUCT; }
310 bool is_exit() const { return type() == EXIT; }
Ben Murdochb0fe1622011-05-05 13:52:32 +0100311 bool is_optimized() const { return type() == OPTIMIZED; }
Ben Murdoch097c5b22016-05-18 11:27:45 +0100312 bool is_interpreted() const { return type() == INTERPRETED; }
Steve Blocka7e24c12009-10-30 11:49:00 +0000313 bool is_arguments_adaptor() const { return type() == ARGUMENTS_ADAPTOR; }
314 bool is_internal() const { return type() == INTERNAL; }
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000315 bool is_stub_failure_trampoline() const {
316 return type() == STUB_FAILURE_TRAMPOLINE;
317 }
Steve Blocka7e24c12009-10-30 11:49:00 +0000318 bool is_construct() const { return type() == CONSTRUCT; }
319 virtual bool is_standard() const { return false; }
320
Ben Murdochb0fe1622011-05-05 13:52:32 +0100321 bool is_java_script() const {
322 Type type = this->type();
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000323 return (type == JAVA_SCRIPT) || (type == OPTIMIZED) ||
324 (type == INTERPRETED);
Ben Murdochb0fe1622011-05-05 13:52:32 +0100325 }
326
Steve Blocka7e24c12009-10-30 11:49:00 +0000327 // Accessors.
328 Address sp() const { return state_.sp; }
329 Address fp() const { return state_.fp; }
330 Address caller_sp() const { return GetCallerStackPointer(); }
331
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000332 // If this frame is optimized and was dynamically aligned return its old
333 // unaligned frame pointer. When the frame is deoptimized its FP will shift
334 // up one word and become unaligned.
335 Address UnpaddedFP() const;
336
Steve Blocka7e24c12009-10-30 11:49:00 +0000337 Address pc() const { return *pc_address(); }
338 void set_pc(Address pc) { *pc_address() = pc; }
339
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000340 Address constant_pool() const { return *constant_pool_address(); }
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000341 void set_constant_pool(Address constant_pool) {
342 *constant_pool_address() = constant_pool;
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000343 }
344
Steve Block6ded16b2010-05-10 14:33:55 +0100345 virtual void SetCallerFp(Address caller_fp) = 0;
346
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000347 // Manually changes value of fp in this object.
348 void UpdateFp(Address fp) { state_.fp = fp; }
349
Steve Blocka7e24c12009-10-30 11:49:00 +0000350 Address* pc_address() const { return state_.pc_address; }
351
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000352 Address* constant_pool_address() const {
353 return state_.constant_pool_address;
354 }
355
Steve Blocka7e24c12009-10-30 11:49:00 +0000356 // Get the id of this stack frame.
357 Id id() const { return static_cast<Id>(OffsetFrom(caller_sp())); }
358
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000359 // Get the top handler from the current stack iterator.
360 inline StackHandler* top_handler() const;
Steve Blocka7e24c12009-10-30 11:49:00 +0000361
362 // Get the type of this frame.
363 virtual Type type() const = 0;
364
365 // Get the code associated with this frame.
Iain Merrick75681382010-08-19 15:07:18 +0100366 // This method could be called during marking phase of GC.
367 virtual Code* unchecked_code() const = 0;
368
369 // Get the code associated with this frame.
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100370 inline Code* LookupCode() const;
Kristian Monsen80d68ea2010-09-08 11:05:35 +0100371
372 // Get the code object that contains the given pc.
Steve Block44f0eee2011-05-26 01:26:41 +0100373 static inline Code* GetContainingCode(Isolate* isolate, Address pc);
Steve Blocka7e24c12009-10-30 11:49:00 +0000374
Ben Murdochb0fe1622011-05-05 13:52:32 +0100375 // Get the code object containing the given pc and fill in the
376 // safepoint entry and the number of stack slots. The pc must be at
377 // a safepoint.
Ben Murdoch8b112d22011-06-08 16:22:53 +0100378 static Code* GetSafepointData(Isolate* isolate,
379 Address pc,
Ben Murdochb8e0da22011-05-16 14:20:40 +0100380 SafepointEntry* safepoint_entry,
Ben Murdochb0fe1622011-05-05 13:52:32 +0100381 unsigned* stack_slots);
382
Kristian Monsen80d68ea2010-09-08 11:05:35 +0100383 virtual void Iterate(ObjectVisitor* v) const = 0;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000384 static void IteratePc(ObjectVisitor* v, Address* pc_address,
385 Address* constant_pool_address, Code* holder);
Steve Blocka7e24c12009-10-30 11:49:00 +0000386
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100387 // Sets a callback function for return-address rewriting profilers
388 // to resolve the location of a return address to the location of the
389 // profiler's stashed return address.
390 static void SetReturnAddressLocationResolver(
391 ReturnAddressLocationResolver resolver);
Steve Blocka7e24c12009-10-30 11:49:00 +0000392
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000393 // Resolves pc_address through the resolution address function if one is set.
394 static inline Address* ResolveReturnAddressLocation(Address* pc_address);
395
Steve Blocka7e24c12009-10-30 11:49:00 +0000396 // Printing support.
397 enum PrintMode { OVERVIEW, DETAILS };
398 virtual void Print(StringStream* accumulator,
399 PrintMode mode,
400 int index) const { }
401
Ben Murdoch8b112d22011-06-08 16:22:53 +0100402 Isolate* isolate() const { return isolate_; }
403
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000404 protected:
405 inline explicit StackFrame(StackFrameIteratorBase* iterator);
406 virtual ~StackFrame() { }
407
Steve Blocka7e24c12009-10-30 11:49:00 +0000408 // Compute the stack pointer for the calling frame.
409 virtual Address GetCallerStackPointer() const = 0;
410
411 // Printing support.
412 static void PrintIndex(StringStream* accumulator,
413 PrintMode mode,
414 int index);
415
Steve Blocka7e24c12009-10-30 11:49:00 +0000416 // Compute the stack frame type for the given state.
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000417 static Type ComputeType(const StackFrameIteratorBase* iterator, State* state);
418
419#ifdef DEBUG
420 bool can_access_heap_objects() const;
421#endif
Steve Blocka7e24c12009-10-30 11:49:00 +0000422
423 private:
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000424 const StackFrameIteratorBase* iterator_;
Ben Murdoch8b112d22011-06-08 16:22:53 +0100425 Isolate* isolate_;
Steve Blocka7e24c12009-10-30 11:49:00 +0000426 State state_;
427
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000428 static ReturnAddressLocationResolver return_address_location_resolver_;
429
Steve Blocka7e24c12009-10-30 11:49:00 +0000430 // Fill in the state of the calling frame.
431 virtual void ComputeCallerState(State* state) const = 0;
432
433 // Get the type and the state of the calling frame.
434 virtual Type GetCallerState(State* state) const;
435
Ben Murdoch8b112d22011-06-08 16:22:53 +0100436 static const intptr_t kIsolateTag = 1;
437
Steve Blocka7e24c12009-10-30 11:49:00 +0000438 friend class StackFrameIterator;
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000439 friend class StackFrameIteratorBase;
Steve Blocka7e24c12009-10-30 11:49:00 +0000440 friend class StackHandlerIterator;
441 friend class SafeStackFrameIterator;
442
Steve Block6ded16b2010-05-10 14:33:55 +0100443 private:
444 void operator=(const StackFrame& original);
Steve Blocka7e24c12009-10-30 11:49:00 +0000445};
446
447
448// Entry frames are used to enter JavaScript execution from C.
449class EntryFrame: public StackFrame {
450 public:
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000451 Type type() const override { return ENTRY; }
Steve Blocka7e24c12009-10-30 11:49:00 +0000452
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000453 Code* unchecked_code() const override;
Steve Blocka7e24c12009-10-30 11:49:00 +0000454
455 // Garbage collection support.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000456 void Iterate(ObjectVisitor* v) const override;
Steve Blocka7e24c12009-10-30 11:49:00 +0000457
458 static EntryFrame* cast(StackFrame* frame) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000459 DCHECK(frame->is_entry());
Steve Blocka7e24c12009-10-30 11:49:00 +0000460 return static_cast<EntryFrame*>(frame);
461 }
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000462 void SetCallerFp(Address caller_fp) override;
Steve Blocka7e24c12009-10-30 11:49:00 +0000463
464 protected:
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000465 inline explicit EntryFrame(StackFrameIteratorBase* iterator);
Steve Blocka7e24c12009-10-30 11:49:00 +0000466
467 // The caller stack pointer for entry frames is always zero. The
468 // real information about the caller frame is available through the
469 // link to the top exit frame.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000470 Address GetCallerStackPointer() const override { return 0; }
Steve Blocka7e24c12009-10-30 11:49:00 +0000471
472 private:
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000473 void ComputeCallerState(State* state) const override;
474 Type GetCallerState(State* state) const override;
Steve Blocka7e24c12009-10-30 11:49:00 +0000475
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000476 friend class StackFrameIteratorBase;
Steve Blocka7e24c12009-10-30 11:49:00 +0000477};
478
479
480class EntryConstructFrame: public EntryFrame {
481 public:
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000482 Type type() const override { return ENTRY_CONSTRUCT; }
Steve Blocka7e24c12009-10-30 11:49:00 +0000483
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000484 Code* unchecked_code() const override;
Steve Blocka7e24c12009-10-30 11:49:00 +0000485
486 static EntryConstructFrame* cast(StackFrame* frame) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000487 DCHECK(frame->is_entry_construct());
Steve Blocka7e24c12009-10-30 11:49:00 +0000488 return static_cast<EntryConstructFrame*>(frame);
489 }
490
491 protected:
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000492 inline explicit EntryConstructFrame(StackFrameIteratorBase* iterator);
Steve Blocka7e24c12009-10-30 11:49:00 +0000493
494 private:
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000495 friend class StackFrameIteratorBase;
Steve Blocka7e24c12009-10-30 11:49:00 +0000496};
497
498
499// Exit frames are used to exit JavaScript execution and go to C.
500class ExitFrame: public StackFrame {
501 public:
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000502 Type type() const override { return EXIT; }
Steve Blocka7e24c12009-10-30 11:49:00 +0000503
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000504 Code* unchecked_code() const override;
Steve Blocka7e24c12009-10-30 11:49:00 +0000505
Steve Blockd0582a62009-12-15 09:54:21 +0000506 Object*& code_slot() const;
507
Steve Blocka7e24c12009-10-30 11:49:00 +0000508 // Garbage collection support.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000509 void Iterate(ObjectVisitor* v) const override;
Steve Blocka7e24c12009-10-30 11:49:00 +0000510
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000511 void SetCallerFp(Address caller_fp) override;
Steve Block6ded16b2010-05-10 14:33:55 +0100512
Steve Blocka7e24c12009-10-30 11:49:00 +0000513 static ExitFrame* cast(StackFrame* frame) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000514 DCHECK(frame->is_exit());
Steve Blocka7e24c12009-10-30 11:49:00 +0000515 return static_cast<ExitFrame*>(frame);
516 }
517
518 // Compute the state and type of an exit frame given a frame
519 // pointer. Used when constructing the first stack frame seen by an
520 // iterator and the frames following entry frames.
521 static Type GetStateForFramePointer(Address fp, State* state);
Kristian Monsen0d5e1162010-09-30 15:31:59 +0100522 static Address ComputeStackPointer(Address fp);
523 static void FillState(Address fp, Address sp, State* state);
Steve Blocka7e24c12009-10-30 11:49:00 +0000524
525 protected:
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000526 inline explicit ExitFrame(StackFrameIteratorBase* iterator);
Steve Blocka7e24c12009-10-30 11:49:00 +0000527
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000528 Address GetCallerStackPointer() const override;
Steve Blocka7e24c12009-10-30 11:49:00 +0000529
530 private:
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000531 void ComputeCallerState(State* state) const override;
Steve Blocka7e24c12009-10-30 11:49:00 +0000532
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000533 friend class StackFrameIteratorBase;
Steve Blocka7e24c12009-10-30 11:49:00 +0000534};
535
536
Steve Blocka7e24c12009-10-30 11:49:00 +0000537class StandardFrame: public StackFrame {
538 public:
539 // Testers.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000540 bool is_standard() const override { return true; }
Steve Blocka7e24c12009-10-30 11:49:00 +0000541
542 // Accessors.
543 inline Object* context() const;
544
545 // Access the expressions in the stack frame including locals.
546 inline Object* GetExpression(int index) const;
547 inline void SetExpression(int index, Object* value);
548 int ComputeExpressionsCount() const;
549
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000550 void SetCallerFp(Address caller_fp) override;
Steve Block6ded16b2010-05-10 14:33:55 +0100551
Steve Blocka7e24c12009-10-30 11:49:00 +0000552 static StandardFrame* cast(StackFrame* frame) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000553 DCHECK(frame->is_standard());
Steve Blocka7e24c12009-10-30 11:49:00 +0000554 return static_cast<StandardFrame*>(frame);
555 }
556
557 protected:
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000558 inline explicit StandardFrame(StackFrameIteratorBase* iterator);
Steve Blocka7e24c12009-10-30 11:49:00 +0000559
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000560 void ComputeCallerState(State* state) const override;
Steve Blocka7e24c12009-10-30 11:49:00 +0000561
562 // Accessors.
563 inline Address caller_fp() const;
564 inline Address caller_pc() const;
565
566 // Computes the address of the PC field in the standard frame given
567 // by the provided frame pointer.
568 static inline Address ComputePCAddress(Address fp);
569
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000570 // Computes the address of the constant pool field in the standard
571 // frame given by the provided frame pointer.
572 static inline Address ComputeConstantPoolAddress(Address fp);
573
Steve Blocka7e24c12009-10-30 11:49:00 +0000574 // Iterate over expression stack including stack handlers, locals,
575 // and parts of the fixed part including context and code fields.
576 void IterateExpressions(ObjectVisitor* v) const;
577
578 // Returns the address of the n'th expression stack element.
Ben Murdoch097c5b22016-05-18 11:27:45 +0100579 virtual Address GetExpressionAddress(int n) const;
Steve Blocka7e24c12009-10-30 11:49:00 +0000580
Steve Blocka7e24c12009-10-30 11:49:00 +0000581 // Determines if the standard frame for the given frame pointer is
582 // an arguments adaptor frame.
583 static inline bool IsArgumentsAdaptorFrame(Address fp);
584
585 // Determines if the standard frame for the given frame pointer is a
586 // construct frame.
587 static inline bool IsConstructFrame(Address fp);
588
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000589 // Used by OptimizedFrames and StubFrames.
590 void IterateCompiledFrame(ObjectVisitor* v) const;
591
Steve Blocka7e24c12009-10-30 11:49:00 +0000592 private:
593 friend class StackFrame;
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000594 friend class SafeStackFrameIterator;
Steve Blocka7e24c12009-10-30 11:49:00 +0000595};
596
597
Ben Murdochb0fe1622011-05-05 13:52:32 +0100598class FrameSummary BASE_EMBEDDED {
599 public:
Ben Murdoch097c5b22016-05-18 11:27:45 +0100600 FrameSummary(Object* receiver, JSFunction* function,
601 AbstractCode* abstract_code, int code_offset,
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000602 bool is_constructor);
603
Ben Murdochb0fe1622011-05-05 13:52:32 +0100604 Handle<Object> receiver() { return receiver_; }
605 Handle<JSFunction> function() { return function_; }
Ben Murdoch097c5b22016-05-18 11:27:45 +0100606 Handle<AbstractCode> abstract_code() { return abstract_code_; }
607 int code_offset() { return code_offset_; }
Ben Murdochb0fe1622011-05-05 13:52:32 +0100608 bool is_constructor() { return is_constructor_; }
609
610 void Print();
611
612 private:
613 Handle<Object> receiver_;
614 Handle<JSFunction> function_;
Ben Murdoch097c5b22016-05-18 11:27:45 +0100615 Handle<AbstractCode> abstract_code_;
616 int code_offset_;
Ben Murdochb0fe1622011-05-05 13:52:32 +0100617 bool is_constructor_;
618};
619
620
Steve Blocka7e24c12009-10-30 11:49:00 +0000621class JavaScriptFrame: public StandardFrame {
622 public:
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000623 Type type() const override { return JAVA_SCRIPT; }
Steve Blocka7e24c12009-10-30 11:49:00 +0000624
625 // Accessors.
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000626 inline JSFunction* function() const;
Steve Blocka7e24c12009-10-30 11:49:00 +0000627 inline Object* receiver() const;
628 inline void set_receiver(Object* value);
629
630 // Access the parameters.
Ben Murdoch8b112d22011-06-08 16:22:53 +0100631 inline Address GetParameterSlot(int index) const;
632 inline Object* GetParameter(int index) const;
633 inline int ComputeParametersCount() const {
634 return GetNumberOfIncomingArguments();
635 }
Steve Blocka7e24c12009-10-30 11:49:00 +0000636
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000637 // Access the operand stack.
638 inline Address GetOperandSlot(int index) const;
639 inline Object* GetOperand(int index) const;
640 inline int ComputeOperandsCount() const;
641
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000642 // Generator support to preserve operand stack.
643 void SaveOperandStack(FixedArray* store) const;
644 void RestoreOperandStack(FixedArray* store);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000645
646 // Debugger access.
647 void SetParameterValue(int index, Object* value) const;
648
Steve Blocka7e24c12009-10-30 11:49:00 +0000649 // Check if this frame is a constructor frame invoked through 'new'.
650 bool IsConstructor() const;
651
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000652 // Determines whether this frame includes inlined activations. To get details
653 // about the inlined frames use {GetFunctions} and {Summarize}.
654 bool HasInlinedFrames() const;
655
Steve Blocka7e24c12009-10-30 11:49:00 +0000656 // Check if this frame has "adapted" arguments in the sense that the
657 // actual passed arguments are available in an arguments adaptor
658 // frame below it on the stack.
659 inline bool has_adapted_arguments() const;
Ben Murdoch3fb3ca82011-12-02 17:19:32 +0000660 int GetArgumentsLength() const;
Steve Blocka7e24c12009-10-30 11:49:00 +0000661
662 // Garbage collection support.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000663 void Iterate(ObjectVisitor* v) const override;
Steve Blocka7e24c12009-10-30 11:49:00 +0000664
665 // Printing support.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000666 void Print(StringStream* accumulator, PrintMode mode,
667 int index) const override;
Steve Blocka7e24c12009-10-30 11:49:00 +0000668
669 // Determine the code for the frame.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000670 Code* unchecked_code() const override;
Ben Murdoch3fb3ca82011-12-02 17:19:32 +0000671
Ben Murdochb0fe1622011-05-05 13:52:32 +0100672 // Return a list with JSFunctions of this frame.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000673 virtual void GetFunctions(List<JSFunction*>* functions) const;
Ben Murdochb0fe1622011-05-05 13:52:32 +0100674
675 // Build a list with summaries for this frame including all inlined frames.
676 virtual void Summarize(List<FrameSummary>* frames);
677
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000678 // Lookup exception handler for current {pc}, returns -1 if none found. Also
Ben Murdoch097c5b22016-05-18 11:27:45 +0100679 // returns data associated with the handler site specific to the frame type:
680 // - JavaScriptFrame : Data is the stack depth at entry of the try-block.
681 // - OptimizedFrame : Data is the stack slot count of the entire frame.
682 // - InterpretedFrame: Data is the register index holding the context.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000683 virtual int LookupExceptionHandlerInTable(
Ben Murdoch097c5b22016-05-18 11:27:45 +0100684 int* data, HandlerTable::CatchPrediction* prediction);
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000685
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000686 // Architecture-specific register description.
687 static Register fp_register();
688 static Register context_register();
689 static Register constant_pool_pointer_register();
690
Steve Blocka7e24c12009-10-30 11:49:00 +0000691 static JavaScriptFrame* cast(StackFrame* frame) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000692 DCHECK(frame->is_java_script());
Steve Blocka7e24c12009-10-30 11:49:00 +0000693 return static_cast<JavaScriptFrame*>(frame);
694 }
695
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000696 static void PrintFunctionAndOffset(JSFunction* function, Code* code,
697 Address pc, FILE* file,
698 bool print_line_number);
699
700 static void PrintTop(Isolate* isolate, FILE* file, bool print_args,
701 bool print_line_number);
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100702
Steve Blocka7e24c12009-10-30 11:49:00 +0000703 protected:
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000704 inline explicit JavaScriptFrame(StackFrameIteratorBase* iterator);
Steve Blocka7e24c12009-10-30 11:49:00 +0000705
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000706 Address GetCallerStackPointer() const override;
Steve Blocka7e24c12009-10-30 11:49:00 +0000707
Ben Murdoch8b112d22011-06-08 16:22:53 +0100708 virtual int GetNumberOfIncomingArguments() const;
709
Ben Murdochb0fe1622011-05-05 13:52:32 +0100710 // Garbage collection support. Iterates over incoming arguments,
711 // receiver, and any callee-saved registers.
712 void IterateArguments(ObjectVisitor* v) const;
713
Steve Blocka7e24c12009-10-30 11:49:00 +0000714 private:
Steve Blocka7e24c12009-10-30 11:49:00 +0000715 inline Object* function_slot_object() const;
716
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000717 friend class StackFrameIteratorBase;
718};
719
720
721class StubFrame : public StandardFrame {
722 public:
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000723 Type type() const override { return STUB; }
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000724
725 // GC support.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000726 void Iterate(ObjectVisitor* v) const override;
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000727
728 // Determine the code for the frame.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000729 Code* unchecked_code() const override;
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000730
731 protected:
732 inline explicit StubFrame(StackFrameIteratorBase* iterator);
733
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000734 Address GetCallerStackPointer() const override;
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000735
736 virtual int GetNumberOfIncomingArguments() const;
737
738 friend class StackFrameIteratorBase;
Steve Blocka7e24c12009-10-30 11:49:00 +0000739};
740
741
Ben Murdochb0fe1622011-05-05 13:52:32 +0100742class OptimizedFrame : public JavaScriptFrame {
743 public:
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000744 Type type() const override { return OPTIMIZED; }
Ben Murdochb0fe1622011-05-05 13:52:32 +0100745
746 // GC support.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000747 void Iterate(ObjectVisitor* v) const override;
Ben Murdoch3fb3ca82011-12-02 17:19:32 +0000748
Ben Murdochb0fe1622011-05-05 13:52:32 +0100749 // Return a list with JSFunctions of this frame.
750 // The functions are ordered bottom-to-top (i.e. functions.last()
751 // is the top-most activation)
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000752 void GetFunctions(List<JSFunction*>* functions) const override;
Ben Murdochb0fe1622011-05-05 13:52:32 +0100753
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000754 void Summarize(List<FrameSummary>* frames) override;
Ben Murdochb0fe1622011-05-05 13:52:32 +0100755
Ben Murdoch097c5b22016-05-18 11:27:45 +0100756 // Lookup exception handler for current {pc}, returns -1 if none found.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000757 int LookupExceptionHandlerInTable(
Ben Murdoch097c5b22016-05-18 11:27:45 +0100758 int* data, HandlerTable::CatchPrediction* prediction) override;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000759
760 DeoptimizationInputData* GetDeoptimizationData(int* deopt_index) const;
761
762 static int StackSlotOffsetRelativeToFp(int slot_index);
Ben Murdochb0fe1622011-05-05 13:52:32 +0100763
764 protected:
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000765 inline explicit OptimizedFrame(StackFrameIteratorBase* iterator);
Ben Murdochb0fe1622011-05-05 13:52:32 +0100766
767 private:
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000768 friend class StackFrameIteratorBase;
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000769
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000770 Object* StackSlotAt(int index) const;
771};
772
773
774class InterpretedFrame : public JavaScriptFrame {
Ben Murdoch097c5b22016-05-18 11:27:45 +0100775 public:
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000776 Type type() const override { return INTERPRETED; }
777
Ben Murdoch097c5b22016-05-18 11:27:45 +0100778 // Lookup exception handler for current {pc}, returns -1 if none found.
779 int LookupExceptionHandlerInTable(
780 int* data, HandlerTable::CatchPrediction* prediction) override;
781
782 // Returns the current offset into the bytecode stream.
783 int GetBytecodeOffset() const;
784
785 // Updates the current offset into the bytecode stream, mainly used for stack
786 // unwinding to continue execution at a different bytecode offset.
787 void PatchBytecodeOffset(int new_offset);
788
789 // Returns the frame's current bytecode array.
790 Object* GetBytecodeArray() const;
791
792 // Updates the frame's BytecodeArray with |bytecode_array|. Used by the
793 // debugger to swap execution onto a BytecodeArray patched with breakpoints.
794 void PatchBytecodeArray(Object* bytecode_array);
795
796 // Access to the interpreter register file for this frame.
797 Object* GetInterpreterRegister(int register_index) const;
798
799 // Build a list with summaries for this frame including all inlined frames.
800 void Summarize(List<FrameSummary>* frames) override;
801
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000802 protected:
803 inline explicit InterpretedFrame(StackFrameIteratorBase* iterator);
804
Ben Murdoch097c5b22016-05-18 11:27:45 +0100805 Address GetExpressionAddress(int n) const override;
806
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000807 private:
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000808 friend class StackFrameIteratorBase;
Ben Murdochb0fe1622011-05-05 13:52:32 +0100809};
810
811
Steve Blocka7e24c12009-10-30 11:49:00 +0000812// Arguments adaptor frames are automatically inserted below
813// JavaScript frames when the actual number of parameters does not
814// match the formal number of parameters.
815class ArgumentsAdaptorFrame: public JavaScriptFrame {
816 public:
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000817 Type type() const override { return ARGUMENTS_ADAPTOR; }
Steve Blocka7e24c12009-10-30 11:49:00 +0000818
819 // Determine the code for the frame.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000820 Code* unchecked_code() const override;
Steve Blocka7e24c12009-10-30 11:49:00 +0000821
822 static ArgumentsAdaptorFrame* cast(StackFrame* frame) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000823 DCHECK(frame->is_arguments_adaptor());
Steve Blocka7e24c12009-10-30 11:49:00 +0000824 return static_cast<ArgumentsAdaptorFrame*>(frame);
825 }
826
827 // Printing support.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000828 void Print(StringStream* accumulator, PrintMode mode,
829 int index) const override;
Ben Murdoch589d6972011-11-30 16:04:58 +0000830
Ben Murdoch097c5b22016-05-18 11:27:45 +0100831 static int GetLength(Address fp);
832
Steve Blocka7e24c12009-10-30 11:49:00 +0000833 protected:
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000834 inline explicit ArgumentsAdaptorFrame(StackFrameIteratorBase* iterator);
Steve Blocka7e24c12009-10-30 11:49:00 +0000835
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000836 int GetNumberOfIncomingArguments() const override;
Ben Murdoch8b112d22011-06-08 16:22:53 +0100837
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000838 Address GetCallerStackPointer() const override;
Steve Blocka7e24c12009-10-30 11:49:00 +0000839
840 private:
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000841 friend class StackFrameIteratorBase;
Steve Blocka7e24c12009-10-30 11:49:00 +0000842};
843
844
845class InternalFrame: public StandardFrame {
846 public:
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000847 Type type() const override { return INTERNAL; }
Steve Blocka7e24c12009-10-30 11:49:00 +0000848
849 // Garbage collection support.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000850 void Iterate(ObjectVisitor* v) const override;
Steve Blocka7e24c12009-10-30 11:49:00 +0000851
852 // Determine the code for the frame.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000853 Code* unchecked_code() const override;
Steve Blocka7e24c12009-10-30 11:49:00 +0000854
855 static InternalFrame* cast(StackFrame* frame) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000856 DCHECK(frame->is_internal());
Steve Blocka7e24c12009-10-30 11:49:00 +0000857 return static_cast<InternalFrame*>(frame);
858 }
859
860 protected:
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000861 inline explicit InternalFrame(StackFrameIteratorBase* iterator);
Steve Blocka7e24c12009-10-30 11:49:00 +0000862
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000863 Address GetCallerStackPointer() const override;
Steve Blocka7e24c12009-10-30 11:49:00 +0000864
865 private:
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000866 friend class StackFrameIteratorBase;
867};
868
869
870class StubFailureTrampolineFrame: public StandardFrame {
871 public:
872 // sizeof(Arguments) - sizeof(Arguments*) is 3 * kPointerSize), but the
873 // presubmit script complains about using sizeof() on a type.
874 static const int kFirstRegisterParameterFrameOffset =
875 StandardFrameConstants::kMarkerOffset - 3 * kPointerSize;
876
877 static const int kCallerStackParameterCountFrameOffset =
878 StandardFrameConstants::kMarkerOffset - 2 * kPointerSize;
879
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000880 Type type() const override { return STUB_FAILURE_TRAMPOLINE; }
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000881
882 // Get the code associated with this frame.
883 // This method could be called during marking phase of GC.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000884 Code* unchecked_code() const override;
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000885
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000886 void Iterate(ObjectVisitor* v) const override;
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000887
888 // Architecture-specific register description.
889 static Register fp_register();
890 static Register context_register();
891 static Register constant_pool_pointer_register();
892
893 protected:
894 inline explicit StubFailureTrampolineFrame(
895 StackFrameIteratorBase* iterator);
896
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000897 Address GetCallerStackPointer() const override;
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000898
899 private:
900 friend class StackFrameIteratorBase;
Steve Blocka7e24c12009-10-30 11:49:00 +0000901};
902
903
904// Construct frames are special trampoline frames introduced to handle
905// function invocations through 'new'.
906class ConstructFrame: public InternalFrame {
907 public:
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000908 Type type() const override { return CONSTRUCT; }
Steve Blocka7e24c12009-10-30 11:49:00 +0000909
910 static ConstructFrame* cast(StackFrame* frame) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000911 DCHECK(frame->is_construct());
Steve Blocka7e24c12009-10-30 11:49:00 +0000912 return static_cast<ConstructFrame*>(frame);
913 }
914
915 protected:
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000916 inline explicit ConstructFrame(StackFrameIteratorBase* iterator);
Steve Blocka7e24c12009-10-30 11:49:00 +0000917
918 private:
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000919 friend class StackFrameIteratorBase;
Steve Blocka7e24c12009-10-30 11:49:00 +0000920};
921
922
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000923class StackFrameIteratorBase BASE_EMBEDDED {
Steve Blocka7e24c12009-10-30 11:49:00 +0000924 public:
Ben Murdoch8b112d22011-06-08 16:22:53 +0100925 Isolate* isolate() const { return isolate_; }
926
Steve Blocka7e24c12009-10-30 11:49:00 +0000927 bool done() const { return frame_ == NULL; }
Steve Blocka7e24c12009-10-30 11:49:00 +0000928
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000929 protected:
930 // An iterator that iterates over a given thread's stack.
931 StackFrameIteratorBase(Isolate* isolate, bool can_access_heap_objects);
Steve Blocka7e24c12009-10-30 11:49:00 +0000932
Ben Murdoch8b112d22011-06-08 16:22:53 +0100933 Isolate* isolate_;
Steve Blocka7e24c12009-10-30 11:49:00 +0000934#define DECLARE_SINGLETON(ignore, type) type type##_;
935 STACK_FRAME_TYPE_LIST(DECLARE_SINGLETON)
936#undef DECLARE_SINGLETON
937 StackFrame* frame_;
938 StackHandler* handler_;
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000939 const bool can_access_heap_objects_;
Steve Blocka7e24c12009-10-30 11:49:00 +0000940
941 StackHandler* handler() const {
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000942 DCHECK(!done());
Steve Blocka7e24c12009-10-30 11:49:00 +0000943 return handler_;
944 }
945
946 // Get the type-specific frame singleton in a given state.
947 StackFrame* SingletonFor(StackFrame::Type type, StackFrame::State* state);
948 // A helper function, can return a NULL pointer.
949 StackFrame* SingletonFor(StackFrame::Type type);
950
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000951 private:
Steve Blocka7e24c12009-10-30 11:49:00 +0000952 friend class StackFrame;
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000953 DISALLOW_COPY_AND_ASSIGN(StackFrameIteratorBase);
954};
955
956
957class StackFrameIterator: public StackFrameIteratorBase {
958 public:
959 // An iterator that iterates over the isolate's current thread's stack,
960 explicit StackFrameIterator(Isolate* isolate);
961 // An iterator that iterates over a given thread's stack.
962 StackFrameIterator(Isolate* isolate, ThreadLocalTop* t);
963
964 StackFrame* frame() const {
965 DCHECK(!done());
966 return frame_;
967 }
968 void Advance();
969
970 private:
971 // Go back to the first frame.
972 void Reset(ThreadLocalTop* top);
973
Steve Blocka7e24c12009-10-30 11:49:00 +0000974 DISALLOW_COPY_AND_ASSIGN(StackFrameIterator);
975};
976
977
978// Iterator that supports iterating through all JavaScript frames.
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000979class JavaScriptFrameIterator BASE_EMBEDDED {
Steve Blocka7e24c12009-10-30 11:49:00 +0000980 public:
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000981 inline explicit JavaScriptFrameIterator(Isolate* isolate);
982 inline JavaScriptFrameIterator(Isolate* isolate, ThreadLocalTop* top);
Steve Blocka7e24c12009-10-30 11:49:00 +0000983 // Skip frames until the frame with the given id is reached.
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000984 JavaScriptFrameIterator(Isolate* isolate, StackFrame::Id id);
Steve Block44f0eee2011-05-26 01:26:41 +0100985
Steve Blocka7e24c12009-10-30 11:49:00 +0000986 inline JavaScriptFrame* frame() const;
987
988 bool done() const { return iterator_.done(); }
989 void Advance();
990
991 // Advance to the frame holding the arguments for the current
992 // frame. This only affects the current frame if it has adapted
993 // arguments.
994 void AdvanceToArgumentsFrame();
995
Steve Blocka7e24c12009-10-30 11:49:00 +0000996 private:
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000997 StackFrameIterator iterator_;
Steve Blocka7e24c12009-10-30 11:49:00 +0000998};
999
1000
Steve Blocka7e24c12009-10-30 11:49:00 +00001001// NOTE: The stack trace frame iterator is an iterator that only
1002// traverse proper JavaScript frames; that is JavaScript frames that
1003// have proper JavaScript functions. This excludes the problematic
1004// functions in runtime.js.
1005class StackTraceFrameIterator: public JavaScriptFrameIterator {
1006 public:
Ben Murdoch8b112d22011-06-08 16:22:53 +01001007 explicit StackTraceFrameIterator(Isolate* isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +00001008 void Advance();
Leon Clarke4515c472010-02-03 11:58:03 +00001009
1010 private:
1011 bool IsValidFrame();
Steve Blocka7e24c12009-10-30 11:49:00 +00001012};
1013
1014
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001015class SafeStackFrameIterator: public StackFrameIteratorBase {
Steve Blocka7e24c12009-10-30 11:49:00 +00001016 public:
Steve Block44f0eee2011-05-26 01:26:41 +01001017 SafeStackFrameIterator(Isolate* isolate,
1018 Address fp, Address sp,
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001019 Address js_entry_sp);
Steve Blocka7e24c12009-10-30 11:49:00 +00001020
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001021 inline StackFrame* frame() const;
Steve Blocka7e24c12009-10-30 11:49:00 +00001022 void Advance();
Steve Blocka7e24c12009-10-30 11:49:00 +00001023
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001024 StackFrame::Type top_frame_type() const { return top_frame_type_; }
Leon Clarked91b9f72010-01-27 17:25:45 +00001025
1026 private:
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001027 void AdvanceOneFrame();
Kristian Monsen0d5e1162010-09-30 15:31:59 +01001028
Steve Blocka7e24c12009-10-30 11:49:00 +00001029 bool IsValidStackAddress(Address addr) const {
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001030 return low_bound_ <= addr && addr <= high_bound_;
Steve Blocka7e24c12009-10-30 11:49:00 +00001031 }
Steve Blocka7e24c12009-10-30 11:49:00 +00001032 bool IsValidFrame(StackFrame* frame) const;
1033 bool IsValidCaller(StackFrame* frame);
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001034 bool IsValidExitFrame(Address fp) const;
1035 bool IsValidTop(ThreadLocalTop* top) const;
Steve Blocka7e24c12009-10-30 11:49:00 +00001036
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001037 const Address low_bound_;
1038 const Address high_bound_;
1039 StackFrame::Type top_frame_type_;
1040 ExternalCallbackScope* external_callback_scope_;
Steve Blocka7e24c12009-10-30 11:49:00 +00001041};
Steve Blocka7e24c12009-10-30 11:49:00 +00001042
1043
1044class StackFrameLocator BASE_EMBEDDED {
1045 public:
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001046 explicit StackFrameLocator(Isolate* isolate) : iterator_(isolate) {}
1047
Steve Blocka7e24c12009-10-30 11:49:00 +00001048 // Find the nth JavaScript frame on the stack. The caller must
1049 // guarantee that such a frame exists.
1050 JavaScriptFrame* FindJavaScriptFrame(int n);
1051
1052 private:
1053 StackFrameIterator iterator_;
1054};
1055
1056
Steve Block6ded16b2010-05-10 14:33:55 +01001057// Reads all frames on the current stack and copies them into the current
1058// zone memory.
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001059Vector<StackFrame*> CreateStackMap(Isolate* isolate, Zone* zone);
Steve Block6ded16b2010-05-10 14:33:55 +01001060
Ben Murdoch4a90d5f2016-03-22 12:00:34 +00001061} // namespace internal
1062} // namespace v8
Steve Blocka7e24c12009-10-30 11:49:00 +00001063
1064#endif // V8_FRAMES_H_