blob: e550f765ca611a7df7fdd0549fb709399e6a66d0 [file] [log] [blame]
yangguo@chromium.org78d1ad42012-02-09 13:53:47 +00001// Copyright 2012 the V8 project authors. All rights reserved.
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002// Redistribution and use in source and binary forms, with or without
3// modification, are permitted provided that the following conditions are
4// met:
5//
6// * Redistributions of source code must retain the above copyright
7// notice, this list of conditions and the following disclaimer.
8// * Redistributions in binary form must reproduce the above
9// copyright notice, this list of conditions and the following
10// disclaimer in the documentation and/or other materials provided
11// with the distribution.
12// * Neither the name of Google Inc. nor the names of its
13// contributors may be used to endorse or promote products derived
14// from this software without specific prior written permission.
15//
16// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
19// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
20// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27
28#ifndef V8_FRAMES_H_
29#define V8_FRAMES_H_
30
lrn@chromium.org1c092762011-05-09 09:42:16 +000031#include "allocation.h"
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +000032#include "handles.h"
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +000033#include "safepoint-table.h"
34
kasperl@chromium.org71affb52009-05-26 05:44:31 +000035namespace v8 {
36namespace internal {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +000037
38typedef uint32_t RegList;
39
40// Get the number of registers in a given register list.
41int NumRegs(RegList list);
42
43// Return the code of the n-th saved register available to JavaScript.
44int JSCallerSavedCode(int n);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +000045
46
47// Forward declarations.
48class StackFrameIterator;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +000049class ThreadLocalTop;
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +000050class Isolate;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +000051
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +000052class InnerPointerToCodeCache {
ricow@chromium.orgd236f4d2010-09-01 06:52:08 +000053 public:
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +000054 struct InnerPointerToCodeCacheEntry {
55 Address inner_pointer;
ricow@chromium.orgd236f4d2010-09-01 06:52:08 +000056 Code* code;
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +000057 SafepointEntry safepoint_entry;
ricow@chromium.orgd236f4d2010-09-01 06:52:08 +000058 };
59
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +000060 explicit InnerPointerToCodeCache(Isolate* isolate) : isolate_(isolate) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +000061 Flush();
ricow@chromium.orgd236f4d2010-09-01 06:52:08 +000062 }
63
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +000064 Code* GcSafeFindCodeForInnerPointer(Address inner_pointer);
65 Code* GcSafeCastToCode(HeapObject* object, Address inner_pointer);
ricow@chromium.orgd236f4d2010-09-01 06:52:08 +000066
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +000067 void Flush() {
ricow@chromium.orgd236f4d2010-09-01 06:52:08 +000068 memset(&cache_[0], 0, sizeof(cache_));
69 }
70
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +000071 InnerPointerToCodeCacheEntry* GetCacheEntry(Address inner_pointer);
ricow@chromium.orgd236f4d2010-09-01 06:52:08 +000072
73 private:
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +000074 InnerPointerToCodeCacheEntry* cache(int index) { return &cache_[index]; }
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +000075
76 Isolate* isolate_;
77
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +000078 static const int kInnerPointerToCodeCacheSize = 1024;
79 InnerPointerToCodeCacheEntry cache_[kInnerPointerToCodeCacheSize];
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +000080
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +000081 DISALLOW_COPY_AND_ASSIGN(InnerPointerToCodeCache);
ricow@chromium.orgd236f4d2010-09-01 06:52:08 +000082};
83
84
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +000085class StackHandler BASE_EMBEDDED {
86 public:
jkummerow@chromium.org04e4f1e2011-11-14 13:36:17 +000087 enum Kind {
yangguo@chromium.org78d1ad42012-02-09 13:53:47 +000088 JS_ENTRY,
89 CATCH,
90 FINALLY,
91 LAST_KIND = FINALLY
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +000092 };
93
jkummerow@chromium.org04e4f1e2011-11-14 13:36:17 +000094 static const int kKindWidth = 2;
yangguo@chromium.org78d1ad42012-02-09 13:53:47 +000095 STATIC_ASSERT(LAST_KIND < (1 << kKindWidth));
96 static const int kIndexWidth = 32 - kKindWidth;
jkummerow@chromium.org04e4f1e2011-11-14 13:36:17 +000097 class KindField: public BitField<StackHandler::Kind, 0, kKindWidth> {};
yangguo@chromium.org78d1ad42012-02-09 13:53:47 +000098 class IndexField: public BitField<unsigned, kKindWidth, kIndexWidth> {};
jkummerow@chromium.org04e4f1e2011-11-14 13:36:17 +000099
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000100 // Get the address of this stack handler.
101 inline Address address() const;
102
103 // Get the next stack handler in the chain.
104 inline StackHandler* next() const;
105
106 // Tells whether the given address is inside this handler.
107 inline bool includes(Address address) const;
108
109 // Garbage collection support.
ricow@chromium.orgd236f4d2010-09-01 06:52:08 +0000110 inline void Iterate(ObjectVisitor* v, Code* holder) const;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000111
112 // Conversion support.
113 static inline StackHandler* FromAddress(Address address);
114
115 // Testers
yangguo@chromium.org78d1ad42012-02-09 13:53:47 +0000116 inline bool is_js_entry() const;
117 inline bool is_catch() const;
118 inline bool is_finally() const;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000119
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000120 private:
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000121 // Accessors.
jkummerow@chromium.org04e4f1e2011-11-14 13:36:17 +0000122 inline Kind kind() const;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000123
whesse@chromium.org4acdc2c2011-08-15 13:01:23 +0000124 inline Object** context_address() const;
jkummerow@chromium.org04e4f1e2011-11-14 13:36:17 +0000125 inline Object** code_address() const;
mads.s.ager31e71382008-08-13 09:32:07 +0000126
127 DISALLOW_IMPLICIT_CONSTRUCTORS(StackHandler);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000128};
129
130
131#define STACK_FRAME_TYPE_LIST(V) \
132 V(ENTRY, EntryFrame) \
133 V(ENTRY_CONSTRUCT, EntryConstructFrame) \
134 V(EXIT, ExitFrame) \
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000135 V(JAVA_SCRIPT, JavaScriptFrame) \
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000136 V(OPTIMIZED, OptimizedFrame) \
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000137 V(INTERNAL, InternalFrame) \
ager@chromium.org7c537e22008-10-16 08:43:32 +0000138 V(CONSTRUCT, ConstructFrame) \
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000139 V(ARGUMENTS_ADAPTOR, ArgumentsAdaptorFrame)
140
141
142// Abstract base class for all stack frames.
143class StackFrame BASE_EMBEDDED {
144 public:
145#define DECLARE_TYPE(type, ignore) type,
146 enum Type {
147 NONE = 0,
148 STACK_FRAME_TYPE_LIST(DECLARE_TYPE)
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +0000149 NUMBER_OF_TYPES,
150 // Used by FrameScope to indicate that the stack frame is constructed
151 // manually and the FrameScope does not need to emit code.
152 MANUAL
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000153 };
154#undef DECLARE_TYPE
155
156 // Opaque data type for identifying stack frames. Used extensively
157 // by the debugger.
ricow@chromium.org0b9f8502010-08-18 07:45:01 +0000158 // ID_MIN_VALUE and ID_MAX_VALUE are specified to ensure that enumeration type
159 // has correct value range (see Issue 830 for more details).
160 enum Id {
161 ID_MIN_VALUE = kMinInt,
162 ID_MAX_VALUE = kMaxInt,
163 NO_ID = 0
164 };
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000165
kmillikin@chromium.orgc53e10d2011-05-18 09:12:58 +0000166 // Used to mark the outermost JS entry frame.
167 enum JsFrameMarker {
168 INNER_JSENTRY_FRAME = 0,
169 OUTERMOST_JSENTRY_FRAME = 1
170 };
171
fschneider@chromium.orgc20610a2010-09-22 09:44:58 +0000172 struct State {
173 State() : sp(NULL), fp(NULL), pc_address(NULL) { }
174 Address sp;
175 Address fp;
176 Address* pc_address;
177 };
178
vegorov@chromium.org74f333b2011-04-06 11:17:46 +0000179 // Copy constructor; it breaks the connection to host iterator
180 // (as an iterator usually lives on stack).
ager@chromium.org357bf652010-04-12 11:30:10 +0000181 StackFrame(const StackFrame& original) {
182 this->state_ = original.state_;
183 this->iterator_ = NULL;
vegorov@chromium.org74f333b2011-04-06 11:17:46 +0000184 this->isolate_ = original.isolate_;
ager@chromium.org357bf652010-04-12 11:30:10 +0000185 }
186
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000187 // Type testers.
188 bool is_entry() const { return type() == ENTRY; }
189 bool is_entry_construct() const { return type() == ENTRY_CONSTRUCT; }
190 bool is_exit() const { return type() == EXIT; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000191 bool is_optimized() const { return type() == OPTIMIZED; }
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000192 bool is_arguments_adaptor() const { return type() == ARGUMENTS_ADAPTOR; }
193 bool is_internal() const { return type() == INTERNAL; }
ager@chromium.org7c537e22008-10-16 08:43:32 +0000194 bool is_construct() const { return type() == CONSTRUCT; }
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000195 virtual bool is_standard() const { return false; }
196
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000197 bool is_java_script() const {
198 Type type = this->type();
199 return (type == JAVA_SCRIPT) || (type == OPTIMIZED);
200 }
201
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000202 // Accessors.
203 Address sp() const { return state_.sp; }
204 Address fp() const { return state_.fp; }
ager@chromium.orgeadaf222009-06-16 09:43:10 +0000205 Address caller_sp() const { return GetCallerStackPointer(); }
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000206
207 Address pc() const { return *pc_address(); }
208 void set_pc(Address pc) { *pc_address() = pc; }
209
ager@chromium.org357bf652010-04-12 11:30:10 +0000210 virtual void SetCallerFp(Address caller_fp) = 0;
211
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000212 Address* pc_address() const { return state_.pc_address; }
213
214 // Get the id of this stack frame.
ager@chromium.orgeadaf222009-06-16 09:43:10 +0000215 Id id() const { return static_cast<Id>(OffsetFrom(caller_sp())); }
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000216
217 // Checks if this frame includes any stack handlers.
218 bool HasHandler() const;
219
220 // Get the type of this frame.
221 virtual Type type() const = 0;
222
223 // Get the code associated with this frame.
ricow@chromium.org0b9f8502010-08-18 07:45:01 +0000224 // This method could be called during marking phase of GC.
225 virtual Code* unchecked_code() const = 0;
226
227 // Get the code associated with this frame.
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +0000228 inline Code* LookupCode() const;
ricow@chromium.orgd236f4d2010-09-01 06:52:08 +0000229
230 // Get the code object that contains the given pc.
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000231 static inline Code* GetContainingCode(Isolate* isolate, Address pc);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000232
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000233 // Get the code object containing the given pc and fill in the
234 // safepoint entry and the number of stack slots. The pc must be at
235 // a safepoint.
vegorov@chromium.org74f333b2011-04-06 11:17:46 +0000236 static Code* GetSafepointData(Isolate* isolate,
237 Address pc,
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +0000238 SafepointEntry* safepoint_entry,
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000239 unsigned* stack_slots);
240
ricow@chromium.orgd236f4d2010-09-01 06:52:08 +0000241 virtual void Iterate(ObjectVisitor* v) const = 0;
242 static void IteratePc(ObjectVisitor* v, Address* pc_address, Code* holder);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000243
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000244
245 // Printing support.
246 enum PrintMode { OVERVIEW, DETAILS };
247 virtual void Print(StringStream* accumulator,
248 PrintMode mode,
249 int index) const { }
250
251 protected:
vegorov@chromium.org74f333b2011-04-06 11:17:46 +0000252 inline explicit StackFrame(StackFrameIterator* iterator);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000253 virtual ~StackFrame() { }
254
vegorov@chromium.org74f333b2011-04-06 11:17:46 +0000255 Isolate* isolate() const { return isolate_; }
256
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000257 // Compute the stack pointer for the calling frame.
258 virtual Address GetCallerStackPointer() const = 0;
259
260 // Printing support.
261 static void PrintIndex(StringStream* accumulator,
262 PrintMode mode,
263 int index);
264
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000265 // Get the top handler from the current stack iterator.
266 inline StackHandler* top_handler() const;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000267
268 // Compute the stack frame type for the given state.
vegorov@chromium.org74f333b2011-04-06 11:17:46 +0000269 static Type ComputeType(Isolate* isolate, State* state);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000270
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000271 private:
272 const StackFrameIterator* iterator_;
vegorov@chromium.org74f333b2011-04-06 11:17:46 +0000273 Isolate* isolate_;
kasperl@chromium.orgb9123622008-09-17 14:05:56 +0000274 State state_;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000275
ager@chromium.orgbb29dc92009-03-24 13:25:23 +0000276 // Fill in the state of the calling frame.
277 virtual void ComputeCallerState(State* state) const = 0;
278
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000279 // Get the type and the state of the calling frame.
ager@chromium.orgbb29dc92009-03-24 13:25:23 +0000280 virtual Type GetCallerState(State* state) const;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000281
vegorov@chromium.org74f333b2011-04-06 11:17:46 +0000282 static const intptr_t kIsolateTag = 1;
283
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000284 friend class StackFrameIterator;
285 friend class StackHandlerIterator;
ager@chromium.orgbb29dc92009-03-24 13:25:23 +0000286 friend class SafeStackFrameIterator;
mads.s.ager31e71382008-08-13 09:32:07 +0000287
ager@chromium.org357bf652010-04-12 11:30:10 +0000288 private:
289 void operator=(const StackFrame& original);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000290};
291
292
293// Entry frames are used to enter JavaScript execution from C.
294class EntryFrame: public StackFrame {
295 public:
296 virtual Type type() const { return ENTRY; }
297
ricow@chromium.org0b9f8502010-08-18 07:45:01 +0000298 virtual Code* unchecked_code() const;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000299
300 // Garbage collection support.
301 virtual void Iterate(ObjectVisitor* v) const;
302
303 static EntryFrame* cast(StackFrame* frame) {
304 ASSERT(frame->is_entry());
305 return static_cast<EntryFrame*>(frame);
306 }
ager@chromium.org357bf652010-04-12 11:30:10 +0000307 virtual void SetCallerFp(Address caller_fp);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000308
309 protected:
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +0000310 inline explicit EntryFrame(StackFrameIterator* iterator);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000311
312 // The caller stack pointer for entry frames is always zero. The
313 // real information about the caller frame is available through the
314 // link to the top exit frame.
315 virtual Address GetCallerStackPointer() const { return 0; }
316
317 private:
ager@chromium.orgbb29dc92009-03-24 13:25:23 +0000318 virtual void ComputeCallerState(State* state) const;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000319 virtual Type GetCallerState(State* state) const;
320
321 friend class StackFrameIterator;
322};
323
324
325class EntryConstructFrame: public EntryFrame {
326 public:
327 virtual Type type() const { return ENTRY_CONSTRUCT; }
328
ricow@chromium.org0b9f8502010-08-18 07:45:01 +0000329 virtual Code* unchecked_code() const;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000330
331 static EntryConstructFrame* cast(StackFrame* frame) {
332 ASSERT(frame->is_entry_construct());
333 return static_cast<EntryConstructFrame*>(frame);
334 }
335
336 protected:
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +0000337 inline explicit EntryConstructFrame(StackFrameIterator* iterator);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000338
339 private:
340 friend class StackFrameIterator;
341};
342
343
344// Exit frames are used to exit JavaScript execution and go to C.
345class ExitFrame: public StackFrame {
346 public:
347 virtual Type type() const { return EXIT; }
348
ricow@chromium.org0b9f8502010-08-18 07:45:01 +0000349 virtual Code* unchecked_code() const;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000350
ager@chromium.orgc4c92722009-11-18 14:12:51 +0000351 Object*& code_slot() const;
352
ager@chromium.org32912102009-01-16 10:38:43 +0000353 // Garbage collection support.
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000354 virtual void Iterate(ObjectVisitor* v) const;
355
ager@chromium.org357bf652010-04-12 11:30:10 +0000356 virtual void SetCallerFp(Address caller_fp);
357
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000358 static ExitFrame* cast(StackFrame* frame) {
359 ASSERT(frame->is_exit());
360 return static_cast<ExitFrame*>(frame);
361 }
362
363 // Compute the state and type of an exit frame given a frame
364 // pointer. Used when constructing the first stack frame seen by an
365 // iterator and the frames following entry frames.
366 static Type GetStateForFramePointer(Address fp, State* state);
fschneider@chromium.orgc20610a2010-09-22 09:44:58 +0000367 static Address ComputeStackPointer(Address fp);
368 static void FillState(Address fp, Address sp, State* state);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000369
370 protected:
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +0000371 inline explicit ExitFrame(StackFrameIterator* iterator);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000372
373 virtual Address GetCallerStackPointer() const;
374
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000375 private:
ager@chromium.orgbb29dc92009-03-24 13:25:23 +0000376 virtual void ComputeCallerState(State* state) const;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000377
378 friend class StackFrameIterator;
379};
380
381
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000382class StandardFrame: public StackFrame {
383 public:
384 // Testers.
385 virtual bool is_standard() const { return true; }
386
387 // Accessors.
388 inline Object* context() const;
389
390 // Access the expressions in the stack frame including locals.
391 inline Object* GetExpression(int index) const;
392 inline void SetExpression(int index, Object* value);
393 int ComputeExpressionsCount() const;
ricow@chromium.org4f693d62011-07-04 14:01:31 +0000394 static Object* GetExpression(Address fp, int index);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000395
ager@chromium.org357bf652010-04-12 11:30:10 +0000396 virtual void SetCallerFp(Address caller_fp);
397
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000398 static StandardFrame* cast(StackFrame* frame) {
399 ASSERT(frame->is_standard());
400 return static_cast<StandardFrame*>(frame);
401 }
402
403 protected:
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +0000404 inline explicit StandardFrame(StackFrameIterator* iterator);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000405
ager@chromium.orgbb29dc92009-03-24 13:25:23 +0000406 virtual void ComputeCallerState(State* state) const;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000407
408 // Accessors.
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000409 inline Address caller_fp() const;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000410 inline Address caller_pc() const;
411
412 // Computes the address of the PC field in the standard frame given
413 // by the provided frame pointer.
414 static inline Address ComputePCAddress(Address fp);
415
416 // Iterate over expression stack including stack handlers, locals,
417 // and parts of the fixed part including context and code fields.
418 void IterateExpressions(ObjectVisitor* v) const;
419
420 // Returns the address of the n'th expression stack element.
421 Address GetExpressionAddress(int n) const;
ricow@chromium.org4f693d62011-07-04 14:01:31 +0000422 static Address GetExpressionAddress(Address fp, int n);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000423
424 // Determines if the n'th expression stack element is in a stack
425 // handler or not. Requires traversing all handlers in this frame.
426 bool IsExpressionInsideHandler(int n) const;
427
428 // Determines if the standard frame for the given frame pointer is
429 // an arguments adaptor frame.
430 static inline bool IsArgumentsAdaptorFrame(Address fp);
431
ager@chromium.org7c537e22008-10-16 08:43:32 +0000432 // Determines if the standard frame for the given frame pointer is a
433 // construct frame.
434 static inline bool IsConstructFrame(Address fp);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000435
436 private:
437 friend class StackFrame;
sgjesse@chromium.org720dc0b2010-05-10 09:25:39 +0000438 friend class StackFrameIterator;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000439};
440
441
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000442class FrameSummary BASE_EMBEDDED {
443 public:
444 FrameSummary(Object* receiver,
445 JSFunction* function,
446 Code* code,
447 int offset,
448 bool is_constructor)
449 : receiver_(receiver),
450 function_(function),
451 code_(code),
452 offset_(offset),
453 is_constructor_(is_constructor) { }
454 Handle<Object> receiver() { return receiver_; }
455 Handle<JSFunction> function() { return function_; }
456 Handle<Code> code() { return code_; }
kmillikin@chromium.orgc36ce6e2011-04-04 08:25:31 +0000457 Address pc() { return code_->address() + offset_; }
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000458 int offset() { return offset_; }
459 bool is_constructor() { return is_constructor_; }
460
461 void Print();
462
463 private:
464 Handle<Object> receiver_;
465 Handle<JSFunction> function_;
466 Handle<Code> code_;
467 int offset_;
468 bool is_constructor_;
469};
470
471
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000472class JavaScriptFrame: public StandardFrame {
473 public:
474 virtual Type type() const { return JAVA_SCRIPT; }
475
476 // Accessors.
477 inline Object* function() const;
478 inline Object* receiver() const;
479 inline void set_receiver(Object* value);
480
481 // Access the parameters.
karlklose@chromium.org44bc7082011-04-11 12:33:05 +0000482 inline Address GetParameterSlot(int index) const;
483 inline Object* GetParameter(int index) const;
484 inline int ComputeParametersCount() const {
485 return GetNumberOfIncomingArguments();
486 }
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000487
ager@chromium.org7c537e22008-10-16 08:43:32 +0000488 // Check if this frame is a constructor frame invoked through 'new'.
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000489 bool IsConstructor() const;
490
491 // Check if this frame has "adapted" arguments in the sense that the
492 // actual passed arguments are available in an arguments adaptor
493 // frame below it on the stack.
494 inline bool has_adapted_arguments() const;
ricow@chromium.org4f693d62011-07-04 14:01:31 +0000495 int GetArgumentsLength() const;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000496
ager@chromium.org32912102009-01-16 10:38:43 +0000497 // Garbage collection support.
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000498 virtual void Iterate(ObjectVisitor* v) const;
499
500 // Printing support.
501 virtual void Print(StringStream* accumulator,
502 PrintMode mode,
503 int index) const;
504
505 // Determine the code for the frame.
ricow@chromium.org0b9f8502010-08-18 07:45:01 +0000506 virtual Code* unchecked_code() const;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000507
ricow@chromium.org4f693d62011-07-04 14:01:31 +0000508 // Returns the levels of inlining for this frame.
509 virtual int GetInlineCount() { return 1; }
510
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000511 // Return a list with JSFunctions of this frame.
512 virtual void GetFunctions(List<JSFunction*>* functions);
513
514 // Build a list with summaries for this frame including all inlined frames.
515 virtual void Summarize(List<FrameSummary>* frames);
516
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000517 static JavaScriptFrame* cast(StackFrame* frame) {
518 ASSERT(frame->is_java_script());
519 return static_cast<JavaScriptFrame*>(frame);
520 }
521
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +0000522 static void PrintTop(FILE* file, bool print_args, bool print_line_number);
523
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000524 protected:
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +0000525 inline explicit JavaScriptFrame(StackFrameIterator* iterator);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000526
527 virtual Address GetCallerStackPointer() const;
528
karlklose@chromium.org44bc7082011-04-11 12:33:05 +0000529 virtual int GetNumberOfIncomingArguments() const;
530
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000531 // Garbage collection support. Iterates over incoming arguments,
532 // receiver, and any callee-saved registers.
533 void IterateArguments(ObjectVisitor* v) const;
534
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000535 private:
ager@chromium.orgbb29dc92009-03-24 13:25:23 +0000536 inline Object* function_slot_object() const;
537
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000538 friend class StackFrameIterator;
fschneider@chromium.orgc20610a2010-09-22 09:44:58 +0000539 friend class StackTracer;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000540};
541
542
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000543class OptimizedFrame : public JavaScriptFrame {
544 public:
545 virtual Type type() const { return OPTIMIZED; }
546
547 // GC support.
548 virtual void Iterate(ObjectVisitor* v) const;
549
ricow@chromium.org4f693d62011-07-04 14:01:31 +0000550 virtual int GetInlineCount();
551
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000552 // Return a list with JSFunctions of this frame.
553 // The functions are ordered bottom-to-top (i.e. functions.last()
554 // is the top-most activation)
555 virtual void GetFunctions(List<JSFunction*>* functions);
556
557 virtual void Summarize(List<FrameSummary>* frames);
558
559 DeoptimizationInputData* GetDeoptimizationData(int* deopt_index);
560
561 protected:
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +0000562 inline explicit OptimizedFrame(StackFrameIterator* iterator);
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000563
564 private:
565 friend class StackFrameIterator;
566};
567
568
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000569// Arguments adaptor frames are automatically inserted below
570// JavaScript frames when the actual number of parameters does not
571// match the formal number of parameters.
572class ArgumentsAdaptorFrame: public JavaScriptFrame {
573 public:
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000574 virtual Type type() const { return ARGUMENTS_ADAPTOR; }
575
576 // Determine the code for the frame.
ricow@chromium.org0b9f8502010-08-18 07:45:01 +0000577 virtual Code* unchecked_code() const;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000578
579 static ArgumentsAdaptorFrame* cast(StackFrame* frame) {
580 ASSERT(frame->is_arguments_adaptor());
581 return static_cast<ArgumentsAdaptorFrame*>(frame);
582 }
583
584 // Printing support.
585 virtual void Print(StringStream* accumulator,
586 PrintMode mode,
587 int index) const;
kmillikin@chromium.org83e16822011-09-13 08:21:47 +0000588
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000589 protected:
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +0000590 inline explicit ArgumentsAdaptorFrame(StackFrameIterator* iterator);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000591
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +0000592 virtual int GetNumberOfIncomingArguments() const;
karlklose@chromium.org44bc7082011-04-11 12:33:05 +0000593
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000594 virtual Address GetCallerStackPointer() const;
595
596 private:
597 friend class StackFrameIterator;
598};
599
600
601class InternalFrame: public StandardFrame {
602 public:
603 virtual Type type() const { return INTERNAL; }
604
ager@chromium.org32912102009-01-16 10:38:43 +0000605 // Garbage collection support.
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000606 virtual void Iterate(ObjectVisitor* v) const;
607
608 // Determine the code for the frame.
ricow@chromium.org0b9f8502010-08-18 07:45:01 +0000609 virtual Code* unchecked_code() const;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000610
611 static InternalFrame* cast(StackFrame* frame) {
612 ASSERT(frame->is_internal());
613 return static_cast<InternalFrame*>(frame);
614 }
615
616 protected:
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +0000617 inline explicit InternalFrame(StackFrameIterator* iterator);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000618
619 virtual Address GetCallerStackPointer() const;
620
621 private:
622 friend class StackFrameIterator;
623};
624
625
ager@chromium.org7c537e22008-10-16 08:43:32 +0000626// Construct frames are special trampoline frames introduced to handle
627// function invocations through 'new'.
628class ConstructFrame: public InternalFrame {
629 public:
630 virtual Type type() const { return CONSTRUCT; }
631
632 static ConstructFrame* cast(StackFrame* frame) {
633 ASSERT(frame->is_construct());
634 return static_cast<ConstructFrame*>(frame);
635 }
636
637 protected:
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +0000638 inline explicit ConstructFrame(StackFrameIterator* iterator);
ager@chromium.org7c537e22008-10-16 08:43:32 +0000639
640 private:
641 friend class StackFrameIterator;
642};
643
644
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000645class StackFrameIterator BASE_EMBEDDED {
646 public:
vegorov@chromium.org74f333b2011-04-06 11:17:46 +0000647 // An iterator that iterates over the current thread's stack,
648 // and uses current isolate.
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000649 StackFrameIterator();
650
vegorov@chromium.org74f333b2011-04-06 11:17:46 +0000651 // An iterator that iterates over the isolate's current thread's stack,
652 explicit StackFrameIterator(Isolate* isolate);
653
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000654 // An iterator that iterates over a given thread's stack.
vegorov@chromium.org74f333b2011-04-06 11:17:46 +0000655 StackFrameIterator(Isolate* isolate, ThreadLocalTop* t);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000656
ager@chromium.orgbb29dc92009-03-24 13:25:23 +0000657 // An iterator that can start from a given FP address.
658 // If use_top, then work as usual, if fp isn't NULL, use it,
659 // otherwise, do nothing.
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000660 StackFrameIterator(Isolate* isolate, bool use_top, Address fp, Address sp);
kasperl@chromium.org7be3c992009-03-12 07:19:55 +0000661
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000662 StackFrame* frame() const {
663 ASSERT(!done());
664 return frame_;
665 }
666
vegorov@chromium.org74f333b2011-04-06 11:17:46 +0000667 Isolate* isolate() const { return isolate_; }
668
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000669 bool done() const { return frame_ == NULL; }
ager@chromium.orgbb29dc92009-03-24 13:25:23 +0000670 void Advance() { (this->*advance_)(); }
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000671
672 // Go back to the first frame.
673 void Reset();
674
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000675 private:
vegorov@chromium.org74f333b2011-04-06 11:17:46 +0000676 Isolate* isolate_;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000677#define DECLARE_SINGLETON(ignore, type) type type##_;
678 STACK_FRAME_TYPE_LIST(DECLARE_SINGLETON)
679#undef DECLARE_SINGLETON
680 StackFrame* frame_;
681 StackHandler* handler_;
kasper.lund7276f142008-07-30 08:49:36 +0000682 ThreadLocalTop* thread_;
ager@chromium.orgbb29dc92009-03-24 13:25:23 +0000683 Address fp_;
684 Address sp_;
685 void (StackFrameIterator::*advance_)();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000686
687 StackHandler* handler() const {
688 ASSERT(!done());
689 return handler_;
690 }
691
692 // Get the type-specific frame singleton in a given state.
693 StackFrame* SingletonFor(StackFrame::Type type, StackFrame::State* state);
ager@chromium.orgbb29dc92009-03-24 13:25:23 +0000694 // A helper function, can return a NULL pointer.
695 StackFrame* SingletonFor(StackFrame::Type type);
696
697 void AdvanceWithHandler();
698 void AdvanceWithoutHandler();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000699
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000700 friend class StackFrame;
ager@chromium.orgbb29dc92009-03-24 13:25:23 +0000701 friend class SafeStackFrameIterator;
mads.s.ager@gmail.com9a4089a2008-09-01 08:55:01 +0000702 DISALLOW_COPY_AND_ASSIGN(StackFrameIterator);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000703};
704
705
706// Iterator that supports iterating through all JavaScript frames.
kasperl@chromium.org7be3c992009-03-12 07:19:55 +0000707template<typename Iterator>
708class JavaScriptFrameIteratorTemp BASE_EMBEDDED {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000709 public:
kasperl@chromium.org7be3c992009-03-12 07:19:55 +0000710 JavaScriptFrameIteratorTemp() { if (!done()) Advance(); }
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000711
vegorov@chromium.org74f333b2011-04-06 11:17:46 +0000712 inline explicit JavaScriptFrameIteratorTemp(Isolate* isolate);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000713
rossberg@chromium.orgb4b2aa62011-10-13 09:49:59 +0000714 inline JavaScriptFrameIteratorTemp(Isolate* isolate, ThreadLocalTop* top);
715
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000716 // Skip frames until the frame with the given id is reached.
vegorov@chromium.org74f333b2011-04-06 11:17:46 +0000717 explicit JavaScriptFrameIteratorTemp(StackFrame::Id id) { AdvanceToId(id); }
718
719 inline JavaScriptFrameIteratorTemp(Isolate* isolate, StackFrame::Id id);
kasperl@chromium.org7be3c992009-03-12 07:19:55 +0000720
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +0000721 JavaScriptFrameIteratorTemp(Address fp,
722 Address sp,
723 Address low_bound,
724 Address high_bound) :
ager@chromium.orgbb29dc92009-03-24 13:25:23 +0000725 iterator_(fp, sp, low_bound, high_bound) {
726 if (!done()) Advance();
727 }
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000728
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000729 JavaScriptFrameIteratorTemp(Isolate* isolate,
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +0000730 Address fp,
731 Address sp,
732 Address low_bound,
733 Address high_bound) :
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000734 iterator_(isolate, fp, sp, low_bound, high_bound) {
735 if (!done()) Advance();
736 }
737
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000738 inline JavaScriptFrame* frame() const;
739
740 bool done() const { return iterator_.done(); }
741 void Advance();
742
743 // Advance to the frame holding the arguments for the current
744 // frame. This only affects the current frame if it has adapted
745 // arguments.
746 void AdvanceToArgumentsFrame();
747
748 // Go back to the first frame.
749 void Reset();
750
751 private:
vegorov@chromium.org74f333b2011-04-06 11:17:46 +0000752 inline void AdvanceToId(StackFrame::Id id);
753
kasperl@chromium.org7be3c992009-03-12 07:19:55 +0000754 Iterator iterator_;
755};
756
757
758typedef JavaScriptFrameIteratorTemp<StackFrameIterator> JavaScriptFrameIterator;
759
760
761// NOTE: The stack trace frame iterator is an iterator that only
762// traverse proper JavaScript frames; that is JavaScript frames that
763// have proper JavaScript functions. This excludes the problematic
764// functions in runtime.js.
765class StackTraceFrameIterator: public JavaScriptFrameIterator {
766 public:
767 StackTraceFrameIterator();
vegorov@chromium.org74f333b2011-04-06 11:17:46 +0000768 explicit StackTraceFrameIterator(Isolate* isolate);
kasperl@chromium.org7be3c992009-03-12 07:19:55 +0000769 void Advance();
sgjesse@chromium.orgb302e562010-02-03 11:26:59 +0000770
771 private:
772 bool IsValidFrame();
kasperl@chromium.org7be3c992009-03-12 07:19:55 +0000773};
774
775
776class SafeStackFrameIterator BASE_EMBEDDED {
777 public:
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000778 SafeStackFrameIterator(Isolate* isolate,
779 Address fp, Address sp,
ager@chromium.orgbb29dc92009-03-24 13:25:23 +0000780 Address low_bound, Address high_bound);
kasperl@chromium.org7be3c992009-03-12 07:19:55 +0000781
782 StackFrame* frame() const {
783 ASSERT(is_working_iterator_);
784 return iterator_.frame();
785 }
786
787 bool done() const { return iteration_done_ ? true : iterator_.done(); }
788
789 void Advance();
790 void Reset();
791
vegorov@chromium.org74f333b2011-04-06 11:17:46 +0000792 static bool is_active(Isolate* isolate);
ricow@chromium.orgd236f4d2010-09-01 06:52:08 +0000793
ager@chromium.orgbb29dc92009-03-24 13:25:23 +0000794 static bool IsWithinBounds(
kasperl@chromium.org7be3c992009-03-12 07:19:55 +0000795 Address low_bound, Address high_bound, Address addr) {
796 return low_bound <= addr && addr <= high_bound;
797 }
sgjesse@chromium.orgb302e562010-02-03 11:26:59 +0000798
799 private:
fschneider@chromium.orgc20610a2010-09-22 09:44:58 +0000800 class StackAddressValidator {
801 public:
802 StackAddressValidator(Address low_bound, Address high_bound)
803 : low_bound_(low_bound), high_bound_(high_bound) { }
804 bool IsValid(Address addr) const {
805 return IsWithinBounds(low_bound_, high_bound_, addr);
806 }
807 private:
808 Address low_bound_;
809 Address high_bound_;
810 };
811
812 class ExitFrameValidator {
813 public:
814 explicit ExitFrameValidator(const StackAddressValidator& validator)
815 : validator_(validator) { }
816 ExitFrameValidator(Address low_bound, Address high_bound)
817 : validator_(low_bound, high_bound) { }
818 bool IsValidFP(Address fp);
819 private:
820 StackAddressValidator validator_;
821 };
822
ager@chromium.orgbb29dc92009-03-24 13:25:23 +0000823 bool IsValidStackAddress(Address addr) const {
fschneider@chromium.orgc20610a2010-09-22 09:44:58 +0000824 return stack_validator_.IsValid(addr);
kasperl@chromium.org7be3c992009-03-12 07:19:55 +0000825 }
kasperl@chromium.orgd1e3e722009-04-14 13:38:25 +0000826 bool CanIterateHandles(StackFrame* frame, StackHandler* handler);
ager@chromium.orgbb29dc92009-03-24 13:25:23 +0000827 bool IsValidFrame(StackFrame* frame) const;
828 bool IsValidCaller(StackFrame* frame);
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000829 static bool IsValidTop(Isolate* isolate,
830 Address low_bound, Address high_bound);
kasperl@chromium.org7be3c992009-03-12 07:19:55 +0000831
ricow@chromium.orgd236f4d2010-09-01 06:52:08 +0000832 // This is a nasty hack to make sure the active count is incremented
833 // before the constructor for the embedded iterator is invoked. This
834 // is needed because the constructor will start looking at frames
835 // right away and we need to make sure it doesn't start inspecting
836 // heap objects.
837 class ActiveCountMaintainer BASE_EMBEDDED {
838 public:
vegorov@chromium.org74f333b2011-04-06 11:17:46 +0000839 explicit ActiveCountMaintainer(Isolate* isolate);
840 ~ActiveCountMaintainer();
841 private:
842 Isolate* isolate_;
ricow@chromium.orgd236f4d2010-09-01 06:52:08 +0000843 };
844
845 ActiveCountMaintainer maintainer_;
fschneider@chromium.orgc20610a2010-09-22 09:44:58 +0000846 StackAddressValidator stack_validator_;
ager@chromium.orgbb29dc92009-03-24 13:25:23 +0000847 const bool is_valid_top_;
848 const bool is_valid_fp_;
kasperl@chromium.org7be3c992009-03-12 07:19:55 +0000849 const bool is_working_iterator_;
850 bool iteration_done_;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000851 StackFrameIterator iterator_;
852};
853
854
kasperl@chromium.org7be3c992009-03-12 07:19:55 +0000855typedef JavaScriptFrameIteratorTemp<SafeStackFrameIterator>
856 SafeJavaScriptFrameIterator;
857
858
859class SafeStackTraceFrameIterator: public SafeJavaScriptFrameIterator {
860 public:
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000861 explicit SafeStackTraceFrameIterator(Isolate* isolate,
862 Address fp, Address sp,
ager@chromium.orgbb29dc92009-03-24 13:25:23 +0000863 Address low_bound, Address high_bound);
kasperl@chromium.org7be3c992009-03-12 07:19:55 +0000864 void Advance();
865};
kasperl@chromium.org7be3c992009-03-12 07:19:55 +0000866
867
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000868class StackFrameLocator BASE_EMBEDDED {
869 public:
870 // Find the nth JavaScript frame on the stack. The caller must
871 // guarantee that such a frame exists.
872 JavaScriptFrame* FindJavaScriptFrame(int n);
873
874 private:
875 StackFrameIterator iterator_;
876};
877
878
ager@chromium.org357bf652010-04-12 11:30:10 +0000879// Reads all frames on the current stack and copies them into the current
880// zone memory.
881Vector<StackFrame*> CreateStackMap();
882
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000883} } // namespace v8::internal
884
885#endif // V8_FRAMES_H_