v8  3.11.10(node0.8.26)
V8 is Google's open source JavaScript engine
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
frames.h
Go to the documentation of this file.
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
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 
31 #include "allocation.h"
32 #include "handles.h"
33 #include "safepoint-table.h"
34 
35 namespace v8 {
36 namespace internal {
37 
38 typedef uint32_t RegList;
39 
40 // Get the number of registers in a given register list.
41 int NumRegs(RegList list);
42 
44 
45 // Return the code of the n-th saved register available to JavaScript.
46 int JSCallerSavedCode(int n);
47 
48 
49 // Forward declarations.
50 class StackFrameIterator;
51 class ThreadLocalTop;
52 class Isolate;
53 
55  public:
59  SafepointEntry safepoint_entry;
60  };
61 
62  explicit InnerPointerToCodeCache(Isolate* isolate) : isolate_(isolate) {
63  Flush();
64  }
65 
67  Code* GcSafeCastToCode(HeapObject* object, Address inner_pointer);
68 
69  void Flush() {
70  memset(&cache_[0], 0, sizeof(cache_));
71  }
72 
73  InnerPointerToCodeCacheEntry* GetCacheEntry(Address inner_pointer);
74 
75  private:
76  InnerPointerToCodeCacheEntry* cache(int index) { return &cache_[index]; }
77 
78  Isolate* isolate_;
79 
80  static const int kInnerPointerToCodeCacheSize = 1024;
81  InnerPointerToCodeCacheEntry cache_[kInnerPointerToCodeCacheSize];
82 
83  DISALLOW_COPY_AND_ASSIGN(InnerPointerToCodeCache);
84 };
85 
86 
87 class StackHandler BASE_EMBEDDED {
88  public:
89  enum Kind {
93  LAST_KIND = FINALLY
94  };
95 
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> {};
101 
102  // Get the address of this stack handler.
103  inline Address address() const;
104 
105  // Get the next stack handler in the chain.
106  inline StackHandler* next() const;
107 
108  // Tells whether the given address is inside this handler.
109  inline bool includes(Address address) const;
110 
111  // Garbage collection support.
112  inline void Iterate(ObjectVisitor* v, Code* holder) const;
113 
114  // Conversion support.
115  static inline StackHandler* FromAddress(Address address);
116 
117  // Testers
118  inline bool is_js_entry() const;
119  inline bool is_catch() const;
120  inline bool is_finally() const;
121 
122  private:
123  // Accessors.
124  inline Kind kind() const;
125 
126  inline Object** context_address() const;
127  inline Object** code_address() const;
128 
129  DISALLOW_IMPLICIT_CONSTRUCTORS(StackHandler);
130 };
131 
132 
133 #define STACK_FRAME_TYPE_LIST(V) \
134  V(ENTRY, EntryFrame) \
135  V(ENTRY_CONSTRUCT, EntryConstructFrame) \
136  V(EXIT, ExitFrame) \
137  V(JAVA_SCRIPT, JavaScriptFrame) \
138  V(OPTIMIZED, OptimizedFrame) \
139  V(INTERNAL, InternalFrame) \
140  V(CONSTRUCT, ConstructFrame) \
141  V(ARGUMENTS_ADAPTOR, ArgumentsAdaptorFrame)
142 
143 
144 // Abstract base class for all stack frames.
146  public:
147 #define DECLARE_TYPE(type, ignore) type,
148  enum Type {
149  NONE = 0,
151  NUMBER_OF_TYPES,
152  // Used by FrameScope to indicate that the stack frame is constructed
153  // manually and the FrameScope does not need to emit code.
154  MANUAL
155  };
156 #undef DECLARE_TYPE
157 
158  // Opaque data type for identifying stack frames. Used extensively
159  // by the debugger.
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).
162  enum Id {
163  ID_MIN_VALUE = kMinInt,
164  ID_MAX_VALUE = kMaxInt,
165  NO_ID = 0
166  };
167 
168  // Used to mark the outermost JS entry frame.
170  INNER_JSENTRY_FRAME = 0,
171  OUTERMOST_JSENTRY_FRAME = 1
172  };
173 
174  struct State {
175  State() : sp(NULL), fp(NULL), pc_address(NULL) { }
179  };
180 
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_;
187  }
188 
189  // Type testers.
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; }
198 
199  bool is_java_script() const {
200  Type type = this->type();
201  return (type == JAVA_SCRIPT) || (type == OPTIMIZED);
202  }
203 
204  // Accessors.
205  Address sp() const { return state_.sp; }
206  Address fp() const { return state_.fp; }
207  Address caller_sp() const { return GetCallerStackPointer(); }
208 
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;
213 
214  Address pc() const { return *pc_address(); }
215  void set_pc(Address pc) { *pc_address() = pc; }
216 
217  virtual void SetCallerFp(Address caller_fp) = 0;
218 
219  // Manually changes value of fp in this object.
220  void UpdateFp(Address fp) { state_.fp = fp; }
221 
222  Address* pc_address() const { return state_.pc_address; }
223 
224  // Get the id of this stack frame.
225  Id id() const { return static_cast<Id>(OffsetFrom(caller_sp())); }
226 
227  // Checks if this frame includes any stack handlers.
228  bool HasHandler() const;
229 
230  // Get the type of this frame.
231  virtual Type type() const = 0;
232 
233  // Get the code associated with this frame.
234  // This method could be called during marking phase of GC.
235  virtual Code* unchecked_code() const = 0;
236 
237  // Get the code associated with this frame.
238  inline Code* LookupCode() const;
239 
240  // Get the code object that contains the given pc.
241  static inline Code* GetContainingCode(Isolate* isolate, Address pc);
242 
243  // Get the code object containing the given pc and fill in the
244  // safepoint entry and the number of stack slots. The pc must be at
245  // a safepoint.
246  static Code* GetSafepointData(Isolate* isolate,
247  Address pc,
248  SafepointEntry* safepoint_entry,
249  unsigned* stack_slots);
250 
251  virtual void Iterate(ObjectVisitor* v) const = 0;
252  static void IteratePc(ObjectVisitor* v, Address* pc_address, Code* holder);
253 
254  // Sets a callback function for return-address rewriting profilers
255  // to resolve the location of a return address to the location of the
256  // profiler's stashed return address.
257  static void SetReturnAddressLocationResolver(
259 
260  // Printing support.
261  enum PrintMode { OVERVIEW, DETAILS };
262  virtual void Print(StringStream* accumulator,
263  PrintMode mode,
264  int index) const { }
265 
266  protected:
267  inline explicit StackFrame(StackFrameIterator* iterator);
268  virtual ~StackFrame() { }
269 
270  Isolate* isolate() const { return isolate_; }
271 
272  // Compute the stack pointer for the calling frame.
273  virtual Address GetCallerStackPointer() const = 0;
274 
275  // Printing support.
276  static void PrintIndex(StringStream* accumulator,
277  PrintMode mode,
278  int index);
279 
280  // Get the top handler from the current stack iterator.
281  inline StackHandler* top_handler() const;
282 
283  // Compute the stack frame type for the given state.
284  static Type ComputeType(Isolate* isolate, State* state);
285 
286  private:
287  const StackFrameIterator* iterator_;
288  Isolate* isolate_;
289  State state_;
290 
291  // Fill in the state of the calling frame.
292  virtual void ComputeCallerState(State* state) const = 0;
293 
294  // Get the type and the state of the calling frame.
295  virtual Type GetCallerState(State* state) const;
296 
297  static const intptr_t kIsolateTag = 1;
298 
299  friend class StackFrameIterator;
300  friend class StackHandlerIterator;
301  friend class SafeStackFrameIterator;
302 
303  private:
304  void operator=(const StackFrame& original);
305 };
306 
307 
308 // Entry frames are used to enter JavaScript execution from C.
309 class EntryFrame: public StackFrame {
310  public:
311  virtual Type type() const { return ENTRY; }
312 
313  virtual Code* unchecked_code() const;
314 
315  // Garbage collection support.
316  virtual void Iterate(ObjectVisitor* v) const;
317 
318  static EntryFrame* cast(StackFrame* frame) {
319  ASSERT(frame->is_entry());
320  return static_cast<EntryFrame*>(frame);
321  }
322  virtual void SetCallerFp(Address caller_fp);
323 
324  protected:
325  inline explicit EntryFrame(StackFrameIterator* iterator);
326 
327  // The caller stack pointer for entry frames is always zero. The
328  // real information about the caller frame is available through the
329  // link to the top exit frame.
330  virtual Address GetCallerStackPointer() const { return 0; }
331 
332  private:
333  virtual void ComputeCallerState(State* state) const;
334  virtual Type GetCallerState(State* state) const;
335 
336  friend class StackFrameIterator;
337 };
338 
339 
341  public:
342  virtual Type type() const { return ENTRY_CONSTRUCT; }
343 
344  virtual Code* unchecked_code() const;
345 
347  ASSERT(frame->is_entry_construct());
348  return static_cast<EntryConstructFrame*>(frame);
349  }
350 
351  protected:
352  inline explicit EntryConstructFrame(StackFrameIterator* iterator);
353 
354  private:
355  friend class StackFrameIterator;
356 };
357 
358 
359 // Exit frames are used to exit JavaScript execution and go to C.
360 class ExitFrame: public StackFrame {
361  public:
362  virtual Type type() const { return EXIT; }
363 
364  virtual Code* unchecked_code() const;
365 
366  Object*& code_slot() const;
367 
368  // Garbage collection support.
369  virtual void Iterate(ObjectVisitor* v) const;
370 
371  virtual void SetCallerFp(Address caller_fp);
372 
373  static ExitFrame* cast(StackFrame* frame) {
374  ASSERT(frame->is_exit());
375  return static_cast<ExitFrame*>(frame);
376  }
377 
378  // Compute the state and type of an exit frame given a frame
379  // pointer. Used when constructing the first stack frame seen by an
380  // iterator and the frames following entry frames.
381  static Type GetStateForFramePointer(Address fp, State* state);
382  static Address ComputeStackPointer(Address fp);
383  static void FillState(Address fp, Address sp, State* state);
384 
385  protected:
386  inline explicit ExitFrame(StackFrameIterator* iterator);
387 
388  virtual Address GetCallerStackPointer() const;
389 
390  private:
391  virtual void ComputeCallerState(State* state) const;
392 
393  friend class StackFrameIterator;
394 };
395 
396 
397 class StandardFrame: public StackFrame {
398  public:
399  // Testers.
400  virtual bool is_standard() const { return true; }
401 
402  // Accessors.
403  inline Object* context() const;
404 
405  // Access the expressions in the stack frame including locals.
406  inline Object* GetExpression(int index) const;
407  inline void SetExpression(int index, Object* value);
408  int ComputeExpressionsCount() const;
409  static Object* GetExpression(Address fp, int index);
410 
411  virtual void SetCallerFp(Address caller_fp);
412 
413  static StandardFrame* cast(StackFrame* frame) {
414  ASSERT(frame->is_standard());
415  return static_cast<StandardFrame*>(frame);
416  }
417 
418  protected:
419  inline explicit StandardFrame(StackFrameIterator* iterator);
420 
421  virtual void ComputeCallerState(State* state) const;
422 
423  // Accessors.
424  inline Address caller_fp() const;
425  inline Address caller_pc() const;
426 
427  // Computes the address of the PC field in the standard frame given
428  // by the provided frame pointer.
429  static inline Address ComputePCAddress(Address fp);
430 
431  // Iterate over expression stack including stack handlers, locals,
432  // and parts of the fixed part including context and code fields.
433  void IterateExpressions(ObjectVisitor* v) const;
434 
435  // Returns the address of the n'th expression stack element.
436  Address GetExpressionAddress(int n) const;
437  static Address GetExpressionAddress(Address fp, int n);
438 
439  // Determines if the n'th expression stack element is in a stack
440  // handler or not. Requires traversing all handlers in this frame.
441  bool IsExpressionInsideHandler(int n) const;
442 
443  // Determines if the standard frame for the given frame pointer is
444  // an arguments adaptor frame.
445  static inline bool IsArgumentsAdaptorFrame(Address fp);
446 
447  // Determines if the standard frame for the given frame pointer is a
448  // construct frame.
449  static inline bool IsConstructFrame(Address fp);
450 
451  private:
452  friend class StackFrame;
453  friend class StackFrameIterator;
454 };
455 
456 
457 class FrameSummary BASE_EMBEDDED {
458  public:
459  FrameSummary(Object* receiver,
460  JSFunction* function,
461  Code* code,
462  int offset,
463  bool is_constructor)
464  : receiver_(receiver),
465  function_(function),
466  code_(code),
467  offset_(offset),
468  is_constructor_(is_constructor) { }
469  Handle<Object> receiver() { return receiver_; }
470  Handle<JSFunction> function() { return function_; }
471  Handle<Code> code() { return code_; }
472  Address pc() { return code_->address() + offset_; }
473  int offset() { return offset_; }
474  bool is_constructor() { return is_constructor_; }
475 
476  void Print();
477 
478  private:
479  Handle<Object> receiver_;
480  Handle<JSFunction> function_;
481  Handle<Code> code_;
482  int offset_;
483  bool is_constructor_;
484 };
485 
486 
488  public:
489  virtual Type type() const { return JAVA_SCRIPT; }
490 
491  // Accessors.
492  inline Object* function() const;
493  inline Object* receiver() const;
494  inline void set_receiver(Object* value);
495 
496  // Access the parameters.
497  inline Address GetParameterSlot(int index) const;
498  inline Object* GetParameter(int index) const;
499  inline int ComputeParametersCount() const {
500  return GetNumberOfIncomingArguments();
501  }
502 
503  // Check if this frame is a constructor frame invoked through 'new'.
504  bool IsConstructor() const;
505 
506  // Check if this frame has "adapted" arguments in the sense that the
507  // actual passed arguments are available in an arguments adaptor
508  // frame below it on the stack.
509  inline bool has_adapted_arguments() const;
510  int GetArgumentsLength() const;
511 
512  // Garbage collection support.
513  virtual void Iterate(ObjectVisitor* v) const;
514 
515  // Printing support.
516  virtual void Print(StringStream* accumulator,
517  PrintMode mode,
518  int index) const;
519 
520  // Determine the code for the frame.
521  virtual Code* unchecked_code() const;
522 
523  // Returns the levels of inlining for this frame.
524  virtual int GetInlineCount() { return 1; }
525 
526  // Return a list with JSFunctions of this frame.
527  virtual void GetFunctions(List<JSFunction*>* functions);
528 
529  // Build a list with summaries for this frame including all inlined frames.
530  virtual void Summarize(List<FrameSummary>* frames);
531 
532  static JavaScriptFrame* cast(StackFrame* frame) {
533  ASSERT(frame->is_java_script());
534  return static_cast<JavaScriptFrame*>(frame);
535  }
536 
537  static void PrintTop(FILE* file, bool print_args, bool print_line_number);
538 
539  protected:
540  inline explicit JavaScriptFrame(StackFrameIterator* iterator);
541 
542  virtual Address GetCallerStackPointer() const;
543 
544  virtual int GetNumberOfIncomingArguments() const;
545 
546  // Garbage collection support. Iterates over incoming arguments,
547  // receiver, and any callee-saved registers.
548  void IterateArguments(ObjectVisitor* v) const;
549 
550  private:
551  inline Object* function_slot_object() const;
552 
553  friend class StackFrameIterator;
554  friend class StackTracer;
555 };
556 
557 
559  public:
560  virtual Type type() const { return OPTIMIZED; }
561 
562  // GC support.
563  virtual void Iterate(ObjectVisitor* v) const;
564 
565  virtual int GetInlineCount();
566 
567  // Return a list with JSFunctions of this frame.
568  // The functions are ordered bottom-to-top (i.e. functions.last()
569  // is the top-most activation)
570  virtual void GetFunctions(List<JSFunction*>* functions);
571 
572  virtual void Summarize(List<FrameSummary>* frames);
573 
574  DeoptimizationInputData* GetDeoptimizationData(int* deopt_index);
575 
576  protected:
577  inline explicit OptimizedFrame(StackFrameIterator* iterator);
578 
579  private:
580  friend class StackFrameIterator;
581 };
582 
583 
584 // Arguments adaptor frames are automatically inserted below
585 // JavaScript frames when the actual number of parameters does not
586 // match the formal number of parameters.
588  public:
589  virtual Type type() const { return ARGUMENTS_ADAPTOR; }
590 
591  // Determine the code for the frame.
592  virtual Code* unchecked_code() const;
593 
595  ASSERT(frame->is_arguments_adaptor());
596  return static_cast<ArgumentsAdaptorFrame*>(frame);
597  }
598 
599  // Printing support.
600  virtual void Print(StringStream* accumulator,
601  PrintMode mode,
602  int index) const;
603 
604  protected:
605  inline explicit ArgumentsAdaptorFrame(StackFrameIterator* iterator);
606 
607  virtual int GetNumberOfIncomingArguments() const;
608 
609  virtual Address GetCallerStackPointer() const;
610 
611  private:
612  friend class StackFrameIterator;
613 };
614 
615 
617  public:
618  virtual Type type() const { return INTERNAL; }
619 
620  // Garbage collection support.
621  virtual void Iterate(ObjectVisitor* v) const;
622 
623  // Determine the code for the frame.
624  virtual Code* unchecked_code() const;
625 
626  static InternalFrame* cast(StackFrame* frame) {
627  ASSERT(frame->is_internal());
628  return static_cast<InternalFrame*>(frame);
629  }
630 
631  protected:
632  inline explicit InternalFrame(StackFrameIterator* iterator);
633 
634  virtual Address GetCallerStackPointer() const;
635 
636  private:
637  friend class StackFrameIterator;
638 };
639 
640 
641 // Construct frames are special trampoline frames introduced to handle
642 // function invocations through 'new'.
644  public:
645  virtual Type type() const { return CONSTRUCT; }
646 
647  static ConstructFrame* cast(StackFrame* frame) {
648  ASSERT(frame->is_construct());
649  return static_cast<ConstructFrame*>(frame);
650  }
651 
652  protected:
653  inline explicit ConstructFrame(StackFrameIterator* iterator);
654 
655  private:
656  friend class StackFrameIterator;
657 };
658 
659 
660 class StackFrameIterator BASE_EMBEDDED {
661  public:
662  // An iterator that iterates over the current thread's stack,
663  // and uses current isolate.
664  StackFrameIterator();
665 
666  // An iterator that iterates over the isolate's current thread's stack,
667  explicit StackFrameIterator(Isolate* isolate);
668 
669  // An iterator that iterates over a given thread's stack.
670  StackFrameIterator(Isolate* isolate, ThreadLocalTop* t);
671 
672  // An iterator that can start from a given FP address.
673  // If use_top, then work as usual, if fp isn't NULL, use it,
674  // otherwise, do nothing.
675  StackFrameIterator(Isolate* isolate, bool use_top, Address fp, Address sp);
676 
677  StackFrame* frame() const {
678  ASSERT(!done());
679  return frame_;
680  }
681 
682  Isolate* isolate() const { return isolate_; }
683 
684  bool done() const { return frame_ == NULL; }
685  void Advance() { (this->*advance_)(); }
686 
687  // Go back to the first frame.
688  void Reset();
689 
690  private:
691  Isolate* isolate_;
692 #define DECLARE_SINGLETON(ignore, type) type type##_;
694 #undef DECLARE_SINGLETON
695  StackFrame* frame_;
696  StackHandler* handler_;
697  ThreadLocalTop* thread_;
698  Address fp_;
699  Address sp_;
700  void (StackFrameIterator::*advance_)();
701 
702  StackHandler* handler() const {
703  ASSERT(!done());
704  return handler_;
705  }
706 
707  // Get the type-specific frame singleton in a given state.
708  StackFrame* SingletonFor(StackFrame::Type type, StackFrame::State* state);
709  // A helper function, can return a NULL pointer.
710  StackFrame* SingletonFor(StackFrame::Type type);
711 
712  void AdvanceWithHandler();
713  void AdvanceWithoutHandler();
714 
715  friend class StackFrame;
716  friend class SafeStackFrameIterator;
717  DISALLOW_COPY_AND_ASSIGN(StackFrameIterator);
718 };
719 
720 
721 // Iterator that supports iterating through all JavaScript frames.
722 template<typename Iterator>
723 class JavaScriptFrameIteratorTemp BASE_EMBEDDED {
724  public:
725  JavaScriptFrameIteratorTemp() { if (!done()) Advance(); }
726 
727  inline explicit JavaScriptFrameIteratorTemp(Isolate* isolate);
728 
729  inline JavaScriptFrameIteratorTemp(Isolate* isolate, ThreadLocalTop* top);
730 
731  // Skip frames until the frame with the given id is reached.
732  explicit JavaScriptFrameIteratorTemp(StackFrame::Id id) { AdvanceToId(id); }
733 
734  inline JavaScriptFrameIteratorTemp(Isolate* isolate, StackFrame::Id id);
735 
737  Address sp,
738  Address low_bound,
739  Address high_bound) :
740  iterator_(fp, sp, low_bound, high_bound) {
741  if (!done()) Advance();
742  }
743 
745  Address fp,
746  Address sp,
747  Address low_bound,
748  Address high_bound) :
749  iterator_(isolate, fp, sp, low_bound, high_bound) {
750  if (!done()) Advance();
751  }
752 
753  inline JavaScriptFrame* frame() const;
754 
755  bool done() const { return iterator_.done(); }
756  void Advance();
757 
758  // Advance to the frame holding the arguments for the current
759  // frame. This only affects the current frame if it has adapted
760  // arguments.
761  void AdvanceToArgumentsFrame();
762 
763  // Go back to the first frame.
764  void Reset();
765 
766  private:
767  inline void AdvanceToId(StackFrame::Id id);
768 
769  Iterator iterator_;
770 };
771 
772 
773 typedef JavaScriptFrameIteratorTemp<StackFrameIterator> JavaScriptFrameIterator;
774 
775 
776 // NOTE: The stack trace frame iterator is an iterator that only
777 // traverse proper JavaScript frames; that is JavaScript frames that
778 // have proper JavaScript functions. This excludes the problematic
779 // functions in runtime.js.
781  public:
783  explicit StackTraceFrameIterator(Isolate* isolate);
784  void Advance();
785 
786  private:
787  bool IsValidFrame();
788 };
789 
790 
791 class SafeStackFrameIterator BASE_EMBEDDED {
792  public:
793  SafeStackFrameIterator(Isolate* isolate,
794  Address fp, Address sp,
795  Address low_bound, Address high_bound);
796 
797  StackFrame* frame() const {
798  ASSERT(is_working_iterator_);
799  return iterator_.frame();
800  }
801 
802  bool done() const { return iteration_done_ ? true : iterator_.done(); }
803 
804  void Advance();
805  void Reset();
806 
807  static bool is_active(Isolate* isolate);
808 
809  static bool IsWithinBounds(
810  Address low_bound, Address high_bound, Address addr) {
811  return low_bound <= addr && addr <= high_bound;
812  }
813 
814  private:
815  class StackAddressValidator {
816  public:
817  StackAddressValidator(Address low_bound, Address high_bound)
818  : low_bound_(low_bound), high_bound_(high_bound) { }
819  bool IsValid(Address addr) const {
820  return IsWithinBounds(low_bound_, high_bound_, addr);
821  }
822  private:
823  Address low_bound_;
824  Address high_bound_;
825  };
826 
827  class ExitFrameValidator {
828  public:
829  explicit ExitFrameValidator(const StackAddressValidator& validator)
830  : validator_(validator) { }
831  ExitFrameValidator(Address low_bound, Address high_bound)
832  : validator_(low_bound, high_bound) { }
833  bool IsValidFP(Address fp);
834  private:
835  StackAddressValidator validator_;
836  };
837 
838  bool IsValidStackAddress(Address addr) const {
839  return stack_validator_.IsValid(addr);
840  }
841  bool CanIterateHandles(StackFrame* frame, StackHandler* handler);
842  bool IsValidFrame(StackFrame* frame) const;
843  bool IsValidCaller(StackFrame* frame);
844  static bool IsValidTop(Isolate* isolate,
845  Address low_bound, Address high_bound);
846 
847  // This is a nasty hack to make sure the active count is incremented
848  // before the constructor for the embedded iterator is invoked. This
849  // is needed because the constructor will start looking at frames
850  // right away and we need to make sure it doesn't start inspecting
851  // heap objects.
852  class ActiveCountMaintainer BASE_EMBEDDED {
853  public:
854  explicit ActiveCountMaintainer(Isolate* isolate);
855  ~ActiveCountMaintainer();
856  private:
857  Isolate* isolate_;
858  };
859 
860  ActiveCountMaintainer maintainer_;
861  StackAddressValidator stack_validator_;
862  const bool is_valid_top_;
863  const bool is_valid_fp_;
864  const bool is_working_iterator_;
865  bool iteration_done_;
866  StackFrameIterator iterator_;
867 };
868 
869 
870 typedef JavaScriptFrameIteratorTemp<SafeStackFrameIterator>
872 
873 
875  public:
876  explicit SafeStackTraceFrameIterator(Isolate* isolate,
877  Address fp, Address sp,
878  Address low_bound, Address high_bound);
879  void Advance();
880 };
881 
882 
883 class StackFrameLocator BASE_EMBEDDED {
884  public:
885  // Find the nth JavaScript frame on the stack. The caller must
886  // guarantee that such a frame exists.
887  JavaScriptFrame* FindJavaScriptFrame(int n);
888 
889  private:
890  StackFrameIterator iterator_;
891 };
892 
893 
894 // Reads all frames on the current stack and copies them into the current
895 // zone memory.
896 Vector<StackFrame*> CreateStackMap(Zone* zone);
897 
898 } } // namespace v8::internal
899 
900 #endif // V8_FRAMES_H_
byte * Address
Definition: globals.h:172
virtual Type type() const
Definition: frames.h:645
const int kMinInt
Definition: globals.h:225
Definition: frames.h:56
void Reset()
Definition: flags.cc:1446
Code * GcSafeCastToCode(HeapObject *object, Address inner_pointer)
Definition: frames.cc:1307
static bool IsWithinBounds(Address low_bound, Address high_bound, Address addr)
Definition: frames.h:809
static EntryFrame * cast(StackFrame *frame)
Definition: frames.h:318
int NumRegs(RegList reglist)
Definition: frames.cc:1375
bool done() const
Definition: frames.h:684
virtual bool is_standard() const
Definition: frames.h:197
void UpdateFp(Address fp)
Definition: frames.h:220
static StandardFrame * cast(StackFrame *frame)
Definition: frames.h:413
uint32_t RegList
Definition: frames.h:38
const int kMaxInt
Definition: globals.h:224
InnerPointerToCodeCache(Isolate *isolate)
Definition: frames.h:62
JavaScriptFrameIteratorTemp(Isolate *isolate, Address fp, Address sp, Address low_bound, Address high_bound)
Definition: frames.h:744
#define ASSERT(condition)
Definition: checks.h:270
static ConstructFrame * cast(StackFrame *frame)
Definition: frames.h:647
v8::Handle< v8::Value > Print(const v8::Arguments &args)
Address fp() const
Definition: frames.h:206
static InternalFrame * cast(StackFrame *frame)
Definition: frames.h:626
StackFrame * frame() const
Definition: frames.h:677
Vector< StackFrame * > CreateStackMap(Zone *zone)
Definition: frames.cc:1427
bool is_optimized() const
Definition: frames.h:193
int ComputeParametersCount() const
Definition: frames.h:499
Address sp() const
Definition: frames.h:205
bool is_internal() const
Definition: frames.h:195
virtual Type type() const
Definition: frames.h:589
bool is_construct() const
Definition: frames.h:196
#define STACK_FRAME_TYPE_LIST(V)
Definition: frames.h:133
#define DECLARE_TYPE(type, ignore)
Definition: frames.h:147
Handle< Object > receiver()
Definition: frames.h:469
int JSCallerSavedCode(int n)
Definition: frames.cc:1395
virtual Type type() const
Definition: frames.h:560
const Register sp
HANDLE HANDLE LPSTACKFRAME64 StackFrame
Address pc() const
Definition: frames.h:214
#define DECLARE_SINGLETON(ignore, type)
Definition: frames.h:692
STATIC_ASSERT((FixedDoubleArray::kHeaderSize &kDoubleAlignmentMask)==0)
virtual void Print(StringStream *accumulator, PrintMode mode, int index) const
Definition: frames.h:262
bool is_exit() const
Definition: frames.h:192
Address * pc_address() const
Definition: frames.h:222
intptr_t OffsetFrom(T x)
Definition: utils.h:126
bool is_arguments_adaptor() const
Definition: frames.h:194
uintptr_t(* ReturnAddressLocationResolver)(uintptr_t return_addr_location)
Definition: v8.h:2917
#define DISALLOW_IMPLICIT_CONSTRUCTORS(TypeName)
Definition: globals.h:332
FrameSummary(Object *receiver, JSFunction *function, Code *code, int offset, bool is_constructor)
Definition: frames.h:459
#define DISALLOW_COPY_AND_ASSIGN(TypeName)
Definition: globals.h:321
const Register pc
Code * code
Definition: frames.h:58
JavaScriptFrameIteratorTemp< SafeStackFrameIterator > SafeJavaScriptFrameIterator
Definition: frames.h:871
virtual Type type() const
Definition: frames.h:342
virtual Type type() const
Definition: frames.h:362
void set_pc(Address pc)
Definition: frames.h:215
virtual Type type() const
Definition: frames.h:618
static JavaScriptFrame * cast(StackFrame *frame)
Definition: frames.h:532
#define BASE_EMBEDDED
Definition: allocation.h:68
bool is_entry() const
Definition: frames.h:190
static ExitFrame * cast(StackFrame *frame)
Definition: frames.h:373
Address caller_sp() const
Definition: frames.h:207
Isolate * isolate() const
Definition: frames.h:270
void SetUpJSCallerSavedCodeData()
Definition: frames.cc:1386
JavaScriptFrameIteratorTemp< StackFrameIterator > JavaScriptFrameIterator
Definition: frames.h:773
InnerPointerToCodeCacheEntry * GetCacheEntry(Address inner_pointer)
Definition: frames.cc:1349
Definition: frames.h:340
activate correct semantics for inheriting readonliness enable harmony semantics for typeof enable harmony enable harmony proxies enable all harmony harmony_scoping harmony_proxies harmony_scoping tracks arrays with only smi values automatically unbox arrays of doubles use crankshaft use hydrogen range analysis use hydrogen global value numbering use function inlining maximum number of AST nodes considered for a single inlining loop invariant code motion print statistics for hydrogen trace generated IR for specified phases trace register allocator trace range analysis trace representation types environment for every instruction put a break point before deoptimizing polymorphic inlining perform array bounds checks elimination trace on stack replacement optimize closures functions with arguments object optimize functions containing for in loops profiler considers IC stability primitive functions trigger their own optimization re try self optimization if it failed insert an interrupt check at function exit execution budget before interrupt is triggered call count before self optimization self_optimization count_based_interrupts weighted_back_edges trace_opt emit comments in code disassembly enable use of SSE3 instructions if available enable use of CMOV instruction if available enable use of SAHF instruction if enable use of VFP3 instructions if available this implies enabling ARMv7 enable use of ARMv7 instructions if enable use of MIPS FPU instructions if NULL
Definition: flags.cc:274
Handle< Code > code()
Definition: frames.h:471
bool is_java_script() const
Definition: frames.h:199
Address inner_pointer
Definition: frames.h:57
virtual Type type() const
Definition: frames.h:489
SafepointEntry safepoint_entry
Definition: frames.h:59
virtual bool is_standard() const
Definition: frames.h:400
bool is_entry_construct() const
Definition: frames.h:191
JavaScriptFrameIteratorTemp(Address fp, Address sp, Address low_bound, Address high_bound)
Definition: frames.h:736
const Register fp
StackFrame(const StackFrame &original)
Definition: frames.h:183
Code * GcSafeFindCodeForInnerPointer(Address inner_pointer)
Definition: frames.cc:1315
static EntryConstructFrame * cast(StackFrame *frame)
Definition: frames.h:346
virtual int GetInlineCount()
Definition: frames.h:524
static ArgumentsAdaptorFrame * cast(StackFrame *frame)
Definition: frames.h:594
Definition: frames.h:309
virtual Address GetCallerStackPointer() const
Definition: frames.h:330
JavaScriptFrameIteratorTemp(StackFrame::Id id)
Definition: frames.h:732
FlagType type() const
Definition: flags.cc:1358
virtual Type type() const
Definition: frames.h:311