LCOV - code coverage report
Current view: top level - src - frames.h (source / functions) Hit Total Coverage
Test: app.info Lines: 99 107 92.5 %
Date: 2019-01-20 Functions: 36 90 40.0 %

          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/handles.h"
       9             : #include "src/objects.h"
      10             : #include "src/objects/code.h"
      11             : #include "src/safepoint-table.h"
      12             : 
      13             : namespace v8 {
      14             : namespace internal {
      15             : namespace wasm {
      16             : class WasmCode;
      17             : }
      18             : 
      19             : // Forward declarations.
      20             : class AbstractCode;
      21             : class Debug;
      22             : class ExternalCallbackScope;
      23             : class InnerPointerToCodeCache;
      24             : class Isolate;
      25             : class ObjectVisitor;
      26             : class RootVisitor;
      27             : class StackFrameIteratorBase;
      28             : class StringStream;
      29             : class ThreadLocalTop;
      30             : class WasmDebugInfo;
      31             : class WasmInstanceObject;
      32             : class WasmModuleObject;
      33             : 
      34             : class StackHandlerConstants : public AllStatic {
      35             :  public:
      36             :   static const int kNextOffset = 0 * kSystemPointerSize;
      37             :   static const int kPaddingOffset = 1 * kSystemPointerSize;
      38             : 
      39             :   static const int kSize = kPaddingOffset + kSystemPointerSize;
      40             :   static const int kSlotCount = kSize >> kSystemPointerSizeLog2;
      41             : };
      42             : 
      43             : class StackHandler {
      44             :  public:
      45             :   // Get the address of this stack handler.
      46             :   inline Address address() const;
      47             : 
      48             :   // Get the next stack handler in the chain.
      49             :   inline StackHandler* next() const;
      50             : 
      51             :   // Get the next stack handler, as an Address. This is safe to use even
      52             :   // when the next handler is null.
      53             :   inline Address next_address() const;
      54             : 
      55             :   // Conversion support.
      56             :   static inline StackHandler* FromAddress(Address address);
      57             : 
      58             :  private:
      59             :   DISALLOW_IMPLICIT_CONSTRUCTORS(StackHandler);
      60             : };
      61             : 
      62             : #define STACK_FRAME_TYPE_LIST(V)                                          \
      63             :   V(ENTRY, EntryFrame)                                                    \
      64             :   V(CONSTRUCT_ENTRY, ConstructEntryFrame)                                 \
      65             :   V(EXIT, ExitFrame)                                                      \
      66             :   V(OPTIMIZED, OptimizedFrame)                                            \
      67             :   V(WASM_COMPILED, WasmCompiledFrame)                                     \
      68             :   V(WASM_TO_JS, WasmToJsFrame)                                            \
      69             :   V(JS_TO_WASM, JsToWasmFrame)                                            \
      70             :   V(WASM_INTERPRETER_ENTRY, WasmInterpreterEntryFrame)                    \
      71             :   V(C_WASM_ENTRY, CWasmEntryFrame)                                        \
      72             :   V(WASM_COMPILE_LAZY, WasmCompileLazyFrame)                              \
      73             :   V(INTERPRETED, InterpretedFrame)                                        \
      74             :   V(STUB, StubFrame)                                                      \
      75             :   V(BUILTIN_CONTINUATION, BuiltinContinuationFrame)                       \
      76             :   V(JAVA_SCRIPT_BUILTIN_CONTINUATION, JavaScriptBuiltinContinuationFrame) \
      77             :   V(JAVA_SCRIPT_BUILTIN_CONTINUATION_WITH_CATCH,                          \
      78             :     JavaScriptBuiltinContinuationWithCatchFrame)                          \
      79             :   V(INTERNAL, InternalFrame)                                              \
      80             :   V(CONSTRUCT, ConstructFrame)                                            \
      81             :   V(ARGUMENTS_ADAPTOR, ArgumentsAdaptorFrame)                             \
      82             :   V(BUILTIN, BuiltinFrame)                                                \
      83             :   V(BUILTIN_EXIT, BuiltinExitFrame)                                       \
      84             :   V(NATIVE, NativeFrame)
      85             : 
      86             : // Abstract base class for all stack frames.
      87             : class StackFrame {
      88             :  public:
      89             : #define DECLARE_TYPE(type, ignore) type,
      90             :   enum Type {
      91             :     NONE = 0,
      92             :     STACK_FRAME_TYPE_LIST(DECLARE_TYPE)
      93             :     NUMBER_OF_TYPES,
      94             :     // Used by FrameScope to indicate that the stack frame is constructed
      95             :     // manually and the FrameScope does not need to emit code.
      96             :     MANUAL
      97             :   };
      98             : #undef DECLARE_TYPE
      99             : 
     100             :   // Opaque data type for identifying stack frames. Used extensively
     101             :   // by the debugger.
     102             :   // ID_MIN_VALUE and ID_MAX_VALUE are specified to ensure that enumeration type
     103             :   // has correct value range (see Issue 830 for more details).
     104             :   enum Id {
     105             :     ID_MIN_VALUE = kMinInt,
     106             :     ID_MAX_VALUE = kMaxInt,
     107             :     NO_ID = 0
     108             :   };
     109             : 
     110             :   // Used to mark the outermost JS entry frame.
     111             :   //
     112             :   // The mark is an opaque value that should be pushed onto the stack directly,
     113             :   // carefully crafted to not be interpreted as a tagged pointer.
     114             :   enum JsFrameMarker {
     115             :     INNER_JSENTRY_FRAME = (0 << kSmiTagSize) | kSmiTag,
     116             :     OUTERMOST_JSENTRY_FRAME = (1 << kSmiTagSize) | kSmiTag
     117             :   };
     118             :   STATIC_ASSERT((INNER_JSENTRY_FRAME & kHeapObjectTagMask) != kHeapObjectTag);
     119             :   STATIC_ASSERT((OUTERMOST_JSENTRY_FRAME & kHeapObjectTagMask) !=
     120             :                 kHeapObjectTag);
     121             : 
     122             :   struct State {
     123             :     Address sp = kNullAddress;
     124             :     Address fp = kNullAddress;
     125             :     Address* pc_address = nullptr;
     126             :     Address* callee_pc_address = nullptr;
     127             :     Address* constant_pool_address = nullptr;
     128             :   };
     129             : 
     130             :   // Convert a stack frame type to a marker that can be stored on the stack.
     131             :   //
     132             :   // The marker is an opaque value, not intended to be interpreted in any way
     133             :   // except being checked by IsTypeMarker or converted by MarkerToType.
     134             :   // It has the same tagging as Smis, so any marker value that does not pass
     135             :   // IsTypeMarker can instead be interpreted as a tagged pointer.
     136             :   //
     137             :   // Note that the marker is not a Smi: Smis on 64-bit architectures are stored
     138             :   // in the top 32 bits of a 64-bit value, which in turn makes them expensive
     139             :   // (in terms of code/instruction size) to push as immediates onto the stack.
     140             :   static int32_t TypeToMarker(Type type) {
     141             :     DCHECK_GE(type, 0);
     142     1892998 :     return (type << kSmiTagSize) | kSmiTag;
     143             :   }
     144             : 
     145             :   // Convert a marker back to a stack frame type.
     146             :   //
     147             :   // Unlike the return value of TypeToMarker, this takes an intptr_t, as that is
     148             :   // the type of the value on the stack.
     149             :   static Type MarkerToType(intptr_t marker) {
     150             :     DCHECK(IsTypeMarker(marker));
     151    12930091 :     return static_cast<Type>(marker >> kSmiTagSize);
     152             :   }
     153             : 
     154             :   // Check if a marker is a stack frame type marker or a tagged pointer.
     155             :   //
     156             :   // Returns true if the given marker is tagged as a stack frame type marker,
     157             :   // and should be converted back to a stack frame type using MarkerToType.
     158             :   // Otherwise, the value is a tagged function pointer.
     159             :   static bool IsTypeMarker(intptr_t function_or_marker) {
     160    35919177 :     return (function_or_marker & kSmiTagMask) == kSmiTag;
     161             :   }
     162             : 
     163             :   // Copy constructor; it breaks the connection to host iterator
     164             :   // (as an iterator usually lives on stack).
     165             :   StackFrame(const StackFrame& original) V8_NOEXCEPT {
     166             :     this->state_ = original.state_;
     167             :     this->iterator_ = nullptr;
     168             :     this->isolate_ = original.isolate_;
     169             :   }
     170             : 
     171             :   // Type testers.
     172      125511 :   bool is_entry() const { return type() == ENTRY; }
     173      100103 :   bool is_construct_entry() const { return type() == CONSTRUCT_ENTRY; }
     174       59753 :   bool is_exit() const { return type() == EXIT; }
     175    22070063 :   bool is_optimized() const { return type() == OPTIMIZED; }
     176      507731 :   bool is_interpreted() const { return type() == INTERPRETED; }
     177         455 :   bool is_wasm_compiled() const { return type() == WASM_COMPILED; }
     178             :   bool is_wasm_compile_lazy() const { return type() == WASM_COMPILE_LAZY; }
     179             :   bool is_wasm_to_js() const { return type() == WASM_TO_JS; }
     180             :   bool is_js_to_wasm() const { return type() == JS_TO_WASM; }
     181             :   bool is_wasm_interpreter_entry() const {
     182      383462 :     return type() == WASM_INTERPRETER_ENTRY;
     183             :   }
     184      525461 :   bool is_arguments_adaptor() const { return type() == ARGUMENTS_ADAPTOR; }
     185             :   bool is_builtin() const { return type() == BUILTIN; }
     186           0 :   bool is_internal() const { return type() == INTERNAL; }
     187             :   bool is_builtin_continuation() const {
     188             :     return type() == BUILTIN_CONTINUATION;
     189             :   }
     190             :   bool is_java_script_builtin_continuation() const {
     191             :     return type() == JAVA_SCRIPT_BUILTIN_CONTINUATION;
     192             :   }
     193             :   bool is_java_script_builtin_with_catch_continuation() const {
     194             :     return type() == JAVA_SCRIPT_BUILTIN_CONTINUATION_WITH_CATCH;
     195             :   }
     196          10 :   bool is_construct() const { return type() == CONSTRUCT; }
     197       59457 :   bool is_builtin_exit() const { return type() == BUILTIN_EXIT; }
     198           0 :   virtual bool is_standard() const { return false; }
     199             : 
     200    12936598 :   bool is_java_script() const {
     201    12936598 :     Type type = this->type();
     202    25944372 :     return (type == OPTIMIZED) || (type == INTERPRETED) || (type == BUILTIN) ||
     203    25944131 :            (type == JAVA_SCRIPT_BUILTIN_CONTINUATION) ||
     204    12936598 :            (type == JAVA_SCRIPT_BUILTIN_CONTINUATION_WITH_CATCH);
     205             :   }
     206             :   bool is_wasm() const {
     207     5255599 :     Type type = this->type();
     208     5255599 :     return type == WASM_COMPILED || type == WASM_INTERPRETER_ENTRY;
     209             :   }
     210             : 
     211             :   // Accessors.
     212             :   Address sp() const { return state_.sp; }
     213       39266 :   Address fp() const { return state_.fp; }
     214             :   Address callee_pc() const {
     215      349877 :     return state_.callee_pc_address ? *state_.callee_pc_address : kNullAddress;
     216             :   }
     217    58716792 :   Address caller_sp() const { return GetCallerStackPointer(); }
     218             : 
     219             :   // If this frame is optimized and was dynamically aligned return its old
     220             :   // unaligned frame pointer.  When the frame is deoptimized its FP will shift
     221             :   // up one word and become unaligned.
     222             :   Address UnpaddedFP() const;
     223             : 
     224    24917832 :   Address pc() const { return *pc_address(); }
     225      263959 :   void set_pc(Address pc) { *pc_address() = pc; }
     226             : 
     227             :   Address constant_pool() const { return *constant_pool_address(); }
     228             :   void set_constant_pool(Address constant_pool) {
     229             :     *constant_pool_address() = constant_pool;
     230             :   }
     231             : 
     232             :   Address* pc_address() const { return state_.pc_address; }
     233             : 
     234             :   Address* constant_pool_address() const {
     235             :     return state_.constant_pool_address;
     236             :   }
     237             : 
     238             :   // Get the id of this stack frame.
     239     1981204 :   Id id() const { return static_cast<Id>(caller_sp()); }
     240             : 
     241             :   // Get the top handler from the current stack iterator.
     242             :   inline StackHandler* top_handler() const;
     243             : 
     244             :   // Get the type of this frame.
     245             :   virtual Type type() const = 0;
     246             : 
     247             :   // Get the code associated with this frame.
     248             :   // This method could be called during marking phase of GC.
     249             :   virtual Code unchecked_code() const = 0;
     250             : 
     251             :   // Search for the code associated with this frame.
     252             :   Code LookupCode() const;
     253             : 
     254             :   virtual void Iterate(RootVisitor* v) const = 0;
     255             :   static void IteratePc(RootVisitor* v, Address* pc_address,
     256             :                         Address* constant_pool_address, Code holder);
     257             : 
     258             :   // Sets a callback function for return-address rewriting profilers
     259             :   // to resolve the location of a return address to the location of the
     260             :   // profiler's stashed return address.
     261             :   static void SetReturnAddressLocationResolver(
     262             :       ReturnAddressLocationResolver resolver);
     263             : 
     264             :   // Resolves pc_address through the resolution address function if one is set.
     265             :   static inline Address* ResolveReturnAddressLocation(Address* pc_address);
     266             : 
     267             :   // Printing support.
     268             :   enum PrintMode { OVERVIEW, DETAILS };
     269             :   virtual void Print(StringStream* accumulator, PrintMode mode,
     270             :                      int index) const;
     271             : 
     272             :   Isolate* isolate() const { return isolate_; }
     273             : 
     274             :   void operator=(const StackFrame& original) = delete;
     275             : 
     276             :  protected:
     277             :   inline explicit StackFrame(StackFrameIteratorBase* iterator);
     278   178833354 :   virtual ~StackFrame() = default;
     279             : 
     280             :   // Compute the stack pointer for the calling frame.
     281             :   virtual Address GetCallerStackPointer() const = 0;
     282             : 
     283             :   // Compute the stack frame type for the given state.
     284             :   static Type ComputeType(const StackFrameIteratorBase* iterator, State* state);
     285             : 
     286             : #ifdef DEBUG
     287             :   bool can_access_heap_objects() const;
     288             : #endif
     289             : 
     290             :  private:
     291             :   const StackFrameIteratorBase* iterator_;
     292             :   Isolate* isolate_;
     293             :   State state_;
     294             : 
     295             :   static ReturnAddressLocationResolver return_address_location_resolver_;
     296             : 
     297             :   // Fill in the state of the calling frame.
     298             :   virtual void ComputeCallerState(State* state) const = 0;
     299             : 
     300             :   // Get the type and the state of the calling frame.
     301             :   virtual Type GetCallerState(State* state) const;
     302             : 
     303             :   static const intptr_t kIsolateTag = 1;
     304             : 
     305             :   friend class StackFrameIterator;
     306             :   friend class StackFrameIteratorBase;
     307             :   friend class StackHandlerIterator;
     308             :   friend class SafeStackFrameIterator;
     309             : };
     310             : 
     311     8515874 : class NativeFrame : public StackFrame {
     312             :  public:
     313           0 :   Type type() const override { return NATIVE; }
     314             : 
     315             :   Code unchecked_code() const override;
     316             : 
     317             :   // Garbage collection support.
     318           0 :   void Iterate(RootVisitor* v) const override {}
     319             : 
     320             :  protected:
     321             :   inline explicit NativeFrame(StackFrameIteratorBase* iterator);
     322             : 
     323             :   Address GetCallerStackPointer() const override;
     324             : 
     325             :  private:
     326             :   void ComputeCallerState(State* state) const override;
     327             : 
     328             :   friend class StackFrameIteratorBase;
     329             : };
     330             : 
     331             : // Entry frames are used to enter JavaScript execution from C.
     332    17031748 : class EntryFrame: public StackFrame {
     333             :  public:
     334     2090454 :   Type type() const override { return ENTRY; }
     335             : 
     336             :   Code unchecked_code() const override;
     337             : 
     338             :   // Garbage collection support.
     339             :   void Iterate(RootVisitor* v) const override;
     340             : 
     341             :   static EntryFrame* cast(StackFrame* frame) {
     342             :     DCHECK(frame->is_entry());
     343             :     return static_cast<EntryFrame*>(frame);
     344             :   }
     345             : 
     346             :  protected:
     347             :   inline explicit EntryFrame(StackFrameIteratorBase* iterator);
     348             : 
     349             :   // The caller stack pointer for entry frames is always zero. The
     350             :   // real information about the caller frame is available through the
     351             :   // link to the top exit frame.
     352         479 :   Address GetCallerStackPointer() const override { return 0; }
     353             : 
     354             :  private:
     355             :   void ComputeCallerState(State* state) const override;
     356             :   Type GetCallerState(State* state) const override;
     357             : 
     358             :   friend class StackFrameIteratorBase;
     359             : };
     360             : 
     361     8515874 : class ConstructEntryFrame : public EntryFrame {
     362             :  public:
     363          42 :   Type type() const override { return CONSTRUCT_ENTRY; }
     364             : 
     365             :   Code unchecked_code() const override;
     366             : 
     367             :   static ConstructEntryFrame* cast(StackFrame* frame) {
     368             :     DCHECK(frame->is_construct_entry());
     369             :     return static_cast<ConstructEntryFrame*>(frame);
     370             :   }
     371             : 
     372             :  protected:
     373             :   inline explicit ConstructEntryFrame(StackFrameIteratorBase* iterator);
     374             : 
     375             :  private:
     376             :   friend class StackFrameIteratorBase;
     377             : };
     378             : 
     379             : 
     380             : // Exit frames are used to exit JavaScript execution and go to C.
     381    17031748 : class ExitFrame: public StackFrame {
     382             :  public:
     383     7112223 :   Type type() const override { return EXIT; }
     384             : 
     385             :   Code unchecked_code() const override;
     386             : 
     387             :   Address& code_slot() const;
     388             : 
     389             :   // Garbage collection support.
     390             :   void Iterate(RootVisitor* v) const override;
     391             : 
     392             :   static ExitFrame* cast(StackFrame* frame) {
     393             :     DCHECK(frame->is_exit());
     394             :     return static_cast<ExitFrame*>(frame);
     395             :   }
     396             : 
     397             :   // Compute the state and type of an exit frame given a frame
     398             :   // pointer. Used when constructing the first stack frame seen by an
     399             :   // iterator and the frames following entry frames.
     400             :   static Type GetStateForFramePointer(Address fp, State* state);
     401             :   static Address ComputeStackPointer(Address fp);
     402             :   static StackFrame::Type ComputeFrameType(Address fp);
     403             :   static void FillState(Address fp, Address sp, State* state);
     404             : 
     405             :  protected:
     406             :   inline explicit ExitFrame(StackFrameIteratorBase* iterator);
     407             : 
     408             :   Address GetCallerStackPointer() const override;
     409             : 
     410             :  private:
     411             :   void ComputeCallerState(State* state) const override;
     412             : 
     413             :   friend class StackFrameIteratorBase;
     414             : };
     415             : 
     416             : // Builtin exit frames are a special case of exit frames, which are used
     417             : // whenever C++ builtins (e.g., Math.acos) are called. Their main purpose is
     418             : // to allow such builtins to appear in stack traces.
     419     8515874 : class BuiltinExitFrame : public ExitFrame {
     420             :  public:
     421     1166516 :   Type type() const override { return BUILTIN_EXIT; }
     422             : 
     423             :   static BuiltinExitFrame* cast(StackFrame* frame) {
     424             :     DCHECK(frame->is_builtin_exit());
     425             :     return static_cast<BuiltinExitFrame*>(frame);
     426             :   }
     427             : 
     428             :   JSFunction function() const;
     429             :   Object receiver() const;
     430             : 
     431             :   bool IsConstructor() const;
     432             : 
     433             :   void Print(StringStream* accumulator, PrintMode mode,
     434             :              int index) const override;
     435             : 
     436             :  protected:
     437             :   inline explicit BuiltinExitFrame(StackFrameIteratorBase* iterator);
     438             : 
     439             :  private:
     440             :   Object GetParameter(int i) const;
     441             :   int ComputeParametersCount() const;
     442             : 
     443             :   inline Object receiver_slot_object() const;
     444             :   inline Object argc_slot_object() const;
     445             :   inline Object target_slot_object() const;
     446             :   inline Object new_target_slot_object() const;
     447             : 
     448             :   friend class StackFrameIteratorBase;
     449             : };
     450             : 
     451             : class StandardFrame;
     452             : 
     453             : class FrameSummary {
     454             :  public:
     455             : // Subclasses for the different summary kinds:
     456             : #define FRAME_SUMMARY_VARIANTS(F)                                             \
     457             :   F(JAVA_SCRIPT, JavaScriptFrameSummary, java_script_summary_, JavaScript)    \
     458             :   F(WASM_COMPILED, WasmCompiledFrameSummary, wasm_compiled_summary_,          \
     459             :     WasmCompiled)                                                             \
     460             :   F(WASM_INTERPRETED, WasmInterpretedFrameSummary, wasm_interpreted_summary_, \
     461             :     WasmInterpreted)
     462             : 
     463             : #define FRAME_SUMMARY_KIND(kind, type, field, desc) kind,
     464             :   enum Kind { FRAME_SUMMARY_VARIANTS(FRAME_SUMMARY_KIND) };
     465             : #undef FRAME_SUMMARY_KIND
     466             : 
     467             :   class FrameSummaryBase {
     468             :    public:
     469             :     FrameSummaryBase(Isolate* isolate, Kind kind)
     470     7550946 :         : isolate_(isolate), kind_(kind) {}
     471             :     Isolate* isolate() const { return isolate_; }
     472             :     Kind kind() const { return kind_; }
     473             : 
     474             :    private:
     475             :     Isolate* isolate_;
     476             :     Kind kind_;
     477             :   };
     478             : 
     479             :   class JavaScriptFrameSummary : public FrameSummaryBase {
     480             :    public:
     481             :     JavaScriptFrameSummary(Isolate* isolate, Object receiver,
     482             :                            JSFunction function, AbstractCode abstract_code,
     483             :                            int code_offset, bool is_constructor);
     484             : 
     485             :     Handle<Object> receiver() const { return receiver_; }
     486             :     Handle<JSFunction> function() const { return function_; }
     487             :     Handle<AbstractCode> abstract_code() const { return abstract_code_; }
     488             :     int code_offset() const { return code_offset_; }
     489             :     bool is_constructor() const { return is_constructor_; }
     490             :     bool is_subject_to_debugging() const;
     491             :     int SourcePosition() const;
     492             :     int SourceStatementPosition() const;
     493             :     Handle<Object> script() const;
     494             :     Handle<String> FunctionName() const;
     495             :     Handle<Context> native_context() const;
     496             : 
     497             :    private:
     498             :     Handle<Object> receiver_;
     499             :     Handle<JSFunction> function_;
     500             :     Handle<AbstractCode> abstract_code_;
     501             :     int code_offset_;
     502             :     bool is_constructor_;
     503             :   };
     504             : 
     505             :   class WasmFrameSummary : public FrameSummaryBase {
     506             :    protected:
     507             :     WasmFrameSummary(Isolate*, Kind, Handle<WasmInstanceObject>,
     508             :                      bool at_to_number_conversion);
     509             : 
     510             :    public:
     511             :     Handle<Object> receiver() const;
     512             :     uint32_t function_index() const;
     513             :     int byte_offset() const;
     514             :     bool is_constructor() const { return false; }
     515             :     bool is_subject_to_debugging() const { return true; }
     516             :     int SourcePosition() const;
     517           0 :     int SourceStatementPosition() const { return SourcePosition(); }
     518             :     Handle<Script> script() const;
     519             :     Handle<WasmInstanceObject> wasm_instance() const { return wasm_instance_; }
     520             :     Handle<String> FunctionName() const;
     521             :     Handle<Context> native_context() const;
     522             :     bool at_to_number_conversion() const { return at_to_number_conversion_; }
     523             : 
     524             :    private:
     525             :     Handle<WasmInstanceObject> wasm_instance_;
     526             :     bool at_to_number_conversion_;
     527             :   };
     528             : 
     529             :   class WasmCompiledFrameSummary : public WasmFrameSummary {
     530             :    public:
     531             :     WasmCompiledFrameSummary(Isolate*, Handle<WasmInstanceObject>,
     532             :                              wasm::WasmCode*, int code_offset,
     533             :                              bool at_to_number_conversion);
     534             :     uint32_t function_index() const;
     535             :     wasm::WasmCode* code() const { return code_; }
     536             :     int code_offset() const { return code_offset_; }
     537             :     int byte_offset() const;
     538             :     static int GetWasmSourcePosition(const wasm::WasmCode* code, int offset);
     539             : 
     540             :    private:
     541             :     wasm::WasmCode* const code_;
     542             :     int code_offset_;
     543             :   };
     544             : 
     545             :   class WasmInterpretedFrameSummary : public WasmFrameSummary {
     546             :    public:
     547             :     WasmInterpretedFrameSummary(Isolate*, Handle<WasmInstanceObject>,
     548             :                                 uint32_t function_index, int byte_offset);
     549             :     uint32_t function_index() const { return function_index_; }
     550             :     int code_offset() const { return byte_offset_; }
     551             :     int byte_offset() const { return byte_offset_; }
     552             : 
     553             :    private:
     554             :     uint32_t function_index_;
     555             :     int byte_offset_;
     556             :   };
     557             : 
     558             : #undef FRAME_SUMMARY_FIELD
     559             : #define FRAME_SUMMARY_CONS(kind, type, field, desc) \
     560             :   FrameSummary(type summ) : field(summ) {}  // NOLINT
     561     8656077 :   FRAME_SUMMARY_VARIANTS(FRAME_SUMMARY_CONS)
     562             : #undef FRAME_SUMMARY_CONS
     563             : 
     564             :   ~FrameSummary();
     565             : 
     566             :   static FrameSummary GetTop(const StandardFrame* frame);
     567             :   static FrameSummary GetBottom(const StandardFrame* frame);
     568             :   static FrameSummary GetSingle(const StandardFrame* frame);
     569             :   static FrameSummary Get(const StandardFrame* frame, int index);
     570             : 
     571             :   // Dispatched accessors.
     572             :   Handle<Object> receiver() const;
     573             :   int code_offset() const;
     574             :   bool is_constructor() const;
     575             :   bool is_subject_to_debugging() const;
     576             :   Handle<Object> script() const;
     577             :   int SourcePosition() const;
     578             :   int SourceStatementPosition() const;
     579             :   Handle<String> FunctionName() const;
     580             :   Handle<Context> native_context() const;
     581             : 
     582             : #define FRAME_SUMMARY_CAST(kind_, type, field, desc)      \
     583             :   bool Is##desc() const { return base_.kind() == kind_; } \
     584             :   const type& As##desc() const {                          \
     585             :     DCHECK_EQ(base_.kind(), kind_);                       \
     586             :     return field;                                         \
     587             :   }
     588     6219992 :   FRAME_SUMMARY_VARIANTS(FRAME_SUMMARY_CAST)
     589             : #undef FRAME_SUMMARY_CAST
     590             : 
     591         585 :   bool IsWasm() const { return IsWasmCompiled() || IsWasmInterpreted(); }
     592             :   const WasmFrameSummary& AsWasm() const {
     593         585 :     if (IsWasmCompiled()) return AsWasmCompiled();
     594         420 :     return AsWasmInterpreted();
     595             :   }
     596             : 
     597             :  private:
     598             : #define FRAME_SUMMARY_FIELD(kind, type, field, desc) type field;
     599             :   union {
     600             :     FrameSummaryBase base_;
     601             :     FRAME_SUMMARY_VARIANTS(FRAME_SUMMARY_FIELD)
     602             :   };
     603             : };
     604             : 
     605   136253984 : class StandardFrame : public StackFrame {
     606             :  public:
     607             :   // Testers.
     608           0 :   bool is_standard() const override { return true; }
     609             : 
     610             :   // Accessors.
     611             :   virtual Object receiver() const;
     612             :   virtual Script script() const;
     613             :   virtual Object context() const;
     614             :   virtual int position() const;
     615             : 
     616             :   // Access the expressions in the stack frame including locals.
     617             :   inline Object GetExpression(int index) const;
     618             :   inline void SetExpression(int index, Object value);
     619             :   int ComputeExpressionsCount() const;
     620             : 
     621             :   // Access the parameters.
     622             :   virtual Object GetParameter(int index) const;
     623             :   virtual int ComputeParametersCount() const;
     624             : 
     625             :   // Check if this frame is a constructor frame invoked through 'new'.
     626             :   virtual bool IsConstructor() const;
     627             : 
     628             :   // Build a list with summaries for this frame including all inlined frames.
     629             :   // The functions are ordered bottom-to-top (i.e. summaries.last() is the
     630             :   // top-most activation; caller comes before callee).
     631             :   virtual void Summarize(std::vector<FrameSummary>* frames) const;
     632             : 
     633             :   static StandardFrame* cast(StackFrame* frame) {
     634             :     DCHECK(frame->is_standard());
     635             :     return static_cast<StandardFrame*>(frame);
     636             :   }
     637             : 
     638             :  protected:
     639             :   inline explicit StandardFrame(StackFrameIteratorBase* iterator);
     640             : 
     641             :   void ComputeCallerState(State* state) const override;
     642             : 
     643             :   // Accessors.
     644             :   inline Address caller_fp() const;
     645             :   inline Address caller_pc() const;
     646             : 
     647             :   // Computes the address of the PC field in the standard frame given
     648             :   // by the provided frame pointer.
     649             :   static inline Address ComputePCAddress(Address fp);
     650             : 
     651             :   // Computes the address of the constant pool  field in the standard
     652             :   // frame given by the provided frame pointer.
     653             :   static inline Address ComputeConstantPoolAddress(Address fp);
     654             : 
     655             :   // Iterate over expression stack including stack handlers, locals,
     656             :   // and parts of the fixed part including context and code fields.
     657             :   void IterateExpressions(RootVisitor* v) const;
     658             : 
     659             :   // Returns the address of the n'th expression stack element.
     660             :   virtual Address GetExpressionAddress(int n) const;
     661             : 
     662             :   // Determines if the standard frame for the given frame pointer is
     663             :   // an arguments adaptor frame.
     664             :   static inline bool IsArgumentsAdaptorFrame(Address fp);
     665             : 
     666             :   // Determines if the standard frame for the given frame pointer is a
     667             :   // construct frame.
     668             :   static inline bool IsConstructFrame(Address fp);
     669             : 
     670             :   // Used by OptimizedFrames and StubFrames.
     671             :   void IterateCompiledFrame(RootVisitor* v) const;
     672             : 
     673             :  private:
     674             :   friend class StackFrame;
     675             :   friend class SafeStackFrameIterator;
     676             : };
     677             : 
     678    51095244 : class JavaScriptFrame : public StandardFrame {
     679             :  public:
     680             :   Type type() const override = 0;
     681             : 
     682             :   void Summarize(std::vector<FrameSummary>* frames) const override;
     683             : 
     684             :   // Accessors.
     685             :   virtual JSFunction function() const;
     686             :   Object unchecked_function() const;
     687             :   Object receiver() const override;
     688             :   Object context() const override;
     689             :   Script script() const override;
     690             : 
     691             :   inline void set_receiver(Object value);
     692             : 
     693             :   // Access the parameters.
     694             :   inline Address GetParameterSlot(int index) const;
     695             :   Object GetParameter(int index) const override;
     696             :   int ComputeParametersCount() const override;
     697             : 
     698             :   // Debugger access.
     699             :   void SetParameterValue(int index, Object value) const;
     700             : 
     701             :   // Check if this frame is a constructor frame invoked through 'new'.
     702             :   bool IsConstructor() const override;
     703             : 
     704             :   // Determines whether this frame includes inlined activations. To get details
     705             :   // about the inlined frames use {GetFunctions} and {Summarize}.
     706             :   bool HasInlinedFrames() const;
     707             : 
     708             :   // Check if this frame has "adapted" arguments in the sense that the
     709             :   // actual passed arguments are available in an arguments adaptor
     710             :   // frame below it on the stack.
     711             :   inline bool has_adapted_arguments() const;
     712             : 
     713             :   // Garbage collection support.
     714             :   void Iterate(RootVisitor* v) const override;
     715             : 
     716             :   // Printing support.
     717             :   void Print(StringStream* accumulator, PrintMode mode,
     718             :              int index) const override;
     719             : 
     720             :   // Determine the code for the frame.
     721             :   Code unchecked_code() const override;
     722             : 
     723             :   // Return a list with {SharedFunctionInfo} objects of this frame.
     724             :   virtual void GetFunctions(std::vector<SharedFunctionInfo>* functions) const;
     725             : 
     726             :   void GetFunctions(std::vector<Handle<SharedFunctionInfo>>* functions) const;
     727             : 
     728             :   // Lookup exception handler for current {pc}, returns -1 if none found. Also
     729             :   // returns data associated with the handler site specific to the frame type:
     730             :   //  - OptimizedFrame  : Data is the stack slot count of the entire frame.
     731             :   //  - InterpretedFrame: Data is the register index holding the context.
     732             :   virtual int LookupExceptionHandlerInTable(
     733             :       int* data, HandlerTable::CatchPrediction* prediction);
     734             : 
     735             :   // Architecture-specific register description.
     736             :   static Register fp_register();
     737             :   static Register context_register();
     738             :   static Register constant_pool_pointer_register();
     739             : 
     740           9 :   static JavaScriptFrame* cast(StackFrame* frame) {
     741             :     DCHECK(frame->is_java_script());
     742           9 :     return static_cast<JavaScriptFrame*>(frame);
     743             :   }
     744             : 
     745             :   static void PrintFunctionAndOffset(JSFunction function, AbstractCode code,
     746             :                                      int code_offset, FILE* file,
     747             :                                      bool print_line_number);
     748             : 
     749             :   static void PrintTop(Isolate* isolate, FILE* file, bool print_args,
     750             :                        bool print_line_number);
     751             : 
     752             :   static void CollectFunctionAndOffsetForICStats(JSFunction function,
     753             :                                                  AbstractCode code,
     754             :                                                  int code_offset);
     755             :   static void CollectTopFrameForICStats(Isolate* isolate);
     756             : 
     757             :  protected:
     758             :   inline explicit JavaScriptFrame(StackFrameIteratorBase* iterator);
     759             : 
     760             :   Address GetCallerStackPointer() const override;
     761             : 
     762             :   virtual int GetNumberOfIncomingArguments() const;
     763             : 
     764          63 :   virtual void PrintFrameKind(StringStream* accumulator) const {}
     765             : 
     766             :  private:
     767             :   inline Object function_slot_object() const;
     768             : 
     769             :   friend class StackFrameIteratorBase;
     770             : };
     771             : 
     772             : 
     773    34063496 : class StubFrame : public StandardFrame {
     774             :  public:
     775     6267124 :   Type type() const override { return STUB; }
     776             : 
     777             :   // GC support.
     778             :   void Iterate(RootVisitor* v) const override;
     779             : 
     780             :   // Determine the code for the frame.
     781             :   Code unchecked_code() const override;
     782             : 
     783             :   // Lookup exception handler for current {pc}, returns -1 if none found. Only
     784             :   // TurboFan stub frames are supported. Also returns data associated with the
     785             :   // handler site:
     786             :   //  - TurboFan stub: Data is the stack slot count of the entire frame.
     787             :   int LookupExceptionHandlerInTable(int* data);
     788             : 
     789             :  protected:
     790             :   inline explicit StubFrame(StackFrameIteratorBase* iterator);
     791             : 
     792             :   Address GetCallerStackPointer() const override;
     793             : 
     794             :   virtual int GetNumberOfIncomingArguments() const;
     795             : 
     796             :   friend class StackFrameIteratorBase;
     797             : };
     798             : 
     799             : 
     800     8515874 : class OptimizedFrame : public JavaScriptFrame {
     801             :  public:
     802     9555955 :   Type type() const override { return OPTIMIZED; }
     803             : 
     804             :   // GC support.
     805             :   void Iterate(RootVisitor* v) const override;
     806             : 
     807             :   // Return a list with {SharedFunctionInfo} objects of this frame.
     808             :   // The functions are ordered bottom-to-top (i.e. functions.last()
     809             :   // is the top-most activation)
     810             :   void GetFunctions(std::vector<SharedFunctionInfo>* functions) const override;
     811             : 
     812             :   void Summarize(std::vector<FrameSummary>* frames) const override;
     813             : 
     814             :   // Lookup exception handler for current {pc}, returns -1 if none found.
     815             :   int LookupExceptionHandlerInTable(
     816             :       int* data, HandlerTable::CatchPrediction* prediction) override;
     817             : 
     818             :   DeoptimizationData GetDeoptimizationData(int* deopt_index) const;
     819             : 
     820             :   Object receiver() const override;
     821             : 
     822             :   static int StackSlotOffsetRelativeToFp(int slot_index);
     823             : 
     824             :  protected:
     825             :   inline explicit OptimizedFrame(StackFrameIteratorBase* iterator);
     826             : 
     827             :   int GetNumberOfIncomingArguments() const override;
     828             : 
     829             :  private:
     830             :   friend class StackFrameIteratorBase;
     831             : 
     832             :   Object StackSlotAt(int index) const;
     833             : };
     834             : 
     835             : 
     836     8515874 : class InterpretedFrame : public JavaScriptFrame {
     837             :  public:
     838    35564430 :   Type type() const override { return INTERPRETED; }
     839             : 
     840             :   // Accessors.
     841             :   int position() const override;
     842             : 
     843             :   // Lookup exception handler for current {pc}, returns -1 if none found.
     844             :   int LookupExceptionHandlerInTable(
     845             :       int* data, HandlerTable::CatchPrediction* prediction) override;
     846             : 
     847             :   // Returns the current offset into the bytecode stream.
     848             :   int GetBytecodeOffset() const;
     849             : 
     850             :   // Updates the current offset into the bytecode stream, mainly used for stack
     851             :   // unwinding to continue execution at a different bytecode offset.
     852             :   void PatchBytecodeOffset(int new_offset);
     853             : 
     854             :   // Returns the frame's current bytecode array.
     855             :   BytecodeArray GetBytecodeArray() const;
     856             : 
     857             :   // Updates the frame's BytecodeArray with |bytecode_array|. Used by the
     858             :   // debugger to swap execution onto a BytecodeArray patched with breakpoints.
     859             :   void PatchBytecodeArray(BytecodeArray bytecode_array);
     860             : 
     861             :   // Access to the interpreter register file for this frame.
     862             :   Object ReadInterpreterRegister(int register_index) const;
     863             :   void WriteInterpreterRegister(int register_index, Object value);
     864             : 
     865             :   // Build a list with summaries for this frame including all inlined frames.
     866             :   void Summarize(std::vector<FrameSummary>* frames) const override;
     867             : 
     868             :   static int GetBytecodeOffset(Address fp);
     869             : 
     870        6590 :   static InterpretedFrame* cast(StackFrame* frame) {
     871             :     DCHECK(frame->is_interpreted());
     872        6590 :     return static_cast<InterpretedFrame*>(frame);
     873             :   }
     874             : 
     875             :  protected:
     876             :   inline explicit InterpretedFrame(StackFrameIteratorBase* iterator);
     877             : 
     878             :   Address GetExpressionAddress(int n) const override;
     879             : 
     880             :  private:
     881             :   friend class StackFrameIteratorBase;
     882             : };
     883             : 
     884             : 
     885             : // Arguments adaptor frames are automatically inserted below
     886             : // JavaScript frames when the actual number of parameters does not
     887             : // match the formal number of parameters.
     888     8515874 : class ArgumentsAdaptorFrame: public JavaScriptFrame {
     889             :  public:
     890     2971923 :   Type type() const override { return ARGUMENTS_ADAPTOR; }
     891             : 
     892             :   // Determine the code for the frame.
     893             :   Code unchecked_code() const override;
     894             : 
     895           9 :   static ArgumentsAdaptorFrame* cast(StackFrame* frame) {
     896             :     DCHECK(frame->is_arguments_adaptor());
     897           9 :     return static_cast<ArgumentsAdaptorFrame*>(frame);
     898             :   }
     899             : 
     900             :   // Printing support.
     901             :   void Print(StringStream* accumulator, PrintMode mode,
     902             :              int index) const override;
     903             : 
     904             :  protected:
     905             :   inline explicit ArgumentsAdaptorFrame(StackFrameIteratorBase* iterator);
     906             : 
     907             :   int GetNumberOfIncomingArguments() const override;
     908             : 
     909             :  private:
     910             :   friend class StackFrameIteratorBase;
     911             : };
     912             : 
     913             : // Builtin frames are built for builtins with JavaScript linkage, such as
     914             : // various standard library functions (i.e. Math.asin, Math.floor, etc.).
     915     8515874 : class BuiltinFrame final : public JavaScriptFrame {
     916             :  public:
     917           0 :   Type type() const final { return BUILTIN; }
     918             : 
     919             :   static BuiltinFrame* cast(StackFrame* frame) {
     920             :     DCHECK(frame->is_builtin());
     921             :     return static_cast<BuiltinFrame*>(frame);
     922             :   }
     923             : 
     924             :  protected:
     925             :   inline explicit BuiltinFrame(StackFrameIteratorBase* iterator);
     926             : 
     927             :   int GetNumberOfIncomingArguments() const final;
     928             :   void PrintFrameKind(StringStream* accumulator) const override;
     929             : 
     930             :  private:
     931             :   friend class StackFrameIteratorBase;
     932             : };
     933             : 
     934     8515874 : class WasmCompiledFrame final : public StandardFrame {
     935             :  public:
     936     6165444 :   Type type() const override { return WASM_COMPILED; }
     937             : 
     938             :   // GC support.
     939             :   void Iterate(RootVisitor* v) const override;
     940             : 
     941             :   // Printing support.
     942             :   void Print(StringStream* accumulator, PrintMode mode,
     943             :              int index) const override;
     944             : 
     945             :   // Lookup exception handler for current {pc}, returns -1 if none found. Also
     946             :   // returns the stack slot count of the entire frame.
     947             :   int LookupExceptionHandlerInTable(int* data);
     948             : 
     949             :   // Determine the code for the frame.
     950             :   Code unchecked_code() const override;
     951             : 
     952             :   // Accessors.
     953             :   WasmInstanceObject wasm_instance() const;
     954             :   wasm::WasmCode* wasm_code() const;
     955             :   uint32_t function_index() const;
     956             :   Script script() const override;
     957             :   int position() const override;
     958             :   bool at_to_number_conversion() const;
     959             : 
     960             :   void Summarize(std::vector<FrameSummary>* frames) const override;
     961             : 
     962          90 :   static WasmCompiledFrame* cast(StackFrame* frame) {
     963             :     DCHECK(frame->is_wasm_compiled());
     964          90 :     return static_cast<WasmCompiledFrame*>(frame);
     965             :   }
     966             : 
     967             :  protected:
     968             :   inline explicit WasmCompiledFrame(StackFrameIteratorBase* iterator);
     969             : 
     970             :   Address GetCallerStackPointer() const override;
     971             : 
     972             :  private:
     973             :   friend class StackFrameIteratorBase;
     974             :   WasmModuleObject module_object() const;
     975             : };
     976             : 
     977     8515874 : class WasmInterpreterEntryFrame final : public StandardFrame {
     978             :  public:
     979       17805 :   Type type() const override { return WASM_INTERPRETER_ENTRY; }
     980             : 
     981             :   // GC support.
     982             :   void Iterate(RootVisitor* v) const override;
     983             : 
     984             :   // Printing support.
     985             :   void Print(StringStream* accumulator, PrintMode mode,
     986             :              int index) const override;
     987             : 
     988             :   void Summarize(std::vector<FrameSummary>* frames) const override;
     989             : 
     990             :   // Determine the code for the frame.
     991             :   Code unchecked_code() const override;
     992             : 
     993             :   // Accessors.
     994             :   WasmDebugInfo debug_info() const;
     995             :   WasmInstanceObject wasm_instance() const;
     996             : 
     997             :   Script script() const override;
     998             :   int position() const override;
     999             :   Object context() const override;
    1000             : 
    1001       39248 :   static WasmInterpreterEntryFrame* cast(StackFrame* frame) {
    1002             :     DCHECK(frame->is_wasm_interpreter_entry());
    1003       39248 :     return static_cast<WasmInterpreterEntryFrame*>(frame);
    1004             :   }
    1005             : 
    1006             :  protected:
    1007             :   inline explicit WasmInterpreterEntryFrame(StackFrameIteratorBase* iterator);
    1008             : 
    1009             :   Address GetCallerStackPointer() const override;
    1010             : 
    1011             :  private:
    1012             :   friend class StackFrameIteratorBase;
    1013             :   WasmModuleObject module_object() const;
    1014             : };
    1015             : 
    1016     8515874 : class WasmToJsFrame : public StubFrame {
    1017             :  public:
    1018        4758 :   Type type() const override { return WASM_TO_JS; }
    1019             : 
    1020             :  protected:
    1021             :   inline explicit WasmToJsFrame(StackFrameIteratorBase* iterator);
    1022             : 
    1023             :  private:
    1024             :   friend class StackFrameIteratorBase;
    1025             : };
    1026             : 
    1027     8515874 : class JsToWasmFrame : public StubFrame {
    1028             :  public:
    1029      515088 :   Type type() const override { return JS_TO_WASM; }
    1030             : 
    1031             :  protected:
    1032             :   inline explicit JsToWasmFrame(StackFrameIteratorBase* iterator);
    1033             : 
    1034             :  private:
    1035             :   friend class StackFrameIteratorBase;
    1036             : };
    1037             : 
    1038     8515874 : class CWasmEntryFrame : public StubFrame {
    1039             :  public:
    1040        2620 :   Type type() const override { return C_WASM_ENTRY; }
    1041             : 
    1042             :  protected:
    1043             :   inline explicit CWasmEntryFrame(StackFrameIteratorBase* iterator);
    1044             : 
    1045             :  private:
    1046             :   friend class StackFrameIteratorBase;
    1047             : };
    1048             : 
    1049     8515874 : class WasmCompileLazyFrame : public StandardFrame {
    1050             :  public:
    1051           0 :   Type type() const override { return WASM_COMPILE_LAZY; }
    1052             : 
    1053             :   Code unchecked_code() const override;
    1054             :   WasmInstanceObject wasm_instance() const;
    1055             :   FullObjectSlot wasm_instance_slot() const;
    1056             : 
    1057             :   // Garbage collection support.
    1058             :   void Iterate(RootVisitor* v) const override;
    1059             : 
    1060             :   static WasmCompileLazyFrame* cast(StackFrame* frame) {
    1061             :     DCHECK(frame->is_wasm_compile_lazy());
    1062             :     return static_cast<WasmCompileLazyFrame*>(frame);
    1063             :   }
    1064             : 
    1065             :  protected:
    1066             :   inline explicit WasmCompileLazyFrame(StackFrameIteratorBase* iterator);
    1067             : 
    1068             :   Address GetCallerStackPointer() const override;
    1069             : 
    1070             :  private:
    1071             :   friend class StackFrameIteratorBase;
    1072             : };
    1073             : 
    1074    25547622 : class InternalFrame: public StandardFrame {
    1075             :  public:
    1076     2694926 :   Type type() const override { return INTERNAL; }
    1077             : 
    1078             :   // Garbage collection support.
    1079             :   void Iterate(RootVisitor* v) const override;
    1080             : 
    1081             :   // Determine the code for the frame.
    1082             :   Code unchecked_code() const override;
    1083             : 
    1084             :   static InternalFrame* cast(StackFrame* frame) {
    1085             :     DCHECK(frame->is_internal());
    1086             :     return static_cast<InternalFrame*>(frame);
    1087             :   }
    1088             : 
    1089             :  protected:
    1090             :   inline explicit InternalFrame(StackFrameIteratorBase* iterator);
    1091             : 
    1092             :   Address GetCallerStackPointer() const override;
    1093             : 
    1094             :  private:
    1095             :   friend class StackFrameIteratorBase;
    1096             : };
    1097             : 
    1098             : 
    1099             : // Construct frames are special trampoline frames introduced to handle
    1100             : // function invocations through 'new'.
    1101     8515874 : class ConstructFrame: public InternalFrame {
    1102             :  public:
    1103      476355 :   Type type() const override { return CONSTRUCT; }
    1104             : 
    1105             :   static ConstructFrame* cast(StackFrame* frame) {
    1106             :     DCHECK(frame->is_construct());
    1107             :     return static_cast<ConstructFrame*>(frame);
    1108             :   }
    1109             : 
    1110             :  protected:
    1111             :   inline explicit ConstructFrame(StackFrameIteratorBase* iterator);
    1112             : 
    1113             :  private:
    1114             :   friend class StackFrameIteratorBase;
    1115             : };
    1116             : 
    1117     8515874 : class BuiltinContinuationFrame : public InternalFrame {
    1118             :  public:
    1119           8 :   Type type() const override { return BUILTIN_CONTINUATION; }
    1120             : 
    1121             :   static BuiltinContinuationFrame* cast(StackFrame* frame) {
    1122             :     DCHECK(frame->is_builtin_continuation());
    1123             :     return static_cast<BuiltinContinuationFrame*>(frame);
    1124             :   }
    1125             : 
    1126             :  protected:
    1127             :   inline explicit BuiltinContinuationFrame(StackFrameIteratorBase* iterator);
    1128             : 
    1129             :  private:
    1130             :   friend class StackFrameIteratorBase;
    1131             : };
    1132             : 
    1133    17031748 : class JavaScriptBuiltinContinuationFrame : public JavaScriptFrame {
    1134             :  public:
    1135         756 :   Type type() const override { return JAVA_SCRIPT_BUILTIN_CONTINUATION; }
    1136             : 
    1137             :   static JavaScriptBuiltinContinuationFrame* cast(StackFrame* frame) {
    1138             :     DCHECK(frame->is_java_script_builtin_continuation());
    1139             :     return static_cast<JavaScriptBuiltinContinuationFrame*>(frame);
    1140             :   }
    1141             : 
    1142             :   int ComputeParametersCount() const override;
    1143             :   intptr_t GetSPToFPDelta() const;
    1144             : 
    1145             :   Object context() const override;
    1146             : 
    1147             :  protected:
    1148             :   inline explicit JavaScriptBuiltinContinuationFrame(
    1149             :       StackFrameIteratorBase* iterator);
    1150             : 
    1151             :  private:
    1152             :   friend class StackFrameIteratorBase;
    1153             : };
    1154             : 
    1155     8515874 : class JavaScriptBuiltinContinuationWithCatchFrame
    1156             :     : public JavaScriptBuiltinContinuationFrame {
    1157             :  public:
    1158          24 :   Type type() const override {
    1159          24 :     return JAVA_SCRIPT_BUILTIN_CONTINUATION_WITH_CATCH;
    1160             :   }
    1161             : 
    1162             :   static JavaScriptBuiltinContinuationWithCatchFrame* cast(StackFrame* frame) {
    1163             :     DCHECK(frame->is_java_script_builtin_with_catch_continuation());
    1164             :     return static_cast<JavaScriptBuiltinContinuationWithCatchFrame*>(frame);
    1165             :   }
    1166             : 
    1167             :   // Patch in the exception object at the appropriate location into the stack
    1168             :   // frame.
    1169             :   void SetException(Object exception);
    1170             : 
    1171             :  protected:
    1172             :   inline explicit JavaScriptBuiltinContinuationWithCatchFrame(
    1173             :       StackFrameIteratorBase* iterator);
    1174             : 
    1175             :  private:
    1176             :   friend class StackFrameIteratorBase;
    1177             : };
    1178             : 
    1179    17031748 : class StackFrameIteratorBase {
    1180             :  public:
    1181             :   Isolate* isolate() const { return isolate_; }
    1182             : 
    1183      329091 :   bool done() const { return frame_ == nullptr; }
    1184             : 
    1185             :  protected:
    1186             :   // An iterator that iterates over a given thread's stack.
    1187             :   StackFrameIteratorBase(Isolate* isolate, bool can_access_heap_objects);
    1188             : 
    1189             :   Isolate* isolate_;
    1190             : #define DECLARE_SINGLETON(ignore, type) type type##_;
    1191             :   STACK_FRAME_TYPE_LIST(DECLARE_SINGLETON)
    1192             : #undef DECLARE_SINGLETON
    1193             :   StackFrame* frame_;
    1194             :   StackHandler* handler_;
    1195             :   const bool can_access_heap_objects_;
    1196             : 
    1197             :   StackHandler* handler() const {
    1198             :     DCHECK(!done());
    1199             :     return handler_;
    1200             :   }
    1201             : 
    1202             :   // Get the type-specific frame singleton in a given state.
    1203             :   StackFrame* SingletonFor(StackFrame::Type type, StackFrame::State* state);
    1204             :   // A helper function, can return a nullptr pointer.
    1205             :   StackFrame* SingletonFor(StackFrame::Type type);
    1206             : 
    1207             :  private:
    1208             :   friend class StackFrame;
    1209             :   DISALLOW_COPY_AND_ASSIGN(StackFrameIteratorBase);
    1210             : };
    1211             : 
    1212             : 
    1213     8372535 : class StackFrameIterator: public StackFrameIteratorBase {
    1214             :  public:
    1215             :   // An iterator that iterates over the isolate's current thread's stack,
    1216             :   explicit StackFrameIterator(Isolate* isolate);
    1217             :   // An iterator that iterates over a given thread's stack.
    1218             :   StackFrameIterator(Isolate* isolate, ThreadLocalTop* t);
    1219             : 
    1220       78514 :   StackFrame* frame() const {
    1221             :     DCHECK(!done());
    1222       78514 :     return frame_;
    1223             :   }
    1224             :   void Advance();
    1225             : 
    1226             :  private:
    1227             :   // Go back to the first frame.
    1228             :   void Reset(ThreadLocalTop* top);
    1229             : 
    1230             :   DISALLOW_COPY_AND_ASSIGN(StackFrameIterator);
    1231             : };
    1232             : 
    1233             : // Iterator that supports iterating through all JavaScript frames.
    1234      510382 : class JavaScriptFrameIterator {
    1235             :  public:
    1236             :   inline explicit JavaScriptFrameIterator(Isolate* isolate);
    1237             :   inline JavaScriptFrameIterator(Isolate* isolate, ThreadLocalTop* top);
    1238             : 
    1239             :   inline JavaScriptFrame* frame() const;
    1240             : 
    1241     1972132 :   bool done() const { return iterator_.done(); }
    1242             :   void Advance();
    1243        3518 :   void AdvanceOneFrame() { iterator_.Advance(); }
    1244             : 
    1245             :  private:
    1246             :   StackFrameIterator iterator_;
    1247             : };
    1248             : 
    1249             : // NOTE: The stack trace frame iterator is an iterator that only traverse proper
    1250             : // JavaScript frames that have proper JavaScript functions and WebAssembly
    1251             : // frames.
    1252         180 : class StackTraceFrameIterator {
    1253             :  public:
    1254             :   explicit StackTraceFrameIterator(Isolate* isolate);
    1255             :   // Skip frames until the frame with the given id is reached.
    1256             :   StackTraceFrameIterator(Isolate* isolate, StackFrame::Id id);
    1257    13759023 :   bool done() const { return iterator_.done(); }
    1258             :   void Advance();
    1259             :   void AdvanceOneFrame() { iterator_.Advance(); }
    1260             : 
    1261             :   inline StandardFrame* frame() const;
    1262             : 
    1263             :   inline bool is_javascript() const;
    1264             :   inline bool is_wasm() const;
    1265             :   inline JavaScriptFrame* javascript_frame() const;
    1266             : 
    1267             :  private:
    1268             :   StackFrameIterator iterator_;
    1269             :   bool IsValidFrame(StackFrame* frame) const;
    1270             : };
    1271             : 
    1272             : 
    1273       25308 : class SafeStackFrameIterator: public StackFrameIteratorBase {
    1274             :  public:
    1275             :   SafeStackFrameIterator(Isolate* isolate,
    1276             :                          Address fp, Address sp,
    1277             :                          Address js_entry_sp);
    1278             : 
    1279             :   inline StackFrame* frame() const;
    1280             :   void Advance();
    1281             : 
    1282             :   StackFrame::Type top_frame_type() const { return top_frame_type_; }
    1283             : 
    1284             :  private:
    1285             :   void AdvanceOneFrame();
    1286             : 
    1287             :   bool IsValidStackAddress(Address addr) const {
    1288      552129 :     return low_bound_ <= addr && addr <= high_bound_;
    1289             :   }
    1290             :   bool IsValidFrame(StackFrame* frame) const;
    1291             :   bool IsValidCaller(StackFrame* frame);
    1292             :   bool IsValidExitFrame(Address fp) const;
    1293             :   bool IsValidTop(ThreadLocalTop* top) const;
    1294             : 
    1295             :   const Address low_bound_;
    1296             :   const Address high_bound_;
    1297             :   StackFrame::Type top_frame_type_;
    1298             :   ExternalCallbackScope* external_callback_scope_;
    1299             : };
    1300             : }  // namespace internal
    1301             : }  // namespace v8
    1302             : 
    1303             : #endif  // V8_FRAMES_H_

Generated by: LCOV version 1.10