Home | History | Annotate | Download | only in src
      1 // Copyright 2012 the V8 project authors. All rights reserved.
      2 // Use of this source code is governed by a BSD-style license that can be
      3 // found in the LICENSE file.
      4 
      5 #ifndef V8_FRAMES_H_
      6 #define V8_FRAMES_H_
      7 
      8 #include "src/allocation.h"
      9 #include "src/handles.h"
     10 #include "src/safepoint-table.h"
     11 
     12 namespace v8 {
     13 namespace internal {
     14 
     15 #if V8_TARGET_ARCH_ARM64
     16 typedef uint64_t RegList;
     17 #else
     18 typedef uint32_t RegList;
     19 #endif
     20 
     21 // Get the number of registers in a given register list.
     22 int NumRegs(RegList list);
     23 
     24 void SetUpJSCallerSavedCodeData();
     25 
     26 // Return the code of the n-th saved register available to JavaScript.
     27 int JSCallerSavedCode(int n);
     28 
     29 
     30 // Forward declarations.
     31 class ExternalCallbackScope;
     32 class StackFrameIteratorBase;
     33 class ThreadLocalTop;
     34 class Isolate;
     35 
     36 class InnerPointerToCodeCache {
     37  public:
     38   struct InnerPointerToCodeCacheEntry {
     39     Address inner_pointer;
     40     Code* code;
     41     SafepointEntry safepoint_entry;
     42   };
     43 
     44   explicit InnerPointerToCodeCache(Isolate* isolate) : isolate_(isolate) {
     45     Flush();
     46   }
     47 
     48   Code* GcSafeFindCodeForInnerPointer(Address inner_pointer);
     49   Code* GcSafeCastToCode(HeapObject* object, Address inner_pointer);
     50 
     51   void Flush() {
     52     memset(&cache_[0], 0, sizeof(cache_));
     53   }
     54 
     55   InnerPointerToCodeCacheEntry* GetCacheEntry(Address inner_pointer);
     56 
     57  private:
     58   InnerPointerToCodeCacheEntry* cache(int index) { return &cache_[index]; }
     59 
     60   Isolate* isolate_;
     61 
     62   static const int kInnerPointerToCodeCacheSize = 1024;
     63   InnerPointerToCodeCacheEntry cache_[kInnerPointerToCodeCacheSize];
     64 
     65   DISALLOW_COPY_AND_ASSIGN(InnerPointerToCodeCache);
     66 };
     67 
     68 
     69 // Every try-block pushes the context register.
     70 class TryBlockConstant : public AllStatic {
     71  public:
     72   static const int kElementCount = 1;
     73 };
     74 
     75 
     76 class StackHandlerConstants : public AllStatic {
     77  public:
     78   static const int kNextOffset = 0 * kPointerSize;
     79 
     80   static const int kSize = kNextOffset + kPointerSize;
     81   static const int kSlotCount = kSize >> kPointerSizeLog2;
     82 };
     83 
     84 
     85 class StackHandler BASE_EMBEDDED {
     86  public:
     87   // Get the address of this stack handler.
     88   inline Address address() const;
     89 
     90   // Get the next stack handler in the chain.
     91   inline StackHandler* next() const;
     92 
     93   // Conversion support.
     94   static inline StackHandler* FromAddress(Address address);
     95 
     96  private:
     97   DISALLOW_IMPLICIT_CONSTRUCTORS(StackHandler);
     98 };
     99 
    100 
    101 #define STACK_FRAME_TYPE_LIST(V)                         \
    102   V(ENTRY, EntryFrame)                                   \
    103   V(ENTRY_CONSTRUCT, EntryConstructFrame)                \
    104   V(EXIT, ExitFrame)                                     \
    105   V(JAVA_SCRIPT, JavaScriptFrame)                        \
    106   V(OPTIMIZED, OptimizedFrame)                           \
    107   V(INTERPRETED, InterpretedFrame)                       \
    108   V(STUB, StubFrame)                                     \
    109   V(STUB_FAILURE_TRAMPOLINE, StubFailureTrampolineFrame) \
    110   V(INTERNAL, InternalFrame)                             \
    111   V(CONSTRUCT, ConstructFrame)                           \
    112   V(ARGUMENTS_ADAPTOR, ArgumentsAdaptorFrame)
    113 
    114 
    115 class StandardFrameConstants : public AllStatic {
    116  public:
    117   // Fixed part of the frame consists of return address, caller fp,
    118   // constant pool (if FLAG_enable_embedded_constant_pool), context, and
    119   // function. StandardFrame::IterateExpressions assumes that kLastObjectOffset
    120   // is the last object pointer.
    121   static const int kCPSlotSize =
    122       FLAG_enable_embedded_constant_pool ? kPointerSize : 0;
    123   static const int kFixedFrameSizeFromFp =  2 * kPointerSize + kCPSlotSize;
    124   static const int kFixedFrameSizeAboveFp = kPCOnStackSize + kFPOnStackSize;
    125   static const int kFixedFrameSize =
    126       kFixedFrameSizeAboveFp + kFixedFrameSizeFromFp;
    127   static const int kFixedSlotCountAboveFp =
    128       kFixedFrameSizeAboveFp / kPointerSize;
    129   static const int kFixedSlotCount = kFixedFrameSize / kPointerSize;
    130   static const int kCPSlotCount = kCPSlotSize / kPointerSize;
    131   static const int kExpressionsOffset = -3 * kPointerSize - kCPSlotSize;
    132   static const int kMarkerOffset = -2 * kPointerSize - kCPSlotSize;
    133   static const int kContextOffset = -1 * kPointerSize - kCPSlotSize;
    134   static const int kConstantPoolOffset = kCPSlotSize ? -1 * kPointerSize : 0;
    135   static const int kCallerFPOffset = 0 * kPointerSize;
    136   static const int kCallerPCOffset = +1 * kFPOnStackSize;
    137   static const int kCallerSPOffset = kCallerPCOffset + 1 * kPCOnStackSize;
    138 
    139   static const int kLastObjectOffset = kContextOffset;
    140 };
    141 
    142 
    143 class ArgumentsAdaptorFrameConstants : public AllStatic {
    144  public:
    145   // FP-relative.
    146   static const int kLengthOffset = StandardFrameConstants::kExpressionsOffset;
    147 
    148   static const int kFrameSize =
    149       StandardFrameConstants::kFixedFrameSize + kPointerSize;
    150 };
    151 
    152 
    153 class InternalFrameConstants : public AllStatic {
    154  public:
    155   // FP-relative.
    156   static const int kCodeOffset = StandardFrameConstants::kExpressionsOffset;
    157 };
    158 
    159 
    160 class ConstructFrameConstants : public AllStatic {
    161  public:
    162   // FP-relative.
    163   static const int kImplicitReceiverOffset =
    164       StandardFrameConstants::kExpressionsOffset - 3 * kPointerSize;
    165   static const int kLengthOffset =
    166       StandardFrameConstants::kExpressionsOffset - 2 * kPointerSize;
    167   static const int kAllocationSiteOffset =
    168       StandardFrameConstants::kExpressionsOffset - 1 * kPointerSize;
    169   static const int kCodeOffset =
    170       StandardFrameConstants::kExpressionsOffset - 0 * kPointerSize;
    171 
    172   static const int kFrameSize =
    173       StandardFrameConstants::kFixedFrameSize + 4 * kPointerSize;
    174 };
    175 
    176 
    177 class InterpreterFrameConstants : public AllStatic {
    178  public:
    179   // Fixed frame includes new.target and bytecode offset.
    180   static const int kFixedFrameSize =
    181       StandardFrameConstants::kFixedFrameSize + 2 * kPointerSize;
    182   static const int kFixedFrameSizeFromFp =
    183       StandardFrameConstants::kFixedFrameSizeFromFp + 2 * kPointerSize;
    184 
    185   // FP-relative.
    186   static const int kRegisterFilePointerFromFp =
    187       -StandardFrameConstants::kFixedFrameSizeFromFp - 3 * kPointerSize;
    188 
    189   // Register file pointer relative.
    190   static const int kLastParamFromRegisterPointer =
    191       StandardFrameConstants::kFixedFrameSize + 3 * kPointerSize;
    192 
    193   static const int kBytecodeOffsetFromRegisterPointer = 1 * kPointerSize;
    194   static const int kNewTargetFromRegisterPointer = 2 * kPointerSize;
    195   static const int kFunctionFromRegisterPointer = 3 * kPointerSize;
    196   static const int kContextFromRegisterPointer = 4 * kPointerSize;
    197 };
    198 
    199 
    200 // Abstract base class for all stack frames.
    201 class StackFrame BASE_EMBEDDED {
    202  public:
    203 #define DECLARE_TYPE(type, ignore) type,
    204   enum Type {
    205     NONE = 0,
    206     STACK_FRAME_TYPE_LIST(DECLARE_TYPE)
    207     NUMBER_OF_TYPES,
    208     // Used by FrameScope to indicate that the stack frame is constructed
    209     // manually and the FrameScope does not need to emit code.
    210     MANUAL
    211   };
    212 #undef DECLARE_TYPE
    213 
    214   // Opaque data type for identifying stack frames. Used extensively
    215   // by the debugger.
    216   // ID_MIN_VALUE and ID_MAX_VALUE are specified to ensure that enumeration type
    217   // has correct value range (see Issue 830 for more details).
    218   enum Id {
    219     ID_MIN_VALUE = kMinInt,
    220     ID_MAX_VALUE = kMaxInt,
    221     NO_ID = 0
    222   };
    223 
    224   // Used to mark the outermost JS entry frame.
    225   enum JsFrameMarker {
    226     INNER_JSENTRY_FRAME = 0,
    227     OUTERMOST_JSENTRY_FRAME = 1
    228   };
    229 
    230   struct State {
    231     State() : sp(NULL), fp(NULL), pc_address(NULL),
    232               constant_pool_address(NULL) { }
    233     Address sp;
    234     Address fp;
    235     Address* pc_address;
    236     Address* constant_pool_address;
    237   };
    238 
    239   // Copy constructor; it breaks the connection to host iterator
    240   // (as an iterator usually lives on stack).
    241   StackFrame(const StackFrame& original) {
    242     this->state_ = original.state_;
    243     this->iterator_ = NULL;
    244     this->isolate_ = original.isolate_;
    245   }
    246 
    247   // Type testers.
    248   bool is_entry() const { return type() == ENTRY; }
    249   bool is_entry_construct() const { return type() == ENTRY_CONSTRUCT; }
    250   bool is_exit() const { return type() == EXIT; }
    251   bool is_optimized() const { return type() == OPTIMIZED; }
    252   bool is_arguments_adaptor() const { return type() == ARGUMENTS_ADAPTOR; }
    253   bool is_internal() const { return type() == INTERNAL; }
    254   bool is_stub_failure_trampoline() const {
    255     return type() == STUB_FAILURE_TRAMPOLINE;
    256   }
    257   bool is_construct() const { return type() == CONSTRUCT; }
    258   virtual bool is_standard() const { return false; }
    259 
    260   bool is_java_script() const {
    261     Type type = this->type();
    262     return (type == JAVA_SCRIPT) || (type == OPTIMIZED) ||
    263            (type == INTERPRETED);
    264   }
    265 
    266   // Accessors.
    267   Address sp() const { return state_.sp; }
    268   Address fp() const { return state_.fp; }
    269   Address caller_sp() const { return GetCallerStackPointer(); }
    270 
    271   // If this frame is optimized and was dynamically aligned return its old
    272   // unaligned frame pointer.  When the frame is deoptimized its FP will shift
    273   // up one word and become unaligned.
    274   Address UnpaddedFP() const;
    275 
    276   Address pc() const { return *pc_address(); }
    277   void set_pc(Address pc) { *pc_address() = pc; }
    278 
    279   Address constant_pool() const { return *constant_pool_address(); }
    280   void set_constant_pool(Address constant_pool) {
    281     *constant_pool_address() = constant_pool;
    282   }
    283 
    284   virtual void SetCallerFp(Address caller_fp) = 0;
    285 
    286   // Manually changes value of fp in this object.
    287   void UpdateFp(Address fp) { state_.fp = fp; }
    288 
    289   Address* pc_address() const { return state_.pc_address; }
    290 
    291   Address* constant_pool_address() const {
    292     return state_.constant_pool_address;
    293   }
    294 
    295   // Get the id of this stack frame.
    296   Id id() const { return static_cast<Id>(OffsetFrom(caller_sp())); }
    297 
    298   // Get the top handler from the current stack iterator.
    299   inline StackHandler* top_handler() const;
    300 
    301   // Get the type of this frame.
    302   virtual Type type() const = 0;
    303 
    304   // Get the code associated with this frame.
    305   // This method could be called during marking phase of GC.
    306   virtual Code* unchecked_code() const = 0;
    307 
    308   // Get the code associated with this frame.
    309   inline Code* LookupCode() const;
    310 
    311   // Get the code object that contains the given pc.
    312   static inline Code* GetContainingCode(Isolate* isolate, Address pc);
    313 
    314   // Get the code object containing the given pc and fill in the
    315   // safepoint entry and the number of stack slots. The pc must be at
    316   // a safepoint.
    317   static Code* GetSafepointData(Isolate* isolate,
    318                                 Address pc,
    319                                 SafepointEntry* safepoint_entry,
    320                                 unsigned* stack_slots);
    321 
    322   virtual void Iterate(ObjectVisitor* v) const = 0;
    323   static void IteratePc(ObjectVisitor* v, Address* pc_address,
    324                         Address* constant_pool_address, Code* holder);
    325 
    326   // Sets a callback function for return-address rewriting profilers
    327   // to resolve the location of a return address to the location of the
    328   // profiler's stashed return address.
    329   static void SetReturnAddressLocationResolver(
    330       ReturnAddressLocationResolver resolver);
    331 
    332   // Resolves pc_address through the resolution address function if one is set.
    333   static inline Address* ResolveReturnAddressLocation(Address* pc_address);
    334 
    335   // Printing support.
    336   enum PrintMode { OVERVIEW, DETAILS };
    337   virtual void Print(StringStream* accumulator,
    338                      PrintMode mode,
    339                      int index) const { }
    340 
    341   Isolate* isolate() const { return isolate_; }
    342 
    343  protected:
    344   inline explicit StackFrame(StackFrameIteratorBase* iterator);
    345   virtual ~StackFrame() { }
    346 
    347   // Compute the stack pointer for the calling frame.
    348   virtual Address GetCallerStackPointer() const = 0;
    349 
    350   // Printing support.
    351   static void PrintIndex(StringStream* accumulator,
    352                          PrintMode mode,
    353                          int index);
    354 
    355   // Compute the stack frame type for the given state.
    356   static Type ComputeType(const StackFrameIteratorBase* iterator, State* state);
    357 
    358 #ifdef DEBUG
    359   bool can_access_heap_objects() const;
    360 #endif
    361 
    362  private:
    363   const StackFrameIteratorBase* iterator_;
    364   Isolate* isolate_;
    365   State state_;
    366 
    367   static ReturnAddressLocationResolver return_address_location_resolver_;
    368 
    369   // Fill in the state of the calling frame.
    370   virtual void ComputeCallerState(State* state) const = 0;
    371 
    372   // Get the type and the state of the calling frame.
    373   virtual Type GetCallerState(State* state) const;
    374 
    375   static const intptr_t kIsolateTag = 1;
    376 
    377   friend class StackFrameIterator;
    378   friend class StackFrameIteratorBase;
    379   friend class StackHandlerIterator;
    380   friend class SafeStackFrameIterator;
    381 
    382  private:
    383   void operator=(const StackFrame& original);
    384 };
    385 
    386 
    387 // Entry frames are used to enter JavaScript execution from C.
    388 class EntryFrame: public StackFrame {
    389  public:
    390   Type type() const override { return ENTRY; }
    391 
    392   Code* unchecked_code() const override;
    393 
    394   // Garbage collection support.
    395   void Iterate(ObjectVisitor* v) const override;
    396 
    397   static EntryFrame* cast(StackFrame* frame) {
    398     DCHECK(frame->is_entry());
    399     return static_cast<EntryFrame*>(frame);
    400   }
    401   void SetCallerFp(Address caller_fp) override;
    402 
    403  protected:
    404   inline explicit EntryFrame(StackFrameIteratorBase* iterator);
    405 
    406   // The caller stack pointer for entry frames is always zero. The
    407   // real information about the caller frame is available through the
    408   // link to the top exit frame.
    409   Address GetCallerStackPointer() const override { return 0; }
    410 
    411  private:
    412   void ComputeCallerState(State* state) const override;
    413   Type GetCallerState(State* state) const override;
    414 
    415   friend class StackFrameIteratorBase;
    416 };
    417 
    418 
    419 class EntryConstructFrame: public EntryFrame {
    420  public:
    421   Type type() const override { return ENTRY_CONSTRUCT; }
    422 
    423   Code* unchecked_code() const override;
    424 
    425   static EntryConstructFrame* cast(StackFrame* frame) {
    426     DCHECK(frame->is_entry_construct());
    427     return static_cast<EntryConstructFrame*>(frame);
    428   }
    429 
    430  protected:
    431   inline explicit EntryConstructFrame(StackFrameIteratorBase* iterator);
    432 
    433  private:
    434   friend class StackFrameIteratorBase;
    435 };
    436 
    437 
    438 // Exit frames are used to exit JavaScript execution and go to C.
    439 class ExitFrame: public StackFrame {
    440  public:
    441   Type type() const override { return EXIT; }
    442 
    443   Code* unchecked_code() const override;
    444 
    445   Object*& code_slot() const;
    446 
    447   // Garbage collection support.
    448   void Iterate(ObjectVisitor* v) const override;
    449 
    450   void SetCallerFp(Address caller_fp) override;
    451 
    452   static ExitFrame* cast(StackFrame* frame) {
    453     DCHECK(frame->is_exit());
    454     return static_cast<ExitFrame*>(frame);
    455   }
    456 
    457   // Compute the state and type of an exit frame given a frame
    458   // pointer. Used when constructing the first stack frame seen by an
    459   // iterator and the frames following entry frames.
    460   static Type GetStateForFramePointer(Address fp, State* state);
    461   static Address ComputeStackPointer(Address fp);
    462   static void FillState(Address fp, Address sp, State* state);
    463 
    464  protected:
    465   inline explicit ExitFrame(StackFrameIteratorBase* iterator);
    466 
    467   Address GetCallerStackPointer() const override;
    468 
    469  private:
    470   void ComputeCallerState(State* state) const override;
    471 
    472   friend class StackFrameIteratorBase;
    473 };
    474 
    475 
    476 class StandardFrame: public StackFrame {
    477  public:
    478   // Testers.
    479   bool is_standard() const override { return true; }
    480 
    481   // Accessors.
    482   inline Object* context() const;
    483 
    484   // Access the expressions in the stack frame including locals.
    485   inline Object* GetExpression(int index) const;
    486   inline void SetExpression(int index, Object* value);
    487   int ComputeExpressionsCount() const;
    488   static Object* GetExpression(Address fp, int index);
    489 
    490   void SetCallerFp(Address caller_fp) override;
    491 
    492   static StandardFrame* cast(StackFrame* frame) {
    493     DCHECK(frame->is_standard());
    494     return static_cast<StandardFrame*>(frame);
    495   }
    496 
    497  protected:
    498   inline explicit StandardFrame(StackFrameIteratorBase* iterator);
    499 
    500   void ComputeCallerState(State* state) const override;
    501 
    502   // Accessors.
    503   inline Address caller_fp() const;
    504   inline Address caller_pc() const;
    505 
    506   // Computes the address of the PC field in the standard frame given
    507   // by the provided frame pointer.
    508   static inline Address ComputePCAddress(Address fp);
    509 
    510   // Computes the address of the constant pool  field in the standard
    511   // frame given by the provided frame pointer.
    512   static inline Address ComputeConstantPoolAddress(Address fp);
    513 
    514   // Iterate over expression stack including stack handlers, locals,
    515   // and parts of the fixed part including context and code fields.
    516   void IterateExpressions(ObjectVisitor* v) const;
    517 
    518   // Returns the address of the n'th expression stack element.
    519   Address GetExpressionAddress(int n) const;
    520   static Address GetExpressionAddress(Address fp, int n);
    521 
    522   // Determines if the standard frame for the given frame pointer is
    523   // an arguments adaptor frame.
    524   static inline bool IsArgumentsAdaptorFrame(Address fp);
    525 
    526   // Determines if the standard frame for the given frame pointer is a
    527   // construct frame.
    528   static inline bool IsConstructFrame(Address fp);
    529 
    530   // Used by OptimizedFrames and StubFrames.
    531   void IterateCompiledFrame(ObjectVisitor* v) const;
    532 
    533  private:
    534   friend class StackFrame;
    535   friend class SafeStackFrameIterator;
    536 };
    537 
    538 
    539 class FrameSummary BASE_EMBEDDED {
    540  public:
    541   FrameSummary(Object* receiver, JSFunction* function, Code* code, int offset,
    542                bool is_constructor);
    543 
    544   Handle<Object> receiver() { return receiver_; }
    545   Handle<JSFunction> function() { return function_; }
    546   Handle<Code> code() { return code_; }
    547   Address pc() { return code_->address() + offset_; }
    548   int offset() { return offset_; }
    549   bool is_constructor() { return is_constructor_; }
    550 
    551   void Print();
    552 
    553  private:
    554   Handle<Object> receiver_;
    555   Handle<JSFunction> function_;
    556   Handle<Code> code_;
    557   int offset_;
    558   bool is_constructor_;
    559 };
    560 
    561 
    562 class JavaScriptFrame: public StandardFrame {
    563  public:
    564   Type type() const override { return JAVA_SCRIPT; }
    565 
    566   // Accessors.
    567   inline JSFunction* function() const;
    568   inline Object* receiver() const;
    569   inline void set_receiver(Object* value);
    570 
    571   // Access the parameters.
    572   inline Address GetParameterSlot(int index) const;
    573   inline Object* GetParameter(int index) const;
    574   inline int ComputeParametersCount() const {
    575     return GetNumberOfIncomingArguments();
    576   }
    577 
    578   // Access the operand stack.
    579   inline Address GetOperandSlot(int index) const;
    580   inline Object* GetOperand(int index) const;
    581   inline int ComputeOperandsCount() const;
    582 
    583   // Generator support to preserve operand stack.
    584   void SaveOperandStack(FixedArray* store) const;
    585   void RestoreOperandStack(FixedArray* store);
    586 
    587   // Debugger access.
    588   void SetParameterValue(int index, Object* value) const;
    589 
    590   // Check if this frame is a constructor frame invoked through 'new'.
    591   bool IsConstructor() const;
    592 
    593   // Determines whether this frame includes inlined activations. To get details
    594   // about the inlined frames use {GetFunctions} and {Summarize}.
    595   bool HasInlinedFrames() const;
    596 
    597   // Check if this frame has "adapted" arguments in the sense that the
    598   // actual passed arguments are available in an arguments adaptor
    599   // frame below it on the stack.
    600   inline bool has_adapted_arguments() const;
    601   int GetArgumentsLength() const;
    602 
    603   // Garbage collection support.
    604   void Iterate(ObjectVisitor* v) const override;
    605 
    606   // Printing support.
    607   void Print(StringStream* accumulator, PrintMode mode,
    608              int index) const override;
    609 
    610   // Determine the code for the frame.
    611   Code* unchecked_code() const override;
    612 
    613   // Return a list with JSFunctions of this frame.
    614   virtual void GetFunctions(List<JSFunction*>* functions) const;
    615 
    616   // Build a list with summaries for this frame including all inlined frames.
    617   virtual void Summarize(List<FrameSummary>* frames);
    618 
    619   // Lookup exception handler for current {pc}, returns -1 if none found. Also
    620   // returns the expected number of stack slots at the handler site.
    621   virtual int LookupExceptionHandlerInTable(
    622       int* stack_slots, HandlerTable::CatchPrediction* prediction);
    623 
    624   // Architecture-specific register description.
    625   static Register fp_register();
    626   static Register context_register();
    627   static Register constant_pool_pointer_register();
    628 
    629   static JavaScriptFrame* cast(StackFrame* frame) {
    630     DCHECK(frame->is_java_script());
    631     return static_cast<JavaScriptFrame*>(frame);
    632   }
    633 
    634   static void PrintFunctionAndOffset(JSFunction* function, Code* code,
    635                                      Address pc, FILE* file,
    636                                      bool print_line_number);
    637 
    638   static void PrintTop(Isolate* isolate, FILE* file, bool print_args,
    639                        bool print_line_number);
    640 
    641  protected:
    642   inline explicit JavaScriptFrame(StackFrameIteratorBase* iterator);
    643 
    644   Address GetCallerStackPointer() const override;
    645 
    646   virtual int GetNumberOfIncomingArguments() const;
    647 
    648   // Garbage collection support. Iterates over incoming arguments,
    649   // receiver, and any callee-saved registers.
    650   void IterateArguments(ObjectVisitor* v) const;
    651 
    652  private:
    653   inline Object* function_slot_object() const;
    654 
    655   friend class StackFrameIteratorBase;
    656 };
    657 
    658 
    659 class StubFrame : public StandardFrame {
    660  public:
    661   Type type() const override { return STUB; }
    662 
    663   // GC support.
    664   void Iterate(ObjectVisitor* v) const override;
    665 
    666   // Determine the code for the frame.
    667   Code* unchecked_code() const override;
    668 
    669  protected:
    670   inline explicit StubFrame(StackFrameIteratorBase* iterator);
    671 
    672   Address GetCallerStackPointer() const override;
    673 
    674   virtual int GetNumberOfIncomingArguments() const;
    675 
    676   friend class StackFrameIteratorBase;
    677 };
    678 
    679 
    680 class OptimizedFrame : public JavaScriptFrame {
    681  public:
    682   Type type() const override { return OPTIMIZED; }
    683 
    684   // GC support.
    685   void Iterate(ObjectVisitor* v) const override;
    686 
    687   // Return a list with JSFunctions of this frame.
    688   // The functions are ordered bottom-to-top (i.e. functions.last()
    689   // is the top-most activation)
    690   void GetFunctions(List<JSFunction*>* functions) const override;
    691 
    692   void Summarize(List<FrameSummary>* frames) override;
    693 
    694   // Lookup exception handler for current {pc}, returns -1 if none found. Also
    695   // returns the expected number of stack slots at the handler site.
    696   int LookupExceptionHandlerInTable(
    697       int* stack_slots, HandlerTable::CatchPrediction* prediction) override;
    698 
    699   DeoptimizationInputData* GetDeoptimizationData(int* deopt_index) const;
    700 
    701   static int StackSlotOffsetRelativeToFp(int slot_index);
    702 
    703  protected:
    704   inline explicit OptimizedFrame(StackFrameIteratorBase* iterator);
    705 
    706  private:
    707   friend class StackFrameIteratorBase;
    708 
    709   Object* StackSlotAt(int index) const;
    710 };
    711 
    712 
    713 class InterpretedFrame : public JavaScriptFrame {
    714   Type type() const override { return INTERPRETED; }
    715 
    716  protected:
    717   inline explicit InterpretedFrame(StackFrameIteratorBase* iterator);
    718 
    719  private:
    720   friend class StackFrameIteratorBase;
    721 };
    722 
    723 
    724 // Arguments adaptor frames are automatically inserted below
    725 // JavaScript frames when the actual number of parameters does not
    726 // match the formal number of parameters.
    727 class ArgumentsAdaptorFrame: public JavaScriptFrame {
    728  public:
    729   Type type() const override { return ARGUMENTS_ADAPTOR; }
    730 
    731   // Determine the code for the frame.
    732   Code* unchecked_code() const override;
    733 
    734   static ArgumentsAdaptorFrame* cast(StackFrame* frame) {
    735     DCHECK(frame->is_arguments_adaptor());
    736     return static_cast<ArgumentsAdaptorFrame*>(frame);
    737   }
    738 
    739   // Printing support.
    740   void Print(StringStream* accumulator, PrintMode mode,
    741              int index) const override;
    742 
    743  protected:
    744   inline explicit ArgumentsAdaptorFrame(StackFrameIteratorBase* iterator);
    745 
    746   int GetNumberOfIncomingArguments() const override;
    747 
    748   Address GetCallerStackPointer() const override;
    749 
    750  private:
    751   friend class StackFrameIteratorBase;
    752 };
    753 
    754 
    755 class InternalFrame: public StandardFrame {
    756  public:
    757   Type type() const override { return INTERNAL; }
    758 
    759   // Garbage collection support.
    760   void Iterate(ObjectVisitor* v) const override;
    761 
    762   // Determine the code for the frame.
    763   Code* unchecked_code() const override;
    764 
    765   static InternalFrame* cast(StackFrame* frame) {
    766     DCHECK(frame->is_internal());
    767     return static_cast<InternalFrame*>(frame);
    768   }
    769 
    770  protected:
    771   inline explicit InternalFrame(StackFrameIteratorBase* iterator);
    772 
    773   Address GetCallerStackPointer() const override;
    774 
    775  private:
    776   friend class StackFrameIteratorBase;
    777 };
    778 
    779 
    780 class StubFailureTrampolineFrame: public StandardFrame {
    781  public:
    782   // sizeof(Arguments) - sizeof(Arguments*) is 3 * kPointerSize), but the
    783   // presubmit script complains about using sizeof() on a type.
    784   static const int kFirstRegisterParameterFrameOffset =
    785       StandardFrameConstants::kMarkerOffset - 3 * kPointerSize;
    786 
    787   static const int kCallerStackParameterCountFrameOffset =
    788       StandardFrameConstants::kMarkerOffset - 2 * kPointerSize;
    789 
    790   Type type() const override { return STUB_FAILURE_TRAMPOLINE; }
    791 
    792   // Get the code associated with this frame.
    793   // This method could be called during marking phase of GC.
    794   Code* unchecked_code() const override;
    795 
    796   void Iterate(ObjectVisitor* v) const override;
    797 
    798   // Architecture-specific register description.
    799   static Register fp_register();
    800   static Register context_register();
    801   static Register constant_pool_pointer_register();
    802 
    803  protected:
    804   inline explicit StubFailureTrampolineFrame(
    805       StackFrameIteratorBase* iterator);
    806 
    807   Address GetCallerStackPointer() const override;
    808 
    809  private:
    810   friend class StackFrameIteratorBase;
    811 };
    812 
    813 
    814 // Construct frames are special trampoline frames introduced to handle
    815 // function invocations through 'new'.
    816 class ConstructFrame: public InternalFrame {
    817  public:
    818   Type type() const override { return CONSTRUCT; }
    819 
    820   static ConstructFrame* cast(StackFrame* frame) {
    821     DCHECK(frame->is_construct());
    822     return static_cast<ConstructFrame*>(frame);
    823   }
    824 
    825  protected:
    826   inline explicit ConstructFrame(StackFrameIteratorBase* iterator);
    827 
    828  private:
    829   friend class StackFrameIteratorBase;
    830 };
    831 
    832 
    833 class StackFrameIteratorBase BASE_EMBEDDED {
    834  public:
    835   Isolate* isolate() const { return isolate_; }
    836 
    837   bool done() const { return frame_ == NULL; }
    838 
    839  protected:
    840   // An iterator that iterates over a given thread's stack.
    841   StackFrameIteratorBase(Isolate* isolate, bool can_access_heap_objects);
    842 
    843   Isolate* isolate_;
    844 #define DECLARE_SINGLETON(ignore, type) type type##_;
    845   STACK_FRAME_TYPE_LIST(DECLARE_SINGLETON)
    846 #undef DECLARE_SINGLETON
    847   StackFrame* frame_;
    848   StackHandler* handler_;
    849   const bool can_access_heap_objects_;
    850 
    851   StackHandler* handler() const {
    852     DCHECK(!done());
    853     return handler_;
    854   }
    855 
    856   // Get the type-specific frame singleton in a given state.
    857   StackFrame* SingletonFor(StackFrame::Type type, StackFrame::State* state);
    858   // A helper function, can return a NULL pointer.
    859   StackFrame* SingletonFor(StackFrame::Type type);
    860 
    861  private:
    862   friend class StackFrame;
    863   DISALLOW_COPY_AND_ASSIGN(StackFrameIteratorBase);
    864 };
    865 
    866 
    867 class StackFrameIterator: public StackFrameIteratorBase {
    868  public:
    869   // An iterator that iterates over the isolate's current thread's stack,
    870   explicit StackFrameIterator(Isolate* isolate);
    871   // An iterator that iterates over a given thread's stack.
    872   StackFrameIterator(Isolate* isolate, ThreadLocalTop* t);
    873 
    874   StackFrame* frame() const {
    875     DCHECK(!done());
    876     return frame_;
    877   }
    878   void Advance();
    879 
    880  private:
    881   // Go back to the first frame.
    882   void Reset(ThreadLocalTop* top);
    883 
    884   DISALLOW_COPY_AND_ASSIGN(StackFrameIterator);
    885 };
    886 
    887 
    888 // Iterator that supports iterating through all JavaScript frames.
    889 class JavaScriptFrameIterator BASE_EMBEDDED {
    890  public:
    891   inline explicit JavaScriptFrameIterator(Isolate* isolate);
    892   inline JavaScriptFrameIterator(Isolate* isolate, ThreadLocalTop* top);
    893   // Skip frames until the frame with the given id is reached.
    894   JavaScriptFrameIterator(Isolate* isolate, StackFrame::Id id);
    895 
    896   inline JavaScriptFrame* frame() const;
    897 
    898   bool done() const { return iterator_.done(); }
    899   void Advance();
    900 
    901   // Advance to the frame holding the arguments for the current
    902   // frame. This only affects the current frame if it has adapted
    903   // arguments.
    904   void AdvanceToArgumentsFrame();
    905 
    906  private:
    907   StackFrameIterator iterator_;
    908 };
    909 
    910 
    911 // NOTE: The stack trace frame iterator is an iterator that only
    912 // traverse proper JavaScript frames; that is JavaScript frames that
    913 // have proper JavaScript functions. This excludes the problematic
    914 // functions in runtime.js.
    915 class StackTraceFrameIterator: public JavaScriptFrameIterator {
    916  public:
    917   explicit StackTraceFrameIterator(Isolate* isolate);
    918   void Advance();
    919 
    920  private:
    921   bool IsValidFrame();
    922 };
    923 
    924 
    925 class SafeStackFrameIterator: public StackFrameIteratorBase {
    926  public:
    927   SafeStackFrameIterator(Isolate* isolate,
    928                          Address fp, Address sp,
    929                          Address js_entry_sp);
    930 
    931   inline StackFrame* frame() const;
    932   void Advance();
    933 
    934   StackFrame::Type top_frame_type() const { return top_frame_type_; }
    935 
    936  private:
    937   void AdvanceOneFrame();
    938 
    939   bool IsValidStackAddress(Address addr) const {
    940     return low_bound_ <= addr && addr <= high_bound_;
    941   }
    942   bool IsValidFrame(StackFrame* frame) const;
    943   bool IsValidCaller(StackFrame* frame);
    944   bool IsValidExitFrame(Address fp) const;
    945   bool IsValidTop(ThreadLocalTop* top) const;
    946 
    947   const Address low_bound_;
    948   const Address high_bound_;
    949   StackFrame::Type top_frame_type_;
    950   ExternalCallbackScope* external_callback_scope_;
    951 };
    952 
    953 
    954 class StackFrameLocator BASE_EMBEDDED {
    955  public:
    956   explicit StackFrameLocator(Isolate* isolate) : iterator_(isolate) {}
    957 
    958   // Find the nth JavaScript frame on the stack. The caller must
    959   // guarantee that such a frame exists.
    960   JavaScriptFrame* FindJavaScriptFrame(int n);
    961 
    962  private:
    963   StackFrameIterator iterator_;
    964 };
    965 
    966 
    967 // Reads all frames on the current stack and copies them into the current
    968 // zone memory.
    969 Vector<StackFrame*> CreateStackMap(Isolate* isolate, Zone* zone);
    970 
    971 }  // namespace internal
    972 }  // namespace v8
    973 
    974 #endif  // V8_FRAMES_H_
    975