blob: 20111904f5afad572b3cb588ddff16e2ce42ca94 [file] [log] [blame]
Steve Blocka7e24c12009-10-30 11:49:00 +00001// Copyright 2006-2008 the V8 project authors. All rights reserved.
2// 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
31namespace v8 {
32namespace internal {
33
34typedef uint32_t RegList;
35
36// Get the number of registers in a given register list.
37int NumRegs(RegList list);
38
39// Return the code of the n-th saved register available to JavaScript.
40int JSCallerSavedCode(int n);
41
42
43// Forward declarations.
44class StackFrameIterator;
45class Top;
46class ThreadLocalTop;
47
48
Kristian Monsen80d68ea2010-09-08 11:05:35 +010049class PcToCodeCache : AllStatic {
50 public:
51 struct PcToCodeCacheEntry {
52 Address pc;
53 Code* code;
54 };
55
56 static PcToCodeCacheEntry* cache(int index) {
57 return &cache_[index];
58 }
59
60 static Code* GcSafeFindCodeForPc(Address pc);
61 static Code* GcSafeCastToCode(HeapObject* object, Address pc);
62
63 static void FlushPcToCodeCache() {
64 memset(&cache_[0], 0, sizeof(cache_));
65 }
66
67 static PcToCodeCacheEntry* GetCacheEntry(Address pc);
68
69 private:
70 static const int kPcToCodeCacheSize = 256;
71 static PcToCodeCacheEntry cache_[kPcToCodeCacheSize];
72};
73
74
Steve Blocka7e24c12009-10-30 11:49:00 +000075class StackHandler BASE_EMBEDDED {
76 public:
77 enum State {
78 ENTRY,
79 TRY_CATCH,
80 TRY_FINALLY
81 };
82
83 // Get the address of this stack handler.
84 inline Address address() const;
85
86 // Get the next stack handler in the chain.
87 inline StackHandler* next() const;
88
89 // Tells whether the given address is inside this handler.
90 inline bool includes(Address address) const;
91
92 // Garbage collection support.
Kristian Monsen80d68ea2010-09-08 11:05:35 +010093 inline void Iterate(ObjectVisitor* v, Code* holder) const;
Steve Blocka7e24c12009-10-30 11:49:00 +000094
95 // Conversion support.
96 static inline StackHandler* FromAddress(Address address);
97
98 // Testers
99 bool is_entry() { return state() == ENTRY; }
100 bool is_try_catch() { return state() == TRY_CATCH; }
101 bool is_try_finally() { return state() == TRY_FINALLY; }
102
Steve Blocka7e24c12009-10-30 11:49:00 +0000103 private:
104 // Accessors.
105 inline State state() const;
106
Kristian Monsen80d68ea2010-09-08 11:05:35 +0100107 inline Address* pc_address() const;
Steve Blocka7e24c12009-10-30 11:49:00 +0000108
109 DISALLOW_IMPLICIT_CONSTRUCTORS(StackHandler);
110};
111
112
113#define STACK_FRAME_TYPE_LIST(V) \
114 V(ENTRY, EntryFrame) \
115 V(ENTRY_CONSTRUCT, EntryConstructFrame) \
116 V(EXIT, ExitFrame) \
Steve Blocka7e24c12009-10-30 11:49:00 +0000117 V(JAVA_SCRIPT, JavaScriptFrame) \
118 V(INTERNAL, InternalFrame) \
119 V(CONSTRUCT, ConstructFrame) \
120 V(ARGUMENTS_ADAPTOR, ArgumentsAdaptorFrame)
121
122
123// Abstract base class for all stack frames.
124class StackFrame BASE_EMBEDDED {
125 public:
126#define DECLARE_TYPE(type, ignore) type,
127 enum Type {
128 NONE = 0,
129 STACK_FRAME_TYPE_LIST(DECLARE_TYPE)
130 NUMBER_OF_TYPES
131 };
132#undef DECLARE_TYPE
133
134 // Opaque data type for identifying stack frames. Used extensively
135 // by the debugger.
Iain Merrick75681382010-08-19 15:07:18 +0100136 // ID_MIN_VALUE and ID_MAX_VALUE are specified to ensure that enumeration type
137 // has correct value range (see Issue 830 for more details).
138 enum Id {
139 ID_MIN_VALUE = kMinInt,
140 ID_MAX_VALUE = kMaxInt,
141 NO_ID = 0
142 };
Steve Blocka7e24c12009-10-30 11:49:00 +0000143
Steve Block6ded16b2010-05-10 14:33:55 +0100144 // Copy constructor; it breaks the connection to host iterator.
145 StackFrame(const StackFrame& original) {
146 this->state_ = original.state_;
147 this->iterator_ = NULL;
148 }
149
Steve Blocka7e24c12009-10-30 11:49:00 +0000150 // Type testers.
151 bool is_entry() const { return type() == ENTRY; }
152 bool is_entry_construct() const { return type() == ENTRY_CONSTRUCT; }
153 bool is_exit() const { return type() == EXIT; }
Steve Blocka7e24c12009-10-30 11:49:00 +0000154 bool is_java_script() const { return type() == JAVA_SCRIPT; }
155 bool is_arguments_adaptor() const { return type() == ARGUMENTS_ADAPTOR; }
156 bool is_internal() const { return type() == INTERNAL; }
157 bool is_construct() const { return type() == CONSTRUCT; }
158 virtual bool is_standard() const { return false; }
159
160 // Accessors.
161 Address sp() const { return state_.sp; }
162 Address fp() const { return state_.fp; }
163 Address caller_sp() const { return GetCallerStackPointer(); }
164
165 Address pc() const { return *pc_address(); }
166 void set_pc(Address pc) { *pc_address() = pc; }
167
Steve Block6ded16b2010-05-10 14:33:55 +0100168 virtual void SetCallerFp(Address caller_fp) = 0;
169
Steve Blocka7e24c12009-10-30 11:49:00 +0000170 Address* pc_address() const { return state_.pc_address; }
171
172 // Get the id of this stack frame.
173 Id id() const { return static_cast<Id>(OffsetFrom(caller_sp())); }
174
175 // Checks if this frame includes any stack handlers.
176 bool HasHandler() const;
177
178 // Get the type of this frame.
179 virtual Type type() const = 0;
180
181 // Get the code associated with this frame.
Iain Merrick75681382010-08-19 15:07:18 +0100182 // This method could be called during marking phase of GC.
183 virtual Code* unchecked_code() const = 0;
184
185 // Get the code associated with this frame.
Kristian Monsen80d68ea2010-09-08 11:05:35 +0100186 Code* code() const { return GetContainingCode(pc()); }
187
188 // Get the code object that contains the given pc.
189 Code* GetContainingCode(Address pc) const {
190 return PcToCodeCache::GetCacheEntry(pc)->code;
Iain Merrick75681382010-08-19 15:07:18 +0100191 }
Steve Blocka7e24c12009-10-30 11:49:00 +0000192
Kristian Monsen80d68ea2010-09-08 11:05:35 +0100193 virtual void Iterate(ObjectVisitor* v) const = 0;
194 static void IteratePc(ObjectVisitor* v, Address* pc_address, Code* holder);
Steve Blocka7e24c12009-10-30 11:49:00 +0000195
Steve Blocka7e24c12009-10-30 11:49:00 +0000196
197 // Printing support.
198 enum PrintMode { OVERVIEW, DETAILS };
199 virtual void Print(StringStream* accumulator,
200 PrintMode mode,
201 int index) const { }
202
203 protected:
204 struct State {
205 Address sp;
206 Address fp;
207 Address* pc_address;
208 };
209
210 explicit StackFrame(StackFrameIterator* iterator) : iterator_(iterator) { }
211 virtual ~StackFrame() { }
212
213 // Compute the stack pointer for the calling frame.
214 virtual Address GetCallerStackPointer() const = 0;
215
216 // Printing support.
217 static void PrintIndex(StringStream* accumulator,
218 PrintMode mode,
219 int index);
220
221 // Get the top handler from the current stack iterator.
222 inline StackHandler* top_handler() const;
223
224 // Compute the stack frame type for the given state.
225 static Type ComputeType(State* state);
226
227 private:
228 const StackFrameIterator* iterator_;
229 State state_;
230
231 // Fill in the state of the calling frame.
232 virtual void ComputeCallerState(State* state) const = 0;
233
234 // Get the type and the state of the calling frame.
235 virtual Type GetCallerState(State* state) const;
236
Steve Blocka7e24c12009-10-30 11:49:00 +0000237 friend class StackFrameIterator;
238 friend class StackHandlerIterator;
239 friend class SafeStackFrameIterator;
240
Steve Block6ded16b2010-05-10 14:33:55 +0100241 private:
242 void operator=(const StackFrame& original);
Steve Blocka7e24c12009-10-30 11:49:00 +0000243};
244
245
246// Entry frames are used to enter JavaScript execution from C.
247class EntryFrame: public StackFrame {
248 public:
249 virtual Type type() const { return ENTRY; }
250
Iain Merrick75681382010-08-19 15:07:18 +0100251 virtual Code* unchecked_code() const;
Steve Blocka7e24c12009-10-30 11:49:00 +0000252
253 // Garbage collection support.
254 virtual void Iterate(ObjectVisitor* v) const;
255
256 static EntryFrame* cast(StackFrame* frame) {
257 ASSERT(frame->is_entry());
258 return static_cast<EntryFrame*>(frame);
259 }
Steve Block6ded16b2010-05-10 14:33:55 +0100260 virtual void SetCallerFp(Address caller_fp);
Steve Blocka7e24c12009-10-30 11:49:00 +0000261
262 protected:
263 explicit EntryFrame(StackFrameIterator* iterator) : StackFrame(iterator) { }
264
265 // The caller stack pointer for entry frames is always zero. The
266 // real information about the caller frame is available through the
267 // link to the top exit frame.
268 virtual Address GetCallerStackPointer() const { return 0; }
269
270 private:
271 virtual void ComputeCallerState(State* state) const;
272 virtual Type GetCallerState(State* state) const;
273
274 friend class StackFrameIterator;
275};
276
277
278class EntryConstructFrame: public EntryFrame {
279 public:
280 virtual Type type() const { return ENTRY_CONSTRUCT; }
281
Iain Merrick75681382010-08-19 15:07:18 +0100282 virtual Code* unchecked_code() const;
Steve Blocka7e24c12009-10-30 11:49:00 +0000283
284 static EntryConstructFrame* cast(StackFrame* frame) {
285 ASSERT(frame->is_entry_construct());
286 return static_cast<EntryConstructFrame*>(frame);
287 }
288
289 protected:
290 explicit EntryConstructFrame(StackFrameIterator* iterator)
291 : EntryFrame(iterator) { }
292
293 private:
294 friend class StackFrameIterator;
295};
296
297
298// Exit frames are used to exit JavaScript execution and go to C.
299class ExitFrame: public StackFrame {
300 public:
301 virtual Type type() const { return EXIT; }
302
Iain Merrick75681382010-08-19 15:07:18 +0100303 virtual Code* unchecked_code() const;
Steve Blocka7e24c12009-10-30 11:49:00 +0000304
Steve Blockd0582a62009-12-15 09:54:21 +0000305 Object*& code_slot() const;
306
Steve Blocka7e24c12009-10-30 11:49:00 +0000307 // Garbage collection support.
308 virtual void Iterate(ObjectVisitor* v) const;
309
Steve Block6ded16b2010-05-10 14:33:55 +0100310 virtual void SetCallerFp(Address caller_fp);
311
Steve Blocka7e24c12009-10-30 11:49:00 +0000312 static ExitFrame* cast(StackFrame* frame) {
313 ASSERT(frame->is_exit());
314 return static_cast<ExitFrame*>(frame);
315 }
316
317 // Compute the state and type of an exit frame given a frame
318 // pointer. Used when constructing the first stack frame seen by an
319 // iterator and the frames following entry frames.
320 static Type GetStateForFramePointer(Address fp, State* state);
321
322 protected:
323 explicit ExitFrame(StackFrameIterator* iterator) : StackFrame(iterator) { }
324
325 virtual Address GetCallerStackPointer() const;
326
327 private:
328 virtual void ComputeCallerState(State* state) const;
329
330 friend class StackFrameIterator;
331};
332
333
Steve Blocka7e24c12009-10-30 11:49:00 +0000334class StandardFrame: public StackFrame {
335 public:
336 // Testers.
337 virtual bool is_standard() const { return true; }
338
339 // Accessors.
340 inline Object* context() const;
341
342 // Access the expressions in the stack frame including locals.
343 inline Object* GetExpression(int index) const;
344 inline void SetExpression(int index, Object* value);
345 int ComputeExpressionsCount() const;
346
Steve Block6ded16b2010-05-10 14:33:55 +0100347 virtual void SetCallerFp(Address caller_fp);
348
Steve Blocka7e24c12009-10-30 11:49:00 +0000349 static StandardFrame* cast(StackFrame* frame) {
350 ASSERT(frame->is_standard());
351 return static_cast<StandardFrame*>(frame);
352 }
353
354 protected:
355 explicit StandardFrame(StackFrameIterator* iterator)
356 : StackFrame(iterator) { }
357
358 virtual void ComputeCallerState(State* state) const;
359
360 // Accessors.
361 inline Address caller_fp() const;
362 inline Address caller_pc() const;
363
364 // Computes the address of the PC field in the standard frame given
365 // by the provided frame pointer.
366 static inline Address ComputePCAddress(Address fp);
367
368 // Iterate over expression stack including stack handlers, locals,
369 // and parts of the fixed part including context and code fields.
370 void IterateExpressions(ObjectVisitor* v) const;
371
372 // Returns the address of the n'th expression stack element.
373 Address GetExpressionAddress(int n) const;
374
375 // Determines if the n'th expression stack element is in a stack
376 // handler or not. Requires traversing all handlers in this frame.
377 bool IsExpressionInsideHandler(int n) const;
378
379 // Determines if the standard frame for the given frame pointer is
380 // an arguments adaptor frame.
381 static inline bool IsArgumentsAdaptorFrame(Address fp);
382
383 // Determines if the standard frame for the given frame pointer is a
384 // construct frame.
385 static inline bool IsConstructFrame(Address fp);
386
387 private:
388 friend class StackFrame;
Kristian Monsen25f61362010-05-21 11:50:48 +0100389 friend class StackFrameIterator;
Steve Blocka7e24c12009-10-30 11:49:00 +0000390};
391
392
393class JavaScriptFrame: public StandardFrame {
394 public:
395 virtual Type type() const { return JAVA_SCRIPT; }
396
397 // Accessors.
398 inline Object* function() const;
399 inline Object* receiver() const;
400 inline void set_receiver(Object* value);
401
402 // Access the parameters.
403 Object* GetParameter(int index) const;
404 int ComputeParametersCount() const;
405
406 // Temporary way of getting access to the number of parameters
407 // passed on the stack by the caller. Once argument adaptor frames
408 // has been introduced on ARM, this number will always match the
409 // computed parameters count.
410 int GetProvidedParametersCount() const;
411
412 // Check if this frame is a constructor frame invoked through 'new'.
413 bool IsConstructor() const;
414
415 // Check if this frame has "adapted" arguments in the sense that the
416 // actual passed arguments are available in an arguments adaptor
417 // frame below it on the stack.
418 inline bool has_adapted_arguments() const;
419
420 // Garbage collection support.
421 virtual void Iterate(ObjectVisitor* v) const;
422
423 // Printing support.
424 virtual void Print(StringStream* accumulator,
425 PrintMode mode,
426 int index) const;
427
428 // Determine the code for the frame.
Iain Merrick75681382010-08-19 15:07:18 +0100429 virtual Code* unchecked_code() const;
Steve Blocka7e24c12009-10-30 11:49:00 +0000430
431 static JavaScriptFrame* cast(StackFrame* frame) {
432 ASSERT(frame->is_java_script());
433 return static_cast<JavaScriptFrame*>(frame);
434 }
435
436 protected:
437 explicit JavaScriptFrame(StackFrameIterator* iterator)
Kristian Monsen80d68ea2010-09-08 11:05:35 +0100438 : StandardFrame(iterator) { }
Steve Blocka7e24c12009-10-30 11:49:00 +0000439
440 virtual Address GetCallerStackPointer() const;
441
Steve Blocka7e24c12009-10-30 11:49:00 +0000442 private:
Steve Blocka7e24c12009-10-30 11:49:00 +0000443 inline Object* function_slot_object() const;
444
445 friend class StackFrameIterator;
446};
447
448
449// Arguments adaptor frames are automatically inserted below
450// JavaScript frames when the actual number of parameters does not
451// match the formal number of parameters.
452class ArgumentsAdaptorFrame: public JavaScriptFrame {
453 public:
454 virtual Type type() const { return ARGUMENTS_ADAPTOR; }
455
456 // Determine the code for the frame.
Iain Merrick75681382010-08-19 15:07:18 +0100457 virtual Code* unchecked_code() const;
Steve Blocka7e24c12009-10-30 11:49:00 +0000458
459 static ArgumentsAdaptorFrame* cast(StackFrame* frame) {
460 ASSERT(frame->is_arguments_adaptor());
461 return static_cast<ArgumentsAdaptorFrame*>(frame);
462 }
463
464 // Printing support.
465 virtual void Print(StringStream* accumulator,
466 PrintMode mode,
467 int index) const;
468 protected:
469 explicit ArgumentsAdaptorFrame(StackFrameIterator* iterator)
470 : JavaScriptFrame(iterator) { }
471
472 virtual Address GetCallerStackPointer() const;
473
474 private:
475 friend class StackFrameIterator;
476};
477
478
479class InternalFrame: public StandardFrame {
480 public:
481 virtual Type type() const { return INTERNAL; }
482
483 // Garbage collection support.
484 virtual void Iterate(ObjectVisitor* v) const;
485
486 // Determine the code for the frame.
Iain Merrick75681382010-08-19 15:07:18 +0100487 virtual Code* unchecked_code() const;
Steve Blocka7e24c12009-10-30 11:49:00 +0000488
489 static InternalFrame* cast(StackFrame* frame) {
490 ASSERT(frame->is_internal());
491 return static_cast<InternalFrame*>(frame);
492 }
493
494 protected:
495 explicit InternalFrame(StackFrameIterator* iterator)
496 : StandardFrame(iterator) { }
497
498 virtual Address GetCallerStackPointer() const;
499
500 private:
501 friend class StackFrameIterator;
502};
503
504
505// Construct frames are special trampoline frames introduced to handle
506// function invocations through 'new'.
507class ConstructFrame: public InternalFrame {
508 public:
509 virtual Type type() const { return CONSTRUCT; }
510
511 static ConstructFrame* cast(StackFrame* frame) {
512 ASSERT(frame->is_construct());
513 return static_cast<ConstructFrame*>(frame);
514 }
515
516 protected:
517 explicit ConstructFrame(StackFrameIterator* iterator)
518 : InternalFrame(iterator) { }
519
520 private:
521 friend class StackFrameIterator;
522};
523
524
525class StackFrameIterator BASE_EMBEDDED {
526 public:
527 // An iterator that iterates over the current thread's stack.
528 StackFrameIterator();
529
530 // An iterator that iterates over a given thread's stack.
531 explicit StackFrameIterator(ThreadLocalTop* thread);
532
533 // An iterator that can start from a given FP address.
534 // If use_top, then work as usual, if fp isn't NULL, use it,
535 // otherwise, do nothing.
536 StackFrameIterator(bool use_top, Address fp, Address sp);
537
538 StackFrame* frame() const {
539 ASSERT(!done());
540 return frame_;
541 }
542
543 bool done() const { return frame_ == NULL; }
544 void Advance() { (this->*advance_)(); }
545
546 // Go back to the first frame.
547 void Reset();
548
549 private:
550#define DECLARE_SINGLETON(ignore, type) type type##_;
551 STACK_FRAME_TYPE_LIST(DECLARE_SINGLETON)
552#undef DECLARE_SINGLETON
553 StackFrame* frame_;
554 StackHandler* handler_;
555 ThreadLocalTop* thread_;
556 Address fp_;
557 Address sp_;
558 void (StackFrameIterator::*advance_)();
559
560 StackHandler* handler() const {
561 ASSERT(!done());
562 return handler_;
563 }
564
565 // Get the type-specific frame singleton in a given state.
566 StackFrame* SingletonFor(StackFrame::Type type, StackFrame::State* state);
567 // A helper function, can return a NULL pointer.
568 StackFrame* SingletonFor(StackFrame::Type type);
569
570 void AdvanceWithHandler();
571 void AdvanceWithoutHandler();
572
573 friend class StackFrame;
574 friend class SafeStackFrameIterator;
575 DISALLOW_COPY_AND_ASSIGN(StackFrameIterator);
576};
577
578
579// Iterator that supports iterating through all JavaScript frames.
580template<typename Iterator>
581class JavaScriptFrameIteratorTemp BASE_EMBEDDED {
582 public:
583 JavaScriptFrameIteratorTemp() { if (!done()) Advance(); }
584
585 explicit JavaScriptFrameIteratorTemp(ThreadLocalTop* thread) :
586 iterator_(thread) {
587 if (!done()) Advance();
588 }
589
590 // Skip frames until the frame with the given id is reached.
591 explicit JavaScriptFrameIteratorTemp(StackFrame::Id id);
592
593 JavaScriptFrameIteratorTemp(Address fp, Address sp,
594 Address low_bound, Address high_bound) :
595 iterator_(fp, sp, low_bound, high_bound) {
596 if (!done()) Advance();
597 }
598
599 inline JavaScriptFrame* frame() const;
600
601 bool done() const { return iterator_.done(); }
602 void Advance();
603
604 // Advance to the frame holding the arguments for the current
605 // frame. This only affects the current frame if it has adapted
606 // arguments.
607 void AdvanceToArgumentsFrame();
608
609 // Go back to the first frame.
610 void Reset();
611
612 private:
613 Iterator iterator_;
614};
615
616
617typedef JavaScriptFrameIteratorTemp<StackFrameIterator> JavaScriptFrameIterator;
618
619
620// NOTE: The stack trace frame iterator is an iterator that only
621// traverse proper JavaScript frames; that is JavaScript frames that
622// have proper JavaScript functions. This excludes the problematic
623// functions in runtime.js.
624class StackTraceFrameIterator: public JavaScriptFrameIterator {
625 public:
626 StackTraceFrameIterator();
627 void Advance();
Leon Clarke4515c472010-02-03 11:58:03 +0000628
629 private:
630 bool IsValidFrame();
Steve Blocka7e24c12009-10-30 11:49:00 +0000631};
632
633
634class SafeStackFrameIterator BASE_EMBEDDED {
635 public:
636 SafeStackFrameIterator(Address fp, Address sp,
637 Address low_bound, Address high_bound);
638
639 StackFrame* frame() const {
640 ASSERT(is_working_iterator_);
641 return iterator_.frame();
642 }
643
644 bool done() const { return iteration_done_ ? true : iterator_.done(); }
645
646 void Advance();
647 void Reset();
648
Kristian Monsen80d68ea2010-09-08 11:05:35 +0100649 static bool is_active() { return active_count_ > 0; }
650
Steve Blocka7e24c12009-10-30 11:49:00 +0000651 static bool IsWithinBounds(
652 Address low_bound, Address high_bound, Address addr) {
653 return low_bound <= addr && addr <= high_bound;
654 }
Leon Clarked91b9f72010-01-27 17:25:45 +0000655
656 private:
Steve Blocka7e24c12009-10-30 11:49:00 +0000657 bool IsValidStackAddress(Address addr) const {
658 return IsWithinBounds(low_bound_, high_bound_, addr);
659 }
660 bool CanIterateHandles(StackFrame* frame, StackHandler* handler);
661 bool IsValidFrame(StackFrame* frame) const;
662 bool IsValidCaller(StackFrame* frame);
663
Kristian Monsen80d68ea2010-09-08 11:05:35 +0100664 // This is a nasty hack to make sure the active count is incremented
665 // before the constructor for the embedded iterator is invoked. This
666 // is needed because the constructor will start looking at frames
667 // right away and we need to make sure it doesn't start inspecting
668 // heap objects.
669 class ActiveCountMaintainer BASE_EMBEDDED {
670 public:
671 ActiveCountMaintainer() { active_count_++; }
672 ~ActiveCountMaintainer() { active_count_--; }
673 };
674
675 ActiveCountMaintainer maintainer_;
676 static int active_count_;
Steve Blocka7e24c12009-10-30 11:49:00 +0000677 Address low_bound_;
678 Address high_bound_;
679 const bool is_valid_top_;
680 const bool is_valid_fp_;
681 const bool is_working_iterator_;
682 bool iteration_done_;
683 StackFrameIterator iterator_;
684};
685
686
687#ifdef ENABLE_LOGGING_AND_PROFILING
688typedef JavaScriptFrameIteratorTemp<SafeStackFrameIterator>
689 SafeJavaScriptFrameIterator;
690
691
692class SafeStackTraceFrameIterator: public SafeJavaScriptFrameIterator {
693 public:
694 explicit SafeStackTraceFrameIterator(Address fp, Address sp,
695 Address low_bound, Address high_bound);
696 void Advance();
697};
698#endif
699
700
701class StackFrameLocator BASE_EMBEDDED {
702 public:
703 // Find the nth JavaScript frame on the stack. The caller must
704 // guarantee that such a frame exists.
705 JavaScriptFrame* FindJavaScriptFrame(int n);
706
707 private:
708 StackFrameIterator iterator_;
709};
710
711
Steve Block6ded16b2010-05-10 14:33:55 +0100712// Reads all frames on the current stack and copies them into the current
713// zone memory.
714Vector<StackFrame*> CreateStackMap();
715
Steve Blocka7e24c12009-10-30 11:49:00 +0000716} } // namespace v8::internal
717
718#endif // V8_FRAMES_H_