1 // Copyright 2012 the V8 project authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
8 #include "src/allocation.h"
9 #include "src/handles.h"
10 #include "src/safepoint-table.h"
15 #if V8_TARGET_ARCH_ARM64
16 typedef uint64_t RegList;
18 typedef uint32_t RegList;
21 // Get the number of registers in a given register list.
22 int NumRegs(RegList list);
24 void SetUpJSCallerSavedCodeData();
26 // Return the code of the n-th saved register available to JavaScript.
27 int JSCallerSavedCode(int n);
30 // Forward declarations.
31 class ExternalCallbackScope;
32 class StackFrameIteratorBase;
36 class InnerPointerToCodeCache {
38 struct InnerPointerToCodeCacheEntry {
39 Address inner_pointer;
41 SafepointEntry safepoint_entry;
44 explicit InnerPointerToCodeCache(Isolate* isolate) : isolate_(isolate) {
48 Code* GcSafeFindCodeForInnerPointer(Address inner_pointer);
49 Code* GcSafeCastToCode(HeapObject* object, Address inner_pointer);
52 memset(&cache_[0], 0, sizeof(cache_));
55 InnerPointerToCodeCacheEntry* GetCacheEntry(Address inner_pointer);
58 InnerPointerToCodeCacheEntry* cache(int index) { return &cache_[index]; }
62 static const int kInnerPointerToCodeCacheSize = 1024;
63 InnerPointerToCodeCacheEntry cache_[kInnerPointerToCodeCacheSize];
65 DISALLOW_COPY_AND_ASSIGN(InnerPointerToCodeCache);
69 // Every try-block pushes the context register.
70 class TryBlockConstant : public AllStatic {
72 static const int kElementCount = 1;
76 class StackHandlerConstants : public AllStatic {
78 static const int kNextOffset = 0 * kPointerSize;
80 static const int kSize = kNextOffset + kPointerSize;
81 static const int kSlotCount = kSize >> kPointerSizeLog2;
85 class StackHandler BASE_EMBEDDED {
87 // Get the address of this stack handler.
88 inline Address address() const;
90 // Get the next stack handler in the chain.
91 inline StackHandler* next() const;
93 // Conversion support.
94 static inline StackHandler* FromAddress(Address address);
97 DISALLOW_IMPLICIT_CONSTRUCTORS(StackHandler);
101 #define STACK_FRAME_TYPE_LIST(V) \
102 V(ENTRY, EntryFrame) \
103 V(ENTRY_CONSTRUCT, EntryConstructFrame) \
105 V(JAVA_SCRIPT, JavaScriptFrame) \
106 V(OPTIMIZED, OptimizedFrame) \
108 V(STUB_FAILURE_TRAMPOLINE, StubFailureTrampolineFrame) \
109 V(INTERNAL, InternalFrame) \
110 V(CONSTRUCT, ConstructFrame) \
111 V(ARGUMENTS_ADAPTOR, ArgumentsAdaptorFrame)
114 class StandardFrameConstants : public AllStatic {
116 // Fixed part of the frame consists of return address, caller fp,
117 // constant pool (if FLAG_enable_ool_constant_pool), context, and function.
118 // StandardFrame::IterateExpressions assumes that kLastObjectOffset is the
119 // last object pointer.
120 static const int kCPSlotSize =
121 FLAG_enable_ool_constant_pool ? kPointerSize : 0;
122 static const int kFixedFrameSizeFromFp = 2 * kPointerSize + kCPSlotSize;
123 static const int kFixedFrameSize = kPCOnStackSize + kFPOnStackSize +
124 kFixedFrameSizeFromFp;
125 static const int kExpressionsOffset = -3 * kPointerSize - kCPSlotSize;
126 static const int kMarkerOffset = -2 * kPointerSize - kCPSlotSize;
127 static const int kContextOffset = -1 * kPointerSize - kCPSlotSize;
128 static const int kConstantPoolOffset = FLAG_enable_ool_constant_pool ?
129 -1 * kPointerSize : 0;
130 static const int kCallerFPOffset = 0 * kPointerSize;
131 static const int kCallerPCOffset = +1 * kFPOnStackSize;
132 static const int kCallerSPOffset = kCallerPCOffset + 1 * kPCOnStackSize;
134 static const int kLastObjectOffset = FLAG_enable_ool_constant_pool ?
135 kConstantPoolOffset : kContextOffset;
139 // Abstract base class for all stack frames.
140 class StackFrame BASE_EMBEDDED {
142 #define DECLARE_TYPE(type, ignore) type,
145 STACK_FRAME_TYPE_LIST(DECLARE_TYPE)
147 // Used by FrameScope to indicate that the stack frame is constructed
148 // manually and the FrameScope does not need to emit code.
153 // Opaque data type for identifying stack frames. Used extensively
155 // ID_MIN_VALUE and ID_MAX_VALUE are specified to ensure that enumeration type
156 // has correct value range (see Issue 830 for more details).
158 ID_MIN_VALUE = kMinInt,
159 ID_MAX_VALUE = kMaxInt,
163 // Used to mark the outermost JS entry frame.
165 INNER_JSENTRY_FRAME = 0,
166 OUTERMOST_JSENTRY_FRAME = 1
170 State() : sp(NULL), fp(NULL), pc_address(NULL),
171 constant_pool_address(NULL) { }
175 Address* constant_pool_address;
178 // Copy constructor; it breaks the connection to host iterator
179 // (as an iterator usually lives on stack).
180 StackFrame(const StackFrame& original) {
181 this->state_ = original.state_;
182 this->iterator_ = NULL;
183 this->isolate_ = original.isolate_;
187 bool is_entry() const { return type() == ENTRY; }
188 bool is_entry_construct() const { return type() == ENTRY_CONSTRUCT; }
189 bool is_exit() const { return type() == EXIT; }
190 bool is_optimized() const { return type() == OPTIMIZED; }
191 bool is_arguments_adaptor() const { return type() == ARGUMENTS_ADAPTOR; }
192 bool is_internal() const { return type() == INTERNAL; }
193 bool is_stub_failure_trampoline() const {
194 return type() == STUB_FAILURE_TRAMPOLINE;
196 bool is_construct() const { return type() == CONSTRUCT; }
197 virtual bool is_standard() const { return false; }
199 bool is_java_script() const {
200 Type type = this->type();
201 return (type == JAVA_SCRIPT) || (type == OPTIMIZED);
205 Address sp() const { return state_.sp; }
206 Address fp() const { return state_.fp; }
207 Address caller_sp() const { return GetCallerStackPointer(); }
209 // If this frame is optimized and was dynamically aligned return its old
210 // unaligned frame pointer. When the frame is deoptimized its FP will shift
211 // up one word and become unaligned.
212 Address UnpaddedFP() const;
214 Address pc() const { return *pc_address(); }
215 void set_pc(Address pc) { *pc_address() = pc; }
217 Address constant_pool() const { return *constant_pool_address(); }
218 void set_constant_pool(ConstantPoolArray* constant_pool) {
219 *constant_pool_address() = reinterpret_cast<Address>(constant_pool);
222 virtual void SetCallerFp(Address caller_fp) = 0;
224 // Manually changes value of fp in this object.
225 void UpdateFp(Address fp) { state_.fp = fp; }
227 Address* pc_address() const { return state_.pc_address; }
229 Address* constant_pool_address() const {
230 return state_.constant_pool_address;
233 // Get the id of this stack frame.
234 Id id() const { return static_cast<Id>(OffsetFrom(caller_sp())); }
236 // Get the top handler from the current stack iterator.
237 inline StackHandler* top_handler() const;
239 // Get the type of this frame.
240 virtual Type type() const = 0;
242 // Get the code associated with this frame.
243 // This method could be called during marking phase of GC.
244 virtual Code* unchecked_code() const = 0;
246 // Get the code associated with this frame.
247 inline Code* LookupCode() const;
249 // Get the code object that contains the given pc.
250 static inline Code* GetContainingCode(Isolate* isolate, Address pc);
252 // Get the code object containing the given pc and fill in the
253 // safepoint entry and the number of stack slots. The pc must be at
255 static Code* GetSafepointData(Isolate* isolate,
257 SafepointEntry* safepoint_entry,
258 unsigned* stack_slots);
260 virtual void Iterate(ObjectVisitor* v) const = 0;
261 static void IteratePc(ObjectVisitor* v, Address* pc_address, Code* holder);
263 // Sets a callback function for return-address rewriting profilers
264 // to resolve the location of a return address to the location of the
265 // profiler's stashed return address.
266 static void SetReturnAddressLocationResolver(
267 ReturnAddressLocationResolver resolver);
269 // Resolves pc_address through the resolution address function if one is set.
270 static inline Address* ResolveReturnAddressLocation(Address* pc_address);
273 enum PrintMode { OVERVIEW, DETAILS };
274 virtual void Print(StringStream* accumulator,
278 Isolate* isolate() const { return isolate_; }
281 inline explicit StackFrame(StackFrameIteratorBase* iterator);
282 virtual ~StackFrame() { }
284 // Compute the stack pointer for the calling frame.
285 virtual Address GetCallerStackPointer() const = 0;
288 static void PrintIndex(StringStream* accumulator,
292 // Compute the stack frame type for the given state.
293 static Type ComputeType(const StackFrameIteratorBase* iterator, State* state);
296 bool can_access_heap_objects() const;
300 const StackFrameIteratorBase* iterator_;
304 static ReturnAddressLocationResolver return_address_location_resolver_;
306 // Fill in the state of the calling frame.
307 virtual void ComputeCallerState(State* state) const = 0;
309 // Get the type and the state of the calling frame.
310 virtual Type GetCallerState(State* state) const;
312 static const intptr_t kIsolateTag = 1;
314 friend class StackFrameIterator;
315 friend class StackFrameIteratorBase;
316 friend class StackHandlerIterator;
317 friend class SafeStackFrameIterator;
320 void operator=(const StackFrame& original);
324 // Entry frames are used to enter JavaScript execution from C.
325 class EntryFrame: public StackFrame {
327 virtual Type type() const { return ENTRY; }
329 virtual Code* unchecked_code() const;
331 // Garbage collection support.
332 virtual void Iterate(ObjectVisitor* v) const;
334 static EntryFrame* cast(StackFrame* frame) {
335 DCHECK(frame->is_entry());
336 return static_cast<EntryFrame*>(frame);
338 virtual void SetCallerFp(Address caller_fp);
341 inline explicit EntryFrame(StackFrameIteratorBase* iterator);
343 // The caller stack pointer for entry frames is always zero. The
344 // real information about the caller frame is available through the
345 // link to the top exit frame.
346 virtual Address GetCallerStackPointer() const { return 0; }
349 virtual void ComputeCallerState(State* state) const;
350 virtual Type GetCallerState(State* state) const;
352 friend class StackFrameIteratorBase;
356 class EntryConstructFrame: public EntryFrame {
358 virtual Type type() const { return ENTRY_CONSTRUCT; }
360 virtual Code* unchecked_code() const;
362 static EntryConstructFrame* cast(StackFrame* frame) {
363 DCHECK(frame->is_entry_construct());
364 return static_cast<EntryConstructFrame*>(frame);
368 inline explicit EntryConstructFrame(StackFrameIteratorBase* iterator);
371 friend class StackFrameIteratorBase;
375 // Exit frames are used to exit JavaScript execution and go to C.
376 class ExitFrame: public StackFrame {
378 virtual Type type() const { return EXIT; }
380 virtual Code* unchecked_code() const;
382 Object*& code_slot() const;
383 Object*& constant_pool_slot() const;
385 // Garbage collection support.
386 virtual void Iterate(ObjectVisitor* v) const;
388 virtual void SetCallerFp(Address caller_fp);
390 static ExitFrame* cast(StackFrame* frame) {
391 DCHECK(frame->is_exit());
392 return static_cast<ExitFrame*>(frame);
395 // Compute the state and type of an exit frame given a frame
396 // pointer. Used when constructing the first stack frame seen by an
397 // iterator and the frames following entry frames.
398 static Type GetStateForFramePointer(Address fp, State* state);
399 static Address ComputeStackPointer(Address fp);
400 static void FillState(Address fp, Address sp, State* state);
403 inline explicit ExitFrame(StackFrameIteratorBase* iterator);
405 virtual Address GetCallerStackPointer() const;
408 virtual void ComputeCallerState(State* state) const;
410 friend class StackFrameIteratorBase;
414 class StandardFrame: public StackFrame {
417 virtual bool is_standard() const { return true; }
420 inline Object* context() const;
422 // Access the expressions in the stack frame including locals.
423 inline Object* GetExpression(int index) const;
424 inline void SetExpression(int index, Object* value);
425 int ComputeExpressionsCount() const;
426 static Object* GetExpression(Address fp, int index);
428 virtual void SetCallerFp(Address caller_fp);
430 static StandardFrame* cast(StackFrame* frame) {
431 DCHECK(frame->is_standard());
432 return static_cast<StandardFrame*>(frame);
436 inline explicit StandardFrame(StackFrameIteratorBase* iterator);
438 virtual void ComputeCallerState(State* state) const;
441 inline Address caller_fp() const;
442 inline Address caller_pc() const;
444 // Computes the address of the PC field in the standard frame given
445 // by the provided frame pointer.
446 static inline Address ComputePCAddress(Address fp);
448 // Computes the address of the constant pool field in the standard
449 // frame given by the provided frame pointer.
450 static inline Address ComputeConstantPoolAddress(Address fp);
452 // Iterate over expression stack including stack handlers, locals,
453 // and parts of the fixed part including context and code fields.
454 void IterateExpressions(ObjectVisitor* v) const;
456 // Returns the address of the n'th expression stack element.
457 Address GetExpressionAddress(int n) const;
458 static Address GetExpressionAddress(Address fp, int n);
460 // Determines if the standard frame for the given frame pointer is
461 // an arguments adaptor frame.
462 static inline bool IsArgumentsAdaptorFrame(Address fp);
464 // Determines if the standard frame for the given frame pointer is a
466 static inline bool IsConstructFrame(Address fp);
468 // Used by OptimizedFrames and StubFrames.
469 void IterateCompiledFrame(ObjectVisitor* v) const;
472 friend class StackFrame;
473 friend class SafeStackFrameIterator;
477 class FrameSummary BASE_EMBEDDED {
479 FrameSummary(Object* receiver,
480 JSFunction* function,
484 : receiver_(receiver, function->GetIsolate()),
488 is_constructor_(is_constructor) { }
489 Handle<Object> receiver() { return receiver_; }
490 Handle<JSFunction> function() { return function_; }
491 Handle<Code> code() { return code_; }
492 Address pc() { return code_->address() + offset_; }
493 int offset() { return offset_; }
494 bool is_constructor() { return is_constructor_; }
499 Handle<Object> receiver_;
500 Handle<JSFunction> function_;
503 bool is_constructor_;
507 class JavaScriptFrame: public StandardFrame {
509 virtual Type type() const { return JAVA_SCRIPT; }
512 inline JSFunction* function() const;
513 inline Object* receiver() const;
514 inline void set_receiver(Object* value);
516 // Access the parameters.
517 inline Address GetParameterSlot(int index) const;
518 inline Object* GetParameter(int index) const;
519 inline int ComputeParametersCount() const {
520 return GetNumberOfIncomingArguments();
523 // Access the operand stack.
524 inline Address GetOperandSlot(int index) const;
525 inline Object* GetOperand(int index) const;
526 inline int ComputeOperandsCount() const;
528 // Generator support to preserve operand stack.
529 void SaveOperandStack(FixedArray* store) const;
530 void RestoreOperandStack(FixedArray* store);
533 void SetParameterValue(int index, Object* value) const;
535 // Check if this frame is a constructor frame invoked through 'new'.
536 bool IsConstructor() const;
538 // Check if this frame has "adapted" arguments in the sense that the
539 // actual passed arguments are available in an arguments adaptor
540 // frame below it on the stack.
541 inline bool has_adapted_arguments() const;
542 int GetArgumentsLength() const;
544 // Garbage collection support.
545 virtual void Iterate(ObjectVisitor* v) const;
548 virtual void Print(StringStream* accumulator,
552 // Determine the code for the frame.
553 virtual Code* unchecked_code() const;
555 // Returns the levels of inlining for this frame.
556 virtual int GetInlineCount() { return 1; }
558 // Return a list with JSFunctions of this frame.
559 virtual void GetFunctions(List<JSFunction*>* functions);
561 // Build a list with summaries for this frame including all inlined frames.
562 virtual void Summarize(List<FrameSummary>* frames);
564 // Lookup exception handler for current {pc}, returns -1 if none found. Also
565 // returns the expected number of stack slots at the handler site.
566 virtual int LookupExceptionHandlerInTable(int* stack_slots);
568 // Architecture-specific register description.
569 static Register fp_register();
570 static Register context_register();
571 static Register constant_pool_pointer_register();
573 static JavaScriptFrame* cast(StackFrame* frame) {
574 DCHECK(frame->is_java_script());
575 return static_cast<JavaScriptFrame*>(frame);
578 static void PrintFunctionAndOffset(JSFunction* function, Code* code,
579 Address pc, FILE* file,
580 bool print_line_number);
582 static void PrintTop(Isolate* isolate, FILE* file, bool print_args,
583 bool print_line_number);
586 inline explicit JavaScriptFrame(StackFrameIteratorBase* iterator);
588 virtual Address GetCallerStackPointer() const;
590 virtual int GetNumberOfIncomingArguments() const;
592 // Garbage collection support. Iterates over incoming arguments,
593 // receiver, and any callee-saved registers.
594 void IterateArguments(ObjectVisitor* v) const;
597 inline Object* function_slot_object() const;
599 friend class StackFrameIteratorBase;
603 class StubFrame : public StandardFrame {
605 virtual Type type() const { return STUB; }
608 virtual void Iterate(ObjectVisitor* v) const;
610 // Determine the code for the frame.
611 virtual Code* unchecked_code() const;
614 inline explicit StubFrame(StackFrameIteratorBase* iterator);
616 virtual Address GetCallerStackPointer() const;
618 virtual int GetNumberOfIncomingArguments() const;
620 friend class StackFrameIteratorBase;
624 class OptimizedFrame : public JavaScriptFrame {
626 virtual Type type() const { return OPTIMIZED; }
629 virtual void Iterate(ObjectVisitor* v) const;
631 virtual int GetInlineCount();
633 // Return a list with JSFunctions of this frame.
634 // The functions are ordered bottom-to-top (i.e. functions.last()
635 // is the top-most activation)
636 virtual void GetFunctions(List<JSFunction*>* functions);
638 virtual void Summarize(List<FrameSummary>* frames);
640 // Lookup exception handler for current {pc}, returns -1 if none found. Also
641 // returns the expected number of stack slots at the handler site.
642 virtual int LookupExceptionHandlerInTable(int* stack_slots);
644 DeoptimizationInputData* GetDeoptimizationData(int* deopt_index);
647 inline explicit OptimizedFrame(StackFrameIteratorBase* iterator);
650 JSFunction* LiteralAt(FixedArray* literal_array, int literal_id);
652 friend class StackFrameIteratorBase;
656 // Arguments adaptor frames are automatically inserted below
657 // JavaScript frames when the actual number of parameters does not
658 // match the formal number of parameters.
659 class ArgumentsAdaptorFrame: public JavaScriptFrame {
661 virtual Type type() const { return ARGUMENTS_ADAPTOR; }
663 // Determine the code for the frame.
664 virtual Code* unchecked_code() const;
666 static ArgumentsAdaptorFrame* cast(StackFrame* frame) {
667 DCHECK(frame->is_arguments_adaptor());
668 return static_cast<ArgumentsAdaptorFrame*>(frame);
672 virtual void Print(StringStream* accumulator,
677 inline explicit ArgumentsAdaptorFrame(StackFrameIteratorBase* iterator);
679 virtual int GetNumberOfIncomingArguments() const;
681 virtual Address GetCallerStackPointer() const;
684 friend class StackFrameIteratorBase;
688 class InternalFrame: public StandardFrame {
690 virtual Type type() const { return INTERNAL; }
692 // Garbage collection support.
693 virtual void Iterate(ObjectVisitor* v) const;
695 // Determine the code for the frame.
696 virtual Code* unchecked_code() const;
698 static InternalFrame* cast(StackFrame* frame) {
699 DCHECK(frame->is_internal());
700 return static_cast<InternalFrame*>(frame);
704 inline explicit InternalFrame(StackFrameIteratorBase* iterator);
706 virtual Address GetCallerStackPointer() const;
709 friend class StackFrameIteratorBase;
713 class StubFailureTrampolineFrame: public StandardFrame {
715 // sizeof(Arguments) - sizeof(Arguments*) is 3 * kPointerSize), but the
716 // presubmit script complains about using sizeof() on a type.
717 static const int kFirstRegisterParameterFrameOffset =
718 StandardFrameConstants::kMarkerOffset - 3 * kPointerSize;
720 static const int kCallerStackParameterCountFrameOffset =
721 StandardFrameConstants::kMarkerOffset - 2 * kPointerSize;
723 virtual Type type() const { return STUB_FAILURE_TRAMPOLINE; }
725 // Get the code associated with this frame.
726 // This method could be called during marking phase of GC.
727 virtual Code* unchecked_code() const;
729 virtual void Iterate(ObjectVisitor* v) const;
731 // Architecture-specific register description.
732 static Register fp_register();
733 static Register context_register();
734 static Register constant_pool_pointer_register();
737 inline explicit StubFailureTrampolineFrame(
738 StackFrameIteratorBase* iterator);
740 virtual Address GetCallerStackPointer() const;
743 friend class StackFrameIteratorBase;
747 // Construct frames are special trampoline frames introduced to handle
748 // function invocations through 'new'.
749 class ConstructFrame: public InternalFrame {
751 virtual Type type() const { return CONSTRUCT; }
753 static ConstructFrame* cast(StackFrame* frame) {
754 DCHECK(frame->is_construct());
755 return static_cast<ConstructFrame*>(frame);
759 inline explicit ConstructFrame(StackFrameIteratorBase* iterator);
762 friend class StackFrameIteratorBase;
766 class StackFrameIteratorBase BASE_EMBEDDED {
768 Isolate* isolate() const { return isolate_; }
770 bool done() const { return frame_ == NULL; }
773 // An iterator that iterates over a given thread's stack.
774 StackFrameIteratorBase(Isolate* isolate, bool can_access_heap_objects);
777 #define DECLARE_SINGLETON(ignore, type) type type##_;
778 STACK_FRAME_TYPE_LIST(DECLARE_SINGLETON)
779 #undef DECLARE_SINGLETON
781 StackHandler* handler_;
782 const bool can_access_heap_objects_;
784 StackHandler* handler() const {
789 // Get the type-specific frame singleton in a given state.
790 StackFrame* SingletonFor(StackFrame::Type type, StackFrame::State* state);
791 // A helper function, can return a NULL pointer.
792 StackFrame* SingletonFor(StackFrame::Type type);
795 friend class StackFrame;
796 DISALLOW_COPY_AND_ASSIGN(StackFrameIteratorBase);
800 class StackFrameIterator: public StackFrameIteratorBase {
802 // An iterator that iterates over the isolate's current thread's stack,
803 explicit StackFrameIterator(Isolate* isolate);
804 // An iterator that iterates over a given thread's stack.
805 StackFrameIterator(Isolate* isolate, ThreadLocalTop* t);
807 StackFrame* frame() const {
814 // Go back to the first frame.
815 void Reset(ThreadLocalTop* top);
817 DISALLOW_COPY_AND_ASSIGN(StackFrameIterator);
821 // Iterator that supports iterating through all JavaScript frames.
822 class JavaScriptFrameIterator BASE_EMBEDDED {
824 inline explicit JavaScriptFrameIterator(Isolate* isolate);
825 inline JavaScriptFrameIterator(Isolate* isolate, ThreadLocalTop* top);
826 // Skip frames until the frame with the given id is reached.
827 JavaScriptFrameIterator(Isolate* isolate, StackFrame::Id id);
829 inline JavaScriptFrame* frame() const;
831 bool done() const { return iterator_.done(); }
834 // Advance to the frame holding the arguments for the current
835 // frame. This only affects the current frame if it has adapted
837 void AdvanceToArgumentsFrame();
840 StackFrameIterator iterator_;
844 // NOTE: The stack trace frame iterator is an iterator that only
845 // traverse proper JavaScript frames; that is JavaScript frames that
846 // have proper JavaScript functions. This excludes the problematic
847 // functions in runtime.js.
848 class StackTraceFrameIterator: public JavaScriptFrameIterator {
850 explicit StackTraceFrameIterator(Isolate* isolate);
858 class SafeStackFrameIterator: public StackFrameIteratorBase {
860 SafeStackFrameIterator(Isolate* isolate,
861 Address fp, Address sp,
862 Address js_entry_sp);
864 inline StackFrame* frame() const;
867 StackFrame::Type top_frame_type() const { return top_frame_type_; }
870 void AdvanceOneFrame();
872 bool IsValidStackAddress(Address addr) const {
873 return low_bound_ <= addr && addr <= high_bound_;
875 bool IsValidFrame(StackFrame* frame) const;
876 bool IsValidCaller(StackFrame* frame);
877 bool IsValidExitFrame(Address fp) const;
878 bool IsValidTop(ThreadLocalTop* top) const;
880 const Address low_bound_;
881 const Address high_bound_;
882 StackFrame::Type top_frame_type_;
883 ExternalCallbackScope* external_callback_scope_;
887 class StackFrameLocator BASE_EMBEDDED {
889 explicit StackFrameLocator(Isolate* isolate) : iterator_(isolate) {}
891 // Find the nth JavaScript frame on the stack. The caller must
892 // guarantee that such a frame exists.
893 JavaScriptFrame* FindJavaScriptFrame(int n);
896 StackFrameIterator iterator_;
900 // Reads all frames on the current stack and copies them into the current
902 Vector<StackFrame*> CreateStackMap(Isolate* isolate, Zone* zone);
904 } } // namespace v8::internal
906 #endif // V8_FRAMES_H_