blob: 03d53dd6a1cbdf0990205760bc398bb96b4416b1 [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;
Emily Bernierd0a1eb72015-03-24 16:35:39 -040074#if V8_TARGET_LITTLE_ENDIAN || !V8_HOST_ARCH_64_BIT
75 static const int kStateIntOffset = kStateOffset;
76#else
77 static const int kStateIntOffset = kStateOffset + kIntSize;
78#endif
Ben Murdochb8a8cc12014-11-26 15:28:44 +000079 static const int kContextOffset = 3 * kPointerSize;
80 static const int kFPOffset = 4 * kPointerSize;
81
82 static const int kSize = kFPOffset + kFPOnStackSize;
83 static const int kSlotCount = kSize >> kPointerSizeLog2;
84};
85
86
Steve Blocka7e24c12009-10-30 11:49:00 +000087class StackHandler BASE_EMBEDDED {
88 public:
Ben Murdoch3ef787d2012-04-12 10:51:47 +010089 enum Kind {
90 JS_ENTRY,
91 CATCH,
92 FINALLY,
93 LAST_KIND = FINALLY
Steve Blocka7e24c12009-10-30 11:49:00 +000094 };
95
Ben Murdoch3ef787d2012-04-12 10:51:47 +010096 static const int kKindWidth = 2;
97 STATIC_ASSERT(LAST_KIND < (1 << kKindWidth));
98 static const int kIndexWidth = 32 - kKindWidth;
99 class KindField: public BitField<StackHandler::Kind, 0, kKindWidth> {};
100 class IndexField: public BitField<unsigned, kKindWidth, kIndexWidth> {};
101
Steve Blocka7e24c12009-10-30 11:49:00 +0000102 // Get the address of this stack handler.
103 inline Address address() const;
104
105 // Get the next stack handler in the chain.
106 inline StackHandler* next() const;
107
108 // Tells whether the given address is inside this handler.
109 inline bool includes(Address address) const;
110
111 // Garbage collection support.
Kristian Monsen80d68ea2010-09-08 11:05:35 +0100112 inline void Iterate(ObjectVisitor* v, Code* holder) const;
Steve Blocka7e24c12009-10-30 11:49:00 +0000113
114 // Conversion support.
115 static inline StackHandler* FromAddress(Address address);
116
117 // Testers
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100118 inline bool is_js_entry() const;
119 inline bool is_catch() const;
120 inline bool is_finally() const;
Steve Blocka7e24c12009-10-30 11:49:00 +0000121
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000122 // Generator support to preserve stack handlers.
123 void Unwind(Isolate* isolate, FixedArray* array, int offset,
124 int previous_handler_offset) const;
125 int Rewind(Isolate* isolate, FixedArray* array, int offset, Address fp);
126
Steve Blocka7e24c12009-10-30 11:49:00 +0000127 private:
128 // Accessors.
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100129 inline Kind kind() const;
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000130 inline unsigned index() const;
Steve Blocka7e24c12009-10-30 11:49:00 +0000131
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000132 inline Object** constant_pool_address() const;
Ben Murdoch69a99ed2011-11-30 16:03:39 +0000133 inline Object** context_address() const;
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100134 inline Object** code_address() const;
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000135 inline void SetFp(Address slot, Address fp);
Steve Blocka7e24c12009-10-30 11:49:00 +0000136
137 DISALLOW_IMPLICIT_CONSTRUCTORS(StackHandler);
138};
139
140
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000141#define STACK_FRAME_TYPE_LIST(V) \
142 V(ENTRY, EntryFrame) \
143 V(ENTRY_CONSTRUCT, EntryConstructFrame) \
144 V(EXIT, ExitFrame) \
145 V(JAVA_SCRIPT, JavaScriptFrame) \
146 V(OPTIMIZED, OptimizedFrame) \
147 V(STUB, StubFrame) \
148 V(STUB_FAILURE_TRAMPOLINE, StubFailureTrampolineFrame) \
149 V(INTERNAL, InternalFrame) \
150 V(CONSTRUCT, ConstructFrame) \
151 V(ARGUMENTS_ADAPTOR, ArgumentsAdaptorFrame)
152
153
154class StandardFrameConstants : public AllStatic {
155 public:
156 // Fixed part of the frame consists of return address, caller fp,
157 // constant pool (if FLAG_enable_ool_constant_pool), context, and function.
158 // StandardFrame::IterateExpressions assumes that kLastObjectOffset is the
159 // last object pointer.
160 static const int kCPSlotSize =
161 FLAG_enable_ool_constant_pool ? kPointerSize : 0;
162 static const int kFixedFrameSizeFromFp = 2 * kPointerSize + kCPSlotSize;
163 static const int kFixedFrameSize = kPCOnStackSize + kFPOnStackSize +
164 kFixedFrameSizeFromFp;
165 static const int kExpressionsOffset = -3 * kPointerSize - kCPSlotSize;
166 static const int kMarkerOffset = -2 * kPointerSize - kCPSlotSize;
167 static const int kContextOffset = -1 * kPointerSize - kCPSlotSize;
168 static const int kConstantPoolOffset = FLAG_enable_ool_constant_pool ?
169 -1 * kPointerSize : 0;
170 static const int kCallerFPOffset = 0 * kPointerSize;
171 static const int kCallerPCOffset = +1 * kFPOnStackSize;
172 static const int kCallerSPOffset = kCallerPCOffset + 1 * kPCOnStackSize;
173
174 static const int kLastObjectOffset = FLAG_enable_ool_constant_pool ?
175 kConstantPoolOffset : kContextOffset;
176};
Steve Blocka7e24c12009-10-30 11:49:00 +0000177
178
179// Abstract base class for all stack frames.
180class StackFrame BASE_EMBEDDED {
181 public:
182#define DECLARE_TYPE(type, ignore) type,
183 enum Type {
184 NONE = 0,
185 STACK_FRAME_TYPE_LIST(DECLARE_TYPE)
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100186 NUMBER_OF_TYPES,
187 // Used by FrameScope to indicate that the stack frame is constructed
188 // manually and the FrameScope does not need to emit code.
189 MANUAL
Steve Blocka7e24c12009-10-30 11:49:00 +0000190 };
191#undef DECLARE_TYPE
192
193 // Opaque data type for identifying stack frames. Used extensively
194 // by the debugger.
Iain Merrick75681382010-08-19 15:07:18 +0100195 // ID_MIN_VALUE and ID_MAX_VALUE are specified to ensure that enumeration type
196 // has correct value range (see Issue 830 for more details).
197 enum Id {
198 ID_MIN_VALUE = kMinInt,
199 ID_MAX_VALUE = kMaxInt,
200 NO_ID = 0
201 };
Steve Blocka7e24c12009-10-30 11:49:00 +0000202
Steve Block053d10c2011-06-13 19:13:29 +0100203 // Used to mark the outermost JS entry frame.
204 enum JsFrameMarker {
205 INNER_JSENTRY_FRAME = 0,
206 OUTERMOST_JSENTRY_FRAME = 1
207 };
208
Kristian Monsen0d5e1162010-09-30 15:31:59 +0100209 struct State {
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000210 State() : sp(NULL), fp(NULL), pc_address(NULL),
211 constant_pool_address(NULL) { }
Kristian Monsen0d5e1162010-09-30 15:31:59 +0100212 Address sp;
213 Address fp;
214 Address* pc_address;
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000215 Address* constant_pool_address;
Kristian Monsen0d5e1162010-09-30 15:31:59 +0100216 };
217
Ben Murdoch8b112d22011-06-08 16:22:53 +0100218 // Copy constructor; it breaks the connection to host iterator
219 // (as an iterator usually lives on stack).
Steve Block6ded16b2010-05-10 14:33:55 +0100220 StackFrame(const StackFrame& original) {
221 this->state_ = original.state_;
222 this->iterator_ = NULL;
Ben Murdoch8b112d22011-06-08 16:22:53 +0100223 this->isolate_ = original.isolate_;
Steve Block6ded16b2010-05-10 14:33:55 +0100224 }
225
Steve Blocka7e24c12009-10-30 11:49:00 +0000226 // Type testers.
227 bool is_entry() const { return type() == ENTRY; }
228 bool is_entry_construct() const { return type() == ENTRY_CONSTRUCT; }
229 bool is_exit() const { return type() == EXIT; }
Ben Murdochb0fe1622011-05-05 13:52:32 +0100230 bool is_optimized() const { return type() == OPTIMIZED; }
Steve Blocka7e24c12009-10-30 11:49:00 +0000231 bool is_arguments_adaptor() const { return type() == ARGUMENTS_ADAPTOR; }
232 bool is_internal() const { return type() == INTERNAL; }
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000233 bool is_stub_failure_trampoline() const {
234 return type() == STUB_FAILURE_TRAMPOLINE;
235 }
Steve Blocka7e24c12009-10-30 11:49:00 +0000236 bool is_construct() const { return type() == CONSTRUCT; }
237 virtual bool is_standard() const { return false; }
238
Ben Murdochb0fe1622011-05-05 13:52:32 +0100239 bool is_java_script() const {
240 Type type = this->type();
241 return (type == JAVA_SCRIPT) || (type == OPTIMIZED);
242 }
243
Steve Blocka7e24c12009-10-30 11:49:00 +0000244 // Accessors.
245 Address sp() const { return state_.sp; }
246 Address fp() const { return state_.fp; }
247 Address caller_sp() const { return GetCallerStackPointer(); }
248
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000249 // If this frame is optimized and was dynamically aligned return its old
250 // unaligned frame pointer. When the frame is deoptimized its FP will shift
251 // up one word and become unaligned.
252 Address UnpaddedFP() const;
253
Steve Blocka7e24c12009-10-30 11:49:00 +0000254 Address pc() const { return *pc_address(); }
255 void set_pc(Address pc) { *pc_address() = pc; }
256
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000257 Address constant_pool() const { return *constant_pool_address(); }
258 void set_constant_pool(ConstantPoolArray* constant_pool) {
259 *constant_pool_address() = reinterpret_cast<Address>(constant_pool);
260 }
261
Steve Block6ded16b2010-05-10 14:33:55 +0100262 virtual void SetCallerFp(Address caller_fp) = 0;
263
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000264 // Manually changes value of fp in this object.
265 void UpdateFp(Address fp) { state_.fp = fp; }
266
Steve Blocka7e24c12009-10-30 11:49:00 +0000267 Address* pc_address() const { return state_.pc_address; }
268
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000269 Address* constant_pool_address() const {
270 return state_.constant_pool_address;
271 }
272
Steve Blocka7e24c12009-10-30 11:49:00 +0000273 // Get the id of this stack frame.
274 Id id() const { return static_cast<Id>(OffsetFrom(caller_sp())); }
275
276 // Checks if this frame includes any stack handlers.
277 bool HasHandler() const;
278
279 // Get the type of this frame.
280 virtual Type type() const = 0;
281
282 // Get the code associated with this frame.
Iain Merrick75681382010-08-19 15:07:18 +0100283 // This method could be called during marking phase of GC.
284 virtual Code* unchecked_code() const = 0;
285
286 // Get the code associated with this frame.
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100287 inline Code* LookupCode() const;
Kristian Monsen80d68ea2010-09-08 11:05:35 +0100288
289 // Get the code object that contains the given pc.
Steve Block44f0eee2011-05-26 01:26:41 +0100290 static inline Code* GetContainingCode(Isolate* isolate, Address pc);
Steve Blocka7e24c12009-10-30 11:49:00 +0000291
Ben Murdochb0fe1622011-05-05 13:52:32 +0100292 // Get the code object containing the given pc and fill in the
293 // safepoint entry and the number of stack slots. The pc must be at
294 // a safepoint.
Ben Murdoch8b112d22011-06-08 16:22:53 +0100295 static Code* GetSafepointData(Isolate* isolate,
296 Address pc,
Ben Murdochb8e0da22011-05-16 14:20:40 +0100297 SafepointEntry* safepoint_entry,
Ben Murdochb0fe1622011-05-05 13:52:32 +0100298 unsigned* stack_slots);
299
Kristian Monsen80d68ea2010-09-08 11:05:35 +0100300 virtual void Iterate(ObjectVisitor* v) const = 0;
301 static void IteratePc(ObjectVisitor* v, Address* pc_address, Code* holder);
Steve Blocka7e24c12009-10-30 11:49:00 +0000302
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100303 // Sets a callback function for return-address rewriting profilers
304 // to resolve the location of a return address to the location of the
305 // profiler's stashed return address.
306 static void SetReturnAddressLocationResolver(
307 ReturnAddressLocationResolver resolver);
Steve Blocka7e24c12009-10-30 11:49:00 +0000308
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000309 // Resolves pc_address through the resolution address function if one is set.
310 static inline Address* ResolveReturnAddressLocation(Address* pc_address);
311
312
Steve Blocka7e24c12009-10-30 11:49:00 +0000313 // Printing support.
314 enum PrintMode { OVERVIEW, DETAILS };
315 virtual void Print(StringStream* accumulator,
316 PrintMode mode,
317 int index) const { }
318
Ben Murdoch8b112d22011-06-08 16:22:53 +0100319 Isolate* isolate() const { return isolate_; }
320
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000321 protected:
322 inline explicit StackFrame(StackFrameIteratorBase* iterator);
323 virtual ~StackFrame() { }
324
Steve Blocka7e24c12009-10-30 11:49:00 +0000325 // Compute the stack pointer for the calling frame.
326 virtual Address GetCallerStackPointer() const = 0;
327
328 // Printing support.
329 static void PrintIndex(StringStream* accumulator,
330 PrintMode mode,
331 int index);
332
333 // Get the top handler from the current stack iterator.
334 inline StackHandler* top_handler() const;
335
336 // Compute the stack frame type for the given state.
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000337 static Type ComputeType(const StackFrameIteratorBase* iterator, State* state);
338
339#ifdef DEBUG
340 bool can_access_heap_objects() const;
341#endif
Steve Blocka7e24c12009-10-30 11:49:00 +0000342
343 private:
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000344 const StackFrameIteratorBase* iterator_;
Ben Murdoch8b112d22011-06-08 16:22:53 +0100345 Isolate* isolate_;
Steve Blocka7e24c12009-10-30 11:49:00 +0000346 State state_;
347
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000348 static ReturnAddressLocationResolver return_address_location_resolver_;
349
Steve Blocka7e24c12009-10-30 11:49:00 +0000350 // Fill in the state of the calling frame.
351 virtual void ComputeCallerState(State* state) const = 0;
352
353 // Get the type and the state of the calling frame.
354 virtual Type GetCallerState(State* state) const;
355
Ben Murdoch8b112d22011-06-08 16:22:53 +0100356 static const intptr_t kIsolateTag = 1;
357
Steve Blocka7e24c12009-10-30 11:49:00 +0000358 friend class StackFrameIterator;
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000359 friend class StackFrameIteratorBase;
Steve Blocka7e24c12009-10-30 11:49:00 +0000360 friend class StackHandlerIterator;
361 friend class SafeStackFrameIterator;
362
Steve Block6ded16b2010-05-10 14:33:55 +0100363 private:
364 void operator=(const StackFrame& original);
Steve Blocka7e24c12009-10-30 11:49:00 +0000365};
366
367
368// Entry frames are used to enter JavaScript execution from C.
369class EntryFrame: public StackFrame {
370 public:
371 virtual Type type() const { return ENTRY; }
372
Iain Merrick75681382010-08-19 15:07:18 +0100373 virtual Code* unchecked_code() const;
Steve Blocka7e24c12009-10-30 11:49:00 +0000374
375 // Garbage collection support.
376 virtual void Iterate(ObjectVisitor* v) const;
377
378 static EntryFrame* cast(StackFrame* frame) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000379 DCHECK(frame->is_entry());
Steve Blocka7e24c12009-10-30 11:49:00 +0000380 return static_cast<EntryFrame*>(frame);
381 }
Steve Block6ded16b2010-05-10 14:33:55 +0100382 virtual void SetCallerFp(Address caller_fp);
Steve Blocka7e24c12009-10-30 11:49:00 +0000383
384 protected:
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000385 inline explicit EntryFrame(StackFrameIteratorBase* iterator);
Steve Blocka7e24c12009-10-30 11:49:00 +0000386
387 // The caller stack pointer for entry frames is always zero. The
388 // real information about the caller frame is available through the
389 // link to the top exit frame.
390 virtual Address GetCallerStackPointer() const { return 0; }
391
392 private:
393 virtual void ComputeCallerState(State* state) const;
394 virtual Type GetCallerState(State* state) const;
395
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000396 friend class StackFrameIteratorBase;
Steve Blocka7e24c12009-10-30 11:49:00 +0000397};
398
399
400class EntryConstructFrame: public EntryFrame {
401 public:
402 virtual Type type() const { return ENTRY_CONSTRUCT; }
403
Iain Merrick75681382010-08-19 15:07:18 +0100404 virtual Code* unchecked_code() const;
Steve Blocka7e24c12009-10-30 11:49:00 +0000405
406 static EntryConstructFrame* cast(StackFrame* frame) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000407 DCHECK(frame->is_entry_construct());
Steve Blocka7e24c12009-10-30 11:49:00 +0000408 return static_cast<EntryConstructFrame*>(frame);
409 }
410
411 protected:
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000412 inline explicit EntryConstructFrame(StackFrameIteratorBase* iterator);
Steve Blocka7e24c12009-10-30 11:49:00 +0000413
414 private:
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000415 friend class StackFrameIteratorBase;
Steve Blocka7e24c12009-10-30 11:49:00 +0000416};
417
418
419// Exit frames are used to exit JavaScript execution and go to C.
420class ExitFrame: public StackFrame {
421 public:
422 virtual Type type() const { return EXIT; }
423
Iain Merrick75681382010-08-19 15:07:18 +0100424 virtual Code* unchecked_code() const;
Steve Blocka7e24c12009-10-30 11:49:00 +0000425
Steve Blockd0582a62009-12-15 09:54:21 +0000426 Object*& code_slot() const;
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000427 Object*& constant_pool_slot() const;
Steve Blockd0582a62009-12-15 09:54:21 +0000428
Steve Blocka7e24c12009-10-30 11:49:00 +0000429 // Garbage collection support.
430 virtual void Iterate(ObjectVisitor* v) const;
431
Steve Block6ded16b2010-05-10 14:33:55 +0100432 virtual void SetCallerFp(Address caller_fp);
433
Steve Blocka7e24c12009-10-30 11:49:00 +0000434 static ExitFrame* cast(StackFrame* frame) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000435 DCHECK(frame->is_exit());
Steve Blocka7e24c12009-10-30 11:49:00 +0000436 return static_cast<ExitFrame*>(frame);
437 }
438
439 // Compute the state and type of an exit frame given a frame
440 // pointer. Used when constructing the first stack frame seen by an
441 // iterator and the frames following entry frames.
442 static Type GetStateForFramePointer(Address fp, State* state);
Kristian Monsen0d5e1162010-09-30 15:31:59 +0100443 static Address ComputeStackPointer(Address fp);
444 static void FillState(Address fp, Address sp, State* state);
Steve Blocka7e24c12009-10-30 11:49:00 +0000445
446 protected:
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000447 inline explicit ExitFrame(StackFrameIteratorBase* iterator);
Steve Blocka7e24c12009-10-30 11:49:00 +0000448
449 virtual Address GetCallerStackPointer() const;
450
451 private:
452 virtual void ComputeCallerState(State* state) const;
453
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000454 friend class StackFrameIteratorBase;
Steve Blocka7e24c12009-10-30 11:49:00 +0000455};
456
457
Steve Blocka7e24c12009-10-30 11:49:00 +0000458class StandardFrame: public StackFrame {
459 public:
460 // Testers.
461 virtual bool is_standard() const { return true; }
462
463 // Accessors.
464 inline Object* context() const;
465
466 // Access the expressions in the stack frame including locals.
467 inline Object* GetExpression(int index) const;
468 inline void SetExpression(int index, Object* value);
469 int ComputeExpressionsCount() const;
Ben Murdoch3fb3ca82011-12-02 17:19:32 +0000470 static Object* GetExpression(Address fp, int index);
Steve Blocka7e24c12009-10-30 11:49:00 +0000471
Steve Block6ded16b2010-05-10 14:33:55 +0100472 virtual void SetCallerFp(Address caller_fp);
473
Steve Blocka7e24c12009-10-30 11:49:00 +0000474 static StandardFrame* cast(StackFrame* frame) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000475 DCHECK(frame->is_standard());
Steve Blocka7e24c12009-10-30 11:49:00 +0000476 return static_cast<StandardFrame*>(frame);
477 }
478
479 protected:
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000480 inline explicit StandardFrame(StackFrameIteratorBase* iterator);
Steve Blocka7e24c12009-10-30 11:49:00 +0000481
482 virtual void ComputeCallerState(State* state) const;
483
484 // Accessors.
485 inline Address caller_fp() const;
486 inline Address caller_pc() const;
487
488 // Computes the address of the PC field in the standard frame given
489 // by the provided frame pointer.
490 static inline Address ComputePCAddress(Address fp);
491
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000492 // Computes the address of the constant pool field in the standard
493 // frame given by the provided frame pointer.
494 static inline Address ComputeConstantPoolAddress(Address fp);
495
Steve Blocka7e24c12009-10-30 11:49:00 +0000496 // Iterate over expression stack including stack handlers, locals,
497 // and parts of the fixed part including context and code fields.
498 void IterateExpressions(ObjectVisitor* v) const;
499
500 // Returns the address of the n'th expression stack element.
501 Address GetExpressionAddress(int n) const;
Ben Murdoch3fb3ca82011-12-02 17:19:32 +0000502 static Address GetExpressionAddress(Address fp, int n);
Steve Blocka7e24c12009-10-30 11:49:00 +0000503
504 // Determines if the n'th expression stack element is in a stack
505 // handler or not. Requires traversing all handlers in this frame.
506 bool IsExpressionInsideHandler(int n) const;
507
508 // Determines if the standard frame for the given frame pointer is
509 // an arguments adaptor frame.
510 static inline bool IsArgumentsAdaptorFrame(Address fp);
511
512 // Determines if the standard frame for the given frame pointer is a
513 // construct frame.
514 static inline bool IsConstructFrame(Address fp);
515
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000516 // Used by OptimizedFrames and StubFrames.
517 void IterateCompiledFrame(ObjectVisitor* v) const;
518
Steve Blocka7e24c12009-10-30 11:49:00 +0000519 private:
520 friend class StackFrame;
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000521 friend class SafeStackFrameIterator;
Steve Blocka7e24c12009-10-30 11:49:00 +0000522};
523
524
Ben Murdochb0fe1622011-05-05 13:52:32 +0100525class FrameSummary BASE_EMBEDDED {
526 public:
527 FrameSummary(Object* receiver,
528 JSFunction* function,
529 Code* code,
530 int offset,
531 bool is_constructor)
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000532 : receiver_(receiver, function->GetIsolate()),
Ben Murdochb0fe1622011-05-05 13:52:32 +0100533 function_(function),
534 code_(code),
535 offset_(offset),
536 is_constructor_(is_constructor) { }
537 Handle<Object> receiver() { return receiver_; }
538 Handle<JSFunction> function() { return function_; }
539 Handle<Code> code() { return code_; }
Ben Murdoch8b112d22011-06-08 16:22:53 +0100540 Address pc() { return code_->address() + offset_; }
Ben Murdochb0fe1622011-05-05 13:52:32 +0100541 int offset() { return offset_; }
542 bool is_constructor() { return is_constructor_; }
543
544 void Print();
545
546 private:
547 Handle<Object> receiver_;
548 Handle<JSFunction> function_;
549 Handle<Code> code_;
550 int offset_;
551 bool is_constructor_;
552};
553
554
Steve Blocka7e24c12009-10-30 11:49:00 +0000555class JavaScriptFrame: public StandardFrame {
556 public:
557 virtual Type type() const { return JAVA_SCRIPT; }
558
559 // Accessors.
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000560 inline JSFunction* function() const;
Steve Blocka7e24c12009-10-30 11:49:00 +0000561 inline Object* receiver() const;
562 inline void set_receiver(Object* value);
563
564 // Access the parameters.
Ben Murdoch8b112d22011-06-08 16:22:53 +0100565 inline Address GetParameterSlot(int index) const;
566 inline Object* GetParameter(int index) const;
567 inline int ComputeParametersCount() const {
568 return GetNumberOfIncomingArguments();
569 }
Steve Blocka7e24c12009-10-30 11:49:00 +0000570
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000571 // Access the operand stack.
572 inline Address GetOperandSlot(int index) const;
573 inline Object* GetOperand(int index) const;
574 inline int ComputeOperandsCount() const;
575
576 // Generator support to preserve operand stack and stack handlers.
577 void SaveOperandStack(FixedArray* store, int* stack_handler_index) const;
578 void RestoreOperandStack(FixedArray* store, int stack_handler_index);
579
580 // Debugger access.
581 void SetParameterValue(int index, Object* value) const;
582
Steve Blocka7e24c12009-10-30 11:49:00 +0000583 // Check if this frame is a constructor frame invoked through 'new'.
584 bool IsConstructor() const;
585
586 // Check if this frame has "adapted" arguments in the sense that the
587 // actual passed arguments are available in an arguments adaptor
588 // frame below it on the stack.
589 inline bool has_adapted_arguments() const;
Ben Murdoch3fb3ca82011-12-02 17:19:32 +0000590 int GetArgumentsLength() const;
Steve Blocka7e24c12009-10-30 11:49:00 +0000591
592 // Garbage collection support.
593 virtual void Iterate(ObjectVisitor* v) const;
594
595 // Printing support.
596 virtual void Print(StringStream* accumulator,
597 PrintMode mode,
598 int index) const;
599
600 // Determine the code for the frame.
Iain Merrick75681382010-08-19 15:07:18 +0100601 virtual Code* unchecked_code() const;
Steve Blocka7e24c12009-10-30 11:49:00 +0000602
Ben Murdoch3fb3ca82011-12-02 17:19:32 +0000603 // Returns the levels of inlining for this frame.
604 virtual int GetInlineCount() { return 1; }
605
Ben Murdochb0fe1622011-05-05 13:52:32 +0100606 // Return a list with JSFunctions of this frame.
607 virtual void GetFunctions(List<JSFunction*>* functions);
608
609 // Build a list with summaries for this frame including all inlined frames.
610 virtual void Summarize(List<FrameSummary>* frames);
611
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000612 // Architecture-specific register description.
613 static Register fp_register();
614 static Register context_register();
615 static Register constant_pool_pointer_register();
616
Steve Blocka7e24c12009-10-30 11:49:00 +0000617 static JavaScriptFrame* cast(StackFrame* frame) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000618 DCHECK(frame->is_java_script());
Steve Blocka7e24c12009-10-30 11:49:00 +0000619 return static_cast<JavaScriptFrame*>(frame);
620 }
621
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000622 static void PrintFunctionAndOffset(JSFunction* function, Code* code,
623 Address pc, FILE* file,
624 bool print_line_number);
625
626 static void PrintTop(Isolate* isolate, FILE* file, bool print_args,
627 bool print_line_number);
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100628
Steve Blocka7e24c12009-10-30 11:49:00 +0000629 protected:
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000630 inline explicit JavaScriptFrame(StackFrameIteratorBase* iterator);
Steve Blocka7e24c12009-10-30 11:49:00 +0000631
632 virtual Address GetCallerStackPointer() const;
633
Ben Murdoch8b112d22011-06-08 16:22:53 +0100634 virtual int GetNumberOfIncomingArguments() const;
635
Ben Murdochb0fe1622011-05-05 13:52:32 +0100636 // Garbage collection support. Iterates over incoming arguments,
637 // receiver, and any callee-saved registers.
638 void IterateArguments(ObjectVisitor* v) const;
639
Steve Blocka7e24c12009-10-30 11:49:00 +0000640 private:
Steve Blocka7e24c12009-10-30 11:49:00 +0000641 inline Object* function_slot_object() const;
642
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000643 friend class StackFrameIteratorBase;
644};
645
646
647class StubFrame : public StandardFrame {
648 public:
649 virtual Type type() const { return STUB; }
650
651 // GC support.
652 virtual void Iterate(ObjectVisitor* v) const;
653
654 // Determine the code for the frame.
655 virtual Code* unchecked_code() const;
656
657 protected:
658 inline explicit StubFrame(StackFrameIteratorBase* iterator);
659
660 virtual Address GetCallerStackPointer() const;
661
662 virtual int GetNumberOfIncomingArguments() const;
663
664 friend class StackFrameIteratorBase;
Steve Blocka7e24c12009-10-30 11:49:00 +0000665};
666
667
Ben Murdochb0fe1622011-05-05 13:52:32 +0100668class OptimizedFrame : public JavaScriptFrame {
669 public:
670 virtual Type type() const { return OPTIMIZED; }
671
672 // GC support.
673 virtual void Iterate(ObjectVisitor* v) const;
674
Ben Murdoch3fb3ca82011-12-02 17:19:32 +0000675 virtual int GetInlineCount();
676
Ben Murdochb0fe1622011-05-05 13:52:32 +0100677 // Return a list with JSFunctions of this frame.
678 // The functions are ordered bottom-to-top (i.e. functions.last()
679 // is the top-most activation)
680 virtual void GetFunctions(List<JSFunction*>* functions);
681
682 virtual void Summarize(List<FrameSummary>* frames);
683
684 DeoptimizationInputData* GetDeoptimizationData(int* deopt_index);
685
686 protected:
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000687 inline explicit OptimizedFrame(StackFrameIteratorBase* iterator);
Ben Murdochb0fe1622011-05-05 13:52:32 +0100688
689 private:
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000690 JSFunction* LiteralAt(FixedArray* literal_array, int literal_id);
691
692 friend class StackFrameIteratorBase;
Ben Murdochb0fe1622011-05-05 13:52:32 +0100693};
694
695
Steve Blocka7e24c12009-10-30 11:49:00 +0000696// Arguments adaptor frames are automatically inserted below
697// JavaScript frames when the actual number of parameters does not
698// match the formal number of parameters.
699class ArgumentsAdaptorFrame: public JavaScriptFrame {
700 public:
701 virtual Type type() const { return ARGUMENTS_ADAPTOR; }
702
703 // Determine the code for the frame.
Iain Merrick75681382010-08-19 15:07:18 +0100704 virtual Code* unchecked_code() const;
Steve Blocka7e24c12009-10-30 11:49:00 +0000705
706 static ArgumentsAdaptorFrame* cast(StackFrame* frame) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000707 DCHECK(frame->is_arguments_adaptor());
Steve Blocka7e24c12009-10-30 11:49:00 +0000708 return static_cast<ArgumentsAdaptorFrame*>(frame);
709 }
710
711 // Printing support.
712 virtual void Print(StringStream* accumulator,
713 PrintMode mode,
714 int index) const;
Ben Murdoch589d6972011-11-30 16:04:58 +0000715
Steve Blocka7e24c12009-10-30 11:49:00 +0000716 protected:
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000717 inline explicit ArgumentsAdaptorFrame(StackFrameIteratorBase* iterator);
Steve Blocka7e24c12009-10-30 11:49:00 +0000718
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100719 virtual int GetNumberOfIncomingArguments() const;
Ben Murdoch8b112d22011-06-08 16:22:53 +0100720
Steve Blocka7e24c12009-10-30 11:49:00 +0000721 virtual Address GetCallerStackPointer() const;
722
723 private:
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000724 friend class StackFrameIteratorBase;
Steve Blocka7e24c12009-10-30 11:49:00 +0000725};
726
727
728class InternalFrame: public StandardFrame {
729 public:
730 virtual Type type() const { return INTERNAL; }
731
732 // Garbage collection support.
733 virtual void Iterate(ObjectVisitor* v) const;
734
735 // Determine the code for the frame.
Iain Merrick75681382010-08-19 15:07:18 +0100736 virtual Code* unchecked_code() const;
Steve Blocka7e24c12009-10-30 11:49:00 +0000737
738 static InternalFrame* cast(StackFrame* frame) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000739 DCHECK(frame->is_internal());
Steve Blocka7e24c12009-10-30 11:49:00 +0000740 return static_cast<InternalFrame*>(frame);
741 }
742
743 protected:
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000744 inline explicit InternalFrame(StackFrameIteratorBase* iterator);
Steve Blocka7e24c12009-10-30 11:49:00 +0000745
746 virtual Address GetCallerStackPointer() const;
747
748 private:
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000749 friend class StackFrameIteratorBase;
750};
751
752
753class StubFailureTrampolineFrame: public StandardFrame {
754 public:
755 // sizeof(Arguments) - sizeof(Arguments*) is 3 * kPointerSize), but the
756 // presubmit script complains about using sizeof() on a type.
757 static const int kFirstRegisterParameterFrameOffset =
758 StandardFrameConstants::kMarkerOffset - 3 * kPointerSize;
759
760 static const int kCallerStackParameterCountFrameOffset =
761 StandardFrameConstants::kMarkerOffset - 2 * kPointerSize;
762
763 virtual Type type() const { return STUB_FAILURE_TRAMPOLINE; }
764
765 // Get the code associated with this frame.
766 // This method could be called during marking phase of GC.
767 virtual Code* unchecked_code() const;
768
769 virtual void Iterate(ObjectVisitor* v) const;
770
771 // Architecture-specific register description.
772 static Register fp_register();
773 static Register context_register();
774 static Register constant_pool_pointer_register();
775
776 protected:
777 inline explicit StubFailureTrampolineFrame(
778 StackFrameIteratorBase* iterator);
779
780 virtual Address GetCallerStackPointer() const;
781
782 private:
783 friend class StackFrameIteratorBase;
Steve Blocka7e24c12009-10-30 11:49:00 +0000784};
785
786
787// Construct frames are special trampoline frames introduced to handle
788// function invocations through 'new'.
789class ConstructFrame: public InternalFrame {
790 public:
791 virtual Type type() const { return CONSTRUCT; }
792
793 static ConstructFrame* cast(StackFrame* frame) {
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000794 DCHECK(frame->is_construct());
Steve Blocka7e24c12009-10-30 11:49:00 +0000795 return static_cast<ConstructFrame*>(frame);
796 }
797
798 protected:
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000799 inline explicit ConstructFrame(StackFrameIteratorBase* iterator);
Steve Blocka7e24c12009-10-30 11:49:00 +0000800
801 private:
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000802 friend class StackFrameIteratorBase;
Steve Blocka7e24c12009-10-30 11:49:00 +0000803};
804
805
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000806class StackFrameIteratorBase BASE_EMBEDDED {
Steve Blocka7e24c12009-10-30 11:49:00 +0000807 public:
Ben Murdoch8b112d22011-06-08 16:22:53 +0100808 Isolate* isolate() const { return isolate_; }
809
Steve Blocka7e24c12009-10-30 11:49:00 +0000810 bool done() const { return frame_ == NULL; }
Steve Blocka7e24c12009-10-30 11:49:00 +0000811
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000812 protected:
813 // An iterator that iterates over a given thread's stack.
814 StackFrameIteratorBase(Isolate* isolate, bool can_access_heap_objects);
Steve Blocka7e24c12009-10-30 11:49:00 +0000815
Ben Murdoch8b112d22011-06-08 16:22:53 +0100816 Isolate* isolate_;
Steve Blocka7e24c12009-10-30 11:49:00 +0000817#define DECLARE_SINGLETON(ignore, type) type type##_;
818 STACK_FRAME_TYPE_LIST(DECLARE_SINGLETON)
819#undef DECLARE_SINGLETON
820 StackFrame* frame_;
821 StackHandler* handler_;
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000822 const bool can_access_heap_objects_;
Steve Blocka7e24c12009-10-30 11:49:00 +0000823
824 StackHandler* handler() const {
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000825 DCHECK(!done());
Steve Blocka7e24c12009-10-30 11:49:00 +0000826 return handler_;
827 }
828
829 // Get the type-specific frame singleton in a given state.
830 StackFrame* SingletonFor(StackFrame::Type type, StackFrame::State* state);
831 // A helper function, can return a NULL pointer.
832 StackFrame* SingletonFor(StackFrame::Type type);
833
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000834 private:
Steve Blocka7e24c12009-10-30 11:49:00 +0000835 friend class StackFrame;
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000836 DISALLOW_COPY_AND_ASSIGN(StackFrameIteratorBase);
837};
838
839
840class StackFrameIterator: public StackFrameIteratorBase {
841 public:
842 // An iterator that iterates over the isolate's current thread's stack,
843 explicit StackFrameIterator(Isolate* isolate);
844 // An iterator that iterates over a given thread's stack.
845 StackFrameIterator(Isolate* isolate, ThreadLocalTop* t);
846
847 StackFrame* frame() const {
848 DCHECK(!done());
849 return frame_;
850 }
851 void Advance();
852
853 private:
854 // Go back to the first frame.
855 void Reset(ThreadLocalTop* top);
856
Steve Blocka7e24c12009-10-30 11:49:00 +0000857 DISALLOW_COPY_AND_ASSIGN(StackFrameIterator);
858};
859
860
861// Iterator that supports iterating through all JavaScript frames.
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000862class JavaScriptFrameIterator BASE_EMBEDDED {
Steve Blocka7e24c12009-10-30 11:49:00 +0000863 public:
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000864 inline explicit JavaScriptFrameIterator(Isolate* isolate);
865 inline JavaScriptFrameIterator(Isolate* isolate, ThreadLocalTop* top);
Steve Blocka7e24c12009-10-30 11:49:00 +0000866 // Skip frames until the frame with the given id is reached.
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000867 JavaScriptFrameIterator(Isolate* isolate, StackFrame::Id id);
Steve Block44f0eee2011-05-26 01:26:41 +0100868
Steve Blocka7e24c12009-10-30 11:49:00 +0000869 inline JavaScriptFrame* frame() const;
870
871 bool done() const { return iterator_.done(); }
872 void Advance();
873
874 // Advance to the frame holding the arguments for the current
875 // frame. This only affects the current frame if it has adapted
876 // arguments.
877 void AdvanceToArgumentsFrame();
878
Steve Blocka7e24c12009-10-30 11:49:00 +0000879 private:
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000880 StackFrameIterator iterator_;
Steve Blocka7e24c12009-10-30 11:49:00 +0000881};
882
883
Steve Blocka7e24c12009-10-30 11:49:00 +0000884// NOTE: The stack trace frame iterator is an iterator that only
885// traverse proper JavaScript frames; that is JavaScript frames that
886// have proper JavaScript functions. This excludes the problematic
887// functions in runtime.js.
888class StackTraceFrameIterator: public JavaScriptFrameIterator {
889 public:
Ben Murdoch8b112d22011-06-08 16:22:53 +0100890 explicit StackTraceFrameIterator(Isolate* isolate);
Steve Blocka7e24c12009-10-30 11:49:00 +0000891 void Advance();
Leon Clarke4515c472010-02-03 11:58:03 +0000892
893 private:
894 bool IsValidFrame();
Steve Blocka7e24c12009-10-30 11:49:00 +0000895};
896
897
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000898class SafeStackFrameIterator: public StackFrameIteratorBase {
Steve Blocka7e24c12009-10-30 11:49:00 +0000899 public:
Steve Block44f0eee2011-05-26 01:26:41 +0100900 SafeStackFrameIterator(Isolate* isolate,
901 Address fp, Address sp,
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000902 Address js_entry_sp);
Steve Blocka7e24c12009-10-30 11:49:00 +0000903
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000904 inline StackFrame* frame() const;
Steve Blocka7e24c12009-10-30 11:49:00 +0000905 void Advance();
Steve Blocka7e24c12009-10-30 11:49:00 +0000906
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000907 StackFrame::Type top_frame_type() const { return top_frame_type_; }
Leon Clarked91b9f72010-01-27 17:25:45 +0000908
909 private:
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000910 void AdvanceOneFrame();
Kristian Monsen0d5e1162010-09-30 15:31:59 +0100911
Steve Blocka7e24c12009-10-30 11:49:00 +0000912 bool IsValidStackAddress(Address addr) const {
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000913 return low_bound_ <= addr && addr <= high_bound_;
Steve Blocka7e24c12009-10-30 11:49:00 +0000914 }
Steve Blocka7e24c12009-10-30 11:49:00 +0000915 bool IsValidFrame(StackFrame* frame) const;
916 bool IsValidCaller(StackFrame* frame);
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000917 bool IsValidExitFrame(Address fp) const;
918 bool IsValidTop(ThreadLocalTop* top) const;
Steve Blocka7e24c12009-10-30 11:49:00 +0000919
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000920 const Address low_bound_;
921 const Address high_bound_;
922 StackFrame::Type top_frame_type_;
923 ExternalCallbackScope* external_callback_scope_;
Steve Blocka7e24c12009-10-30 11:49:00 +0000924};
Steve Blocka7e24c12009-10-30 11:49:00 +0000925
926
927class StackFrameLocator BASE_EMBEDDED {
928 public:
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000929 explicit StackFrameLocator(Isolate* isolate) : iterator_(isolate) {}
930
Steve Blocka7e24c12009-10-30 11:49:00 +0000931 // Find the nth JavaScript frame on the stack. The caller must
932 // guarantee that such a frame exists.
933 JavaScriptFrame* FindJavaScriptFrame(int n);
934
935 private:
936 StackFrameIterator iterator_;
937};
938
939
Steve Block6ded16b2010-05-10 14:33:55 +0100940// Reads all frames on the current stack and copies them into the current
941// zone memory.
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000942Vector<StackFrame*> CreateStackMap(Isolate* isolate, Zone* zone);
Steve Block6ded16b2010-05-10 14:33:55 +0100943
Steve Blocka7e24c12009-10-30 11:49:00 +0000944} } // namespace v8::internal
945
946#endif // V8_FRAMES_H_