v8  3.14.5(node0.10.28)
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  JSFunction* LiteralAt(FixedArray* literal_array, int literal_id);
581 
582  friend class StackFrameIterator;
583 };
584 
585 
586 // Arguments adaptor frames are automatically inserted below
587 // JavaScript frames when the actual number of parameters does not
588 // match the formal number of parameters.
590  public:
591  virtual Type type() const { return ARGUMENTS_ADAPTOR; }
592 
593  // Determine the code for the frame.
594  virtual Code* unchecked_code() const;
595 
597  ASSERT(frame->is_arguments_adaptor());
598  return static_cast<ArgumentsAdaptorFrame*>(frame);
599  }
600 
601  // Printing support.
602  virtual void Print(StringStream* accumulator,
603  PrintMode mode,
604  int index) const;
605 
606  protected:
607  inline explicit ArgumentsAdaptorFrame(StackFrameIterator* iterator);
608 
609  virtual int GetNumberOfIncomingArguments() const;
610 
611  virtual Address GetCallerStackPointer() const;
612 
613  private:
614  friend class StackFrameIterator;
615 };
616 
617 
619  public:
620  virtual Type type() const { return INTERNAL; }
621 
622  // Garbage collection support.
623  virtual void Iterate(ObjectVisitor* v) const;
624 
625  // Determine the code for the frame.
626  virtual Code* unchecked_code() const;
627 
628  static InternalFrame* cast(StackFrame* frame) {
629  ASSERT(frame->is_internal());
630  return static_cast<InternalFrame*>(frame);
631  }
632 
633  protected:
634  inline explicit InternalFrame(StackFrameIterator* iterator);
635 
636  virtual Address GetCallerStackPointer() const;
637 
638  private:
639  friend class StackFrameIterator;
640 };
641 
642 
643 // Construct frames are special trampoline frames introduced to handle
644 // function invocations through 'new'.
646  public:
647  virtual Type type() const { return CONSTRUCT; }
648 
649  static ConstructFrame* cast(StackFrame* frame) {
650  ASSERT(frame->is_construct());
651  return static_cast<ConstructFrame*>(frame);
652  }
653 
654  protected:
655  inline explicit ConstructFrame(StackFrameIterator* iterator);
656 
657  private:
658  friend class StackFrameIterator;
659 };
660 
661 
662 class StackFrameIterator BASE_EMBEDDED {
663  public:
664  // An iterator that iterates over the current thread's stack,
665  // and uses current isolate.
666  StackFrameIterator();
667 
668  // An iterator that iterates over the isolate's current thread's stack,
669  explicit StackFrameIterator(Isolate* isolate);
670 
671  // An iterator that iterates over a given thread's stack.
672  StackFrameIterator(Isolate* isolate, ThreadLocalTop* t);
673 
674  // An iterator that can start from a given FP address.
675  // If use_top, then work as usual, if fp isn't NULL, use it,
676  // otherwise, do nothing.
677  StackFrameIterator(Isolate* isolate, bool use_top, Address fp, Address sp);
678 
679  StackFrame* frame() const {
680  ASSERT(!done());
681  return frame_;
682  }
683 
684  Isolate* isolate() const { return isolate_; }
685 
686  bool done() const { return frame_ == NULL; }
687  void Advance() { (this->*advance_)(); }
688 
689  // Go back to the first frame.
690  void Reset();
691 
692  private:
693  Isolate* isolate_;
694 #define DECLARE_SINGLETON(ignore, type) type type##_;
696 #undef DECLARE_SINGLETON
697  StackFrame* frame_;
698  StackHandler* handler_;
699  ThreadLocalTop* thread_;
700  Address fp_;
701  Address sp_;
702  void (StackFrameIterator::*advance_)();
703 
704  StackHandler* handler() const {
705  ASSERT(!done());
706  return handler_;
707  }
708 
709  // Get the type-specific frame singleton in a given state.
710  StackFrame* SingletonFor(StackFrame::Type type, StackFrame::State* state);
711  // A helper function, can return a NULL pointer.
712  StackFrame* SingletonFor(StackFrame::Type type);
713 
714  void AdvanceWithHandler();
715  void AdvanceWithoutHandler();
716 
717  friend class StackFrame;
718  friend class SafeStackFrameIterator;
719  DISALLOW_COPY_AND_ASSIGN(StackFrameIterator);
720 };
721 
722 
723 // Iterator that supports iterating through all JavaScript frames.
724 template<typename Iterator>
725 class JavaScriptFrameIteratorTemp BASE_EMBEDDED {
726  public:
727  JavaScriptFrameIteratorTemp() { if (!done()) Advance(); }
728 
729  inline explicit JavaScriptFrameIteratorTemp(Isolate* isolate);
730 
731  inline JavaScriptFrameIteratorTemp(Isolate* isolate, ThreadLocalTop* top);
732 
733  // Skip frames until the frame with the given id is reached.
734  explicit JavaScriptFrameIteratorTemp(StackFrame::Id id) { AdvanceToId(id); }
735 
736  inline JavaScriptFrameIteratorTemp(Isolate* isolate, StackFrame::Id id);
737 
739  Address sp,
740  Address low_bound,
741  Address high_bound) :
742  iterator_(fp, sp, low_bound, high_bound) {
743  if (!done()) Advance();
744  }
745 
747  Address fp,
748  Address sp,
749  Address low_bound,
750  Address high_bound) :
751  iterator_(isolate, fp, sp, low_bound, high_bound) {
752  if (!done()) Advance();
753  }
754 
755  inline JavaScriptFrame* frame() const;
756 
757  bool done() const { return iterator_.done(); }
758  void Advance();
759 
760  // Advance to the frame holding the arguments for the current
761  // frame. This only affects the current frame if it has adapted
762  // arguments.
763  void AdvanceToArgumentsFrame();
764 
765  // Go back to the first frame.
766  void Reset();
767 
768  private:
769  inline void AdvanceToId(StackFrame::Id id);
770 
771  Iterator iterator_;
772 };
773 
774 
775 typedef JavaScriptFrameIteratorTemp<StackFrameIterator> JavaScriptFrameIterator;
776 
777 
778 // NOTE: The stack trace frame iterator is an iterator that only
779 // traverse proper JavaScript frames; that is JavaScript frames that
780 // have proper JavaScript functions. This excludes the problematic
781 // functions in runtime.js.
783  public:
785  explicit StackTraceFrameIterator(Isolate* isolate);
786  void Advance();
787 
788  private:
789  bool IsValidFrame();
790 };
791 
792 
793 class SafeStackFrameIterator BASE_EMBEDDED {
794  public:
795  SafeStackFrameIterator(Isolate* isolate,
796  Address fp, Address sp,
797  Address low_bound, Address high_bound);
798 
799  StackFrame* frame() const {
800  ASSERT(is_working_iterator_);
801  return iterator_.frame();
802  }
803 
804  bool done() const { return iteration_done_ ? true : iterator_.done(); }
805 
806  void Advance();
807  void Reset();
808 
809  static bool is_active(Isolate* isolate);
810 
811  static bool IsWithinBounds(
812  Address low_bound, Address high_bound, Address addr) {
813  return low_bound <= addr && addr <= high_bound;
814  }
815 
816  private:
817  class StackAddressValidator {
818  public:
819  StackAddressValidator(Address low_bound, Address high_bound)
820  : low_bound_(low_bound), high_bound_(high_bound) { }
821  bool IsValid(Address addr) const {
822  return IsWithinBounds(low_bound_, high_bound_, addr);
823  }
824  private:
825  Address low_bound_;
826  Address high_bound_;
827  };
828 
829  class ExitFrameValidator {
830  public:
831  explicit ExitFrameValidator(const StackAddressValidator& validator)
832  : validator_(validator) { }
833  ExitFrameValidator(Address low_bound, Address high_bound)
834  : validator_(low_bound, high_bound) { }
835  bool IsValidFP(Address fp);
836  private:
837  StackAddressValidator validator_;
838  };
839 
840  bool IsValidStackAddress(Address addr) const {
841  return stack_validator_.IsValid(addr);
842  }
843  bool CanIterateHandles(StackFrame* frame, StackHandler* handler);
844  bool IsValidFrame(StackFrame* frame) const;
845  bool IsValidCaller(StackFrame* frame);
846  static bool IsValidTop(Isolate* isolate,
847  Address low_bound, Address high_bound);
848 
849  // This is a nasty hack to make sure the active count is incremented
850  // before the constructor for the embedded iterator is invoked. This
851  // is needed because the constructor will start looking at frames
852  // right away and we need to make sure it doesn't start inspecting
853  // heap objects.
854  class ActiveCountMaintainer BASE_EMBEDDED {
855  public:
856  explicit ActiveCountMaintainer(Isolate* isolate);
857  ~ActiveCountMaintainer();
858  private:
859  Isolate* isolate_;
860  };
861 
862  ActiveCountMaintainer maintainer_;
863  StackAddressValidator stack_validator_;
864  const bool is_valid_top_;
865  const bool is_valid_fp_;
866  const bool is_working_iterator_;
867  bool iteration_done_;
868  StackFrameIterator iterator_;
869 };
870 
871 
872 typedef JavaScriptFrameIteratorTemp<SafeStackFrameIterator>
874 
875 
877  public:
878  explicit SafeStackTraceFrameIterator(Isolate* isolate,
879  Address fp, Address sp,
880  Address low_bound, Address high_bound);
881  void Advance();
882 };
883 
884 
885 class StackFrameLocator BASE_EMBEDDED {
886  public:
887  // Find the nth JavaScript frame on the stack. The caller must
888  // guarantee that such a frame exists.
889  JavaScriptFrame* FindJavaScriptFrame(int n);
890 
891  private:
892  StackFrameIterator iterator_;
893 };
894 
895 
896 // Reads all frames on the current stack and copies them into the current
897 // zone memory.
898 Vector<StackFrame*> CreateStackMap(Zone* zone);
899 
900 } } // namespace v8::internal
901 
902 #endif // V8_FRAMES_H_
byte * Address
Definition: globals.h:157
virtual Type type() const
Definition: frames.h:647
const int kMinInt
Definition: globals.h:211
Definition: frames.h:56
Code * GcSafeCastToCode(HeapObject *object, Address inner_pointer)
Definition: frames.cc:1315
static bool IsWithinBounds(Address low_bound, Address high_bound, Address addr)
Definition: frames.h:811
static EntryFrame * cast(StackFrame *frame)
Definition: frames.h:318
int NumRegs(RegList reglist)
Definition: frames.cc:1383
bool done() const
Definition: frames.h:686
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:210
InnerPointerToCodeCache(Isolate *isolate)
Definition: frames.h:62
JavaScriptFrameIteratorTemp(Isolate *isolate, Address fp, Address sp, Address low_bound, Address high_bound)
Definition: frames.h:746
#define ASSERT(condition)
Definition: checks.h:270
static ConstructFrame * cast(StackFrame *frame)
Definition: frames.h:649
v8::Handle< v8::Value > Print(const v8::Arguments &args)
Address fp() const
Definition: frames.h:206
static InternalFrame * cast(StackFrame *frame)
Definition: frames.h:628
StackFrame * frame() const
Definition: frames.h:679
Vector< StackFrame * > CreateStackMap(Zone *zone)
Definition: frames.cc:1435
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:591
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:1403
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:694
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:2950
#define DISALLOW_IMPLICIT_CONSTRUCTORS(TypeName)
Definition: globals.h:318
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:307
const Register pc
Code * code
Definition: frames.h:58
JavaScriptFrameIteratorTemp< SafeStackFrameIterator > SafeJavaScriptFrameIterator
Definition: frames.h:873
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:620
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:1394
JavaScriptFrameIteratorTemp< StackFrameIterator > JavaScriptFrameIterator
Definition: frames.h:775
InnerPointerToCodeCacheEntry * GetCacheEntry(Address inner_pointer)
Definition: frames.cc:1357
Definition: frames.h:340
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
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 use dead code elimination trace on stack replacement optimize closures cache optimized code for closures functions with arguments object loop weight for representation inference allow uint32 values on optimize frames if they are used only in safe operations track parallel recompilation enable all profiler experiments number of stack frames inspected by the profiler call recompile stub directly when self optimizing trigger profiler ticks based on counting instead of timing weight back edges by jump distance for interrupt triggering percentage of ICs that must have type info to allow optimization watch_ic_patching retry_self_opt interrupt_at_exit extra verbose compilation tracing generate extra 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 and VFP2 enable use of VFP2 instructions if available enable use of SDIV and UDIV instructions if enable loading bit constant by means of movw movt instruction enable unaligned accesses for enable use of MIPS FPU instructions if NULL
Definition: flags.cc:301
SafepointEntry safepoint_entry
Definition: frames.h:59
virtual bool is_standard() const
Definition: frames.h:400
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 use dead code elimination trace on stack replacement optimize closures cache optimized code for closures functions with arguments object loop weight for representation inference allow uint32 values on optimize frames if they are used only in safe operations track parallel recompilation enable all profiler experiments number of stack frames inspected by the profiler call recompile stub directly when self optimizing trigger profiler ticks based on counting instead of timing weight back edges by jump distance for interrupt triggering percentage of ICs that must have type info to allow optimization watch_ic_patching retry_self_opt interrupt_at_exit extra verbose compilation tracing generate extra code(assertions) for debugging") DEFINE_bool(code_comments
bool is_entry_construct() const
Definition: frames.h:191
JavaScriptFrameIteratorTemp(Address fp, Address sp, Address low_bound, Address high_bound)
Definition: frames.h:738
const Register fp
StackFrame(const StackFrame &original)
Definition: frames.h:183
Code * GcSafeFindCodeForInnerPointer(Address inner_pointer)
Definition: frames.cc:1323
static EntryConstructFrame * cast(StackFrame *frame)
Definition: frames.h:346
virtual int GetInlineCount()
Definition: frames.h:524
static ArgumentsAdaptorFrame * cast(StackFrame *frame)
Definition: frames.h:596
Definition: frames.h:309
virtual Address GetCallerStackPointer() const
Definition: frames.h:330
JavaScriptFrameIteratorTemp(StackFrame::Id id)
Definition: frames.h:734
virtual Type type() const
Definition: frames.h:311