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_embedded_constant_pool), context, and
118 // function. StandardFrame::IterateExpressions assumes that kLastObjectOffset
119 // is the last object pointer.
120 static const int kCPSlotSize =
121 FLAG_enable_embedded_constant_pool ? kPointerSize : 0;
122 static const int kFixedFrameSizeFromFp = 2 * kPointerSize + kCPSlotSize;
123 static const int kFixedFrameSizeAboveFp = kPCOnStackSize + kFPOnStackSize;
124 static const int kFixedFrameSize =
125 kFixedFrameSizeAboveFp + kFixedFrameSizeFromFp;
126 static const int kFixedSlotCountAboveFp =
127 kFixedFrameSizeAboveFp / kPointerSize;
128 static const int kFixedSlotCount = kFixedFrameSize / kPointerSize;
129 static const int kCPSlotCount = kCPSlotSize / kPointerSize;
130 static const int kExpressionsOffset = -3 * kPointerSize - kCPSlotSize;
131 static const int kMarkerOffset = -2 * kPointerSize - kCPSlotSize;
132 static const int kContextOffset = -1 * kPointerSize - kCPSlotSize;
133 static const int kConstantPoolOffset = kCPSlotSize ? -1 * kPointerSize : 0;
134 static const int kCallerFPOffset = 0 * kPointerSize;
135 static const int kCallerPCOffset = +1 * kFPOnStackSize;
136 static const int kCallerSPOffset = kCallerPCOffset + 1 * kPCOnStackSize;
138 static const int kLastObjectOffset = kContextOffset;
142 class ArgumentsAdaptorFrameConstants : public AllStatic {
145 static const int kLengthOffset = StandardFrameConstants::kExpressionsOffset;
147 static const int kFrameSize =
148 StandardFrameConstants::kFixedFrameSize + kPointerSize;
152 class InternalFrameConstants : public AllStatic {
155 static const int kCodeOffset = StandardFrameConstants::kExpressionsOffset;
159 class ConstructFrameConstants : public AllStatic {
162 static const int kImplicitReceiverOffset =
163 StandardFrameConstants::kExpressionsOffset - 4 * kPointerSize;
164 static const int kOriginalConstructorOffset =
165 StandardFrameConstants::kExpressionsOffset - 3 * kPointerSize;
166 static const int kLengthOffset =
167 StandardFrameConstants::kExpressionsOffset - 2 * kPointerSize;
168 static const int kAllocationSiteOffset =
169 StandardFrameConstants::kExpressionsOffset - 1 * kPointerSize;
170 static const int kCodeOffset =
171 StandardFrameConstants::kExpressionsOffset - 0 * kPointerSize;
173 static const int kFrameSize =
174 StandardFrameConstants::kFixedFrameSize + 5 * kPointerSize;
178 class InterpreterFrameConstants : public AllStatic {
180 // Register file pointer relative.
181 static const int kLastParamFromRegisterPointer =
182 StandardFrameConstants::kFixedFrameSize + kPointerSize;
183 static const int kFunctionFromRegisterPointer = kPointerSize;
187 // Abstract base class for all stack frames.
188 class StackFrame BASE_EMBEDDED {
190 #define DECLARE_TYPE(type, ignore) type,
193 STACK_FRAME_TYPE_LIST(DECLARE_TYPE)
195 // Used by FrameScope to indicate that the stack frame is constructed
196 // manually and the FrameScope does not need to emit code.
201 // Opaque data type for identifying stack frames. Used extensively
203 // ID_MIN_VALUE and ID_MAX_VALUE are specified to ensure that enumeration type
204 // has correct value range (see Issue 830 for more details).
206 ID_MIN_VALUE = kMinInt,
207 ID_MAX_VALUE = kMaxInt,
211 // Used to mark the outermost JS entry frame.
213 INNER_JSENTRY_FRAME = 0,
214 OUTERMOST_JSENTRY_FRAME = 1
218 State() : sp(NULL), fp(NULL), pc_address(NULL),
219 constant_pool_address(NULL) { }
223 Address* constant_pool_address;
226 // Copy constructor; it breaks the connection to host iterator
227 // (as an iterator usually lives on stack).
228 StackFrame(const StackFrame& original) {
229 this->state_ = original.state_;
230 this->iterator_ = NULL;
231 this->isolate_ = original.isolate_;
235 bool is_entry() const { return type() == ENTRY; }
236 bool is_entry_construct() const { return type() == ENTRY_CONSTRUCT; }
237 bool is_exit() const { return type() == EXIT; }
238 bool is_optimized() const { return type() == OPTIMIZED; }
239 bool is_arguments_adaptor() const { return type() == ARGUMENTS_ADAPTOR; }
240 bool is_internal() const { return type() == INTERNAL; }
241 bool is_stub_failure_trampoline() const {
242 return type() == STUB_FAILURE_TRAMPOLINE;
244 bool is_construct() const { return type() == CONSTRUCT; }
245 virtual bool is_standard() const { return false; }
247 bool is_java_script() const {
248 Type type = this->type();
249 return (type == JAVA_SCRIPT) || (type == OPTIMIZED);
253 Address sp() const { return state_.sp; }
254 Address fp() const { return state_.fp; }
255 Address caller_sp() const { return GetCallerStackPointer(); }
257 // If this frame is optimized and was dynamically aligned return its old
258 // unaligned frame pointer. When the frame is deoptimized its FP will shift
259 // up one word and become unaligned.
260 Address UnpaddedFP() const;
262 Address pc() const { return *pc_address(); }
263 void set_pc(Address pc) { *pc_address() = pc; }
265 Address constant_pool() const { return *constant_pool_address(); }
266 void set_constant_pool(Address constant_pool) {
267 *constant_pool_address() = constant_pool;
270 virtual void SetCallerFp(Address caller_fp) = 0;
272 // Manually changes value of fp in this object.
273 void UpdateFp(Address fp) { state_.fp = fp; }
275 Address* pc_address() const { return state_.pc_address; }
277 Address* constant_pool_address() const {
278 return state_.constant_pool_address;
281 // Get the id of this stack frame.
282 Id id() const { return static_cast<Id>(OffsetFrom(caller_sp())); }
284 // Get the top handler from the current stack iterator.
285 inline StackHandler* top_handler() const;
287 // Get the type of this frame.
288 virtual Type type() const = 0;
290 // Get the code associated with this frame.
291 // This method could be called during marking phase of GC.
292 virtual Code* unchecked_code() const = 0;
294 // Get the code associated with this frame.
295 inline Code* LookupCode() const;
297 // Get the code object that contains the given pc.
298 static inline Code* GetContainingCode(Isolate* isolate, Address pc);
300 // Get the code object containing the given pc and fill in the
301 // safepoint entry and the number of stack slots. The pc must be at
303 static Code* GetSafepointData(Isolate* isolate,
305 SafepointEntry* safepoint_entry,
306 unsigned* stack_slots);
308 virtual void Iterate(ObjectVisitor* v) const = 0;
309 static void IteratePc(ObjectVisitor* v, Address* pc_address,
310 Address* constant_pool_address, Code* holder);
312 // Sets a callback function for return-address rewriting profilers
313 // to resolve the location of a return address to the location of the
314 // profiler's stashed return address.
315 static void SetReturnAddressLocationResolver(
316 ReturnAddressLocationResolver resolver);
318 // Resolves pc_address through the resolution address function if one is set.
319 static inline Address* ResolveReturnAddressLocation(Address* pc_address);
322 enum PrintMode { OVERVIEW, DETAILS };
323 virtual void Print(StringStream* accumulator,
327 Isolate* isolate() const { return isolate_; }
330 inline explicit StackFrame(StackFrameIteratorBase* iterator);
331 virtual ~StackFrame() { }
333 // Compute the stack pointer for the calling frame.
334 virtual Address GetCallerStackPointer() const = 0;
337 static void PrintIndex(StringStream* accumulator,
341 // Compute the stack frame type for the given state.
342 static Type ComputeType(const StackFrameIteratorBase* iterator, State* state);
345 bool can_access_heap_objects() const;
349 const StackFrameIteratorBase* iterator_;
353 static ReturnAddressLocationResolver return_address_location_resolver_;
355 // Fill in the state of the calling frame.
356 virtual void ComputeCallerState(State* state) const = 0;
358 // Get the type and the state of the calling frame.
359 virtual Type GetCallerState(State* state) const;
361 static const intptr_t kIsolateTag = 1;
363 friend class StackFrameIterator;
364 friend class StackFrameIteratorBase;
365 friend class StackHandlerIterator;
366 friend class SafeStackFrameIterator;
369 void operator=(const StackFrame& original);
373 // Entry frames are used to enter JavaScript execution from C.
374 class EntryFrame: public StackFrame {
376 virtual Type type() const { return ENTRY; }
378 virtual Code* unchecked_code() const;
380 // Garbage collection support.
381 virtual void Iterate(ObjectVisitor* v) const;
383 static EntryFrame* cast(StackFrame* frame) {
384 DCHECK(frame->is_entry());
385 return static_cast<EntryFrame*>(frame);
387 virtual void SetCallerFp(Address caller_fp);
390 inline explicit EntryFrame(StackFrameIteratorBase* iterator);
392 // The caller stack pointer for entry frames is always zero. The
393 // real information about the caller frame is available through the
394 // link to the top exit frame.
395 virtual Address GetCallerStackPointer() const { return 0; }
398 virtual void ComputeCallerState(State* state) const;
399 virtual Type GetCallerState(State* state) const;
401 friend class StackFrameIteratorBase;
405 class EntryConstructFrame: public EntryFrame {
407 virtual Type type() const { return ENTRY_CONSTRUCT; }
409 virtual Code* unchecked_code() const;
411 static EntryConstructFrame* cast(StackFrame* frame) {
412 DCHECK(frame->is_entry_construct());
413 return static_cast<EntryConstructFrame*>(frame);
417 inline explicit EntryConstructFrame(StackFrameIteratorBase* iterator);
420 friend class StackFrameIteratorBase;
424 // Exit frames are used to exit JavaScript execution and go to C.
425 class ExitFrame: public StackFrame {
427 virtual Type type() const { return EXIT; }
429 virtual Code* unchecked_code() const;
431 Object*& code_slot() const;
433 // Garbage collection support.
434 virtual void Iterate(ObjectVisitor* v) const;
436 virtual void SetCallerFp(Address caller_fp);
438 static ExitFrame* cast(StackFrame* frame) {
439 DCHECK(frame->is_exit());
440 return static_cast<ExitFrame*>(frame);
443 // Compute the state and type of an exit frame given a frame
444 // pointer. Used when constructing the first stack frame seen by an
445 // iterator and the frames following entry frames.
446 static Type GetStateForFramePointer(Address fp, State* state);
447 static Address ComputeStackPointer(Address fp);
448 static void FillState(Address fp, Address sp, State* state);
451 inline explicit ExitFrame(StackFrameIteratorBase* iterator);
453 virtual Address GetCallerStackPointer() const;
456 virtual void ComputeCallerState(State* state) const;
458 friend class StackFrameIteratorBase;
462 class StandardFrame: public StackFrame {
465 virtual bool is_standard() const { return true; }
468 inline Object* context() const;
470 // Access the expressions in the stack frame including locals.
471 inline Object* GetExpression(int index) const;
472 inline void SetExpression(int index, Object* value);
473 int ComputeExpressionsCount() const;
474 static Object* GetExpression(Address fp, int index);
476 virtual void SetCallerFp(Address caller_fp);
478 static StandardFrame* cast(StackFrame* frame) {
479 DCHECK(frame->is_standard());
480 return static_cast<StandardFrame*>(frame);
484 inline explicit StandardFrame(StackFrameIteratorBase* iterator);
486 virtual void ComputeCallerState(State* state) const;
489 inline Address caller_fp() const;
490 inline Address caller_pc() const;
492 // Computes the address of the PC field in the standard frame given
493 // by the provided frame pointer.
494 static inline Address ComputePCAddress(Address fp);
496 // Computes the address of the constant pool field in the standard
497 // frame given by the provided frame pointer.
498 static inline Address ComputeConstantPoolAddress(Address fp);
500 // Iterate over expression stack including stack handlers, locals,
501 // and parts of the fixed part including context and code fields.
502 void IterateExpressions(ObjectVisitor* v) const;
504 // Returns the address of the n'th expression stack element.
505 Address GetExpressionAddress(int n) const;
506 static Address GetExpressionAddress(Address fp, int n);
508 // Determines if the standard frame for the given frame pointer is
509 // an arguments adaptor frame.
510 static inline bool IsArgumentsAdaptorFrame(Address fp);
512 // Determines if the standard frame for the given frame pointer is a
514 static inline bool IsConstructFrame(Address fp);
516 // Used by OptimizedFrames and StubFrames.
517 void IterateCompiledFrame(ObjectVisitor* v) const;
520 friend class StackFrame;
521 friend class SafeStackFrameIterator;
525 class FrameSummary BASE_EMBEDDED {
527 FrameSummary(Object* receiver, JSFunction* function, Code* code, int offset,
528 bool is_constructor);
530 Handle<Object> receiver() { return receiver_; }
531 Handle<JSFunction> function() { return function_; }
532 Handle<Code> code() { return code_; }
533 Address pc() { return code_->address() + offset_; }
534 int offset() { return offset_; }
535 bool is_constructor() { return is_constructor_; }
540 Handle<Object> receiver_;
541 Handle<JSFunction> function_;
544 bool is_constructor_;
548 class JavaScriptFrame: public StandardFrame {
550 virtual Type type() const { return JAVA_SCRIPT; }
553 inline JSFunction* function() const;
554 inline Object* receiver() const;
555 inline void set_receiver(Object* value);
557 // Access the parameters.
558 inline Address GetParameterSlot(int index) const;
559 inline Object* GetParameter(int index) const;
560 inline int ComputeParametersCount() const {
561 return GetNumberOfIncomingArguments();
564 // Access the operand stack.
565 inline Address GetOperandSlot(int index) const;
566 inline Object* GetOperand(int index) const;
567 inline int ComputeOperandsCount() const;
569 // Generator support to preserve operand stack.
570 void SaveOperandStack(FixedArray* store) const;
571 void RestoreOperandStack(FixedArray* store);
574 void SetParameterValue(int index, Object* value) const;
576 // Check if this frame is a constructor frame invoked through 'new'.
577 bool IsConstructor() const;
579 // Determines whether this frame includes inlined activations. To get details
580 // about the inlined frames use {GetFunctions} and {Summarize}.
581 bool HasInlinedFrames();
583 // Returns the original constructor function that was used in the constructor
584 // call to this frame. Note that this is only valid on constructor frames.
585 Object* GetOriginalConstructor() const;
587 // Check if this frame has "adapted" arguments in the sense that the
588 // actual passed arguments are available in an arguments adaptor
589 // frame below it on the stack.
590 inline bool has_adapted_arguments() const;
591 int GetArgumentsLength() const;
593 // Garbage collection support.
594 virtual void Iterate(ObjectVisitor* v) const;
597 virtual void Print(StringStream* accumulator,
601 // Determine the code for the frame.
602 virtual Code* unchecked_code() const;
604 // Return a list with JSFunctions of this frame.
605 virtual void GetFunctions(List<JSFunction*>* functions);
607 // Build a list with summaries for this frame including all inlined frames.
608 virtual void Summarize(List<FrameSummary>* frames);
610 // Lookup exception handler for current {pc}, returns -1 if none found. Also
611 // returns the expected number of stack slots at the handler site.
612 virtual int LookupExceptionHandlerInTable(
613 int* stack_slots, HandlerTable::CatchPrediction* prediction);
615 // Architecture-specific register description.
616 static Register fp_register();
617 static Register context_register();
618 static Register constant_pool_pointer_register();
620 static JavaScriptFrame* cast(StackFrame* frame) {
621 DCHECK(frame->is_java_script());
622 return static_cast<JavaScriptFrame*>(frame);
625 static void PrintFunctionAndOffset(JSFunction* function, Code* code,
626 Address pc, FILE* file,
627 bool print_line_number);
629 static void PrintTop(Isolate* isolate, FILE* file, bool print_args,
630 bool print_line_number);
633 inline explicit JavaScriptFrame(StackFrameIteratorBase* iterator);
635 virtual Address GetCallerStackPointer() const;
637 virtual int GetNumberOfIncomingArguments() const;
639 // Garbage collection support. Iterates over incoming arguments,
640 // receiver, and any callee-saved registers.
641 void IterateArguments(ObjectVisitor* v) const;
644 inline Object* function_slot_object() const;
646 friend class StackFrameIteratorBase;
650 class StubFrame : public StandardFrame {
652 virtual Type type() const { return STUB; }
655 virtual void Iterate(ObjectVisitor* v) const;
657 // Determine the code for the frame.
658 virtual Code* unchecked_code() const;
661 inline explicit StubFrame(StackFrameIteratorBase* iterator);
663 virtual Address GetCallerStackPointer() const;
665 virtual int GetNumberOfIncomingArguments() const;
667 friend class StackFrameIteratorBase;
671 class OptimizedFrame : public JavaScriptFrame {
673 virtual Type type() const { return OPTIMIZED; }
676 virtual void Iterate(ObjectVisitor* v) const;
678 // Return a list with JSFunctions of this frame.
679 // The functions are ordered bottom-to-top (i.e. functions.last()
680 // is the top-most activation)
681 virtual void GetFunctions(List<JSFunction*>* functions);
683 virtual void Summarize(List<FrameSummary>* frames);
685 // Lookup exception handler for current {pc}, returns -1 if none found. Also
686 // returns the expected number of stack slots at the handler site.
687 virtual int LookupExceptionHandlerInTable(
688 int* stack_slots, HandlerTable::CatchPrediction* prediction);
690 DeoptimizationInputData* GetDeoptimizationData(int* deopt_index);
692 static int StackSlotOffsetRelativeToFp(int slot_index);
695 inline explicit OptimizedFrame(StackFrameIteratorBase* iterator);
698 friend class StackFrameIteratorBase;
700 Object* StackSlotAt(int index) const;
704 // Arguments adaptor frames are automatically inserted below
705 // JavaScript frames when the actual number of parameters does not
706 // match the formal number of parameters.
707 class ArgumentsAdaptorFrame: public JavaScriptFrame {
709 virtual Type type() const { return ARGUMENTS_ADAPTOR; }
711 // Determine the code for the frame.
712 virtual Code* unchecked_code() const;
714 static ArgumentsAdaptorFrame* cast(StackFrame* frame) {
715 DCHECK(frame->is_arguments_adaptor());
716 return static_cast<ArgumentsAdaptorFrame*>(frame);
720 virtual void Print(StringStream* accumulator,
725 inline explicit ArgumentsAdaptorFrame(StackFrameIteratorBase* iterator);
727 virtual int GetNumberOfIncomingArguments() const;
729 virtual Address GetCallerStackPointer() const;
732 friend class StackFrameIteratorBase;
736 class InternalFrame: public StandardFrame {
738 virtual Type type() const { return INTERNAL; }
740 // Garbage collection support.
741 virtual void Iterate(ObjectVisitor* v) const;
743 // Determine the code for the frame.
744 virtual Code* unchecked_code() const;
746 static InternalFrame* cast(StackFrame* frame) {
747 DCHECK(frame->is_internal());
748 return static_cast<InternalFrame*>(frame);
752 inline explicit InternalFrame(StackFrameIteratorBase* iterator);
754 virtual Address GetCallerStackPointer() const;
757 friend class StackFrameIteratorBase;
761 class StubFailureTrampolineFrame: public StandardFrame {
763 // sizeof(Arguments) - sizeof(Arguments*) is 3 * kPointerSize), but the
764 // presubmit script complains about using sizeof() on a type.
765 static const int kFirstRegisterParameterFrameOffset =
766 StandardFrameConstants::kMarkerOffset - 3 * kPointerSize;
768 static const int kCallerStackParameterCountFrameOffset =
769 StandardFrameConstants::kMarkerOffset - 2 * kPointerSize;
771 virtual Type type() const { return STUB_FAILURE_TRAMPOLINE; }
773 // Get the code associated with this frame.
774 // This method could be called during marking phase of GC.
775 virtual Code* unchecked_code() const;
777 virtual void Iterate(ObjectVisitor* v) const;
779 // Architecture-specific register description.
780 static Register fp_register();
781 static Register context_register();
782 static Register constant_pool_pointer_register();
785 inline explicit StubFailureTrampolineFrame(
786 StackFrameIteratorBase* iterator);
788 virtual Address GetCallerStackPointer() const;
791 friend class StackFrameIteratorBase;
795 // Construct frames are special trampoline frames introduced to handle
796 // function invocations through 'new'.
797 class ConstructFrame: public InternalFrame {
799 virtual Type type() const { return CONSTRUCT; }
801 static ConstructFrame* cast(StackFrame* frame) {
802 DCHECK(frame->is_construct());
803 return static_cast<ConstructFrame*>(frame);
807 inline explicit ConstructFrame(StackFrameIteratorBase* iterator);
810 friend class StackFrameIteratorBase;
814 class StackFrameIteratorBase BASE_EMBEDDED {
816 Isolate* isolate() const { return isolate_; }
818 bool done() const { return frame_ == NULL; }
821 // An iterator that iterates over a given thread's stack.
822 StackFrameIteratorBase(Isolate* isolate, bool can_access_heap_objects);
825 #define DECLARE_SINGLETON(ignore, type) type type##_;
826 STACK_FRAME_TYPE_LIST(DECLARE_SINGLETON)
827 #undef DECLARE_SINGLETON
829 StackHandler* handler_;
830 const bool can_access_heap_objects_;
832 StackHandler* handler() const {
837 // Get the type-specific frame singleton in a given state.
838 StackFrame* SingletonFor(StackFrame::Type type, StackFrame::State* state);
839 // A helper function, can return a NULL pointer.
840 StackFrame* SingletonFor(StackFrame::Type type);
843 friend class StackFrame;
844 DISALLOW_COPY_AND_ASSIGN(StackFrameIteratorBase);
848 class StackFrameIterator: public StackFrameIteratorBase {
850 // An iterator that iterates over the isolate's current thread's stack,
851 explicit StackFrameIterator(Isolate* isolate);
852 // An iterator that iterates over a given thread's stack.
853 StackFrameIterator(Isolate* isolate, ThreadLocalTop* t);
855 StackFrame* frame() const {
862 // Go back to the first frame.
863 void Reset(ThreadLocalTop* top);
865 DISALLOW_COPY_AND_ASSIGN(StackFrameIterator);
869 // Iterator that supports iterating through all JavaScript frames.
870 class JavaScriptFrameIterator BASE_EMBEDDED {
872 inline explicit JavaScriptFrameIterator(Isolate* isolate);
873 inline JavaScriptFrameIterator(Isolate* isolate, ThreadLocalTop* top);
874 // Skip frames until the frame with the given id is reached.
875 JavaScriptFrameIterator(Isolate* isolate, StackFrame::Id id);
877 inline JavaScriptFrame* frame() const;
879 bool done() const { return iterator_.done(); }
882 // Advance to the frame holding the arguments for the current
883 // frame. This only affects the current frame if it has adapted
885 void AdvanceToArgumentsFrame();
888 StackFrameIterator iterator_;
892 // NOTE: The stack trace frame iterator is an iterator that only
893 // traverse proper JavaScript frames; that is JavaScript frames that
894 // have proper JavaScript functions. This excludes the problematic
895 // functions in runtime.js.
896 class StackTraceFrameIterator: public JavaScriptFrameIterator {
898 explicit StackTraceFrameIterator(Isolate* isolate);
906 class SafeStackFrameIterator: public StackFrameIteratorBase {
908 SafeStackFrameIterator(Isolate* isolate,
909 Address fp, Address sp,
910 Address js_entry_sp);
912 inline StackFrame* frame() const;
915 StackFrame::Type top_frame_type() const { return top_frame_type_; }
918 void AdvanceOneFrame();
920 bool IsValidStackAddress(Address addr) const {
921 return low_bound_ <= addr && addr <= high_bound_;
923 bool IsValidFrame(StackFrame* frame) const;
924 bool IsValidCaller(StackFrame* frame);
925 bool IsValidExitFrame(Address fp) const;
926 bool IsValidTop(ThreadLocalTop* top) const;
928 const Address low_bound_;
929 const Address high_bound_;
930 StackFrame::Type top_frame_type_;
931 ExternalCallbackScope* external_callback_scope_;
935 class StackFrameLocator BASE_EMBEDDED {
937 explicit StackFrameLocator(Isolate* isolate) : iterator_(isolate) {}
939 // Find the nth JavaScript frame on the stack. The caller must
940 // guarantee that such a frame exists.
941 JavaScriptFrame* FindJavaScriptFrame(int n);
944 StackFrameIterator iterator_;
948 // Reads all frames on the current stack and copies them into the current
950 Vector<StackFrame*> CreateStackMap(Isolate* isolate, Zone* zone);
952 } // namespace internal
955 #endif // V8_FRAMES_H_