1 // Copyright 2012 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
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.
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.
31 #include "allocation.h"
33 #include "safepoint-table.h"
38 typedef uint32_t RegList;
40 // Get the number of registers in a given register list.
41 int NumRegs(RegList list);
43 void SetUpJSCallerSavedCodeData();
45 // Return the code of the n-th saved register available to JavaScript.
46 int JSCallerSavedCode(int n);
49 // Forward declarations.
50 class StackFrameIterator;
54 class InnerPointerToCodeCache {
56 struct InnerPointerToCodeCacheEntry {
57 Address inner_pointer;
59 SafepointEntry safepoint_entry;
62 explicit InnerPointerToCodeCache(Isolate* isolate) : isolate_(isolate) {
66 Code* GcSafeFindCodeForInnerPointer(Address inner_pointer);
67 Code* GcSafeCastToCode(HeapObject* object, Address inner_pointer);
70 memset(&cache_[0], 0, sizeof(cache_));
73 InnerPointerToCodeCacheEntry* GetCacheEntry(Address inner_pointer);
76 InnerPointerToCodeCacheEntry* cache(int index) { return &cache_[index]; }
80 static const int kInnerPointerToCodeCacheSize = 1024;
81 InnerPointerToCodeCacheEntry cache_[kInnerPointerToCodeCacheSize];
83 DISALLOW_COPY_AND_ASSIGN(InnerPointerToCodeCache);
87 class StackHandler BASE_EMBEDDED {
96 static const int kKindWidth = 2;
97 STATIC_ASSERT(LAST_KIND < (1 << kKindWidth));
98 static const int kIndexWidth = 32 - kKindWidth;
99 class KindField: public BitField<StackHandler::Kind, 0, kKindWidth> {};
100 class IndexField: public BitField<unsigned, kKindWidth, kIndexWidth> {};
102 // Get the address of this stack handler.
103 inline Address address() const;
105 // Get the next stack handler in the chain.
106 inline StackHandler* next() const;
108 // Tells whether the given address is inside this handler.
109 inline bool includes(Address address) const;
111 // Garbage collection support.
112 inline void Iterate(ObjectVisitor* v, Code* holder) const;
114 // Conversion support.
115 static inline StackHandler* FromAddress(Address address);
118 inline bool is_js_entry() const;
119 inline bool is_catch() const;
120 inline bool is_finally() const;
124 inline Kind kind() const;
126 inline Object** context_address() const;
127 inline Object** code_address() const;
129 DISALLOW_IMPLICIT_CONSTRUCTORS(StackHandler);
133 #define STACK_FRAME_TYPE_LIST(V) \
134 V(ENTRY, EntryFrame) \
135 V(ENTRY_CONSTRUCT, EntryConstructFrame) \
137 V(JAVA_SCRIPT, JavaScriptFrame) \
138 V(OPTIMIZED, OptimizedFrame) \
139 V(INTERNAL, InternalFrame) \
140 V(CONSTRUCT, ConstructFrame) \
141 V(ARGUMENTS_ADAPTOR, ArgumentsAdaptorFrame)
144 // Abstract base class for all stack frames.
145 class StackFrame BASE_EMBEDDED {
147 #define DECLARE_TYPE(type, ignore) type,
150 STACK_FRAME_TYPE_LIST(DECLARE_TYPE)
152 // Used by FrameScope to indicate that the stack frame is constructed
153 // manually and the FrameScope does not need to emit code.
158 // Opaque data type for identifying stack frames. Used extensively
160 // ID_MIN_VALUE and ID_MAX_VALUE are specified to ensure that enumeration type
161 // has correct value range (see Issue 830 for more details).
163 ID_MIN_VALUE = kMinInt,
164 ID_MAX_VALUE = kMaxInt,
168 // Used to mark the outermost JS entry frame.
170 INNER_JSENTRY_FRAME = 0,
171 OUTERMOST_JSENTRY_FRAME = 1
175 State() : sp(NULL), fp(NULL), pc_address(NULL) { }
181 // Copy constructor; it breaks the connection to host iterator
182 // (as an iterator usually lives on stack).
183 StackFrame(const StackFrame& original) {
184 this->state_ = original.state_;
185 this->iterator_ = NULL;
186 this->isolate_ = original.isolate_;
190 bool is_entry() const { return type() == ENTRY; }
191 bool is_entry_construct() const { return type() == ENTRY_CONSTRUCT; }
192 bool is_exit() const { return type() == EXIT; }
193 bool is_optimized() const { return type() == OPTIMIZED; }
194 bool is_arguments_adaptor() const { return type() == ARGUMENTS_ADAPTOR; }
195 bool is_internal() const { return type() == INTERNAL; }
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 Address pc() const { return *pc_address(); }
210 void set_pc(Address pc) { *pc_address() = pc; }
212 virtual void SetCallerFp(Address caller_fp) = 0;
214 // Manually changes value of fp in this object.
215 void UpdateFp(Address fp) { state_.fp = fp; }
217 Address* pc_address() const { return state_.pc_address; }
219 // Get the id of this stack frame.
220 Id id() const { return static_cast<Id>(OffsetFrom(caller_sp())); }
222 // Checks if this frame includes any stack handlers.
223 bool HasHandler() const;
225 // Get the type of this frame.
226 virtual Type type() const = 0;
228 // Get the code associated with this frame.
229 // This method could be called during marking phase of GC.
230 virtual Code* unchecked_code() const = 0;
232 // Get the code associated with this frame.
233 inline Code* LookupCode() const;
235 // Get the code object that contains the given pc.
236 static inline Code* GetContainingCode(Isolate* isolate, Address pc);
238 // Get the code object containing the given pc and fill in the
239 // safepoint entry and the number of stack slots. The pc must be at
241 static Code* GetSafepointData(Isolate* isolate,
243 SafepointEntry* safepoint_entry,
244 unsigned* stack_slots);
246 virtual void Iterate(ObjectVisitor* v) const = 0;
247 static void IteratePc(ObjectVisitor* v, Address* pc_address, Code* holder);
249 // Sets a callback function for return-address rewriting profilers
250 // to resolve the location of a return address to the location of the
251 // profiler's stashed return address.
252 static void SetReturnAddressLocationResolver(
253 ReturnAddressLocationResolver resolver);
256 enum PrintMode { OVERVIEW, DETAILS };
257 virtual void Print(StringStream* accumulator,
262 inline explicit StackFrame(StackFrameIterator* iterator);
263 virtual ~StackFrame() { }
265 Isolate* isolate() const { return isolate_; }
267 // Compute the stack pointer for the calling frame.
268 virtual Address GetCallerStackPointer() const = 0;
271 static void PrintIndex(StringStream* accumulator,
275 // Get the top handler from the current stack iterator.
276 inline StackHandler* top_handler() const;
278 // Compute the stack frame type for the given state.
279 static Type ComputeType(Isolate* isolate, State* state);
282 const StackFrameIterator* iterator_;
286 // Fill in the state of the calling frame.
287 virtual void ComputeCallerState(State* state) const = 0;
289 // Get the type and the state of the calling frame.
290 virtual Type GetCallerState(State* state) const;
292 static const intptr_t kIsolateTag = 1;
294 friend class StackFrameIterator;
295 friend class StackHandlerIterator;
296 friend class SafeStackFrameIterator;
299 void operator=(const StackFrame& original);
303 // Entry frames are used to enter JavaScript execution from C.
304 class EntryFrame: public StackFrame {
306 virtual Type type() const { return ENTRY; }
308 virtual Code* unchecked_code() const;
310 // Garbage collection support.
311 virtual void Iterate(ObjectVisitor* v) const;
313 static EntryFrame* cast(StackFrame* frame) {
314 ASSERT(frame->is_entry());
315 return static_cast<EntryFrame*>(frame);
317 virtual void SetCallerFp(Address caller_fp);
320 inline explicit EntryFrame(StackFrameIterator* iterator);
322 // The caller stack pointer for entry frames is always zero. The
323 // real information about the caller frame is available through the
324 // link to the top exit frame.
325 virtual Address GetCallerStackPointer() const { return 0; }
328 virtual void ComputeCallerState(State* state) const;
329 virtual Type GetCallerState(State* state) const;
331 friend class StackFrameIterator;
335 class EntryConstructFrame: public EntryFrame {
337 virtual Type type() const { return ENTRY_CONSTRUCT; }
339 virtual Code* unchecked_code() const;
341 static EntryConstructFrame* cast(StackFrame* frame) {
342 ASSERT(frame->is_entry_construct());
343 return static_cast<EntryConstructFrame*>(frame);
347 inline explicit EntryConstructFrame(StackFrameIterator* iterator);
350 friend class StackFrameIterator;
354 // Exit frames are used to exit JavaScript execution and go to C.
355 class ExitFrame: public StackFrame {
357 virtual Type type() const { return EXIT; }
359 virtual Code* unchecked_code() const;
361 Object*& code_slot() const;
363 // Garbage collection support.
364 virtual void Iterate(ObjectVisitor* v) const;
366 virtual void SetCallerFp(Address caller_fp);
368 static ExitFrame* cast(StackFrame* frame) {
369 ASSERT(frame->is_exit());
370 return static_cast<ExitFrame*>(frame);
373 // Compute the state and type of an exit frame given a frame
374 // pointer. Used when constructing the first stack frame seen by an
375 // iterator and the frames following entry frames.
376 static Type GetStateForFramePointer(Address fp, State* state);
377 static Address ComputeStackPointer(Address fp);
378 static void FillState(Address fp, Address sp, State* state);
381 inline explicit ExitFrame(StackFrameIterator* iterator);
383 virtual Address GetCallerStackPointer() const;
386 virtual void ComputeCallerState(State* state) const;
388 friend class StackFrameIterator;
392 class StandardFrame: public StackFrame {
395 virtual bool is_standard() const { return true; }
398 inline Object* context() const;
400 // Access the expressions in the stack frame including locals.
401 inline Object* GetExpression(int index) const;
402 inline void SetExpression(int index, Object* value);
403 int ComputeExpressionsCount() const;
404 static Object* GetExpression(Address fp, int index);
406 virtual void SetCallerFp(Address caller_fp);
408 static StandardFrame* cast(StackFrame* frame) {
409 ASSERT(frame->is_standard());
410 return static_cast<StandardFrame*>(frame);
414 inline explicit StandardFrame(StackFrameIterator* iterator);
416 virtual void ComputeCallerState(State* state) const;
419 inline Address caller_fp() const;
420 inline Address caller_pc() const;
422 // Computes the address of the PC field in the standard frame given
423 // by the provided frame pointer.
424 static inline Address ComputePCAddress(Address fp);
426 // Iterate over expression stack including stack handlers, locals,
427 // and parts of the fixed part including context and code fields.
428 void IterateExpressions(ObjectVisitor* v) const;
430 // Returns the address of the n'th expression stack element.
431 Address GetExpressionAddress(int n) const;
432 static Address GetExpressionAddress(Address fp, int n);
434 // Determines if the n'th expression stack element is in a stack
435 // handler or not. Requires traversing all handlers in this frame.
436 bool IsExpressionInsideHandler(int n) const;
438 // Determines if the standard frame for the given frame pointer is
439 // an arguments adaptor frame.
440 static inline bool IsArgumentsAdaptorFrame(Address fp);
442 // Determines if the standard frame for the given frame pointer is a
444 static inline bool IsConstructFrame(Address fp);
447 friend class StackFrame;
448 friend class StackFrameIterator;
452 class FrameSummary BASE_EMBEDDED {
454 FrameSummary(Object* receiver,
455 JSFunction* function,
459 : receiver_(receiver),
463 is_constructor_(is_constructor) { }
464 Handle<Object> receiver() { return receiver_; }
465 Handle<JSFunction> function() { return function_; }
466 Handle<Code> code() { return code_; }
467 Address pc() { return code_->address() + offset_; }
468 int offset() { return offset_; }
469 bool is_constructor() { return is_constructor_; }
474 Handle<Object> receiver_;
475 Handle<JSFunction> function_;
478 bool is_constructor_;
482 class JavaScriptFrame: public StandardFrame {
484 virtual Type type() const { return JAVA_SCRIPT; }
487 inline Object* function() const;
488 inline Object* receiver() const;
489 inline void set_receiver(Object* value);
491 // Access the parameters.
492 inline Address GetParameterSlot(int index) const;
493 inline Object* GetParameter(int index) const;
494 inline int ComputeParametersCount() const {
495 return GetNumberOfIncomingArguments();
498 // Check if this frame is a constructor frame invoked through 'new'.
499 bool IsConstructor() const;
501 // Check if this frame has "adapted" arguments in the sense that the
502 // actual passed arguments are available in an arguments adaptor
503 // frame below it on the stack.
504 inline bool has_adapted_arguments() const;
505 int GetArgumentsLength() const;
507 // Garbage collection support.
508 virtual void Iterate(ObjectVisitor* v) const;
511 virtual void Print(StringStream* accumulator,
515 // Determine the code for the frame.
516 virtual Code* unchecked_code() const;
518 // Returns the levels of inlining for this frame.
519 virtual int GetInlineCount() { return 1; }
521 // Return a list with JSFunctions of this frame.
522 virtual void GetFunctions(List<JSFunction*>* functions);
524 // Build a list with summaries for this frame including all inlined frames.
525 virtual void Summarize(List<FrameSummary>* frames);
527 static JavaScriptFrame* cast(StackFrame* frame) {
528 ASSERT(frame->is_java_script());
529 return static_cast<JavaScriptFrame*>(frame);
532 static void PrintTop(FILE* file, bool print_args, bool print_line_number);
535 inline explicit JavaScriptFrame(StackFrameIterator* iterator);
537 virtual Address GetCallerStackPointer() const;
539 virtual int GetNumberOfIncomingArguments() const;
541 // Garbage collection support. Iterates over incoming arguments,
542 // receiver, and any callee-saved registers.
543 void IterateArguments(ObjectVisitor* v) const;
546 inline Object* function_slot_object() const;
548 friend class StackFrameIterator;
549 friend class StackTracer;
553 class OptimizedFrame : public JavaScriptFrame {
555 virtual Type type() const { return OPTIMIZED; }
558 virtual void Iterate(ObjectVisitor* v) const;
560 virtual int GetInlineCount();
562 // Return a list with JSFunctions of this frame.
563 // The functions are ordered bottom-to-top (i.e. functions.last()
564 // is the top-most activation)
565 virtual void GetFunctions(List<JSFunction*>* functions);
567 virtual void Summarize(List<FrameSummary>* frames);
569 DeoptimizationInputData* GetDeoptimizationData(int* deopt_index);
572 inline explicit OptimizedFrame(StackFrameIterator* iterator);
575 friend class StackFrameIterator;
579 // Arguments adaptor frames are automatically inserted below
580 // JavaScript frames when the actual number of parameters does not
581 // match the formal number of parameters.
582 class ArgumentsAdaptorFrame: public JavaScriptFrame {
584 virtual Type type() const { return ARGUMENTS_ADAPTOR; }
586 // Determine the code for the frame.
587 virtual Code* unchecked_code() const;
589 static ArgumentsAdaptorFrame* cast(StackFrame* frame) {
590 ASSERT(frame->is_arguments_adaptor());
591 return static_cast<ArgumentsAdaptorFrame*>(frame);
595 virtual void Print(StringStream* accumulator,
600 inline explicit ArgumentsAdaptorFrame(StackFrameIterator* iterator);
602 virtual int GetNumberOfIncomingArguments() const;
604 virtual Address GetCallerStackPointer() const;
607 friend class StackFrameIterator;
611 class InternalFrame: public StandardFrame {
613 virtual Type type() const { return INTERNAL; }
615 // Garbage collection support.
616 virtual void Iterate(ObjectVisitor* v) const;
618 // Determine the code for the frame.
619 virtual Code* unchecked_code() const;
621 static InternalFrame* cast(StackFrame* frame) {
622 ASSERT(frame->is_internal());
623 return static_cast<InternalFrame*>(frame);
627 inline explicit InternalFrame(StackFrameIterator* iterator);
629 virtual Address GetCallerStackPointer() const;
632 friend class StackFrameIterator;
636 // Construct frames are special trampoline frames introduced to handle
637 // function invocations through 'new'.
638 class ConstructFrame: public InternalFrame {
640 virtual Type type() const { return CONSTRUCT; }
642 static ConstructFrame* cast(StackFrame* frame) {
643 ASSERT(frame->is_construct());
644 return static_cast<ConstructFrame*>(frame);
648 inline explicit ConstructFrame(StackFrameIterator* iterator);
651 friend class StackFrameIterator;
655 class StackFrameIterator BASE_EMBEDDED {
657 // An iterator that iterates over the current thread's stack,
658 // and uses current isolate.
659 StackFrameIterator();
661 // An iterator that iterates over the isolate's current thread's stack,
662 explicit StackFrameIterator(Isolate* isolate);
664 // An iterator that iterates over a given thread's stack.
665 StackFrameIterator(Isolate* isolate, ThreadLocalTop* t);
667 // An iterator that can start from a given FP address.
668 // If use_top, then work as usual, if fp isn't NULL, use it,
669 // otherwise, do nothing.
670 StackFrameIterator(Isolate* isolate, bool use_top, Address fp, Address sp);
672 StackFrame* frame() const {
677 Isolate* isolate() const { return isolate_; }
679 bool done() const { return frame_ == NULL; }
680 void Advance() { (this->*advance_)(); }
682 // Go back to the first frame.
687 #define DECLARE_SINGLETON(ignore, type) type type##_;
688 STACK_FRAME_TYPE_LIST(DECLARE_SINGLETON)
689 #undef DECLARE_SINGLETON
691 StackHandler* handler_;
692 ThreadLocalTop* thread_;
695 void (StackFrameIterator::*advance_)();
697 StackHandler* handler() const {
702 // Get the type-specific frame singleton in a given state.
703 StackFrame* SingletonFor(StackFrame::Type type, StackFrame::State* state);
704 // A helper function, can return a NULL pointer.
705 StackFrame* SingletonFor(StackFrame::Type type);
707 void AdvanceWithHandler();
708 void AdvanceWithoutHandler();
710 friend class StackFrame;
711 friend class SafeStackFrameIterator;
712 DISALLOW_COPY_AND_ASSIGN(StackFrameIterator);
716 // Iterator that supports iterating through all JavaScript frames.
717 template<typename Iterator>
718 class JavaScriptFrameIteratorTemp BASE_EMBEDDED {
720 JavaScriptFrameIteratorTemp() { if (!done()) Advance(); }
722 inline explicit JavaScriptFrameIteratorTemp(Isolate* isolate);
724 inline JavaScriptFrameIteratorTemp(Isolate* isolate, ThreadLocalTop* top);
726 // Skip frames until the frame with the given id is reached.
727 explicit JavaScriptFrameIteratorTemp(StackFrame::Id id) { AdvanceToId(id); }
729 inline JavaScriptFrameIteratorTemp(Isolate* isolate, StackFrame::Id id);
731 JavaScriptFrameIteratorTemp(Address fp,
734 Address high_bound) :
735 iterator_(fp, sp, low_bound, high_bound) {
736 if (!done()) Advance();
739 JavaScriptFrameIteratorTemp(Isolate* isolate,
743 Address high_bound) :
744 iterator_(isolate, fp, sp, low_bound, high_bound) {
745 if (!done()) Advance();
748 inline JavaScriptFrame* frame() const;
750 bool done() const { return iterator_.done(); }
753 // Advance to the frame holding the arguments for the current
754 // frame. This only affects the current frame if it has adapted
756 void AdvanceToArgumentsFrame();
758 // Go back to the first frame.
762 inline void AdvanceToId(StackFrame::Id id);
768 typedef JavaScriptFrameIteratorTemp<StackFrameIterator> JavaScriptFrameIterator;
771 // NOTE: The stack trace frame iterator is an iterator that only
772 // traverse proper JavaScript frames; that is JavaScript frames that
773 // have proper JavaScript functions. This excludes the problematic
774 // functions in runtime.js.
775 class StackTraceFrameIterator: public JavaScriptFrameIterator {
777 StackTraceFrameIterator();
778 explicit StackTraceFrameIterator(Isolate* isolate);
786 class SafeStackFrameIterator BASE_EMBEDDED {
788 SafeStackFrameIterator(Isolate* isolate,
789 Address fp, Address sp,
790 Address low_bound, Address high_bound);
792 StackFrame* frame() const {
793 ASSERT(is_working_iterator_);
794 return iterator_.frame();
797 bool done() const { return iteration_done_ ? true : iterator_.done(); }
802 static bool is_active(Isolate* isolate);
804 static bool IsWithinBounds(
805 Address low_bound, Address high_bound, Address addr) {
806 return low_bound <= addr && addr <= high_bound;
810 class StackAddressValidator {
812 StackAddressValidator(Address low_bound, Address high_bound)
813 : low_bound_(low_bound), high_bound_(high_bound) { }
814 bool IsValid(Address addr) const {
815 return IsWithinBounds(low_bound_, high_bound_, addr);
822 class ExitFrameValidator {
824 explicit ExitFrameValidator(const StackAddressValidator& validator)
825 : validator_(validator) { }
826 ExitFrameValidator(Address low_bound, Address high_bound)
827 : validator_(low_bound, high_bound) { }
828 bool IsValidFP(Address fp);
830 StackAddressValidator validator_;
833 bool IsValidStackAddress(Address addr) const {
834 return stack_validator_.IsValid(addr);
836 bool CanIterateHandles(StackFrame* frame, StackHandler* handler);
837 bool IsValidFrame(StackFrame* frame) const;
838 bool IsValidCaller(StackFrame* frame);
839 static bool IsValidTop(Isolate* isolate,
840 Address low_bound, Address high_bound);
842 // This is a nasty hack to make sure the active count is incremented
843 // before the constructor for the embedded iterator is invoked. This
844 // is needed because the constructor will start looking at frames
845 // right away and we need to make sure it doesn't start inspecting
847 class ActiveCountMaintainer BASE_EMBEDDED {
849 explicit ActiveCountMaintainer(Isolate* isolate);
850 ~ActiveCountMaintainer();
855 ActiveCountMaintainer maintainer_;
856 StackAddressValidator stack_validator_;
857 const bool is_valid_top_;
858 const bool is_valid_fp_;
859 const bool is_working_iterator_;
860 bool iteration_done_;
861 StackFrameIterator iterator_;
865 typedef JavaScriptFrameIteratorTemp<SafeStackFrameIterator>
866 SafeJavaScriptFrameIterator;
869 class SafeStackTraceFrameIterator: public SafeJavaScriptFrameIterator {
871 explicit SafeStackTraceFrameIterator(Isolate* isolate,
872 Address fp, Address sp,
873 Address low_bound, Address high_bound);
878 class StackFrameLocator BASE_EMBEDDED {
880 // Find the nth JavaScript frame on the stack. The caller must
881 // guarantee that such a frame exists.
882 JavaScriptFrame* FindJavaScriptFrame(int n);
885 StackFrameIterator iterator_;
889 // Reads all frames on the current stack and copies them into the current
891 Vector<StackFrame*> CreateStackMap();
893 } } // namespace v8::internal
895 #endif // V8_FRAMES_H_