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 Isolate;
     33 class StackFrameIteratorBase;
     34 class ThreadLocalTop;
     35 class WasmInstanceObject;
     36 
     37 class InnerPointerToCodeCache {
     38  public:
     39   struct InnerPointerToCodeCacheEntry {
     40     Address inner_pointer;
     41     Code* code;
     42     SafepointEntry safepoint_entry;
     43   };
     44 
     45   explicit InnerPointerToCodeCache(Isolate* isolate) : isolate_(isolate) {
     46     Flush();
     47   }
     48 
     49   Code* GcSafeFindCodeForInnerPointer(Address inner_pointer);
     50   Code* GcSafeCastToCode(HeapObject* object, Address inner_pointer);
     51 
     52   void Flush() {
     53     memset(&cache_[0], 0, sizeof(cache_));
     54   }
     55 
     56   InnerPointerToCodeCacheEntry* GetCacheEntry(Address inner_pointer);
     57 
     58  private:
     59   InnerPointerToCodeCacheEntry* cache(int index) { return &cache_[index]; }
     60 
     61   Isolate* isolate_;
     62 
     63   static const int kInnerPointerToCodeCacheSize = 1024;
     64   InnerPointerToCodeCacheEntry cache_[kInnerPointerToCodeCacheSize];
     65 
     66   DISALLOW_COPY_AND_ASSIGN(InnerPointerToCodeCache);
     67 };
     68 
     69 
     70 class StackHandlerConstants : public AllStatic {
     71  public:
     72   static const int kNextOffset = 0 * kPointerSize;
     73 
     74   static const int kSize = kNextOffset + kPointerSize;
     75   static const int kSlotCount = kSize >> kPointerSizeLog2;
     76 };
     77 
     78 
     79 class StackHandler BASE_EMBEDDED {
     80  public:
     81   // Get the address of this stack handler.
     82   inline Address address() const;
     83 
     84   // Get the next stack handler in the chain.
     85   inline StackHandler* next() const;
     86 
     87   // Conversion support.
     88   static inline StackHandler* FromAddress(Address address);
     89 
     90  private:
     91   DISALLOW_IMPLICIT_CONSTRUCTORS(StackHandler);
     92 };
     93 
     94 #define STACK_FRAME_TYPE_LIST(V)                         \
     95   V(ENTRY, EntryFrame)                                   \
     96   V(ENTRY_CONSTRUCT, EntryConstructFrame)                \
     97   V(EXIT, ExitFrame)                                     \
     98   V(JAVA_SCRIPT, JavaScriptFrame)                        \
     99   V(OPTIMIZED, OptimizedFrame)                           \
    100   V(WASM_COMPILED, WasmCompiledFrame)                    \
    101   V(WASM_TO_JS, WasmToJsFrame)                           \
    102   V(JS_TO_WASM, JsToWasmFrame)                           \
    103   V(WASM_INTERPRETER_ENTRY, WasmInterpreterEntryFrame)   \
    104   V(INTERPRETED, InterpretedFrame)                       \
    105   V(STUB, StubFrame)                                     \
    106   V(STUB_FAILURE_TRAMPOLINE, StubFailureTrampolineFrame) \
    107   V(INTERNAL, InternalFrame)                             \
    108   V(CONSTRUCT, ConstructFrame)                           \
    109   V(ARGUMENTS_ADAPTOR, ArgumentsAdaptorFrame)            \
    110   V(BUILTIN, BuiltinFrame)                               \
    111   V(BUILTIN_EXIT, BuiltinExitFrame)
    112 
    113 // Every pointer in a frame has a slot id. On 32-bit platforms, doubles consume
    114 // two slots.
    115 //
    116 // Stack slot indices >= 0 access the callee stack with slot 0 corresponding to
    117 // the callee's saved return address and 1 corresponding to the saved frame
    118 // pointer. Some frames have additional information stored in the fixed header,
    119 // for example JSFunctions store the function context and marker in the fixed
    120 // header, with slot index 2 corresponding to the current function context and 3
    121 // corresponding to the frame marker/JSFunction.
    122 //
    123 //  slot      JS frame
    124 //       +-----------------+--------------------------------
    125 //  -n-1 |   parameter 0   |                            ^
    126 //       |- - - - - - - - -|                            |
    127 //  -n   |                 |                          Caller
    128 //  ...  |       ...       |                       frame slots
    129 //  -2   |  parameter n-1  |                       (slot < 0)
    130 //       |- - - - - - - - -|                            |
    131 //  -1   |   parameter n   |                            v
    132 //  -----+-----------------+--------------------------------
    133 //   0   |   return addr   |   ^                        ^
    134 //       |- - - - - - - - -|   |                        |
    135 //   1   | saved frame ptr | Fixed                      |
    136 //       |- - - - - - - - -| Header <-- frame ptr       |
    137 //   2   | [Constant Pool] |   |                        |
    138 //       |- - - - - - - - -|   |                        |
    139 // 2+cp  |Context/Frm. Type|   v   if a constant pool   |
    140 //       |-----------------+----    is used, cp = 1,    |
    141 // 3+cp  |                 |   ^   otherwise, cp = 0    |
    142 //       |- - - - - - - - -|   |                        |
    143 // 4+cp  |                 |   |                      Callee
    144 //       |- - - - - - - - -|   |                   frame slots
    145 //  ...  |                 | Frame slots           (slot >= 0)
    146 //       |- - - - - - - - -|   |                        |
    147 //       |                 |   v                        |
    148 //  -----+-----------------+----- <-- stack ptr -------------
    149 //
    150 class CommonFrameConstants : public AllStatic {
    151  public:
    152   static const int kCallerFPOffset = 0 * kPointerSize;
    153   static const int kCallerPCOffset = kCallerFPOffset + 1 * kFPOnStackSize;
    154   static const int kCallerSPOffset = kCallerPCOffset + 1 * kPCOnStackSize;
    155 
    156   // Fixed part of the frame consists of return address, caller fp,
    157   // constant pool (if FLAG_enable_embedded_constant_pool), context, and
    158   // function. StandardFrame::IterateExpressions assumes that kLastObjectOffset
    159   // is the last object pointer.
    160   static const int kFixedFrameSizeAboveFp = kPCOnStackSize + kFPOnStackSize;
    161   static const int kFixedSlotCountAboveFp =
    162       kFixedFrameSizeAboveFp / kPointerSize;
    163   static const int kCPSlotSize =
    164       FLAG_enable_embedded_constant_pool ? kPointerSize : 0;
    165   static const int kCPSlotCount = kCPSlotSize / kPointerSize;
    166   static const int kConstantPoolOffset = kCPSlotSize ? -1 * kPointerSize : 0;
    167   static const int kContextOrFrameTypeSize = kPointerSize;
    168   static const int kContextOrFrameTypeOffset =
    169       -(kCPSlotSize + kContextOrFrameTypeSize);
    170 };
    171 
    172 // StandardFrames are used for interpreted, full-codegen and optimized
    173 // JavaScript frames. They always have a context below the saved fp/constant
    174 // pool and below that the JSFunction of the executing function.
    175 //
    176 //  slot      JS frame
    177 //       +-----------------+--------------------------------
    178 //  -n-1 |   parameter 0   |                            ^
    179 //       |- - - - - - - - -|                            |
    180 //  -n   |                 |                          Caller
    181 //  ...  |       ...       |                       frame slots
    182 //  -2   |  parameter n-1  |                       (slot < 0)
    183 //       |- - - - - - - - -|                            |
    184 //  -1   |   parameter n   |                            v
    185 //  -----+-----------------+--------------------------------
    186 //   0   |   return addr   |   ^                        ^
    187 //       |- - - - - - - - -|   |                        |
    188 //   1   | saved frame ptr | Fixed                      |
    189 //       |- - - - - - - - -| Header <-- frame ptr       |
    190 //   2   | [Constant Pool] |   |                        |
    191 //       |- - - - - - - - -|   |                        |
    192 // 2+cp  |     Context     |   |   if a constant pool   |
    193 //       |- - - - - - - - -|   |    is used, cp = 1,    |
    194 // 3+cp  |    JSFunction   |   v   otherwise, cp = 0    |
    195 //       +-----------------+----                        |
    196 // 4+cp  |                 |   ^                      Callee
    197 //       |- - - - - - - - -|   |                   frame slots
    198 //  ...  |                 | Frame slots           (slot >= 0)
    199 //       |- - - - - - - - -|   |                        |
    200 //       |                 |   v                        |
    201 //  -----+-----------------+----- <-- stack ptr -------------
    202 //
    203 class StandardFrameConstants : public CommonFrameConstants {
    204  public:
    205   static const int kFixedFrameSizeFromFp = 2 * kPointerSize + kCPSlotSize;
    206   static const int kFixedFrameSize =
    207       kFixedFrameSizeAboveFp + kFixedFrameSizeFromFp;
    208   static const int kFixedSlotCountFromFp = kFixedFrameSizeFromFp / kPointerSize;
    209   static const int kFixedSlotCount = kFixedFrameSize / kPointerSize;
    210   static const int kContextOffset = kContextOrFrameTypeOffset;
    211   static const int kFunctionOffset = -2 * kPointerSize - kCPSlotSize;
    212   static const int kExpressionsOffset = -3 * kPointerSize - kCPSlotSize;
    213   static const int kLastObjectOffset = kContextOffset;
    214 };
    215 
    216 // OptimizedBuiltinFrameConstants are used for TF-generated builtins. They
    217 // always have a context below the saved fp/constant pool and below that the
    218 // JSFunction of the executing function and below that an integer (not a Smi)
    219 // containing the number of arguments passed to the builtin.
    220 //
    221 //  slot      JS frame
    222 //       +-----------------+--------------------------------
    223 //  -n-1 |   parameter 0   |                            ^
    224 //       |- - - - - - - - -|                            |
    225 //  -n   |                 |                          Caller
    226 //  ...  |       ...       |                       frame slots
    227 //  -2   |  parameter n-1  |                       (slot < 0)
    228 //       |- - - - - - - - -|                            |
    229 //  -1   |   parameter n   |                            v
    230 //  -----+-----------------+--------------------------------
    231 //   0   |   return addr   |   ^                        ^
    232 //       |- - - - - - - - -|   |                        |
    233 //   1   | saved frame ptr | Fixed                      |
    234 //       |- - - - - - - - -| Header <-- frame ptr       |
    235 //   2   | [Constant Pool] |   |                        |
    236 //       |- - - - - - - - -|   |                        |
    237 // 2+cp  |     Context     |   |   if a constant pool   |
    238 //       |- - - - - - - - -|   |    is used, cp = 1,    |
    239 // 3+cp  |    JSFunction   |   |   otherwise, cp = 0    |
    240 //       |- - - - - - - - -|   |                        |
    241 // 4+cp  |      argc       |   v                        |
    242 //       +-----------------+----                        |
    243 // 5+cp  |                 |   ^                      Callee
    244 //       |- - - - - - - - -|   |                   frame slots
    245 //  ...  |                 | Frame slots           (slot >= 0)
    246 //       |- - - - - - - - -|   |                        |
    247 //       |                 |   v                        |
    248 //  -----+-----------------+----- <-- stack ptr -------------
    249 //
    250 class OptimizedBuiltinFrameConstants : public StandardFrameConstants {
    251  public:
    252   static const int kArgCSize = kPointerSize;
    253   static const int kArgCOffset = -3 * kPointerSize - kCPSlotSize;
    254   static const int kFixedFrameSize = kFixedFrameSizeAboveFp - kArgCOffset;
    255   static const int kFixedSlotCount = kFixedFrameSize / kPointerSize;
    256 };
    257 
    258 // TypedFrames have a SMI type maker value below the saved FP/constant pool to
    259 // distinguish them from StandardFrames, which have a context in that position
    260 // instead.
    261 //
    262 //  slot      JS frame
    263 //       +-----------------+--------------------------------
    264 //  -n-1 |   parameter 0   |                            ^
    265 //       |- - - - - - - - -|                            |
    266 //  -n   |                 |                          Caller
    267 //  ...  |       ...       |                       frame slots
    268 //  -2   |  parameter n-1  |                       (slot < 0)
    269 //       |- - - - - - - - -|                            |
    270 //  -1   |   parameter n   |                            v
    271 //  -----+-----------------+--------------------------------
    272 //   0   |   return addr   |   ^                        ^
    273 //       |- - - - - - - - -|   |                        |
    274 //   1   | saved frame ptr | Fixed                      |
    275 //       |- - - - - - - - -| Header <-- frame ptr       |
    276 //   2   | [Constant Pool] |   |                        |
    277 //       |- - - - - - - - -|   |                        |
    278 // 2+cp  |Frame Type Marker|   v   if a constant pool   |
    279 //       |-----------------+----    is used, cp = 1,    |
    280 // 3+cp  |                 |   ^   otherwise, cp = 0    |
    281 //       |- - - - - - - - -|   |                        |
    282 // 4+cp  |                 |   |                      Callee
    283 //       |- - - - - - - - -|   |                   frame slots
    284 //  ...  |                 | Frame slots           (slot >= 0)
    285 //       |- - - - - - - - -|   |                        |
    286 //       |                 |   v                        |
    287 //  -----+-----------------+----- <-- stack ptr -------------
    288 //
    289 class TypedFrameConstants : public CommonFrameConstants {
    290  public:
    291   static const int kFrameTypeSize = kContextOrFrameTypeSize;
    292   static const int kFrameTypeOffset = kContextOrFrameTypeOffset;
    293   static const int kFixedFrameSizeFromFp = kCPSlotSize + kFrameTypeSize;
    294   static const int kFixedSlotCountFromFp = kFixedFrameSizeFromFp / kPointerSize;
    295   static const int kFixedFrameSize =
    296       StandardFrameConstants::kFixedFrameSizeAboveFp + kFixedFrameSizeFromFp;
    297   static const int kFixedSlotCount = kFixedFrameSize / kPointerSize;
    298   static const int kFirstPushedFrameValueOffset =
    299       -StandardFrameConstants::kCPSlotSize - kFrameTypeSize - kPointerSize;
    300 };
    301 
    302 #define TYPED_FRAME_PUSHED_VALUE_OFFSET(x) \
    303   (TypedFrameConstants::kFirstPushedFrameValueOffset - (x)*kPointerSize)
    304 #define TYPED_FRAME_SIZE(count) \
    305   (TypedFrameConstants::kFixedFrameSize + (count)*kPointerSize)
    306 #define TYPED_FRAME_SIZE_FROM_SP(count) \
    307   (TypedFrameConstants::kFixedFrameSizeFromFp + (count)*kPointerSize)
    308 #define DEFINE_TYPED_FRAME_SIZES(count)                                     \
    309   static const int kFixedFrameSize = TYPED_FRAME_SIZE(count);               \
    310   static const int kFixedSlotCount = kFixedFrameSize / kPointerSize;        \
    311   static const int kFixedFrameSizeFromFp = TYPED_FRAME_SIZE_FROM_SP(count); \
    312   static const int kFixedSlotCountFromFp = kFixedFrameSizeFromFp / kPointerSize
    313 
    314 class ArgumentsAdaptorFrameConstants : public TypedFrameConstants {
    315  public:
    316   // FP-relative.
    317   static const int kFunctionOffset = TYPED_FRAME_PUSHED_VALUE_OFFSET(0);
    318   static const int kLengthOffset = TYPED_FRAME_PUSHED_VALUE_OFFSET(1);
    319   DEFINE_TYPED_FRAME_SIZES(2);
    320 };
    321 
    322 class BuiltinFrameConstants : public TypedFrameConstants {
    323  public:
    324   // FP-relative.
    325   static const int kFunctionOffset = TYPED_FRAME_PUSHED_VALUE_OFFSET(0);
    326   static const int kLengthOffset = TYPED_FRAME_PUSHED_VALUE_OFFSET(1);
    327   DEFINE_TYPED_FRAME_SIZES(2);
    328 };
    329 
    330 class InternalFrameConstants : public TypedFrameConstants {
    331  public:
    332   // FP-relative.
    333   static const int kCodeOffset = TYPED_FRAME_PUSHED_VALUE_OFFSET(0);
    334   DEFINE_TYPED_FRAME_SIZES(1);
    335 };
    336 
    337 class FrameDropperFrameConstants : public InternalFrameConstants {
    338  public:
    339   // FP-relative.
    340   static const int kFunctionOffset = TYPED_FRAME_PUSHED_VALUE_OFFSET(1);
    341   DEFINE_TYPED_FRAME_SIZES(2);
    342 };
    343 
    344 class ConstructFrameConstants : public TypedFrameConstants {
    345  public:
    346   // FP-relative.
    347   static const int kContextOffset = TYPED_FRAME_PUSHED_VALUE_OFFSET(0);
    348   static const int kLengthOffset = TYPED_FRAME_PUSHED_VALUE_OFFSET(1);
    349   static const int kImplicitReceiverOffset = TYPED_FRAME_PUSHED_VALUE_OFFSET(2);
    350   DEFINE_TYPED_FRAME_SIZES(3);
    351 };
    352 
    353 class StubFailureTrampolineFrameConstants : public InternalFrameConstants {
    354  public:
    355   static const int kArgumentsArgumentsOffset =
    356       TYPED_FRAME_PUSHED_VALUE_OFFSET(0);
    357   static const int kArgumentsLengthOffset = TYPED_FRAME_PUSHED_VALUE_OFFSET(1);
    358   static const int kArgumentsPointerOffset = TYPED_FRAME_PUSHED_VALUE_OFFSET(2);
    359   static const int kFixedHeaderBottomOffset = kArgumentsPointerOffset;
    360   DEFINE_TYPED_FRAME_SIZES(3);
    361 };
    362 
    363 // Behaves like an exit frame but with target and new target args.
    364 class BuiltinExitFrameConstants : public CommonFrameConstants {
    365  public:
    366   static const int kNewTargetOffset = kCallerPCOffset + 1 * kPointerSize;
    367   static const int kTargetOffset = kNewTargetOffset + 1 * kPointerSize;
    368   static const int kArgcOffset = kTargetOffset + 1 * kPointerSize;
    369 };
    370 
    371 class InterpreterFrameConstants : public AllStatic {
    372  public:
    373   // Fixed frame includes new.target, bytecode array, and bytecode offset.
    374   static const int kFixedFrameSize =
    375       StandardFrameConstants::kFixedFrameSize + 3 * kPointerSize;
    376   static const int kFixedFrameSizeFromFp =
    377       StandardFrameConstants::kFixedFrameSizeFromFp + 3 * kPointerSize;
    378 
    379   // FP-relative.
    380   static const int kLastParamFromFp = StandardFrameConstants::kCallerSPOffset;
    381   static const int kCallerPCOffsetFromFp =
    382       StandardFrameConstants::kCallerPCOffset;
    383   static const int kNewTargetFromFp =
    384       -StandardFrameConstants::kFixedFrameSizeFromFp - 1 * kPointerSize;
    385   static const int kBytecodeArrayFromFp =
    386       -StandardFrameConstants::kFixedFrameSizeFromFp - 2 * kPointerSize;
    387   static const int kBytecodeOffsetFromFp =
    388       -StandardFrameConstants::kFixedFrameSizeFromFp - 3 * kPointerSize;
    389   static const int kRegisterFileFromFp =
    390       -StandardFrameConstants::kFixedFrameSizeFromFp - 4 * kPointerSize;
    391 
    392   static const int kExpressionsOffset = kRegisterFileFromFp;
    393 
    394   // Number of fixed slots in addition to a {StandardFrame}.
    395   static const int kExtraSlotCount =
    396       InterpreterFrameConstants::kFixedFrameSize / kPointerSize -
    397       StandardFrameConstants::kFixedFrameSize / kPointerSize;
    398 
    399   // Expression index for {StandardFrame::GetExpressionAddress}.
    400   static const int kBytecodeArrayExpressionIndex = -2;
    401   static const int kBytecodeOffsetExpressionIndex = -1;
    402   static const int kRegisterFileExpressionIndex = 0;
    403 };
    404 
    405 inline static int FPOffsetToFrameSlot(int frame_offset) {
    406   return StandardFrameConstants::kFixedSlotCountAboveFp - 1 -
    407          frame_offset / kPointerSize;
    408 }
    409 
    410 inline static int FrameSlotToFPOffset(int slot) {
    411   return (StandardFrameConstants::kFixedSlotCountAboveFp - 1 - slot) *
    412          kPointerSize;
    413 }
    414 
    415 // Abstract base class for all stack frames.
    416 class StackFrame BASE_EMBEDDED {
    417  public:
    418 #define DECLARE_TYPE(type, ignore) type,
    419   enum Type {
    420     NONE = 0,
    421     STACK_FRAME_TYPE_LIST(DECLARE_TYPE)
    422     NUMBER_OF_TYPES,
    423     // Used by FrameScope to indicate that the stack frame is constructed
    424     // manually and the FrameScope does not need to emit code.
    425     MANUAL
    426   };
    427 #undef DECLARE_TYPE
    428 
    429   // Opaque data type for identifying stack frames. Used extensively
    430   // by the debugger.
    431   // ID_MIN_VALUE and ID_MAX_VALUE are specified to ensure that enumeration type
    432   // has correct value range (see Issue 830 for more details).
    433   enum Id {
    434     ID_MIN_VALUE = kMinInt,
    435     ID_MAX_VALUE = kMaxInt,
    436     NO_ID = 0
    437   };
    438 
    439   // Used to mark the outermost JS entry frame.
    440   //
    441   // The mark is an opaque value that should be pushed onto the stack directly,
    442   // carefully crafted to not be interpreted as a tagged pointer.
    443   enum JsFrameMarker {
    444     INNER_JSENTRY_FRAME = (0 << kSmiTagSize) | kSmiTag,
    445     OUTERMOST_JSENTRY_FRAME = (1 << kSmiTagSize) | kSmiTag
    446   };
    447   STATIC_ASSERT((INNER_JSENTRY_FRAME & kHeapObjectTagMask) != kHeapObjectTag);
    448   STATIC_ASSERT((OUTERMOST_JSENTRY_FRAME & kHeapObjectTagMask) !=
    449                 kHeapObjectTag);
    450 
    451   struct State {
    452     Address sp = nullptr;
    453     Address fp = nullptr;
    454     Address* pc_address = nullptr;
    455     Address* callee_pc_address = nullptr;
    456     Address* constant_pool_address = nullptr;
    457   };
    458 
    459   // Convert a stack frame type to a marker that can be stored on the stack.
    460   //
    461   // The marker is an opaque value, not intended to be interpreted in any way
    462   // except being checked by IsTypeMarker or converted by MarkerToType.
    463   // It has the same tagging as Smis, so any marker value that does not pass
    464   // IsTypeMarker can instead be interpreted as a tagged pointer.
    465   //
    466   // Note that the marker is not a Smi: Smis on 64-bit architectures are stored
    467   // in the top 32 bits of a 64-bit value, which in turn makes them expensive
    468   // (in terms of code/instruction size) to push as immediates onto the stack.
    469   static int32_t TypeToMarker(Type type) {
    470     DCHECK_GE(type, 0);
    471     return (type << kSmiTagSize) | kSmiTag;
    472   }
    473 
    474   // Convert a marker back to a stack frame type.
    475   //
    476   // Unlike the return value of TypeToMarker, this takes an intptr_t, as that is
    477   // the type of the value on the stack.
    478   static Type MarkerToType(intptr_t marker) {
    479     DCHECK(IsTypeMarker(marker));
    480     return static_cast<Type>(marker >> kSmiTagSize);
    481   }
    482 
    483   // Check if a marker is a stack frame type marker or a tagged pointer.
    484   //
    485   // Returns true if the given marker is tagged as a stack frame type marker,
    486   // and should be converted back to a stack frame type using MarkerToType.
    487   // Otherwise, the value is a tagged function pointer.
    488   static bool IsTypeMarker(intptr_t function_or_marker) {
    489     bool is_marker = ((function_or_marker & kSmiTagMask) == kSmiTag);
    490     return is_marker;
    491   }
    492 
    493   // Copy constructor; it breaks the connection to host iterator
    494   // (as an iterator usually lives on stack).
    495   StackFrame(const StackFrame& original) {
    496     this->state_ = original.state_;
    497     this->iterator_ = NULL;
    498     this->isolate_ = original.isolate_;
    499   }
    500 
    501   // Type testers.
    502   bool is_entry() const { return type() == ENTRY; }
    503   bool is_entry_construct() const { return type() == ENTRY_CONSTRUCT; }
    504   bool is_exit() const { return type() == EXIT; }
    505   bool is_optimized() const { return type() == OPTIMIZED; }
    506   bool is_interpreted() const { return type() == INTERPRETED; }
    507   bool is_wasm_compiled() const { return type() == WASM_COMPILED; }
    508   bool is_wasm_to_js() const { return type() == WASM_TO_JS; }
    509   bool is_js_to_wasm() const { return type() == JS_TO_WASM; }
    510   bool is_wasm_interpreter_entry() const {
    511     return type() == WASM_INTERPRETER_ENTRY;
    512   }
    513   bool is_arguments_adaptor() const { return type() == ARGUMENTS_ADAPTOR; }
    514   bool is_builtin() const { return type() == BUILTIN; }
    515   bool is_internal() const { return type() == INTERNAL; }
    516   bool is_stub_failure_trampoline() const {
    517     return type() == STUB_FAILURE_TRAMPOLINE;
    518   }
    519   bool is_construct() const { return type() == CONSTRUCT; }
    520   bool is_builtin_exit() const { return type() == BUILTIN_EXIT; }
    521   virtual bool is_standard() const { return false; }
    522 
    523   bool is_java_script() const {
    524     Type type = this->type();
    525     return (type == JAVA_SCRIPT) || (type == OPTIMIZED) ||
    526            (type == INTERPRETED) || (type == BUILTIN);
    527   }
    528   bool is_wasm() const {
    529     Type type = this->type();
    530     return type == WASM_COMPILED || type == WASM_INTERPRETER_ENTRY;
    531   }
    532 
    533   // Accessors.
    534   Address sp() const { return state_.sp; }
    535   Address fp() const { return state_.fp; }
    536   Address callee_pc() const {
    537     return state_.callee_pc_address ? *state_.callee_pc_address : nullptr;
    538   }
    539   Address caller_sp() const { return GetCallerStackPointer(); }
    540 
    541   // If this frame is optimized and was dynamically aligned return its old
    542   // unaligned frame pointer.  When the frame is deoptimized its FP will shift
    543   // up one word and become unaligned.
    544   Address UnpaddedFP() const;
    545 
    546   Address pc() const { return *pc_address(); }
    547   void set_pc(Address pc) { *pc_address() = pc; }
    548 
    549   Address constant_pool() const { return *constant_pool_address(); }
    550   void set_constant_pool(Address constant_pool) {
    551     *constant_pool_address() = constant_pool;
    552   }
    553 
    554   virtual void SetCallerFp(Address caller_fp) = 0;
    555 
    556   // Manually changes value of fp in this object.
    557   void UpdateFp(Address fp) { state_.fp = fp; }
    558 
    559   Address* pc_address() const { return state_.pc_address; }
    560 
    561   Address* constant_pool_address() const {
    562     return state_.constant_pool_address;
    563   }
    564 
    565   // Get the id of this stack frame.
    566   Id id() const { return static_cast<Id>(OffsetFrom(caller_sp())); }
    567 
    568   // Get the top handler from the current stack iterator.
    569   inline StackHandler* top_handler() const;
    570 
    571   // Get the type of this frame.
    572   virtual Type type() const = 0;
    573 
    574   // Get the code associated with this frame.
    575   // This method could be called during marking phase of GC.
    576   virtual Code* unchecked_code() const = 0;
    577 
    578   // Get the code associated with this frame.
    579   inline Code* LookupCode() const;
    580 
    581   // Get the code object that contains the given pc.
    582   static inline Code* GetContainingCode(Isolate* isolate, Address pc);
    583 
    584   // Get the code object containing the given pc and fill in the
    585   // safepoint entry and the number of stack slots. The pc must be at
    586   // a safepoint.
    587   static Code* GetSafepointData(Isolate* isolate,
    588                                 Address pc,
    589                                 SafepointEntry* safepoint_entry,
    590                                 unsigned* stack_slots);
    591 
    592   virtual void Iterate(ObjectVisitor* v) const = 0;
    593   static void IteratePc(ObjectVisitor* v, Address* pc_address,
    594                         Address* constant_pool_address, Code* holder);
    595 
    596   // Sets a callback function for return-address rewriting profilers
    597   // to resolve the location of a return address to the location of the
    598   // profiler's stashed return address.
    599   static void SetReturnAddressLocationResolver(
    600       ReturnAddressLocationResolver resolver);
    601 
    602   // Resolves pc_address through the resolution address function if one is set.
    603   static inline Address* ResolveReturnAddressLocation(Address* pc_address);
    604 
    605   // Printing support.
    606   enum PrintMode { OVERVIEW, DETAILS };
    607   virtual void Print(StringStream* accumulator,
    608                      PrintMode mode,
    609                      int index) const { }
    610 
    611   Isolate* isolate() const { return isolate_; }
    612 
    613   void operator=(const StackFrame& original) = delete;
    614 
    615  protected:
    616   inline explicit StackFrame(StackFrameIteratorBase* iterator);
    617   virtual ~StackFrame() { }
    618 
    619   // Compute the stack pointer for the calling frame.
    620   virtual Address GetCallerStackPointer() const = 0;
    621 
    622   // Printing support.
    623   static void PrintIndex(StringStream* accumulator,
    624                          PrintMode mode,
    625                          int index);
    626 
    627   // Compute the stack frame type for the given state.
    628   static Type ComputeType(const StackFrameIteratorBase* iterator, State* state);
    629 
    630 #ifdef DEBUG
    631   bool can_access_heap_objects() const;
    632 #endif
    633 
    634  private:
    635   const StackFrameIteratorBase* iterator_;
    636   Isolate* isolate_;
    637   State state_;
    638 
    639   static ReturnAddressLocationResolver return_address_location_resolver_;
    640 
    641   // Fill in the state of the calling frame.
    642   virtual void ComputeCallerState(State* state) const = 0;
    643 
    644   // Get the type and the state of the calling frame.
    645   virtual Type GetCallerState(State* state) const;
    646 
    647   static const intptr_t kIsolateTag = 1;
    648 
    649   friend class StackFrameIterator;
    650   friend class StackFrameIteratorBase;
    651   friend class StackHandlerIterator;
    652   friend class SafeStackFrameIterator;
    653 };
    654 
    655 
    656 // Entry frames are used to enter JavaScript execution from C.
    657 class EntryFrame: public StackFrame {
    658  public:
    659   Type type() const override { return ENTRY; }
    660 
    661   Code* unchecked_code() const override;
    662 
    663   // Garbage collection support.
    664   void Iterate(ObjectVisitor* v) const override;
    665 
    666   static EntryFrame* cast(StackFrame* frame) {
    667     DCHECK(frame->is_entry());
    668     return static_cast<EntryFrame*>(frame);
    669   }
    670   void SetCallerFp(Address caller_fp) override;
    671 
    672  protected:
    673   inline explicit EntryFrame(StackFrameIteratorBase* iterator);
    674 
    675   // The caller stack pointer for entry frames is always zero. The
    676   // real information about the caller frame is available through the
    677   // link to the top exit frame.
    678   Address GetCallerStackPointer() const override { return 0; }
    679 
    680  private:
    681   void ComputeCallerState(State* state) const override;
    682   Type GetCallerState(State* state) const override;
    683 
    684   friend class StackFrameIteratorBase;
    685 };
    686 
    687 
    688 class EntryConstructFrame: public EntryFrame {
    689  public:
    690   Type type() const override { return ENTRY_CONSTRUCT; }
    691 
    692   Code* unchecked_code() const override;
    693 
    694   static EntryConstructFrame* cast(StackFrame* frame) {
    695     DCHECK(frame->is_entry_construct());
    696     return static_cast<EntryConstructFrame*>(frame);
    697   }
    698 
    699  protected:
    700   inline explicit EntryConstructFrame(StackFrameIteratorBase* iterator);
    701 
    702  private:
    703   friend class StackFrameIteratorBase;
    704 };
    705 
    706 
    707 // Exit frames are used to exit JavaScript execution and go to C.
    708 class ExitFrame: public StackFrame {
    709  public:
    710   Type type() const override { return EXIT; }
    711 
    712   Code* unchecked_code() const override;
    713 
    714   Object*& code_slot() const;
    715 
    716   // Garbage collection support.
    717   void Iterate(ObjectVisitor* v) const override;
    718 
    719   void SetCallerFp(Address caller_fp) override;
    720 
    721   static ExitFrame* cast(StackFrame* frame) {
    722     DCHECK(frame->is_exit());
    723     return static_cast<ExitFrame*>(frame);
    724   }
    725 
    726   // Compute the state and type of an exit frame given a frame
    727   // pointer. Used when constructing the first stack frame seen by an
    728   // iterator and the frames following entry frames.
    729   static Type GetStateForFramePointer(Address fp, State* state);
    730   static Address ComputeStackPointer(Address fp);
    731   static StackFrame::Type ComputeFrameType(Address fp);
    732   static void FillState(Address fp, Address sp, State* state);
    733 
    734  protected:
    735   inline explicit ExitFrame(StackFrameIteratorBase* iterator);
    736 
    737   Address GetCallerStackPointer() const override;
    738 
    739  private:
    740   void ComputeCallerState(State* state) const override;
    741 
    742   friend class StackFrameIteratorBase;
    743 };
    744 
    745 // Builtin exit frames are a special case of exit frames, which are used
    746 // whenever C++ builtins (e.g., Math.acos) are called. Their main purpose is
    747 // to allow such builtins to appear in stack traces.
    748 class BuiltinExitFrame : public ExitFrame {
    749  public:
    750   Type type() const override { return BUILTIN_EXIT; }
    751 
    752   static BuiltinExitFrame* cast(StackFrame* frame) {
    753     DCHECK(frame->is_builtin_exit());
    754     return static_cast<BuiltinExitFrame*>(frame);
    755   }
    756 
    757   JSFunction* function() const;
    758   Object* receiver() const;
    759 
    760   bool IsConstructor() const;
    761 
    762   void Print(StringStream* accumulator, PrintMode mode,
    763              int index) const override;
    764 
    765  protected:
    766   inline explicit BuiltinExitFrame(StackFrameIteratorBase* iterator);
    767 
    768  private:
    769   Object* GetParameter(int i) const;
    770   int ComputeParametersCount() const;
    771 
    772   inline Object* receiver_slot_object() const;
    773   inline Object* argc_slot_object() const;
    774   inline Object* target_slot_object() const;
    775   inline Object* new_target_slot_object() const;
    776 
    777   friend class StackFrameIteratorBase;
    778 };
    779 
    780 class StandardFrame;
    781 
    782 class FrameSummary BASE_EMBEDDED {
    783  public:
    784   // Mode for JavaScriptFrame::Summarize. Exact summary is required to produce
    785   // an exact stack trace. It will trigger an assertion failure if that is not
    786   // possible, e.g., because of missing deoptimization information. The
    787   // approximate mode should produce a summary even without deoptimization
    788   // information, but it might miss frames.
    789   enum Mode { kExactSummary, kApproximateSummary };
    790 
    791 // Subclasses for the different summary kinds:
    792 #define FRAME_SUMMARY_VARIANTS(F)                                             \
    793   F(JAVA_SCRIPT, JavaScriptFrameSummary, java_script_summary_, JavaScript)    \
    794   F(WASM_COMPILED, WasmCompiledFrameSummary, wasm_compiled_summary_,          \
    795     WasmCompiled)                                                             \
    796   F(WASM_INTERPRETED, WasmInterpretedFrameSummary, wasm_interpreted_summary_, \
    797     WasmInterpreted)
    798 
    799 #define FRAME_SUMMARY_KIND(kind, type, field, desc) kind,
    800   enum Kind { FRAME_SUMMARY_VARIANTS(FRAME_SUMMARY_KIND) };
    801 #undef FRAME_SUMMARY_KIND
    802 
    803   class FrameSummaryBase {
    804    public:
    805     FrameSummaryBase(Isolate* isolate, Kind kind)
    806         : isolate_(isolate), kind_(kind) {}
    807     Isolate* isolate() const { return isolate_; }
    808     Kind kind() const { return kind_; }
    809 
    810    private:
    811     Isolate* isolate_;
    812     Kind kind_;
    813   };
    814 
    815   class JavaScriptFrameSummary : public FrameSummaryBase {
    816    public:
    817     JavaScriptFrameSummary(Isolate* isolate, Object* receiver,
    818                            JSFunction* function, AbstractCode* abstract_code,
    819                            int code_offset, bool is_constructor,
    820                            Mode mode = kExactSummary);
    821 
    822     Handle<Object> receiver() const { return receiver_; }
    823     Handle<JSFunction> function() const { return function_; }
    824     Handle<AbstractCode> abstract_code() const { return abstract_code_; }
    825     int code_offset() const { return code_offset_; }
    826     bool is_constructor() const { return is_constructor_; }
    827     bool is_subject_to_debugging() const;
    828     int SourcePosition() const;
    829     int SourceStatementPosition() const;
    830     Handle<Object> script() const;
    831     Handle<String> FunctionName() const;
    832     Handle<Context> native_context() const;
    833 
    834    private:
    835     Handle<Object> receiver_;
    836     Handle<JSFunction> function_;
    837     Handle<AbstractCode> abstract_code_;
    838     int code_offset_;
    839     bool is_constructor_;
    840   };
    841 
    842   class WasmFrameSummary : public FrameSummaryBase {
    843    protected:
    844     WasmFrameSummary(Isolate*, Kind, Handle<WasmInstanceObject>,
    845                      bool at_to_number_conversion);
    846 
    847    public:
    848     Handle<Object> receiver() const;
    849     uint32_t function_index() const;
    850     int byte_offset() const;
    851     bool is_constructor() const { return false; }
    852     bool is_subject_to_debugging() const { return true; }
    853     int SourcePosition() const;
    854     int SourceStatementPosition() const { return SourcePosition(); }
    855     Handle<Script> script() const;
    856     Handle<WasmInstanceObject> wasm_instance() const { return wasm_instance_; }
    857     Handle<String> FunctionName() const;
    858     Handle<Context> native_context() const;
    859     bool at_to_number_conversion() const { return at_to_number_conversion_; }
    860 
    861    private:
    862     Handle<WasmInstanceObject> wasm_instance_;
    863     bool at_to_number_conversion_;
    864   };
    865 
    866   class WasmCompiledFrameSummary : public WasmFrameSummary {
    867    public:
    868     WasmCompiledFrameSummary(Isolate*, Handle<WasmInstanceObject>, Handle<Code>,
    869                              int code_offset, bool at_to_number_conversion);
    870     uint32_t function_index() const;
    871     Handle<Code> code() const { return code_; }
    872     int code_offset() const { return code_offset_; }
    873     int byte_offset() const;
    874 
    875    private:
    876     Handle<Code> code_;
    877     int code_offset_;
    878   };
    879 
    880   class WasmInterpretedFrameSummary : public WasmFrameSummary {
    881    public:
    882     WasmInterpretedFrameSummary(Isolate*, Handle<WasmInstanceObject>,
    883                                 uint32_t function_index, int byte_offset);
    884     uint32_t function_index() const { return function_index_; }
    885     int code_offset() const { return byte_offset_; }
    886     int byte_offset() const { return byte_offset_; }
    887 
    888    private:
    889     uint32_t function_index_;
    890     int byte_offset_;
    891   };
    892 
    893 #undef FRAME_SUMMARY_FIELD
    894 #define FRAME_SUMMARY_CONS(kind, type, field, desc) \
    895   FrameSummary(type summ) : field(summ) {}  // NOLINT
    896   FRAME_SUMMARY_VARIANTS(FRAME_SUMMARY_CONS)
    897 #undef FRAME_SUMMARY_CONS
    898 
    899   ~FrameSummary();
    900 
    901   static FrameSummary GetTop(const StandardFrame* frame);
    902   static FrameSummary GetBottom(const StandardFrame* frame);
    903   static FrameSummary GetSingle(const StandardFrame* frame);
    904   static FrameSummary Get(const StandardFrame* frame, int index);
    905 
    906   // Dispatched accessors.
    907   Handle<Object> receiver() const;
    908   int code_offset() const;
    909   bool is_constructor() const;
    910   bool is_subject_to_debugging() const;
    911   Handle<Object> script() const;
    912   int SourcePosition() const;
    913   int SourceStatementPosition() const;
    914   Handle<String> FunctionName() const;
    915   Handle<Context> native_context() const;
    916 
    917 #define FRAME_SUMMARY_CAST(kind_, type, field, desc)      \
    918   bool Is##desc() const { return base_.kind() == kind_; } \
    919   const type& As##desc() const {                          \
    920     DCHECK_EQ(base_.kind(), kind_);                       \
    921     return field;                                         \
    922   }
    923   FRAME_SUMMARY_VARIANTS(FRAME_SUMMARY_CAST)
    924 #undef FRAME_SUMMARY_CAST
    925 
    926   bool IsWasm() const { return IsWasmCompiled() || IsWasmInterpreted(); }
    927   const WasmFrameSummary& AsWasm() const {
    928     if (IsWasmCompiled()) return AsWasmCompiled();
    929     return AsWasmInterpreted();
    930   }
    931 
    932  private:
    933 #define FRAME_SUMMARY_FIELD(kind, type, field, desc) type field;
    934   union {
    935     FrameSummaryBase base_;
    936     FRAME_SUMMARY_VARIANTS(FRAME_SUMMARY_FIELD)
    937   };
    938 };
    939 
    940 class StandardFrame : public StackFrame {
    941  public:
    942   // Testers.
    943   bool is_standard() const override { return true; }
    944 
    945   // Accessors.
    946   virtual Object* receiver() const;
    947   virtual Script* script() const;
    948   virtual Object* context() const;
    949   virtual int position() const;
    950 
    951   // Access the expressions in the stack frame including locals.
    952   inline Object* GetExpression(int index) const;
    953   inline void SetExpression(int index, Object* value);
    954   int ComputeExpressionsCount() const;
    955 
    956   // Access the parameters.
    957   virtual Object* GetParameter(int index) const;
    958   virtual int ComputeParametersCount() const;
    959 
    960   void SetCallerFp(Address caller_fp) override;
    961 
    962   // Check if this frame is a constructor frame invoked through 'new'.
    963   virtual bool IsConstructor() const;
    964 
    965   // Build a list with summaries for this frame including all inlined frames.
    966   // The functions are ordered bottom-to-top (i.e. summaries.last() is the
    967   // top-most activation; caller comes before callee).
    968   virtual void Summarize(
    969       List<FrameSummary>* frames,
    970       FrameSummary::Mode mode = FrameSummary::kExactSummary) const;
    971 
    972   static StandardFrame* cast(StackFrame* frame) {
    973     DCHECK(frame->is_standard());
    974     return static_cast<StandardFrame*>(frame);
    975   }
    976 
    977  protected:
    978   inline explicit StandardFrame(StackFrameIteratorBase* iterator);
    979 
    980   void ComputeCallerState(State* state) const override;
    981 
    982   // Accessors.
    983   inline Address caller_fp() const;
    984   inline Address caller_pc() const;
    985 
    986   // Computes the address of the PC field in the standard frame given
    987   // by the provided frame pointer.
    988   static inline Address ComputePCAddress(Address fp);
    989 
    990   // Computes the address of the constant pool  field in the standard
    991   // frame given by the provided frame pointer.
    992   static inline Address ComputeConstantPoolAddress(Address fp);
    993 
    994   // Iterate over expression stack including stack handlers, locals,
    995   // and parts of the fixed part including context and code fields.
    996   void IterateExpressions(ObjectVisitor* v) const;
    997 
    998   // Returns the address of the n'th expression stack element.
    999   virtual Address GetExpressionAddress(int n) const;
   1000 
   1001   // Determines if the standard frame for the given frame pointer is
   1002   // an arguments adaptor frame.
   1003   static inline bool IsArgumentsAdaptorFrame(Address fp);
   1004 
   1005   // Determines if the standard frame for the given frame pointer is a
   1006   // construct frame.
   1007   static inline bool IsConstructFrame(Address fp);
   1008 
   1009   // Used by OptimizedFrames and StubFrames.
   1010   void IterateCompiledFrame(ObjectVisitor* v) const;
   1011 
   1012  private:
   1013   friend class StackFrame;
   1014   friend class SafeStackFrameIterator;
   1015 };
   1016 
   1017 class JavaScriptFrame : public StandardFrame {
   1018  public:
   1019   Type type() const override { return JAVA_SCRIPT; }
   1020 
   1021   void Summarize(
   1022       List<FrameSummary>* frames,
   1023       FrameSummary::Mode mode = FrameSummary::kExactSummary) const override;
   1024 
   1025   // Accessors.
   1026   virtual JSFunction* function() const;
   1027   Object* receiver() const override;
   1028   Object* context() const override;
   1029   Script* script() const override;
   1030 
   1031   inline void set_receiver(Object* value);
   1032 
   1033   // Access the parameters.
   1034   inline Address GetParameterSlot(int index) const;
   1035   Object* GetParameter(int index) const override;
   1036   int ComputeParametersCount() const override;
   1037 
   1038   // Access the operand stack.
   1039   inline Address GetOperandSlot(int index) const;
   1040   inline Object* GetOperand(int index) const;
   1041   inline int ComputeOperandsCount() const;
   1042 
   1043   // Debugger access.
   1044   void SetParameterValue(int index, Object* value) const;
   1045 
   1046   // Check if this frame is a constructor frame invoked through 'new'.
   1047   bool IsConstructor() const override;
   1048 
   1049   // Determines whether this frame includes inlined activations. To get details
   1050   // about the inlined frames use {GetFunctions} and {Summarize}.
   1051   bool HasInlinedFrames() const;
   1052 
   1053   // Check if this frame has "adapted" arguments in the sense that the
   1054   // actual passed arguments are available in an arguments adaptor
   1055   // frame below it on the stack.
   1056   inline bool has_adapted_arguments() const;
   1057   int GetArgumentsLength() const;
   1058 
   1059   // Garbage collection support.
   1060   void Iterate(ObjectVisitor* v) const override;
   1061 
   1062   // Printing support.
   1063   void Print(StringStream* accumulator, PrintMode mode,
   1064              int index) const override;
   1065 
   1066   // Determine the code for the frame.
   1067   Code* unchecked_code() const override;
   1068 
   1069   // Return a list with {SharedFunctionInfo} objects of this frame.
   1070   virtual void GetFunctions(List<SharedFunctionInfo*>* functions) const;
   1071 
   1072   void GetFunctions(List<Handle<SharedFunctionInfo>>* functions) const;
   1073 
   1074   // Lookup exception handler for current {pc}, returns -1 if none found. Also
   1075   // returns data associated with the handler site specific to the frame type:
   1076   //  - OptimizedFrame  : Data is the stack slot count of the entire frame.
   1077   //  - InterpretedFrame: Data is the register index holding the context.
   1078   virtual int LookupExceptionHandlerInTable(
   1079       int* data, HandlerTable::CatchPrediction* prediction);
   1080 
   1081   // Architecture-specific register description.
   1082   static Register fp_register();
   1083   static Register context_register();
   1084   static Register constant_pool_pointer_register();
   1085 
   1086   static JavaScriptFrame* cast(StackFrame* frame) {
   1087     DCHECK(frame->is_java_script());
   1088     return static_cast<JavaScriptFrame*>(frame);
   1089   }
   1090 
   1091   static void PrintFunctionAndOffset(JSFunction* function, AbstractCode* code,
   1092                                      int code_offset, FILE* file,
   1093                                      bool print_line_number);
   1094 
   1095   static void PrintTop(Isolate* isolate, FILE* file, bool print_args,
   1096                        bool print_line_number);
   1097 
   1098   static void CollectFunctionAndOffsetForICStats(JSFunction* function,
   1099                                                  AbstractCode* code,
   1100                                                  int code_offset);
   1101   static void CollectTopFrameForICStats(Isolate* isolate);
   1102 
   1103  protected:
   1104   inline explicit JavaScriptFrame(StackFrameIteratorBase* iterator);
   1105 
   1106   Address GetCallerStackPointer() const override;
   1107 
   1108   virtual int GetNumberOfIncomingArguments() const;
   1109 
   1110   // Garbage collection support. Iterates over incoming arguments,
   1111   // receiver, and any callee-saved registers.
   1112   void IterateArguments(ObjectVisitor* v) const;
   1113 
   1114   virtual void PrintFrameKind(StringStream* accumulator) const {}
   1115 
   1116  private:
   1117   inline Object* function_slot_object() const;
   1118 
   1119   friend class StackFrameIteratorBase;
   1120 };
   1121 
   1122 
   1123 class StubFrame : public StandardFrame {
   1124  public:
   1125   Type type() const override { return STUB; }
   1126 
   1127   // GC support.
   1128   void Iterate(ObjectVisitor* v) const override;
   1129 
   1130   // Determine the code for the frame.
   1131   Code* unchecked_code() const override;
   1132 
   1133  protected:
   1134   inline explicit StubFrame(StackFrameIteratorBase* iterator);
   1135 
   1136   Address GetCallerStackPointer() const override;
   1137 
   1138   virtual int GetNumberOfIncomingArguments() const;
   1139 
   1140   friend class StackFrameIteratorBase;
   1141 };
   1142 
   1143 
   1144 class OptimizedFrame : public JavaScriptFrame {
   1145  public:
   1146   Type type() const override { return OPTIMIZED; }
   1147 
   1148   // GC support.
   1149   void Iterate(ObjectVisitor* v) const override;
   1150 
   1151   // Return a list with {SharedFunctionInfo} objects of this frame.
   1152   // The functions are ordered bottom-to-top (i.e. functions.last()
   1153   // is the top-most activation)
   1154   void GetFunctions(List<SharedFunctionInfo*>* functions) const override;
   1155 
   1156   void Summarize(
   1157       List<FrameSummary>* frames,
   1158       FrameSummary::Mode mode = FrameSummary::kExactSummary) const override;
   1159 
   1160   // Lookup exception handler for current {pc}, returns -1 if none found.
   1161   int LookupExceptionHandlerInTable(
   1162       int* data, HandlerTable::CatchPrediction* prediction) override;
   1163 
   1164   DeoptimizationInputData* GetDeoptimizationData(int* deopt_index) const;
   1165 
   1166   Object* receiver() const override;
   1167 
   1168   static int StackSlotOffsetRelativeToFp(int slot_index);
   1169 
   1170  protected:
   1171   inline explicit OptimizedFrame(StackFrameIteratorBase* iterator);
   1172 
   1173  private:
   1174   friend class StackFrameIteratorBase;
   1175 
   1176   Object* StackSlotAt(int index) const;
   1177 };
   1178 
   1179 
   1180 class InterpretedFrame : public JavaScriptFrame {
   1181  public:
   1182   Type type() const override { return INTERPRETED; }
   1183 
   1184   // Accessors.
   1185   int position() const override;
   1186 
   1187   // Lookup exception handler for current {pc}, returns -1 if none found.
   1188   int LookupExceptionHandlerInTable(
   1189       int* data, HandlerTable::CatchPrediction* prediction) override;
   1190 
   1191   // Returns the current offset into the bytecode stream.
   1192   int GetBytecodeOffset() const;
   1193 
   1194   // Updates the current offset into the bytecode stream, mainly used for stack
   1195   // unwinding to continue execution at a different bytecode offset.
   1196   void PatchBytecodeOffset(int new_offset);
   1197 
   1198   // Returns the frame's current bytecode array.
   1199   BytecodeArray* GetBytecodeArray() const;
   1200 
   1201   // Updates the frame's BytecodeArray with |bytecode_array|. Used by the
   1202   // debugger to swap execution onto a BytecodeArray patched with breakpoints.
   1203   void PatchBytecodeArray(BytecodeArray* bytecode_array);
   1204 
   1205   // Access to the interpreter register file for this frame.
   1206   Object* ReadInterpreterRegister(int register_index) const;
   1207   void WriteInterpreterRegister(int register_index, Object* value);
   1208 
   1209   // Build a list with summaries for this frame including all inlined frames.
   1210   void Summarize(
   1211       List<FrameSummary>* frames,
   1212       FrameSummary::Mode mode = FrameSummary::kExactSummary) const override;
   1213 
   1214   static int GetBytecodeOffset(Address fp);
   1215 
   1216  protected:
   1217   inline explicit InterpretedFrame(StackFrameIteratorBase* iterator);
   1218 
   1219   Address GetExpressionAddress(int n) const override;
   1220 
   1221  private:
   1222   friend class StackFrameIteratorBase;
   1223 };
   1224 
   1225 
   1226 // Arguments adaptor frames are automatically inserted below
   1227 // JavaScript frames when the actual number of parameters does not
   1228 // match the formal number of parameters.
   1229 class ArgumentsAdaptorFrame: public JavaScriptFrame {
   1230  public:
   1231   Type type() const override { return ARGUMENTS_ADAPTOR; }
   1232 
   1233   // Determine the code for the frame.
   1234   Code* unchecked_code() const override;
   1235 
   1236   static ArgumentsAdaptorFrame* cast(StackFrame* frame) {
   1237     DCHECK(frame->is_arguments_adaptor());
   1238     return static_cast<ArgumentsAdaptorFrame*>(frame);
   1239   }
   1240 
   1241   // Printing support.
   1242   void Print(StringStream* accumulator, PrintMode mode,
   1243              int index) const override;
   1244 
   1245   static int GetLength(Address fp);
   1246 
   1247  protected:
   1248   inline explicit ArgumentsAdaptorFrame(StackFrameIteratorBase* iterator);
   1249 
   1250   int GetNumberOfIncomingArguments() const override;
   1251 
   1252  private:
   1253   friend class StackFrameIteratorBase;
   1254 };
   1255 
   1256 // Builtin frames are built for builtins with JavaScript linkage, such as
   1257 // various standard library functions (i.e. Math.asin, Math.floor, etc.).
   1258 class BuiltinFrame final : public JavaScriptFrame {
   1259  public:
   1260   Type type() const final { return BUILTIN; }
   1261 
   1262   static BuiltinFrame* cast(StackFrame* frame) {
   1263     DCHECK(frame->is_builtin());
   1264     return static_cast<BuiltinFrame*>(frame);
   1265   }
   1266 
   1267  protected:
   1268   inline explicit BuiltinFrame(StackFrameIteratorBase* iterator);
   1269 
   1270   int GetNumberOfIncomingArguments() const final;
   1271   void PrintFrameKind(StringStream* accumulator) const override;
   1272 
   1273  private:
   1274   friend class StackFrameIteratorBase;
   1275 };
   1276 
   1277 class WasmCompiledFrame : public StandardFrame {
   1278  public:
   1279   Type type() const override { return WASM_COMPILED; }
   1280 
   1281   // GC support.
   1282   void Iterate(ObjectVisitor* v) const override;
   1283 
   1284   // Printing support.
   1285   void Print(StringStream* accumulator, PrintMode mode,
   1286              int index) const override;
   1287 
   1288   // Lookup exception handler for current {pc}, returns -1 if none found. Also
   1289   // returns the stack slot count of the entire frame.
   1290   int LookupExceptionHandlerInTable(int* data);
   1291 
   1292   // Determine the code for the frame.
   1293   Code* unchecked_code() const override;
   1294 
   1295   // Accessors.
   1296   WasmInstanceObject* wasm_instance() const;
   1297   uint32_t function_index() const;
   1298   Script* script() const override;
   1299   int position() const override;
   1300   bool at_to_number_conversion() const;
   1301 
   1302   void Summarize(List<FrameSummary>* frames,
   1303                  FrameSummary::Mode mode) const override;
   1304 
   1305   static WasmCompiledFrame* cast(StackFrame* frame) {
   1306     DCHECK(frame->is_wasm_compiled());
   1307     return static_cast<WasmCompiledFrame*>(frame);
   1308   }
   1309 
   1310  protected:
   1311   inline explicit WasmCompiledFrame(StackFrameIteratorBase* iterator);
   1312 
   1313   Address GetCallerStackPointer() const override;
   1314 
   1315  private:
   1316   friend class StackFrameIteratorBase;
   1317 };
   1318 
   1319 class WasmInterpreterEntryFrame : public StandardFrame {
   1320  public:
   1321   Type type() const override { return WASM_INTERPRETER_ENTRY; }
   1322 
   1323   // GC support.
   1324   void Iterate(ObjectVisitor* v) const override;
   1325 
   1326   // Printing support.
   1327   void Print(StringStream* accumulator, PrintMode mode,
   1328              int index) const override;
   1329 
   1330   void Summarize(
   1331       List<FrameSummary>* frames,
   1332       FrameSummary::Mode mode = FrameSummary::kExactSummary) const override;
   1333 
   1334   // Determine the code for the frame.
   1335   Code* unchecked_code() const override;
   1336 
   1337   // Accessors.
   1338   WasmInstanceObject* wasm_instance() const;
   1339   Script* script() const override;
   1340   int position() const override;
   1341 
   1342   static WasmInterpreterEntryFrame* cast(StackFrame* frame) {
   1343     DCHECK(frame->is_wasm_interpreter_entry());
   1344     return static_cast<WasmInterpreterEntryFrame*>(frame);
   1345   }
   1346 
   1347  protected:
   1348   inline explicit WasmInterpreterEntryFrame(StackFrameIteratorBase* iterator);
   1349 
   1350   Address GetCallerStackPointer() const override;
   1351 
   1352  private:
   1353   friend class StackFrameIteratorBase;
   1354 };
   1355 
   1356 class WasmToJsFrame : public StubFrame {
   1357  public:
   1358   Type type() const override { return WASM_TO_JS; }
   1359 
   1360  protected:
   1361   inline explicit WasmToJsFrame(StackFrameIteratorBase* iterator);
   1362 
   1363  private:
   1364   friend class StackFrameIteratorBase;
   1365 };
   1366 
   1367 class JsToWasmFrame : public StubFrame {
   1368  public:
   1369   Type type() const override { return JS_TO_WASM; }
   1370 
   1371  protected:
   1372   inline explicit JsToWasmFrame(StackFrameIteratorBase* iterator);
   1373 
   1374  private:
   1375   friend class StackFrameIteratorBase;
   1376 };
   1377 
   1378 class InternalFrame: public StandardFrame {
   1379  public:
   1380   Type type() const override { return INTERNAL; }
   1381 
   1382   // Garbage collection support.
   1383   void Iterate(ObjectVisitor* v) const override;
   1384 
   1385   // Determine the code for the frame.
   1386   Code* unchecked_code() const override;
   1387 
   1388   static InternalFrame* cast(StackFrame* frame) {
   1389     DCHECK(frame->is_internal());
   1390     return static_cast<InternalFrame*>(frame);
   1391   }
   1392 
   1393  protected:
   1394   inline explicit InternalFrame(StackFrameIteratorBase* iterator);
   1395 
   1396   Address GetCallerStackPointer() const override;
   1397 
   1398  private:
   1399   friend class StackFrameIteratorBase;
   1400 };
   1401 
   1402 
   1403 class StubFailureTrampolineFrame: public StandardFrame {
   1404  public:
   1405   Type type() const override { return STUB_FAILURE_TRAMPOLINE; }
   1406 
   1407   // Get the code associated with this frame.
   1408   // This method could be called during marking phase of GC.
   1409   Code* unchecked_code() const override;
   1410 
   1411   void Iterate(ObjectVisitor* v) const override;
   1412 
   1413   // Architecture-specific register description.
   1414   static Register fp_register();
   1415   static Register context_register();
   1416   static Register constant_pool_pointer_register();
   1417 
   1418  protected:
   1419   inline explicit StubFailureTrampolineFrame(
   1420       StackFrameIteratorBase* iterator);
   1421 
   1422   Address GetCallerStackPointer() const override;
   1423 
   1424  private:
   1425   friend class StackFrameIteratorBase;
   1426 };
   1427 
   1428 
   1429 // Construct frames are special trampoline frames introduced to handle
   1430 // function invocations through 'new'.
   1431 class ConstructFrame: public InternalFrame {
   1432  public:
   1433   Type type() const override { return CONSTRUCT; }
   1434 
   1435   static ConstructFrame* cast(StackFrame* frame) {
   1436     DCHECK(frame->is_construct());
   1437     return static_cast<ConstructFrame*>(frame);
   1438   }
   1439 
   1440  protected:
   1441   inline explicit ConstructFrame(StackFrameIteratorBase* iterator);
   1442 
   1443  private:
   1444   friend class StackFrameIteratorBase;
   1445 };
   1446 
   1447 
   1448 class StackFrameIteratorBase BASE_EMBEDDED {
   1449  public:
   1450   Isolate* isolate() const { return isolate_; }
   1451 
   1452   bool done() const { return frame_ == NULL; }
   1453 
   1454  protected:
   1455   // An iterator that iterates over a given thread's stack.
   1456   StackFrameIteratorBase(Isolate* isolate, bool can_access_heap_objects);
   1457 
   1458   Isolate* isolate_;
   1459 #define DECLARE_SINGLETON(ignore, type) type type##_;
   1460   STACK_FRAME_TYPE_LIST(DECLARE_SINGLETON)
   1461 #undef DECLARE_SINGLETON
   1462   StackFrame* frame_;
   1463   StackHandler* handler_;
   1464   const bool can_access_heap_objects_;
   1465 
   1466   StackHandler* handler() const {
   1467     DCHECK(!done());
   1468     return handler_;
   1469   }
   1470 
   1471   // Get the type-specific frame singleton in a given state.
   1472   StackFrame* SingletonFor(StackFrame::Type type, StackFrame::State* state);
   1473   // A helper function, can return a NULL pointer.
   1474   StackFrame* SingletonFor(StackFrame::Type type);
   1475 
   1476  private:
   1477   friend class StackFrame;
   1478   DISALLOW_COPY_AND_ASSIGN(StackFrameIteratorBase);
   1479 };
   1480 
   1481 
   1482 class StackFrameIterator: public StackFrameIteratorBase {
   1483  public:
   1484   // An iterator that iterates over the isolate's current thread's stack,
   1485   explicit StackFrameIterator(Isolate* isolate);
   1486   // An iterator that iterates over a given thread's stack.
   1487   StackFrameIterator(Isolate* isolate, ThreadLocalTop* t);
   1488 
   1489   StackFrame* frame() const {
   1490     DCHECK(!done());
   1491     return frame_;
   1492   }
   1493   void Advance();
   1494 
   1495  private:
   1496   // Go back to the first frame.
   1497   void Reset(ThreadLocalTop* top);
   1498 
   1499   DISALLOW_COPY_AND_ASSIGN(StackFrameIterator);
   1500 };
   1501 
   1502 // Iterator that supports iterating through all JavaScript frames.
   1503 class JavaScriptFrameIterator BASE_EMBEDDED {
   1504  public:
   1505   inline explicit JavaScriptFrameIterator(Isolate* isolate);
   1506   inline JavaScriptFrameIterator(Isolate* isolate, ThreadLocalTop* top);
   1507 
   1508   inline JavaScriptFrame* frame() const;
   1509 
   1510   bool done() const { return iterator_.done(); }
   1511   void Advance();
   1512 
   1513   // Advance to the frame holding the arguments for the current
   1514   // frame. This only affects the current frame if it has adapted
   1515   // arguments.
   1516   void AdvanceToArgumentsFrame();
   1517 
   1518  private:
   1519   StackFrameIterator iterator_;
   1520 };
   1521 
   1522 // NOTE: The stack trace frame iterator is an iterator that only traverse proper
   1523 // JavaScript frames that have proper JavaScript functions and WASM frames.
   1524 // This excludes the problematic functions in runtime.js.
   1525 class StackTraceFrameIterator BASE_EMBEDDED {
   1526  public:
   1527   explicit StackTraceFrameIterator(Isolate* isolate);
   1528   // Skip frames until the frame with the given id is reached.
   1529   StackTraceFrameIterator(Isolate* isolate, StackFrame::Id id);
   1530   bool done() const { return iterator_.done(); }
   1531   void Advance();
   1532 
   1533   inline StandardFrame* frame() const;
   1534 
   1535   inline bool is_javascript() const;
   1536   inline bool is_wasm() const;
   1537   inline JavaScriptFrame* javascript_frame() const;
   1538 
   1539   // Advance to the frame holding the arguments for the current
   1540   // frame. This only affects the current frame if it is a javascript frame and
   1541   // has adapted arguments.
   1542   void AdvanceToArgumentsFrame();
   1543 
   1544  private:
   1545   StackFrameIterator iterator_;
   1546   bool IsValidFrame(StackFrame* frame) const;
   1547 };
   1548 
   1549 
   1550 class SafeStackFrameIterator: public StackFrameIteratorBase {
   1551  public:
   1552   SafeStackFrameIterator(Isolate* isolate,
   1553                          Address fp, Address sp,
   1554                          Address js_entry_sp);
   1555 
   1556   inline StackFrame* frame() const;
   1557   void Advance();
   1558 
   1559   StackFrame::Type top_frame_type() const { return top_frame_type_; }
   1560 
   1561  private:
   1562   void AdvanceOneFrame();
   1563 
   1564   bool IsValidStackAddress(Address addr) const {
   1565     return low_bound_ <= addr && addr <= high_bound_;
   1566   }
   1567   bool IsValidFrame(StackFrame* frame) const;
   1568   bool IsValidCaller(StackFrame* frame);
   1569   bool IsValidExitFrame(Address fp) const;
   1570   bool IsValidTop(ThreadLocalTop* top) const;
   1571 
   1572   const Address low_bound_;
   1573   const Address high_bound_;
   1574   StackFrame::Type top_frame_type_;
   1575   ExternalCallbackScope* external_callback_scope_;
   1576 };
   1577 
   1578 
   1579 class StackFrameLocator BASE_EMBEDDED {
   1580  public:
   1581   explicit StackFrameLocator(Isolate* isolate) : iterator_(isolate) {}
   1582 
   1583   // Find the nth JavaScript frame on the stack. The caller must
   1584   // guarantee that such a frame exists.
   1585   JavaScriptFrame* FindJavaScriptFrame(int n);
   1586 
   1587  private:
   1588   StackFrameIterator iterator_;
   1589 };
   1590 
   1591 
   1592 // Reads all frames on the current stack and copies them into the current
   1593 // zone memory.
   1594 Vector<StackFrame*> CreateStackMap(Isolate* isolate, Zone* zone);
   1595 
   1596 }  // namespace internal
   1597 }  // namespace v8
   1598 
   1599 #endif  // V8_FRAMES_H_
   1600