blob: 674d7daeca2bc27c29081eaff2e8dcff464df4fd [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
114
115class StandardFrameConstants : public AllStatic {
116 public:
117 // Fixed part of the frame consists of return address, caller fp,
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000118 // constant pool (if FLAG_enable_embedded_constant_pool), context, and
119 // function. StandardFrame::IterateExpressions assumes that kLastObjectOffset
120 // is the last object pointer.
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000121 static const int kCPSlotSize =
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000122 FLAG_enable_embedded_constant_pool ? kPointerSize : 0;
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000123 static const int kFixedFrameSizeFromFp = 2 * kPointerSize + kCPSlotSize;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000124 static const int kFixedFrameSizeAboveFp = kPCOnStackSize + kFPOnStackSize;
125 static const int kFixedFrameSize =
126 kFixedFrameSizeAboveFp + kFixedFrameSizeFromFp;
127 static const int kFixedSlotCountAboveFp =
128 kFixedFrameSizeAboveFp / kPointerSize;
129 static const int kFixedSlotCount = kFixedFrameSize / kPointerSize;
130 static const int kCPSlotCount = kCPSlotSize / kPointerSize;
131 static const int kExpressionsOffset = -3 * kPointerSize - kCPSlotSize;
132 static const int kMarkerOffset = -2 * kPointerSize - kCPSlotSize;
133 static const int kContextOffset = -1 * kPointerSize - kCPSlotSize;
134 static const int kConstantPoolOffset = kCPSlotSize ? -1 * kPointerSize : 0;
135 static const int kCallerFPOffset = 0 * kPointerSize;
136 static const int kCallerPCOffset = +1 * kFPOnStackSize;
137 static const int kCallerSPOffset = kCallerPCOffset + 1 * kPCOnStackSize;
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000138
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000139 static const int kLastObjectOffset = kContextOffset;
140};
141
142
143class ArgumentsAdaptorFrameConstants : public AllStatic {
144 public:
145 // FP-relative.
146 static const int kLengthOffset = StandardFrameConstants::kExpressionsOffset;
147
148 static const int kFrameSize =
149 StandardFrameConstants::kFixedFrameSize + kPointerSize;
150};
151
152
153class InternalFrameConstants : public AllStatic {
154 public:
155 // FP-relative.
156 static const int kCodeOffset = StandardFrameConstants::kExpressionsOffset;
157};
158
159
160class ConstructFrameConstants : public AllStatic {
161 public:
162 // FP-relative.
163 static const int kImplicitReceiverOffset =
164 StandardFrameConstants::kExpressionsOffset - 3 * kPointerSize;
165 static const int kLengthOffset =
166 StandardFrameConstants::kExpressionsOffset - 2 * kPointerSize;
167 static const int kAllocationSiteOffset =
168 StandardFrameConstants::kExpressionsOffset - 1 * kPointerSize;
169 static const int kCodeOffset =
170 StandardFrameConstants::kExpressionsOffset - 0 * kPointerSize;
171
172 static const int kFrameSize =
173 StandardFrameConstants::kFixedFrameSize + 4 * kPointerSize;
174};
175
176
177class InterpreterFrameConstants : public AllStatic {
178 public:
179 // Fixed frame includes new.target and bytecode offset.
180 static const int kFixedFrameSize =
181 StandardFrameConstants::kFixedFrameSize + 2 * kPointerSize;
182 static const int kFixedFrameSizeFromFp =
183 StandardFrameConstants::kFixedFrameSizeFromFp + 2 * kPointerSize;
184
185 // FP-relative.
186 static const int kRegisterFilePointerFromFp =
187 -StandardFrameConstants::kFixedFrameSizeFromFp - 3 * kPointerSize;
188
189 // Register file pointer relative.
190 static const int kLastParamFromRegisterPointer =
191 StandardFrameConstants::kFixedFrameSize + 3 * kPointerSize;
192
193 static const int kBytecodeOffsetFromRegisterPointer = 1 * kPointerSize;
194 static const int kNewTargetFromRegisterPointer = 2 * kPointerSize;
195 static const int kFunctionFromRegisterPointer = 3 * kPointerSize;
196 static const int kContextFromRegisterPointer = 4 * kPointerSize;
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000197};
Steve Blocka7e24c12009-10-30 11:49:00 +0000198
199
200// Abstract base class for all stack frames.
201class StackFrame BASE_EMBEDDED {
202 public:
203#define DECLARE_TYPE(type, ignore) type,
204 enum Type {
205 NONE = 0,
206 STACK_FRAME_TYPE_LIST(DECLARE_TYPE)
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100207 NUMBER_OF_TYPES,
208 // Used by FrameScope to indicate that the stack frame is constructed
209 // manually and the FrameScope does not need to emit code.
210 MANUAL
Steve Blocka7e24c12009-10-30 11:49:00 +0000211 };
212#undef DECLARE_TYPE
213
214 // Opaque data type for identifying stack frames. Used extensively
215 // by the debugger.
Iain Merrick75681382010-08-19 15:07:18 +0100216 // ID_MIN_VALUE and ID_MAX_VALUE are specified to ensure that enumeration type
217 // has correct value range (see Issue 830 for more details).
218 enum Id {
219 ID_MIN_VALUE = kMinInt,
220 ID_MAX_VALUE = kMaxInt,
221 NO_ID = 0
222 };
Steve Blocka7e24c12009-10-30 11:49:00 +0000223
Steve Block053d10c2011-06-13 19:13:29 +0100224 // Used to mark the outermost JS entry frame.
225 enum JsFrameMarker {
226 INNER_JSENTRY_FRAME = 0,
227 OUTERMOST_JSENTRY_FRAME = 1
228 };
229
Kristian Monsen0d5e1162010-09-30 15:31:59 +0100230 struct State {
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000231 State() : sp(NULL), fp(NULL), pc_address(NULL),
232 constant_pool_address(NULL) { }
Kristian Monsen0d5e1162010-09-30 15:31:59 +0100233 Address sp;
234 Address fp;
235 Address* pc_address;
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000236 Address* constant_pool_address;
Kristian Monsen0d5e1162010-09-30 15:31:59 +0100237 };
238
Ben Murdoch8b112d22011-06-08 16:22:53 +0100239 // Copy constructor; it breaks the connection to host iterator
240 // (as an iterator usually lives on stack).
Steve Block6ded16b2010-05-10 14:33:55 +0100241 StackFrame(const StackFrame& original) {
242 this->state_ = original.state_;
243 this->iterator_ = NULL;
Ben Murdoch8b112d22011-06-08 16:22:53 +0100244 this->isolate_ = original.isolate_;
Steve Block6ded16b2010-05-10 14:33:55 +0100245 }
246
Steve Blocka7e24c12009-10-30 11:49:00 +0000247 // Type testers.
248 bool is_entry() const { return type() == ENTRY; }
249 bool is_entry_construct() const { return type() == ENTRY_CONSTRUCT; }
250 bool is_exit() const { return type() == EXIT; }
Ben Murdochb0fe1622011-05-05 13:52:32 +0100251 bool is_optimized() const { return type() == OPTIMIZED; }
Steve Blocka7e24c12009-10-30 11:49:00 +0000252 bool is_arguments_adaptor() const { return type() == ARGUMENTS_ADAPTOR; }
253 bool is_internal() const { return type() == INTERNAL; }
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000254 bool is_stub_failure_trampoline() const {
255 return type() == STUB_FAILURE_TRAMPOLINE;
256 }
Steve Blocka7e24c12009-10-30 11:49:00 +0000257 bool is_construct() const { return type() == CONSTRUCT; }
258 virtual bool is_standard() const { return false; }
259
Ben Murdochb0fe1622011-05-05 13:52:32 +0100260 bool is_java_script() const {
261 Type type = this->type();
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000262 return (type == JAVA_SCRIPT) || (type == OPTIMIZED) ||
263 (type == INTERPRETED);
Ben Murdochb0fe1622011-05-05 13:52:32 +0100264 }
265
Steve Blocka7e24c12009-10-30 11:49:00 +0000266 // Accessors.
267 Address sp() const { return state_.sp; }
268 Address fp() const { return state_.fp; }
269 Address caller_sp() const { return GetCallerStackPointer(); }
270
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000271 // If this frame is optimized and was dynamically aligned return its old
272 // unaligned frame pointer. When the frame is deoptimized its FP will shift
273 // up one word and become unaligned.
274 Address UnpaddedFP() const;
275
Steve Blocka7e24c12009-10-30 11:49:00 +0000276 Address pc() const { return *pc_address(); }
277 void set_pc(Address pc) { *pc_address() = pc; }
278
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000279 Address constant_pool() const { return *constant_pool_address(); }
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000280 void set_constant_pool(Address constant_pool) {
281 *constant_pool_address() = constant_pool;
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000282 }
283
Steve Block6ded16b2010-05-10 14:33:55 +0100284 virtual void SetCallerFp(Address caller_fp) = 0;
285
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000286 // Manually changes value of fp in this object.
287 void UpdateFp(Address fp) { state_.fp = fp; }
288
Steve Blocka7e24c12009-10-30 11:49:00 +0000289 Address* pc_address() const { return state_.pc_address; }
290
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000291 Address* constant_pool_address() const {
292 return state_.constant_pool_address;
293 }
294
Steve Blocka7e24c12009-10-30 11:49:00 +0000295 // Get the id of this stack frame.
296 Id id() const { return static_cast<Id>(OffsetFrom(caller_sp())); }
297
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000298 // Get the top handler from the current stack iterator.
299 inline StackHandler* top_handler() const;
Steve Blocka7e24c12009-10-30 11:49:00 +0000300
301 // Get the type of this frame.
302 virtual Type type() const = 0;
303
304 // Get the code associated with this frame.
Iain Merrick75681382010-08-19 15:07:18 +0100305 // This method could be called during marking phase of GC.
306 virtual Code* unchecked_code() const = 0;
307
308 // Get the code associated with this frame.
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100309 inline Code* LookupCode() const;
Kristian Monsen80d68ea2010-09-08 11:05:35 +0100310
311 // Get the code object that contains the given pc.
Steve Block44f0eee2011-05-26 01:26:41 +0100312 static inline Code* GetContainingCode(Isolate* isolate, Address pc);
Steve Blocka7e24c12009-10-30 11:49:00 +0000313
Ben Murdochb0fe1622011-05-05 13:52:32 +0100314 // Get the code object containing the given pc and fill in the
315 // safepoint entry and the number of stack slots. The pc must be at
316 // a safepoint.
Ben Murdoch8b112d22011-06-08 16:22:53 +0100317 static Code* GetSafepointData(Isolate* isolate,
318 Address pc,
Ben Murdochb8e0da22011-05-16 14:20:40 +0100319 SafepointEntry* safepoint_entry,
Ben Murdochb0fe1622011-05-05 13:52:32 +0100320 unsigned* stack_slots);
321
Kristian Monsen80d68ea2010-09-08 11:05:35 +0100322 virtual void Iterate(ObjectVisitor* v) const = 0;
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000323 static void IteratePc(ObjectVisitor* v, Address* pc_address,
324 Address* constant_pool_address, Code* holder);
Steve Blocka7e24c12009-10-30 11:49:00 +0000325
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100326 // Sets a callback function for return-address rewriting profilers
327 // to resolve the location of a return address to the location of the
328 // profiler's stashed return address.
329 static void SetReturnAddressLocationResolver(
330 ReturnAddressLocationResolver resolver);
Steve Blocka7e24c12009-10-30 11:49:00 +0000331
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000332 // Resolves pc_address through the resolution address function if one is set.
333 static inline Address* ResolveReturnAddressLocation(Address* pc_address);
334
Steve Blocka7e24c12009-10-30 11:49:00 +0000335 // Printing support.
336 enum PrintMode { OVERVIEW, DETAILS };
337 virtual void Print(StringStream* accumulator,
338 PrintMode mode,
339 int index) const { }
340
Ben Murdoch8b112d22011-06-08 16:22:53 +0100341 Isolate* isolate() const { return isolate_; }
342
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000343 protected:
344 inline explicit StackFrame(StackFrameIteratorBase* iterator);
345 virtual ~StackFrame() { }
346
Steve Blocka7e24c12009-10-30 11:49:00 +0000347 // Compute the stack pointer for the calling frame.
348 virtual Address GetCallerStackPointer() const = 0;
349
350 // Printing support.
351 static void PrintIndex(StringStream* accumulator,
352 PrintMode mode,
353 int index);
354
Steve Blocka7e24c12009-10-30 11:49:00 +0000355 // Compute the stack frame type for the given state.
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000356 static Type ComputeType(const StackFrameIteratorBase* iterator, State* state);
357
358#ifdef DEBUG
359 bool can_access_heap_objects() const;
360#endif
Steve Blocka7e24c12009-10-30 11:49:00 +0000361
362 private:
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000363 const StackFrameIteratorBase* iterator_;
Ben Murdoch8b112d22011-06-08 16:22:53 +0100364 Isolate* isolate_;
Steve Blocka7e24c12009-10-30 11:49:00 +0000365 State state_;
366
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000367 static ReturnAddressLocationResolver return_address_location_resolver_;
368
Steve Blocka7e24c12009-10-30 11:49:00 +0000369 // Fill in the state of the calling frame.
370 virtual void ComputeCallerState(State* state) const = 0;
371
372 // Get the type and the state of the calling frame.
373 virtual Type GetCallerState(State* state) const;
374
Ben Murdoch8b112d22011-06-08 16:22:53 +0100375 static const intptr_t kIsolateTag = 1;
376
Steve Blocka7e24c12009-10-30 11:49:00 +0000377 friend class StackFrameIterator;
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000378 friend class StackFrameIteratorBase;
Steve Blocka7e24c12009-10-30 11:49:00 +0000379 friend class StackHandlerIterator;
380 friend class SafeStackFrameIterator;
381
Steve Block6ded16b2010-05-10 14:33:55 +0100382 private:
383 void operator=(const StackFrame& original);
Steve Blocka7e24c12009-10-30 11:49:00 +0000384};
385
386
387// Entry frames are used to enter JavaScript execution from C.
388class EntryFrame: public StackFrame {
389 public:
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000390 Type type() const override { return ENTRY; }
Steve Blocka7e24c12009-10-30 11:49:00 +0000391
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000392 Code* unchecked_code() const override;
Steve Blocka7e24c12009-10-30 11:49:00 +0000393
394 // Garbage collection support.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000395 void Iterate(ObjectVisitor* v) const override;
Steve Blocka7e24c12009-10-30 11:49:00 +0000396
397 static EntryFrame* cast(StackFrame* frame) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000398 DCHECK(frame->is_entry());
Steve Blocka7e24c12009-10-30 11:49:00 +0000399 return static_cast<EntryFrame*>(frame);
400 }
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000401 void SetCallerFp(Address caller_fp) override;
Steve Blocka7e24c12009-10-30 11:49:00 +0000402
403 protected:
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000404 inline explicit EntryFrame(StackFrameIteratorBase* iterator);
Steve Blocka7e24c12009-10-30 11:49:00 +0000405
406 // The caller stack pointer for entry frames is always zero. The
407 // real information about the caller frame is available through the
408 // link to the top exit frame.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000409 Address GetCallerStackPointer() const override { return 0; }
Steve Blocka7e24c12009-10-30 11:49:00 +0000410
411 private:
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000412 void ComputeCallerState(State* state) const override;
413 Type GetCallerState(State* state) const override;
Steve Blocka7e24c12009-10-30 11:49:00 +0000414
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000415 friend class StackFrameIteratorBase;
Steve Blocka7e24c12009-10-30 11:49:00 +0000416};
417
418
419class EntryConstructFrame: public EntryFrame {
420 public:
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000421 Type type() const override { return ENTRY_CONSTRUCT; }
Steve Blocka7e24c12009-10-30 11:49:00 +0000422
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000423 Code* unchecked_code() const override;
Steve Blocka7e24c12009-10-30 11:49:00 +0000424
425 static EntryConstructFrame* cast(StackFrame* frame) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000426 DCHECK(frame->is_entry_construct());
Steve Blocka7e24c12009-10-30 11:49:00 +0000427 return static_cast<EntryConstructFrame*>(frame);
428 }
429
430 protected:
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000431 inline explicit EntryConstructFrame(StackFrameIteratorBase* iterator);
Steve Blocka7e24c12009-10-30 11:49:00 +0000432
433 private:
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000434 friend class StackFrameIteratorBase;
Steve Blocka7e24c12009-10-30 11:49:00 +0000435};
436
437
438// Exit frames are used to exit JavaScript execution and go to C.
439class ExitFrame: public StackFrame {
440 public:
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000441 Type type() const override { return EXIT; }
Steve Blocka7e24c12009-10-30 11:49:00 +0000442
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000443 Code* unchecked_code() const override;
Steve Blocka7e24c12009-10-30 11:49:00 +0000444
Steve Blockd0582a62009-12-15 09:54:21 +0000445 Object*& code_slot() const;
446
Steve Blocka7e24c12009-10-30 11:49:00 +0000447 // Garbage collection support.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000448 void Iterate(ObjectVisitor* v) const override;
Steve Blocka7e24c12009-10-30 11:49:00 +0000449
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000450 void SetCallerFp(Address caller_fp) override;
Steve Block6ded16b2010-05-10 14:33:55 +0100451
Steve Blocka7e24c12009-10-30 11:49:00 +0000452 static ExitFrame* cast(StackFrame* frame) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000453 DCHECK(frame->is_exit());
Steve Blocka7e24c12009-10-30 11:49:00 +0000454 return static_cast<ExitFrame*>(frame);
455 }
456
457 // Compute the state and type of an exit frame given a frame
458 // pointer. Used when constructing the first stack frame seen by an
459 // iterator and the frames following entry frames.
460 static Type GetStateForFramePointer(Address fp, State* state);
Kristian Monsen0d5e1162010-09-30 15:31:59 +0100461 static Address ComputeStackPointer(Address fp);
462 static void FillState(Address fp, Address sp, State* state);
Steve Blocka7e24c12009-10-30 11:49:00 +0000463
464 protected:
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000465 inline explicit ExitFrame(StackFrameIteratorBase* iterator);
Steve Blocka7e24c12009-10-30 11:49:00 +0000466
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000467 Address GetCallerStackPointer() const override;
Steve Blocka7e24c12009-10-30 11:49:00 +0000468
469 private:
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000470 void ComputeCallerState(State* state) const override;
Steve Blocka7e24c12009-10-30 11:49:00 +0000471
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000472 friend class StackFrameIteratorBase;
Steve Blocka7e24c12009-10-30 11:49:00 +0000473};
474
475
Steve Blocka7e24c12009-10-30 11:49:00 +0000476class StandardFrame: public StackFrame {
477 public:
478 // Testers.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000479 bool is_standard() const override { return true; }
Steve Blocka7e24c12009-10-30 11:49:00 +0000480
481 // Accessors.
482 inline Object* context() const;
483
484 // Access the expressions in the stack frame including locals.
485 inline Object* GetExpression(int index) const;
486 inline void SetExpression(int index, Object* value);
487 int ComputeExpressionsCount() const;
Ben Murdoch3fb3ca82011-12-02 17:19:32 +0000488 static Object* GetExpression(Address fp, int index);
Steve Blocka7e24c12009-10-30 11:49:00 +0000489
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000490 void SetCallerFp(Address caller_fp) override;
Steve Block6ded16b2010-05-10 14:33:55 +0100491
Steve Blocka7e24c12009-10-30 11:49:00 +0000492 static StandardFrame* cast(StackFrame* frame) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000493 DCHECK(frame->is_standard());
Steve Blocka7e24c12009-10-30 11:49:00 +0000494 return static_cast<StandardFrame*>(frame);
495 }
496
497 protected:
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000498 inline explicit StandardFrame(StackFrameIteratorBase* iterator);
Steve Blocka7e24c12009-10-30 11:49:00 +0000499
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000500 void ComputeCallerState(State* state) const override;
Steve Blocka7e24c12009-10-30 11:49:00 +0000501
502 // Accessors.
503 inline Address caller_fp() const;
504 inline Address caller_pc() const;
505
506 // Computes the address of the PC field in the standard frame given
507 // by the provided frame pointer.
508 static inline Address ComputePCAddress(Address fp);
509
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000510 // Computes the address of the constant pool field in the standard
511 // frame given by the provided frame pointer.
512 static inline Address ComputeConstantPoolAddress(Address fp);
513
Steve Blocka7e24c12009-10-30 11:49:00 +0000514 // Iterate over expression stack including stack handlers, locals,
515 // and parts of the fixed part including context and code fields.
516 void IterateExpressions(ObjectVisitor* v) const;
517
518 // Returns the address of the n'th expression stack element.
519 Address GetExpressionAddress(int n) const;
Ben Murdoch3fb3ca82011-12-02 17:19:32 +0000520 static Address GetExpressionAddress(Address fp, int n);
Steve Blocka7e24c12009-10-30 11:49:00 +0000521
Steve Blocka7e24c12009-10-30 11:49:00 +0000522 // Determines if the standard frame for the given frame pointer is
523 // an arguments adaptor frame.
524 static inline bool IsArgumentsAdaptorFrame(Address fp);
525
526 // Determines if the standard frame for the given frame pointer is a
527 // construct frame.
528 static inline bool IsConstructFrame(Address fp);
529
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000530 // Used by OptimizedFrames and StubFrames.
531 void IterateCompiledFrame(ObjectVisitor* v) const;
532
Steve Blocka7e24c12009-10-30 11:49:00 +0000533 private:
534 friend class StackFrame;
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000535 friend class SafeStackFrameIterator;
Steve Blocka7e24c12009-10-30 11:49:00 +0000536};
537
538
Ben Murdochb0fe1622011-05-05 13:52:32 +0100539class FrameSummary BASE_EMBEDDED {
540 public:
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000541 FrameSummary(Object* receiver, JSFunction* function, Code* code, int offset,
542 bool is_constructor);
543
Ben Murdochb0fe1622011-05-05 13:52:32 +0100544 Handle<Object> receiver() { return receiver_; }
545 Handle<JSFunction> function() { return function_; }
546 Handle<Code> code() { return code_; }
Ben Murdoch8b112d22011-06-08 16:22:53 +0100547 Address pc() { return code_->address() + offset_; }
Ben Murdochb0fe1622011-05-05 13:52:32 +0100548 int offset() { return offset_; }
549 bool is_constructor() { return is_constructor_; }
550
551 void Print();
552
553 private:
554 Handle<Object> receiver_;
555 Handle<JSFunction> function_;
556 Handle<Code> code_;
557 int offset_;
558 bool is_constructor_;
559};
560
561
Steve Blocka7e24c12009-10-30 11:49:00 +0000562class JavaScriptFrame: public StandardFrame {
563 public:
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000564 Type type() const override { return JAVA_SCRIPT; }
Steve Blocka7e24c12009-10-30 11:49:00 +0000565
566 // Accessors.
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000567 inline JSFunction* function() const;
Steve Blocka7e24c12009-10-30 11:49:00 +0000568 inline Object* receiver() const;
569 inline void set_receiver(Object* value);
570
571 // Access the parameters.
Ben Murdoch8b112d22011-06-08 16:22:53 +0100572 inline Address GetParameterSlot(int index) const;
573 inline Object* GetParameter(int index) const;
574 inline int ComputeParametersCount() const {
575 return GetNumberOfIncomingArguments();
576 }
Steve Blocka7e24c12009-10-30 11:49:00 +0000577
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000578 // Access the operand stack.
579 inline Address GetOperandSlot(int index) const;
580 inline Object* GetOperand(int index) const;
581 inline int ComputeOperandsCount() const;
582
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000583 // Generator support to preserve operand stack.
584 void SaveOperandStack(FixedArray* store) const;
585 void RestoreOperandStack(FixedArray* store);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000586
587 // Debugger access.
588 void SetParameterValue(int index, Object* value) const;
589
Steve Blocka7e24c12009-10-30 11:49:00 +0000590 // Check if this frame is a constructor frame invoked through 'new'.
591 bool IsConstructor() const;
592
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000593 // Determines whether this frame includes inlined activations. To get details
594 // about the inlined frames use {GetFunctions} and {Summarize}.
595 bool HasInlinedFrames() const;
596
Steve Blocka7e24c12009-10-30 11:49:00 +0000597 // Check if this frame has "adapted" arguments in the sense that the
598 // actual passed arguments are available in an arguments adaptor
599 // frame below it on the stack.
600 inline bool has_adapted_arguments() const;
Ben Murdoch3fb3ca82011-12-02 17:19:32 +0000601 int GetArgumentsLength() const;
Steve Blocka7e24c12009-10-30 11:49:00 +0000602
603 // Garbage collection support.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000604 void Iterate(ObjectVisitor* v) const override;
Steve Blocka7e24c12009-10-30 11:49:00 +0000605
606 // Printing support.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000607 void Print(StringStream* accumulator, PrintMode mode,
608 int index) const override;
Steve Blocka7e24c12009-10-30 11:49:00 +0000609
610 // Determine the code for the frame.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000611 Code* unchecked_code() const override;
Ben Murdoch3fb3ca82011-12-02 17:19:32 +0000612
Ben Murdochb0fe1622011-05-05 13:52:32 +0100613 // Return a list with JSFunctions of this frame.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000614 virtual void GetFunctions(List<JSFunction*>* functions) const;
Ben Murdochb0fe1622011-05-05 13:52:32 +0100615
616 // Build a list with summaries for this frame including all inlined frames.
617 virtual void Summarize(List<FrameSummary>* frames);
618
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000619 // Lookup exception handler for current {pc}, returns -1 if none found. Also
620 // returns the expected number of stack slots at the handler site.
621 virtual int LookupExceptionHandlerInTable(
622 int* stack_slots, HandlerTable::CatchPrediction* prediction);
623
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000624 // Architecture-specific register description.
625 static Register fp_register();
626 static Register context_register();
627 static Register constant_pool_pointer_register();
628
Steve Blocka7e24c12009-10-30 11:49:00 +0000629 static JavaScriptFrame* cast(StackFrame* frame) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000630 DCHECK(frame->is_java_script());
Steve Blocka7e24c12009-10-30 11:49:00 +0000631 return static_cast<JavaScriptFrame*>(frame);
632 }
633
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000634 static void PrintFunctionAndOffset(JSFunction* function, Code* code,
635 Address pc, FILE* file,
636 bool print_line_number);
637
638 static void PrintTop(Isolate* isolate, FILE* file, bool print_args,
639 bool print_line_number);
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100640
Steve Blocka7e24c12009-10-30 11:49:00 +0000641 protected:
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000642 inline explicit JavaScriptFrame(StackFrameIteratorBase* iterator);
Steve Blocka7e24c12009-10-30 11:49:00 +0000643
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000644 Address GetCallerStackPointer() const override;
Steve Blocka7e24c12009-10-30 11:49:00 +0000645
Ben Murdoch8b112d22011-06-08 16:22:53 +0100646 virtual int GetNumberOfIncomingArguments() const;
647
Ben Murdochb0fe1622011-05-05 13:52:32 +0100648 // Garbage collection support. Iterates over incoming arguments,
649 // receiver, and any callee-saved registers.
650 void IterateArguments(ObjectVisitor* v) const;
651
Steve Blocka7e24c12009-10-30 11:49:00 +0000652 private:
Steve Blocka7e24c12009-10-30 11:49:00 +0000653 inline Object* function_slot_object() const;
654
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000655 friend class StackFrameIteratorBase;
656};
657
658
659class StubFrame : public StandardFrame {
660 public:
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000661 Type type() const override { return STUB; }
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000662
663 // GC support.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000664 void Iterate(ObjectVisitor* v) const override;
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000665
666 // Determine the code for the frame.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000667 Code* unchecked_code() const override;
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000668
669 protected:
670 inline explicit StubFrame(StackFrameIteratorBase* iterator);
671
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000672 Address GetCallerStackPointer() const override;
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000673
674 virtual int GetNumberOfIncomingArguments() const;
675
676 friend class StackFrameIteratorBase;
Steve Blocka7e24c12009-10-30 11:49:00 +0000677};
678
679
Ben Murdochb0fe1622011-05-05 13:52:32 +0100680class OptimizedFrame : public JavaScriptFrame {
681 public:
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000682 Type type() const override { return OPTIMIZED; }
Ben Murdochb0fe1622011-05-05 13:52:32 +0100683
684 // GC support.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000685 void Iterate(ObjectVisitor* v) const override;
Ben Murdoch3fb3ca82011-12-02 17:19:32 +0000686
Ben Murdochb0fe1622011-05-05 13:52:32 +0100687 // Return a list with JSFunctions of this frame.
688 // The functions are ordered bottom-to-top (i.e. functions.last()
689 // is the top-most activation)
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000690 void GetFunctions(List<JSFunction*>* functions) const override;
Ben Murdochb0fe1622011-05-05 13:52:32 +0100691
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000692 void Summarize(List<FrameSummary>* frames) override;
Ben Murdochb0fe1622011-05-05 13:52:32 +0100693
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000694 // Lookup exception handler for current {pc}, returns -1 if none found. Also
695 // returns the expected number of stack slots at the handler site.
696 int LookupExceptionHandlerInTable(
697 int* stack_slots, HandlerTable::CatchPrediction* prediction) override;
698
699 DeoptimizationInputData* GetDeoptimizationData(int* deopt_index) const;
700
701 static int StackSlotOffsetRelativeToFp(int slot_index);
Ben Murdochb0fe1622011-05-05 13:52:32 +0100702
703 protected:
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000704 inline explicit OptimizedFrame(StackFrameIteratorBase* iterator);
Ben Murdochb0fe1622011-05-05 13:52:32 +0100705
706 private:
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000707 friend class StackFrameIteratorBase;
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000708
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000709 Object* StackSlotAt(int index) const;
710};
711
712
713class InterpretedFrame : public JavaScriptFrame {
714 Type type() const override { return INTERPRETED; }
715
716 protected:
717 inline explicit InterpretedFrame(StackFrameIteratorBase* iterator);
718
719 private:
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000720 friend class StackFrameIteratorBase;
Ben Murdochb0fe1622011-05-05 13:52:32 +0100721};
722
723
Steve Blocka7e24c12009-10-30 11:49:00 +0000724// Arguments adaptor frames are automatically inserted below
725// JavaScript frames when the actual number of parameters does not
726// match the formal number of parameters.
727class ArgumentsAdaptorFrame: public JavaScriptFrame {
728 public:
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000729 Type type() const override { return ARGUMENTS_ADAPTOR; }
Steve Blocka7e24c12009-10-30 11:49:00 +0000730
731 // Determine the code for the frame.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000732 Code* unchecked_code() const override;
Steve Blocka7e24c12009-10-30 11:49:00 +0000733
734 static ArgumentsAdaptorFrame* cast(StackFrame* frame) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000735 DCHECK(frame->is_arguments_adaptor());
Steve Blocka7e24c12009-10-30 11:49:00 +0000736 return static_cast<ArgumentsAdaptorFrame*>(frame);
737 }
738
739 // Printing support.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000740 void Print(StringStream* accumulator, PrintMode mode,
741 int index) const override;
Ben Murdoch589d6972011-11-30 16:04:58 +0000742
Steve Blocka7e24c12009-10-30 11:49:00 +0000743 protected:
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000744 inline explicit ArgumentsAdaptorFrame(StackFrameIteratorBase* iterator);
Steve Blocka7e24c12009-10-30 11:49:00 +0000745
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000746 int GetNumberOfIncomingArguments() const override;
Ben Murdoch8b112d22011-06-08 16:22:53 +0100747
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000748 Address GetCallerStackPointer() const override;
Steve Blocka7e24c12009-10-30 11:49:00 +0000749
750 private:
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000751 friend class StackFrameIteratorBase;
Steve Blocka7e24c12009-10-30 11:49:00 +0000752};
753
754
755class InternalFrame: public StandardFrame {
756 public:
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000757 Type type() const override { return INTERNAL; }
Steve Blocka7e24c12009-10-30 11:49:00 +0000758
759 // Garbage collection support.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000760 void Iterate(ObjectVisitor* v) const override;
Steve Blocka7e24c12009-10-30 11:49:00 +0000761
762 // Determine the code for the frame.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000763 Code* unchecked_code() const override;
Steve Blocka7e24c12009-10-30 11:49:00 +0000764
765 static InternalFrame* cast(StackFrame* frame) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000766 DCHECK(frame->is_internal());
Steve Blocka7e24c12009-10-30 11:49:00 +0000767 return static_cast<InternalFrame*>(frame);
768 }
769
770 protected:
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000771 inline explicit InternalFrame(StackFrameIteratorBase* iterator);
Steve Blocka7e24c12009-10-30 11:49:00 +0000772
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000773 Address GetCallerStackPointer() const override;
Steve Blocka7e24c12009-10-30 11:49:00 +0000774
775 private:
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000776 friend class StackFrameIteratorBase;
777};
778
779
780class StubFailureTrampolineFrame: public StandardFrame {
781 public:
782 // sizeof(Arguments) - sizeof(Arguments*) is 3 * kPointerSize), but the
783 // presubmit script complains about using sizeof() on a type.
784 static const int kFirstRegisterParameterFrameOffset =
785 StandardFrameConstants::kMarkerOffset - 3 * kPointerSize;
786
787 static const int kCallerStackParameterCountFrameOffset =
788 StandardFrameConstants::kMarkerOffset - 2 * kPointerSize;
789
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000790 Type type() const override { return STUB_FAILURE_TRAMPOLINE; }
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000791
792 // Get the code associated with this frame.
793 // This method could be called during marking phase of GC.
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000794 Code* unchecked_code() const override;
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000795
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000796 void Iterate(ObjectVisitor* v) const override;
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000797
798 // Architecture-specific register description.
799 static Register fp_register();
800 static Register context_register();
801 static Register constant_pool_pointer_register();
802
803 protected:
804 inline explicit StubFailureTrampolineFrame(
805 StackFrameIteratorBase* iterator);
806
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000807 Address GetCallerStackPointer() const override;
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000808
809 private:
810 friend class StackFrameIteratorBase;
Steve Blocka7e24c12009-10-30 11:49:00 +0000811};
812
813
814// Construct frames are special trampoline frames introduced to handle
815// function invocations through 'new'.
816class ConstructFrame: public InternalFrame {
817 public:
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000818 Type type() const override { return CONSTRUCT; }
Steve Blocka7e24c12009-10-30 11:49:00 +0000819
820 static ConstructFrame* cast(StackFrame* frame) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000821 DCHECK(frame->is_construct());
Steve Blocka7e24c12009-10-30 11:49:00 +0000822 return static_cast<ConstructFrame*>(frame);
823 }
824
825 protected:
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000826 inline explicit ConstructFrame(StackFrameIteratorBase* iterator);
Steve Blocka7e24c12009-10-30 11:49:00 +0000827
828 private:
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000829 friend class StackFrameIteratorBase;
Steve Blocka7e24c12009-10-30 11:49:00 +0000830};
831
832
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000833class StackFrameIteratorBase BASE_EMBEDDED {
Steve Blocka7e24c12009-10-30 11:49:00 +0000834 public:
Ben Murdoch8b112d22011-06-08 16:22:53 +0100835 Isolate* isolate() const { return isolate_; }
836
Steve Blocka7e24c12009-10-30 11:49:00 +0000837 bool done() const { return frame_ == NULL; }
Steve Blocka7e24c12009-10-30 11:49:00 +0000838
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000839 protected:
840 // An iterator that iterates over a given thread's stack.
841 StackFrameIteratorBase(Isolate* isolate, bool can_access_heap_objects);
Steve Blocka7e24c12009-10-30 11:49:00 +0000842
Ben Murdoch8b112d22011-06-08 16:22:53 +0100843 Isolate* isolate_;
Steve Blocka7e24c12009-10-30 11:49:00 +0000844#define DECLARE_SINGLETON(ignore, type) type type##_;
845 STACK_FRAME_TYPE_LIST(DECLARE_SINGLETON)
846#undef DECLARE_SINGLETON
847 StackFrame* frame_;
848 StackHandler* handler_;
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000849 const bool can_access_heap_objects_;
Steve Blocka7e24c12009-10-30 11:49:00 +0000850
851 StackHandler* handler() const {
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000852 DCHECK(!done());
Steve Blocka7e24c12009-10-30 11:49:00 +0000853 return handler_;
854 }
855
856 // Get the type-specific frame singleton in a given state.
857 StackFrame* SingletonFor(StackFrame::Type type, StackFrame::State* state);
858 // A helper function, can return a NULL pointer.
859 StackFrame* SingletonFor(StackFrame::Type type);
860
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000861 private:
Steve Blocka7e24c12009-10-30 11:49:00 +0000862 friend class StackFrame;
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000863 DISALLOW_COPY_AND_ASSIGN(StackFrameIteratorBase);
864};
865
866
867class StackFrameIterator: public StackFrameIteratorBase {
868 public:
869 // An iterator that iterates over the isolate's current thread's stack,
870 explicit StackFrameIterator(Isolate* isolate);
871 // An iterator that iterates over a given thread's stack.
872 StackFrameIterator(Isolate* isolate, ThreadLocalTop* t);
873
874 StackFrame* frame() const {
875 DCHECK(!done());
876 return frame_;
877 }
878 void Advance();
879
880 private:
881 // Go back to the first frame.
882 void Reset(ThreadLocalTop* top);
883
Steve Blocka7e24c12009-10-30 11:49:00 +0000884 DISALLOW_COPY_AND_ASSIGN(StackFrameIterator);
885};
886
887
888// Iterator that supports iterating through all JavaScript frames.
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000889class JavaScriptFrameIterator BASE_EMBEDDED {
Steve Blocka7e24c12009-10-30 11:49:00 +0000890 public:
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000891 inline explicit JavaScriptFrameIterator(Isolate* isolate);
892 inline JavaScriptFrameIterator(Isolate* isolate, ThreadLocalTop* top);
Steve Blocka7e24c12009-10-30 11:49:00 +0000893 // Skip frames until the frame with the given id is reached.
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000894 JavaScriptFrameIterator(Isolate* isolate, StackFrame::Id id);
Steve Block44f0eee2011-05-26 01:26:41 +0100895
Steve Blocka7e24c12009-10-30 11:49:00 +0000896 inline JavaScriptFrame* frame() const;
897
898 bool done() const { return iterator_.done(); }
899 void Advance();
900
901 // Advance to the frame holding the arguments for the current
902 // frame. This only affects the current frame if it has adapted
903 // arguments.
904 void AdvanceToArgumentsFrame();
905
Steve Blocka7e24c12009-10-30 11:49:00 +0000906 private:
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000907 StackFrameIterator iterator_;
Steve Blocka7e24c12009-10-30 11:49:00 +0000908};
909
910
Steve Blocka7e24c12009-10-30 11:49:00 +0000911// NOTE: The stack trace frame iterator is an iterator that only
912// traverse proper JavaScript frames; that is JavaScript frames that
913// have proper JavaScript functions. This excludes the problematic
914// functions in runtime.js.
915class StackTraceFrameIterator: public JavaScriptFrameIterator {
916 public:
Ben Murdoch8b112d22011-06-08 16:22:53 +0100917 explicit StackTraceFrameIterator(Isolate* isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +0000918 void Advance();
Leon Clarke4515c472010-02-03 11:58:03 +0000919
920 private:
921 bool IsValidFrame();
Steve Blocka7e24c12009-10-30 11:49:00 +0000922};
923
924
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000925class SafeStackFrameIterator: public StackFrameIteratorBase {
Steve Blocka7e24c12009-10-30 11:49:00 +0000926 public:
Steve Block44f0eee2011-05-26 01:26:41 +0100927 SafeStackFrameIterator(Isolate* isolate,
928 Address fp, Address sp,
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000929 Address js_entry_sp);
Steve Blocka7e24c12009-10-30 11:49:00 +0000930
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000931 inline StackFrame* frame() const;
Steve Blocka7e24c12009-10-30 11:49:00 +0000932 void Advance();
Steve Blocka7e24c12009-10-30 11:49:00 +0000933
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000934 StackFrame::Type top_frame_type() const { return top_frame_type_; }
Leon Clarked91b9f72010-01-27 17:25:45 +0000935
936 private:
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000937 void AdvanceOneFrame();
Kristian Monsen0d5e1162010-09-30 15:31:59 +0100938
Steve Blocka7e24c12009-10-30 11:49:00 +0000939 bool IsValidStackAddress(Address addr) const {
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000940 return low_bound_ <= addr && addr <= high_bound_;
Steve Blocka7e24c12009-10-30 11:49:00 +0000941 }
Steve Blocka7e24c12009-10-30 11:49:00 +0000942 bool IsValidFrame(StackFrame* frame) const;
943 bool IsValidCaller(StackFrame* frame);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000944 bool IsValidExitFrame(Address fp) const;
945 bool IsValidTop(ThreadLocalTop* top) const;
Steve Blocka7e24c12009-10-30 11:49:00 +0000946
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000947 const Address low_bound_;
948 const Address high_bound_;
949 StackFrame::Type top_frame_type_;
950 ExternalCallbackScope* external_callback_scope_;
Steve Blocka7e24c12009-10-30 11:49:00 +0000951};
Steve Blocka7e24c12009-10-30 11:49:00 +0000952
953
954class StackFrameLocator BASE_EMBEDDED {
955 public:
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000956 explicit StackFrameLocator(Isolate* isolate) : iterator_(isolate) {}
957
Steve Blocka7e24c12009-10-30 11:49:00 +0000958 // Find the nth JavaScript frame on the stack. The caller must
959 // guarantee that such a frame exists.
960 JavaScriptFrame* FindJavaScriptFrame(int n);
961
962 private:
963 StackFrameIterator iterator_;
964};
965
966
Steve Block6ded16b2010-05-10 14:33:55 +0100967// Reads all frames on the current stack and copies them into the current
968// zone memory.
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000969Vector<StackFrame*> CreateStackMap(Isolate* isolate, Zone* zone);
Steve Block6ded16b2010-05-10 14:33:55 +0100970
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000971} // namespace internal
972} // namespace v8
Steve Blocka7e24c12009-10-30 11:49:00 +0000973
974#endif // V8_FRAMES_H_