blob: f7e60aef33b1b0fd67342bfa66ea78a5e8bb89b7 [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 Murdochb8a8cc12014-11-26 15:28:44 +000069class StackHandlerConstants : public AllStatic {
70 public:
71 static const int kNextOffset = 0 * kPointerSize;
72 static const int kCodeOffset = 1 * kPointerSize;
73 static const int kStateOffset = 2 * kPointerSize;
74 static const int kContextOffset = 3 * kPointerSize;
75 static const int kFPOffset = 4 * kPointerSize;
76
77 static const int kSize = kFPOffset + kFPOnStackSize;
78 static const int kSlotCount = kSize >> kPointerSizeLog2;
79};
80
81
Steve Blocka7e24c12009-10-30 11:49:00 +000082class StackHandler BASE_EMBEDDED {
83 public:
Ben Murdoch3ef787d2012-04-12 10:51:47 +010084 enum Kind {
85 JS_ENTRY,
86 CATCH,
87 FINALLY,
88 LAST_KIND = FINALLY
Steve Blocka7e24c12009-10-30 11:49:00 +000089 };
90
Ben Murdoch3ef787d2012-04-12 10:51:47 +010091 static const int kKindWidth = 2;
92 STATIC_ASSERT(LAST_KIND < (1 << kKindWidth));
93 static const int kIndexWidth = 32 - kKindWidth;
94 class KindField: public BitField<StackHandler::Kind, 0, kKindWidth> {};
95 class IndexField: public BitField<unsigned, kKindWidth, kIndexWidth> {};
96
Steve Blocka7e24c12009-10-30 11:49:00 +000097 // Get the address of this stack handler.
98 inline Address address() const;
99
100 // Get the next stack handler in the chain.
101 inline StackHandler* next() const;
102
103 // Tells whether the given address is inside this handler.
104 inline bool includes(Address address) const;
105
106 // Garbage collection support.
Kristian Monsen80d68ea2010-09-08 11:05:35 +0100107 inline void Iterate(ObjectVisitor* v, Code* holder) const;
Steve Blocka7e24c12009-10-30 11:49:00 +0000108
109 // Conversion support.
110 static inline StackHandler* FromAddress(Address address);
111
112 // Testers
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100113 inline bool is_js_entry() const;
114 inline bool is_catch() const;
115 inline bool is_finally() const;
Steve Blocka7e24c12009-10-30 11:49:00 +0000116
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000117 // Generator support to preserve stack handlers.
118 void Unwind(Isolate* isolate, FixedArray* array, int offset,
119 int previous_handler_offset) const;
120 int Rewind(Isolate* isolate, FixedArray* array, int offset, Address fp);
121
Steve Blocka7e24c12009-10-30 11:49:00 +0000122 private:
123 // Accessors.
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100124 inline Kind kind() const;
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000125 inline unsigned index() const;
Steve Blocka7e24c12009-10-30 11:49:00 +0000126
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000127 inline Object** constant_pool_address() const;
Ben Murdoch69a99ed2011-11-30 16:03:39 +0000128 inline Object** context_address() const;
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100129 inline Object** code_address() const;
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000130 inline void SetFp(Address slot, Address fp);
Steve Blocka7e24c12009-10-30 11:49:00 +0000131
132 DISALLOW_IMPLICIT_CONSTRUCTORS(StackHandler);
133};
134
135
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000136#define STACK_FRAME_TYPE_LIST(V) \
137 V(ENTRY, EntryFrame) \
138 V(ENTRY_CONSTRUCT, EntryConstructFrame) \
139 V(EXIT, ExitFrame) \
140 V(JAVA_SCRIPT, JavaScriptFrame) \
141 V(OPTIMIZED, OptimizedFrame) \
142 V(STUB, StubFrame) \
143 V(STUB_FAILURE_TRAMPOLINE, StubFailureTrampolineFrame) \
144 V(INTERNAL, InternalFrame) \
145 V(CONSTRUCT, ConstructFrame) \
146 V(ARGUMENTS_ADAPTOR, ArgumentsAdaptorFrame)
147
148
149class StandardFrameConstants : public AllStatic {
150 public:
151 // Fixed part of the frame consists of return address, caller fp,
152 // constant pool (if FLAG_enable_ool_constant_pool), context, and function.
153 // StandardFrame::IterateExpressions assumes that kLastObjectOffset is the
154 // last object pointer.
155 static const int kCPSlotSize =
156 FLAG_enable_ool_constant_pool ? kPointerSize : 0;
157 static const int kFixedFrameSizeFromFp = 2 * kPointerSize + kCPSlotSize;
158 static const int kFixedFrameSize = kPCOnStackSize + kFPOnStackSize +
159 kFixedFrameSizeFromFp;
160 static const int kExpressionsOffset = -3 * kPointerSize - kCPSlotSize;
161 static const int kMarkerOffset = -2 * kPointerSize - kCPSlotSize;
162 static const int kContextOffset = -1 * kPointerSize - kCPSlotSize;
163 static const int kConstantPoolOffset = FLAG_enable_ool_constant_pool ?
164 -1 * kPointerSize : 0;
165 static const int kCallerFPOffset = 0 * kPointerSize;
166 static const int kCallerPCOffset = +1 * kFPOnStackSize;
167 static const int kCallerSPOffset = kCallerPCOffset + 1 * kPCOnStackSize;
168
169 static const int kLastObjectOffset = FLAG_enable_ool_constant_pool ?
170 kConstantPoolOffset : kContextOffset;
171};
Steve Blocka7e24c12009-10-30 11:49:00 +0000172
173
174// Abstract base class for all stack frames.
175class StackFrame BASE_EMBEDDED {
176 public:
177#define DECLARE_TYPE(type, ignore) type,
178 enum Type {
179 NONE = 0,
180 STACK_FRAME_TYPE_LIST(DECLARE_TYPE)
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100181 NUMBER_OF_TYPES,
182 // Used by FrameScope to indicate that the stack frame is constructed
183 // manually and the FrameScope does not need to emit code.
184 MANUAL
Steve Blocka7e24c12009-10-30 11:49:00 +0000185 };
186#undef DECLARE_TYPE
187
188 // Opaque data type for identifying stack frames. Used extensively
189 // by the debugger.
Iain Merrick75681382010-08-19 15:07:18 +0100190 // ID_MIN_VALUE and ID_MAX_VALUE are specified to ensure that enumeration type
191 // has correct value range (see Issue 830 for more details).
192 enum Id {
193 ID_MIN_VALUE = kMinInt,
194 ID_MAX_VALUE = kMaxInt,
195 NO_ID = 0
196 };
Steve Blocka7e24c12009-10-30 11:49:00 +0000197
Steve Block053d10c2011-06-13 19:13:29 +0100198 // Used to mark the outermost JS entry frame.
199 enum JsFrameMarker {
200 INNER_JSENTRY_FRAME = 0,
201 OUTERMOST_JSENTRY_FRAME = 1
202 };
203
Kristian Monsen0d5e1162010-09-30 15:31:59 +0100204 struct State {
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000205 State() : sp(NULL), fp(NULL), pc_address(NULL),
206 constant_pool_address(NULL) { }
Kristian Monsen0d5e1162010-09-30 15:31:59 +0100207 Address sp;
208 Address fp;
209 Address* pc_address;
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000210 Address* constant_pool_address;
Kristian Monsen0d5e1162010-09-30 15:31:59 +0100211 };
212
Ben Murdoch8b112d22011-06-08 16:22:53 +0100213 // Copy constructor; it breaks the connection to host iterator
214 // (as an iterator usually lives on stack).
Steve Block6ded16b2010-05-10 14:33:55 +0100215 StackFrame(const StackFrame& original) {
216 this->state_ = original.state_;
217 this->iterator_ = NULL;
Ben Murdoch8b112d22011-06-08 16:22:53 +0100218 this->isolate_ = original.isolate_;
Steve Block6ded16b2010-05-10 14:33:55 +0100219 }
220
Steve Blocka7e24c12009-10-30 11:49:00 +0000221 // Type testers.
222 bool is_entry() const { return type() == ENTRY; }
223 bool is_entry_construct() const { return type() == ENTRY_CONSTRUCT; }
224 bool is_exit() const { return type() == EXIT; }
Ben Murdochb0fe1622011-05-05 13:52:32 +0100225 bool is_optimized() const { return type() == OPTIMIZED; }
Steve Blocka7e24c12009-10-30 11:49:00 +0000226 bool is_arguments_adaptor() const { return type() == ARGUMENTS_ADAPTOR; }
227 bool is_internal() const { return type() == INTERNAL; }
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000228 bool is_stub_failure_trampoline() const {
229 return type() == STUB_FAILURE_TRAMPOLINE;
230 }
Steve Blocka7e24c12009-10-30 11:49:00 +0000231 bool is_construct() const { return type() == CONSTRUCT; }
232 virtual bool is_standard() const { return false; }
233
Ben Murdochb0fe1622011-05-05 13:52:32 +0100234 bool is_java_script() const {
235 Type type = this->type();
236 return (type == JAVA_SCRIPT) || (type == OPTIMIZED);
237 }
238
Steve Blocka7e24c12009-10-30 11:49:00 +0000239 // Accessors.
240 Address sp() const { return state_.sp; }
241 Address fp() const { return state_.fp; }
242 Address caller_sp() const { return GetCallerStackPointer(); }
243
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000244 // If this frame is optimized and was dynamically aligned return its old
245 // unaligned frame pointer. When the frame is deoptimized its FP will shift
246 // up one word and become unaligned.
247 Address UnpaddedFP() const;
248
Steve Blocka7e24c12009-10-30 11:49:00 +0000249 Address pc() const { return *pc_address(); }
250 void set_pc(Address pc) { *pc_address() = pc; }
251
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000252 Address constant_pool() const { return *constant_pool_address(); }
253 void set_constant_pool(ConstantPoolArray* constant_pool) {
254 *constant_pool_address() = reinterpret_cast<Address>(constant_pool);
255 }
256
Steve Block6ded16b2010-05-10 14:33:55 +0100257 virtual void SetCallerFp(Address caller_fp) = 0;
258
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000259 // Manually changes value of fp in this object.
260 void UpdateFp(Address fp) { state_.fp = fp; }
261
Steve Blocka7e24c12009-10-30 11:49:00 +0000262 Address* pc_address() const { return state_.pc_address; }
263
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000264 Address* constant_pool_address() const {
265 return state_.constant_pool_address;
266 }
267
Steve Blocka7e24c12009-10-30 11:49:00 +0000268 // Get the id of this stack frame.
269 Id id() const { return static_cast<Id>(OffsetFrom(caller_sp())); }
270
271 // Checks if this frame includes any stack handlers.
272 bool HasHandler() const;
273
274 // Get the type of this frame.
275 virtual Type type() const = 0;
276
277 // Get the code associated with this frame.
Iain Merrick75681382010-08-19 15:07:18 +0100278 // This method could be called during marking phase of GC.
279 virtual Code* unchecked_code() const = 0;
280
281 // Get the code associated with this frame.
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100282 inline Code* LookupCode() const;
Kristian Monsen80d68ea2010-09-08 11:05:35 +0100283
284 // Get the code object that contains the given pc.
Steve Block44f0eee2011-05-26 01:26:41 +0100285 static inline Code* GetContainingCode(Isolate* isolate, Address pc);
Steve Blocka7e24c12009-10-30 11:49:00 +0000286
Ben Murdochb0fe1622011-05-05 13:52:32 +0100287 // Get the code object containing the given pc and fill in the
288 // safepoint entry and the number of stack slots. The pc must be at
289 // a safepoint.
Ben Murdoch8b112d22011-06-08 16:22:53 +0100290 static Code* GetSafepointData(Isolate* isolate,
291 Address pc,
Ben Murdochb8e0da22011-05-16 14:20:40 +0100292 SafepointEntry* safepoint_entry,
Ben Murdochb0fe1622011-05-05 13:52:32 +0100293 unsigned* stack_slots);
294
Kristian Monsen80d68ea2010-09-08 11:05:35 +0100295 virtual void Iterate(ObjectVisitor* v) const = 0;
296 static void IteratePc(ObjectVisitor* v, Address* pc_address, Code* holder);
Steve Blocka7e24c12009-10-30 11:49:00 +0000297
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100298 // Sets a callback function for return-address rewriting profilers
299 // to resolve the location of a return address to the location of the
300 // profiler's stashed return address.
301 static void SetReturnAddressLocationResolver(
302 ReturnAddressLocationResolver resolver);
Steve Blocka7e24c12009-10-30 11:49:00 +0000303
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000304 // Resolves pc_address through the resolution address function if one is set.
305 static inline Address* ResolveReturnAddressLocation(Address* pc_address);
306
307
Steve Blocka7e24c12009-10-30 11:49:00 +0000308 // Printing support.
309 enum PrintMode { OVERVIEW, DETAILS };
310 virtual void Print(StringStream* accumulator,
311 PrintMode mode,
312 int index) const { }
313
Ben Murdoch8b112d22011-06-08 16:22:53 +0100314 Isolate* isolate() const { return isolate_; }
315
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000316 protected:
317 inline explicit StackFrame(StackFrameIteratorBase* iterator);
318 virtual ~StackFrame() { }
319
Steve Blocka7e24c12009-10-30 11:49:00 +0000320 // Compute the stack pointer for the calling frame.
321 virtual Address GetCallerStackPointer() const = 0;
322
323 // Printing support.
324 static void PrintIndex(StringStream* accumulator,
325 PrintMode mode,
326 int index);
327
328 // Get the top handler from the current stack iterator.
329 inline StackHandler* top_handler() const;
330
331 // Compute the stack frame type for the given state.
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000332 static Type ComputeType(const StackFrameIteratorBase* iterator, State* state);
333
334#ifdef DEBUG
335 bool can_access_heap_objects() const;
336#endif
Steve Blocka7e24c12009-10-30 11:49:00 +0000337
338 private:
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000339 const StackFrameIteratorBase* iterator_;
Ben Murdoch8b112d22011-06-08 16:22:53 +0100340 Isolate* isolate_;
Steve Blocka7e24c12009-10-30 11:49:00 +0000341 State state_;
342
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000343 static ReturnAddressLocationResolver return_address_location_resolver_;
344
Steve Blocka7e24c12009-10-30 11:49:00 +0000345 // Fill in the state of the calling frame.
346 virtual void ComputeCallerState(State* state) const = 0;
347
348 // Get the type and the state of the calling frame.
349 virtual Type GetCallerState(State* state) const;
350
Ben Murdoch8b112d22011-06-08 16:22:53 +0100351 static const intptr_t kIsolateTag = 1;
352
Steve Blocka7e24c12009-10-30 11:49:00 +0000353 friend class StackFrameIterator;
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000354 friend class StackFrameIteratorBase;
Steve Blocka7e24c12009-10-30 11:49:00 +0000355 friend class StackHandlerIterator;
356 friend class SafeStackFrameIterator;
357
Steve Block6ded16b2010-05-10 14:33:55 +0100358 private:
359 void operator=(const StackFrame& original);
Steve Blocka7e24c12009-10-30 11:49:00 +0000360};
361
362
363// Entry frames are used to enter JavaScript execution from C.
364class EntryFrame: public StackFrame {
365 public:
366 virtual Type type() const { return ENTRY; }
367
Iain Merrick75681382010-08-19 15:07:18 +0100368 virtual Code* unchecked_code() const;
Steve Blocka7e24c12009-10-30 11:49:00 +0000369
370 // Garbage collection support.
371 virtual void Iterate(ObjectVisitor* v) const;
372
373 static EntryFrame* cast(StackFrame* frame) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000374 DCHECK(frame->is_entry());
Steve Blocka7e24c12009-10-30 11:49:00 +0000375 return static_cast<EntryFrame*>(frame);
376 }
Steve Block6ded16b2010-05-10 14:33:55 +0100377 virtual void SetCallerFp(Address caller_fp);
Steve Blocka7e24c12009-10-30 11:49:00 +0000378
379 protected:
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000380 inline explicit EntryFrame(StackFrameIteratorBase* iterator);
Steve Blocka7e24c12009-10-30 11:49:00 +0000381
382 // The caller stack pointer for entry frames is always zero. The
383 // real information about the caller frame is available through the
384 // link to the top exit frame.
385 virtual Address GetCallerStackPointer() const { return 0; }
386
387 private:
388 virtual void ComputeCallerState(State* state) const;
389 virtual Type GetCallerState(State* state) const;
390
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000391 friend class StackFrameIteratorBase;
Steve Blocka7e24c12009-10-30 11:49:00 +0000392};
393
394
395class EntryConstructFrame: public EntryFrame {
396 public:
397 virtual Type type() const { return ENTRY_CONSTRUCT; }
398
Iain Merrick75681382010-08-19 15:07:18 +0100399 virtual Code* unchecked_code() const;
Steve Blocka7e24c12009-10-30 11:49:00 +0000400
401 static EntryConstructFrame* cast(StackFrame* frame) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000402 DCHECK(frame->is_entry_construct());
Steve Blocka7e24c12009-10-30 11:49:00 +0000403 return static_cast<EntryConstructFrame*>(frame);
404 }
405
406 protected:
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000407 inline explicit EntryConstructFrame(StackFrameIteratorBase* iterator);
Steve Blocka7e24c12009-10-30 11:49:00 +0000408
409 private:
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000410 friend class StackFrameIteratorBase;
Steve Blocka7e24c12009-10-30 11:49:00 +0000411};
412
413
414// Exit frames are used to exit JavaScript execution and go to C.
415class ExitFrame: public StackFrame {
416 public:
417 virtual Type type() const { return EXIT; }
418
Iain Merrick75681382010-08-19 15:07:18 +0100419 virtual Code* unchecked_code() const;
Steve Blocka7e24c12009-10-30 11:49:00 +0000420
Steve Blockd0582a62009-12-15 09:54:21 +0000421 Object*& code_slot() const;
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000422 Object*& constant_pool_slot() const;
Steve Blockd0582a62009-12-15 09:54:21 +0000423
Steve Blocka7e24c12009-10-30 11:49:00 +0000424 // Garbage collection support.
425 virtual void Iterate(ObjectVisitor* v) const;
426
Steve Block6ded16b2010-05-10 14:33:55 +0100427 virtual void SetCallerFp(Address caller_fp);
428
Steve Blocka7e24c12009-10-30 11:49:00 +0000429 static ExitFrame* cast(StackFrame* frame) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000430 DCHECK(frame->is_exit());
Steve Blocka7e24c12009-10-30 11:49:00 +0000431 return static_cast<ExitFrame*>(frame);
432 }
433
434 // Compute the state and type of an exit frame given a frame
435 // pointer. Used when constructing the first stack frame seen by an
436 // iterator and the frames following entry frames.
437 static Type GetStateForFramePointer(Address fp, State* state);
Kristian Monsen0d5e1162010-09-30 15:31:59 +0100438 static Address ComputeStackPointer(Address fp);
439 static void FillState(Address fp, Address sp, State* state);
Steve Blocka7e24c12009-10-30 11:49:00 +0000440
441 protected:
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000442 inline explicit ExitFrame(StackFrameIteratorBase* iterator);
Steve Blocka7e24c12009-10-30 11:49:00 +0000443
444 virtual Address GetCallerStackPointer() const;
445
446 private:
447 virtual void ComputeCallerState(State* state) const;
448
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000449 friend class StackFrameIteratorBase;
Steve Blocka7e24c12009-10-30 11:49:00 +0000450};
451
452
Steve Blocka7e24c12009-10-30 11:49:00 +0000453class StandardFrame: public StackFrame {
454 public:
455 // Testers.
456 virtual bool is_standard() const { return true; }
457
458 // Accessors.
459 inline Object* context() const;
460
461 // Access the expressions in the stack frame including locals.
462 inline Object* GetExpression(int index) const;
463 inline void SetExpression(int index, Object* value);
464 int ComputeExpressionsCount() const;
Ben Murdoch3fb3ca82011-12-02 17:19:32 +0000465 static Object* GetExpression(Address fp, int index);
Steve Blocka7e24c12009-10-30 11:49:00 +0000466
Steve Block6ded16b2010-05-10 14:33:55 +0100467 virtual void SetCallerFp(Address caller_fp);
468
Steve Blocka7e24c12009-10-30 11:49:00 +0000469 static StandardFrame* cast(StackFrame* frame) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000470 DCHECK(frame->is_standard());
Steve Blocka7e24c12009-10-30 11:49:00 +0000471 return static_cast<StandardFrame*>(frame);
472 }
473
474 protected:
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000475 inline explicit StandardFrame(StackFrameIteratorBase* iterator);
Steve Blocka7e24c12009-10-30 11:49:00 +0000476
477 virtual void ComputeCallerState(State* state) const;
478
479 // Accessors.
480 inline Address caller_fp() const;
481 inline Address caller_pc() const;
482
483 // Computes the address of the PC field in the standard frame given
484 // by the provided frame pointer.
485 static inline Address ComputePCAddress(Address fp);
486
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000487 // Computes the address of the constant pool field in the standard
488 // frame given by the provided frame pointer.
489 static inline Address ComputeConstantPoolAddress(Address fp);
490
Steve Blocka7e24c12009-10-30 11:49:00 +0000491 // Iterate over expression stack including stack handlers, locals,
492 // and parts of the fixed part including context and code fields.
493 void IterateExpressions(ObjectVisitor* v) const;
494
495 // Returns the address of the n'th expression stack element.
496 Address GetExpressionAddress(int n) const;
Ben Murdoch3fb3ca82011-12-02 17:19:32 +0000497 static Address GetExpressionAddress(Address fp, int n);
Steve Blocka7e24c12009-10-30 11:49:00 +0000498
499 // Determines if the n'th expression stack element is in a stack
500 // handler or not. Requires traversing all handlers in this frame.
501 bool IsExpressionInsideHandler(int n) const;
502
503 // Determines if the standard frame for the given frame pointer is
504 // an arguments adaptor frame.
505 static inline bool IsArgumentsAdaptorFrame(Address fp);
506
507 // Determines if the standard frame for the given frame pointer is a
508 // construct frame.
509 static inline bool IsConstructFrame(Address fp);
510
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000511 // Used by OptimizedFrames and StubFrames.
512 void IterateCompiledFrame(ObjectVisitor* v) const;
513
Steve Blocka7e24c12009-10-30 11:49:00 +0000514 private:
515 friend class StackFrame;
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000516 friend class SafeStackFrameIterator;
Steve Blocka7e24c12009-10-30 11:49:00 +0000517};
518
519
Ben Murdochb0fe1622011-05-05 13:52:32 +0100520class FrameSummary BASE_EMBEDDED {
521 public:
522 FrameSummary(Object* receiver,
523 JSFunction* function,
524 Code* code,
525 int offset,
526 bool is_constructor)
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000527 : receiver_(receiver, function->GetIsolate()),
Ben Murdochb0fe1622011-05-05 13:52:32 +0100528 function_(function),
529 code_(code),
530 offset_(offset),
531 is_constructor_(is_constructor) { }
532 Handle<Object> receiver() { return receiver_; }
533 Handle<JSFunction> function() { return function_; }
534 Handle<Code> code() { return code_; }
Ben Murdoch8b112d22011-06-08 16:22:53 +0100535 Address pc() { return code_->address() + offset_; }
Ben Murdochb0fe1622011-05-05 13:52:32 +0100536 int offset() { return offset_; }
537 bool is_constructor() { return is_constructor_; }
538
539 void Print();
540
541 private:
542 Handle<Object> receiver_;
543 Handle<JSFunction> function_;
544 Handle<Code> code_;
545 int offset_;
546 bool is_constructor_;
547};
548
549
Steve Blocka7e24c12009-10-30 11:49:00 +0000550class JavaScriptFrame: public StandardFrame {
551 public:
552 virtual Type type() const { return JAVA_SCRIPT; }
553
554 // Accessors.
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000555 inline JSFunction* function() const;
Steve Blocka7e24c12009-10-30 11:49:00 +0000556 inline Object* receiver() const;
557 inline void set_receiver(Object* value);
558
559 // Access the parameters.
Ben Murdoch8b112d22011-06-08 16:22:53 +0100560 inline Address GetParameterSlot(int index) const;
561 inline Object* GetParameter(int index) const;
562 inline int ComputeParametersCount() const {
563 return GetNumberOfIncomingArguments();
564 }
Steve Blocka7e24c12009-10-30 11:49:00 +0000565
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000566 // Access the operand stack.
567 inline Address GetOperandSlot(int index) const;
568 inline Object* GetOperand(int index) const;
569 inline int ComputeOperandsCount() const;
570
571 // Generator support to preserve operand stack and stack handlers.
572 void SaveOperandStack(FixedArray* store, int* stack_handler_index) const;
573 void RestoreOperandStack(FixedArray* store, int stack_handler_index);
574
575 // Debugger access.
576 void SetParameterValue(int index, Object* value) const;
577
Steve Blocka7e24c12009-10-30 11:49:00 +0000578 // Check if this frame is a constructor frame invoked through 'new'.
579 bool IsConstructor() const;
580
581 // Check if this frame has "adapted" arguments in the sense that the
582 // actual passed arguments are available in an arguments adaptor
583 // frame below it on the stack.
584 inline bool has_adapted_arguments() const;
Ben Murdoch3fb3ca82011-12-02 17:19:32 +0000585 int GetArgumentsLength() const;
Steve Blocka7e24c12009-10-30 11:49:00 +0000586
587 // Garbage collection support.
588 virtual void Iterate(ObjectVisitor* v) const;
589
590 // Printing support.
591 virtual void Print(StringStream* accumulator,
592 PrintMode mode,
593 int index) const;
594
595 // Determine the code for the frame.
Iain Merrick75681382010-08-19 15:07:18 +0100596 virtual Code* unchecked_code() const;
Steve Blocka7e24c12009-10-30 11:49:00 +0000597
Ben Murdoch3fb3ca82011-12-02 17:19:32 +0000598 // Returns the levels of inlining for this frame.
599 virtual int GetInlineCount() { return 1; }
600
Ben Murdochb0fe1622011-05-05 13:52:32 +0100601 // Return a list with JSFunctions of this frame.
602 virtual void GetFunctions(List<JSFunction*>* functions);
603
604 // Build a list with summaries for this frame including all inlined frames.
605 virtual void Summarize(List<FrameSummary>* frames);
606
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000607 // Architecture-specific register description.
608 static Register fp_register();
609 static Register context_register();
610 static Register constant_pool_pointer_register();
611
Steve Blocka7e24c12009-10-30 11:49:00 +0000612 static JavaScriptFrame* cast(StackFrame* frame) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000613 DCHECK(frame->is_java_script());
Steve Blocka7e24c12009-10-30 11:49:00 +0000614 return static_cast<JavaScriptFrame*>(frame);
615 }
616
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000617 static void PrintFunctionAndOffset(JSFunction* function, Code* code,
618 Address pc, FILE* file,
619 bool print_line_number);
620
621 static void PrintTop(Isolate* isolate, FILE* file, bool print_args,
622 bool print_line_number);
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100623
Steve Blocka7e24c12009-10-30 11:49:00 +0000624 protected:
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000625 inline explicit JavaScriptFrame(StackFrameIteratorBase* iterator);
Steve Blocka7e24c12009-10-30 11:49:00 +0000626
627 virtual Address GetCallerStackPointer() const;
628
Ben Murdoch8b112d22011-06-08 16:22:53 +0100629 virtual int GetNumberOfIncomingArguments() const;
630
Ben Murdochb0fe1622011-05-05 13:52:32 +0100631 // Garbage collection support. Iterates over incoming arguments,
632 // receiver, and any callee-saved registers.
633 void IterateArguments(ObjectVisitor* v) const;
634
Steve Blocka7e24c12009-10-30 11:49:00 +0000635 private:
Steve Blocka7e24c12009-10-30 11:49:00 +0000636 inline Object* function_slot_object() const;
637
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000638 friend class StackFrameIteratorBase;
639};
640
641
642class StubFrame : public StandardFrame {
643 public:
644 virtual Type type() const { return STUB; }
645
646 // GC support.
647 virtual void Iterate(ObjectVisitor* v) const;
648
649 // Determine the code for the frame.
650 virtual Code* unchecked_code() const;
651
652 protected:
653 inline explicit StubFrame(StackFrameIteratorBase* iterator);
654
655 virtual Address GetCallerStackPointer() const;
656
657 virtual int GetNumberOfIncomingArguments() const;
658
659 friend class StackFrameIteratorBase;
Steve Blocka7e24c12009-10-30 11:49:00 +0000660};
661
662
Ben Murdochb0fe1622011-05-05 13:52:32 +0100663class OptimizedFrame : public JavaScriptFrame {
664 public:
665 virtual Type type() const { return OPTIMIZED; }
666
667 // GC support.
668 virtual void Iterate(ObjectVisitor* v) const;
669
Ben Murdoch3fb3ca82011-12-02 17:19:32 +0000670 virtual int GetInlineCount();
671
Ben Murdochb0fe1622011-05-05 13:52:32 +0100672 // Return a list with JSFunctions of this frame.
673 // The functions are ordered bottom-to-top (i.e. functions.last()
674 // is the top-most activation)
675 virtual void GetFunctions(List<JSFunction*>* functions);
676
677 virtual void Summarize(List<FrameSummary>* frames);
678
679 DeoptimizationInputData* GetDeoptimizationData(int* deopt_index);
680
681 protected:
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000682 inline explicit OptimizedFrame(StackFrameIteratorBase* iterator);
Ben Murdochb0fe1622011-05-05 13:52:32 +0100683
684 private:
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000685 JSFunction* LiteralAt(FixedArray* literal_array, int literal_id);
686
687 friend class StackFrameIteratorBase;
Ben Murdochb0fe1622011-05-05 13:52:32 +0100688};
689
690
Steve Blocka7e24c12009-10-30 11:49:00 +0000691// Arguments adaptor frames are automatically inserted below
692// JavaScript frames when the actual number of parameters does not
693// match the formal number of parameters.
694class ArgumentsAdaptorFrame: public JavaScriptFrame {
695 public:
696 virtual Type type() const { return ARGUMENTS_ADAPTOR; }
697
698 // Determine the code for the frame.
Iain Merrick75681382010-08-19 15:07:18 +0100699 virtual Code* unchecked_code() const;
Steve Blocka7e24c12009-10-30 11:49:00 +0000700
701 static ArgumentsAdaptorFrame* cast(StackFrame* frame) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000702 DCHECK(frame->is_arguments_adaptor());
Steve Blocka7e24c12009-10-30 11:49:00 +0000703 return static_cast<ArgumentsAdaptorFrame*>(frame);
704 }
705
706 // Printing support.
707 virtual void Print(StringStream* accumulator,
708 PrintMode mode,
709 int index) const;
Ben Murdoch589d6972011-11-30 16:04:58 +0000710
Steve Blocka7e24c12009-10-30 11:49:00 +0000711 protected:
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000712 inline explicit ArgumentsAdaptorFrame(StackFrameIteratorBase* iterator);
Steve Blocka7e24c12009-10-30 11:49:00 +0000713
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100714 virtual int GetNumberOfIncomingArguments() const;
Ben Murdoch8b112d22011-06-08 16:22:53 +0100715
Steve Blocka7e24c12009-10-30 11:49:00 +0000716 virtual Address GetCallerStackPointer() const;
717
718 private:
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000719 friend class StackFrameIteratorBase;
Steve Blocka7e24c12009-10-30 11:49:00 +0000720};
721
722
723class InternalFrame: public StandardFrame {
724 public:
725 virtual Type type() const { return INTERNAL; }
726
727 // Garbage collection support.
728 virtual void Iterate(ObjectVisitor* v) const;
729
730 // Determine the code for the frame.
Iain Merrick75681382010-08-19 15:07:18 +0100731 virtual Code* unchecked_code() const;
Steve Blocka7e24c12009-10-30 11:49:00 +0000732
733 static InternalFrame* cast(StackFrame* frame) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000734 DCHECK(frame->is_internal());
Steve Blocka7e24c12009-10-30 11:49:00 +0000735 return static_cast<InternalFrame*>(frame);
736 }
737
738 protected:
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000739 inline explicit InternalFrame(StackFrameIteratorBase* iterator);
Steve Blocka7e24c12009-10-30 11:49:00 +0000740
741 virtual Address GetCallerStackPointer() const;
742
743 private:
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000744 friend class StackFrameIteratorBase;
745};
746
747
748class StubFailureTrampolineFrame: public StandardFrame {
749 public:
750 // sizeof(Arguments) - sizeof(Arguments*) is 3 * kPointerSize), but the
751 // presubmit script complains about using sizeof() on a type.
752 static const int kFirstRegisterParameterFrameOffset =
753 StandardFrameConstants::kMarkerOffset - 3 * kPointerSize;
754
755 static const int kCallerStackParameterCountFrameOffset =
756 StandardFrameConstants::kMarkerOffset - 2 * kPointerSize;
757
758 virtual Type type() const { return STUB_FAILURE_TRAMPOLINE; }
759
760 // Get the code associated with this frame.
761 // This method could be called during marking phase of GC.
762 virtual Code* unchecked_code() const;
763
764 virtual void Iterate(ObjectVisitor* v) const;
765
766 // Architecture-specific register description.
767 static Register fp_register();
768 static Register context_register();
769 static Register constant_pool_pointer_register();
770
771 protected:
772 inline explicit StubFailureTrampolineFrame(
773 StackFrameIteratorBase* iterator);
774
775 virtual Address GetCallerStackPointer() const;
776
777 private:
778 friend class StackFrameIteratorBase;
Steve Blocka7e24c12009-10-30 11:49:00 +0000779};
780
781
782// Construct frames are special trampoline frames introduced to handle
783// function invocations through 'new'.
784class ConstructFrame: public InternalFrame {
785 public:
786 virtual Type type() const { return CONSTRUCT; }
787
788 static ConstructFrame* cast(StackFrame* frame) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000789 DCHECK(frame->is_construct());
Steve Blocka7e24c12009-10-30 11:49:00 +0000790 return static_cast<ConstructFrame*>(frame);
791 }
792
793 protected:
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000794 inline explicit ConstructFrame(StackFrameIteratorBase* iterator);
Steve Blocka7e24c12009-10-30 11:49:00 +0000795
796 private:
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000797 friend class StackFrameIteratorBase;
Steve Blocka7e24c12009-10-30 11:49:00 +0000798};
799
800
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000801class StackFrameIteratorBase BASE_EMBEDDED {
Steve Blocka7e24c12009-10-30 11:49:00 +0000802 public:
Ben Murdoch8b112d22011-06-08 16:22:53 +0100803 Isolate* isolate() const { return isolate_; }
804
Steve Blocka7e24c12009-10-30 11:49:00 +0000805 bool done() const { return frame_ == NULL; }
Steve Blocka7e24c12009-10-30 11:49:00 +0000806
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000807 protected:
808 // An iterator that iterates over a given thread's stack.
809 StackFrameIteratorBase(Isolate* isolate, bool can_access_heap_objects);
Steve Blocka7e24c12009-10-30 11:49:00 +0000810
Ben Murdoch8b112d22011-06-08 16:22:53 +0100811 Isolate* isolate_;
Steve Blocka7e24c12009-10-30 11:49:00 +0000812#define DECLARE_SINGLETON(ignore, type) type type##_;
813 STACK_FRAME_TYPE_LIST(DECLARE_SINGLETON)
814#undef DECLARE_SINGLETON
815 StackFrame* frame_;
816 StackHandler* handler_;
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000817 const bool can_access_heap_objects_;
Steve Blocka7e24c12009-10-30 11:49:00 +0000818
819 StackHandler* handler() const {
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000820 DCHECK(!done());
Steve Blocka7e24c12009-10-30 11:49:00 +0000821 return handler_;
822 }
823
824 // Get the type-specific frame singleton in a given state.
825 StackFrame* SingletonFor(StackFrame::Type type, StackFrame::State* state);
826 // A helper function, can return a NULL pointer.
827 StackFrame* SingletonFor(StackFrame::Type type);
828
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000829 private:
Steve Blocka7e24c12009-10-30 11:49:00 +0000830 friend class StackFrame;
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000831 DISALLOW_COPY_AND_ASSIGN(StackFrameIteratorBase);
832};
833
834
835class StackFrameIterator: public StackFrameIteratorBase {
836 public:
837 // An iterator that iterates over the isolate's current thread's stack,
838 explicit StackFrameIterator(Isolate* isolate);
839 // An iterator that iterates over a given thread's stack.
840 StackFrameIterator(Isolate* isolate, ThreadLocalTop* t);
841
842 StackFrame* frame() const {
843 DCHECK(!done());
844 return frame_;
845 }
846 void Advance();
847
848 private:
849 // Go back to the first frame.
850 void Reset(ThreadLocalTop* top);
851
Steve Blocka7e24c12009-10-30 11:49:00 +0000852 DISALLOW_COPY_AND_ASSIGN(StackFrameIterator);
853};
854
855
856// Iterator that supports iterating through all JavaScript frames.
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000857class JavaScriptFrameIterator BASE_EMBEDDED {
Steve Blocka7e24c12009-10-30 11:49:00 +0000858 public:
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000859 inline explicit JavaScriptFrameIterator(Isolate* isolate);
860 inline JavaScriptFrameIterator(Isolate* isolate, ThreadLocalTop* top);
Steve Blocka7e24c12009-10-30 11:49:00 +0000861 // Skip frames until the frame with the given id is reached.
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000862 JavaScriptFrameIterator(Isolate* isolate, StackFrame::Id id);
Steve Block44f0eee2011-05-26 01:26:41 +0100863
Steve Blocka7e24c12009-10-30 11:49:00 +0000864 inline JavaScriptFrame* frame() const;
865
866 bool done() const { return iterator_.done(); }
867 void Advance();
868
869 // Advance to the frame holding the arguments for the current
870 // frame. This only affects the current frame if it has adapted
871 // arguments.
872 void AdvanceToArgumentsFrame();
873
Steve Blocka7e24c12009-10-30 11:49:00 +0000874 private:
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000875 StackFrameIterator iterator_;
Steve Blocka7e24c12009-10-30 11:49:00 +0000876};
877
878
Steve Blocka7e24c12009-10-30 11:49:00 +0000879// NOTE: The stack trace frame iterator is an iterator that only
880// traverse proper JavaScript frames; that is JavaScript frames that
881// have proper JavaScript functions. This excludes the problematic
882// functions in runtime.js.
883class StackTraceFrameIterator: public JavaScriptFrameIterator {
884 public:
Ben Murdoch8b112d22011-06-08 16:22:53 +0100885 explicit StackTraceFrameIterator(Isolate* isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +0000886 void Advance();
Leon Clarke4515c472010-02-03 11:58:03 +0000887
888 private:
889 bool IsValidFrame();
Steve Blocka7e24c12009-10-30 11:49:00 +0000890};
891
892
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000893class SafeStackFrameIterator: public StackFrameIteratorBase {
Steve Blocka7e24c12009-10-30 11:49:00 +0000894 public:
Steve Block44f0eee2011-05-26 01:26:41 +0100895 SafeStackFrameIterator(Isolate* isolate,
896 Address fp, Address sp,
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000897 Address js_entry_sp);
Steve Blocka7e24c12009-10-30 11:49:00 +0000898
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000899 inline StackFrame* frame() const;
Steve Blocka7e24c12009-10-30 11:49:00 +0000900 void Advance();
Steve Blocka7e24c12009-10-30 11:49:00 +0000901
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000902 StackFrame::Type top_frame_type() const { return top_frame_type_; }
Leon Clarked91b9f72010-01-27 17:25:45 +0000903
904 private:
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000905 void AdvanceOneFrame();
Kristian Monsen0d5e1162010-09-30 15:31:59 +0100906
Steve Blocka7e24c12009-10-30 11:49:00 +0000907 bool IsValidStackAddress(Address addr) const {
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000908 return low_bound_ <= addr && addr <= high_bound_;
Steve Blocka7e24c12009-10-30 11:49:00 +0000909 }
Steve Blocka7e24c12009-10-30 11:49:00 +0000910 bool IsValidFrame(StackFrame* frame) const;
911 bool IsValidCaller(StackFrame* frame);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000912 bool IsValidExitFrame(Address fp) const;
913 bool IsValidTop(ThreadLocalTop* top) const;
Steve Blocka7e24c12009-10-30 11:49:00 +0000914
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000915 const Address low_bound_;
916 const Address high_bound_;
917 StackFrame::Type top_frame_type_;
918 ExternalCallbackScope* external_callback_scope_;
Steve Blocka7e24c12009-10-30 11:49:00 +0000919};
Steve Blocka7e24c12009-10-30 11:49:00 +0000920
921
922class StackFrameLocator BASE_EMBEDDED {
923 public:
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000924 explicit StackFrameLocator(Isolate* isolate) : iterator_(isolate) {}
925
Steve Blocka7e24c12009-10-30 11:49:00 +0000926 // Find the nth JavaScript frame on the stack. The caller must
927 // guarantee that such a frame exists.
928 JavaScriptFrame* FindJavaScriptFrame(int n);
929
930 private:
931 StackFrameIterator iterator_;
932};
933
934
Steve Block6ded16b2010-05-10 14:33:55 +0100935// Reads all frames on the current stack and copies them into the current
936// zone memory.
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000937Vector<StackFrame*> CreateStackMap(Isolate* isolate, Zone* zone);
Steve Block6ded16b2010-05-10 14:33:55 +0100938
Steve Blocka7e24c12009-10-30 11:49:00 +0000939} } // namespace v8::internal
940
941#endif // V8_FRAMES_H_