LCOV - code coverage report
Current view: top level - src - frames.h (source / functions) Hit Total Coverage
Test: app.info Lines: 95 102 93.1 %
Date: 2017-04-26 Functions: 39 81 48.1 %

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

Generated by: LCOV version 1.10