LCOV - code coverage report
Current view: top level - src - frames.h (source / functions) Hit Total Coverage
Test: app.info Lines: 83 90 92.2 %
Date: 2019-04-19 Functions: 24 71 33.8 %

          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   193855809 :   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     1576079 :     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    13227336 :     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    37585645 :     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      349673 :   bool is_entry() const { return type() == ENTRY; }
     173      289240 :   bool is_construct_entry() const { return type() == CONSTRUCT_ENTRY; }
     174      141092 :   bool is_exit() const { return type() == EXIT; }
     175    23726062 :   bool is_optimized() const { return type() == OPTIMIZED; }
     176     1698602 :   bool is_interpreted() const { return type() == INTERPRETED; }
     177         364 :   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      384297 :     return type() == WASM_INTERPRETER_ENTRY;
     183             :   }
     184      715613 :   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      140820 :   bool is_builtin_exit() const { return type() == BUILTIN_EXIT; }
     198           0 :   virtual bool is_standard() const { return false; }
     199             : 
     200    12431678 :   bool is_java_script() const {
     201    12431678 :     Type type = this->type();
     202    24559408 :     return (type == OPTIMIZED) || (type == INTERPRETED) || (type == BUILTIN) ||
     203    24559177 :            (type == JAVA_SCRIPT_BUILTIN_CONTINUATION) ||
     204    12431678 :            (type == JAVA_SCRIPT_BUILTIN_CONTINUATION_WITH_CATCH);
     205             :   }
     206             :   bool is_wasm() const {
     207     4947617 :     Type type = this->type();
     208     4947617 :     return type == WASM_COMPILED || type == WASM_INTERPRETER_ENTRY;
     209             :   }
     210             : 
     211             :   // Accessors.
     212             :   Address sp() const { return state_.sp; }
     213             :   Address fp() const { return state_.fp; }
     214             :   Address callee_pc() const {
     215      308388 :     return state_.callee_pc_address ? *state_.callee_pc_address : kNullAddress;
     216             :   }
     217    61024045 :   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    25408686 :   Address pc() const { return *pc_address(); }
     225       33854 :   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     1987300 :   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             :   V8_EXPORT_PRIVATE 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   193858308 :   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    18462696 : 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    36925392 : class EntryFrame: public StackFrame {
     333             :  public:
     334     2230300 :   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    18462696 : 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    36925392 : class ExitFrame: public StackFrame {
     382             :  public:
     383     7760633 :   Type type() const override { return EXIT; }
     384             : 
     385             :   Code unchecked_code() const override;
     386             : 
     387             :   // Garbage collection support.
     388             :   void Iterate(RootVisitor* v) const override;
     389             : 
     390             :   static ExitFrame* cast(StackFrame* frame) {
     391             :     DCHECK(frame->is_exit());
     392             :     return static_cast<ExitFrame*>(frame);
     393             :   }
     394             : 
     395             :   // Compute the state and type of an exit frame given a frame
     396             :   // pointer. Used when constructing the first stack frame seen by an
     397             :   // iterator and the frames following entry frames.
     398             :   static Type GetStateForFramePointer(Address fp, State* state);
     399             :   static Address ComputeStackPointer(Address fp);
     400             :   static StackFrame::Type ComputeFrameType(Address fp);
     401             :   static void FillState(Address fp, Address sp, State* state);
     402             : 
     403             :  protected:
     404             :   inline explicit ExitFrame(StackFrameIteratorBase* iterator);
     405             : 
     406             :   Address GetCallerStackPointer() const override;
     407             : 
     408             :  private:
     409             :   void ComputeCallerState(State* state) const override;
     410             : 
     411             :   friend class StackFrameIteratorBase;
     412             : };
     413             : 
     414             : // Builtin exit frames are a special case of exit frames, which are used
     415             : // whenever C++ builtins (e.g., Math.acos) are called. Their main purpose is
     416             : // to allow such builtins to appear in stack traces.
     417    18462696 : class BuiltinExitFrame : public ExitFrame {
     418             :  public:
     419     1135523 :   Type type() const override { return BUILTIN_EXIT; }
     420             : 
     421             :   static BuiltinExitFrame* cast(StackFrame* frame) {
     422             :     DCHECK(frame->is_builtin_exit());
     423             :     return static_cast<BuiltinExitFrame*>(frame);
     424             :   }
     425             : 
     426             :   JSFunction function() const;
     427             :   Object receiver() const;
     428             : 
     429             :   bool IsConstructor() const;
     430             : 
     431             :   void Print(StringStream* accumulator, PrintMode mode,
     432             :              int index) const override;
     433             : 
     434             :  protected:
     435             :   inline explicit BuiltinExitFrame(StackFrameIteratorBase* iterator);
     436             : 
     437             :  private:
     438             :   Object GetParameter(int i) const;
     439             :   int ComputeParametersCount() const;
     440             : 
     441             :   inline Object receiver_slot_object() const;
     442             :   inline Object argc_slot_object() const;
     443             :   inline Object target_slot_object() const;
     444             :   inline Object new_target_slot_object() const;
     445             : 
     446             :   friend class StackFrameIteratorBase;
     447             :   friend class FrameArrayBuilder;
     448             : };
     449             : 
     450             : class StandardFrame;
     451             : 
     452             : class V8_EXPORT_PRIVATE FrameSummary {
     453             :  public:
     454             : // Subclasses for the different summary kinds:
     455             : #define FRAME_SUMMARY_VARIANTS(F)                                             \
     456             :   F(JAVA_SCRIPT, JavaScriptFrameSummary, java_script_summary_, JavaScript)    \
     457             :   F(WASM_COMPILED, WasmCompiledFrameSummary, wasm_compiled_summary_,          \
     458             :     WasmCompiled)                                                             \
     459             :   F(WASM_INTERPRETED, WasmInterpretedFrameSummary, wasm_interpreted_summary_, \
     460             :     WasmInterpreted)
     461             : 
     462             : #define FRAME_SUMMARY_KIND(kind, type, field, desc) kind,
     463             :   enum Kind { FRAME_SUMMARY_VARIANTS(FRAME_SUMMARY_KIND) };
     464             : #undef FRAME_SUMMARY_KIND
     465             : 
     466             :   class FrameSummaryBase {
     467             :    public:
     468             :     FrameSummaryBase(Isolate* isolate, Kind kind)
     469     7745085 :         : isolate_(isolate), kind_(kind) {}
     470             :     Isolate* isolate() const { return isolate_; }
     471             :     Kind kind() const { return kind_; }
     472             : 
     473             :    private:
     474             :     Isolate* isolate_;
     475             :     Kind kind_;
     476             :   };
     477             : 
     478             :   class JavaScriptFrameSummary : public FrameSummaryBase {
     479             :    public:
     480             :     JavaScriptFrameSummary(Isolate* isolate, Object receiver,
     481             :                            JSFunction function, AbstractCode abstract_code,
     482             :                            int code_offset, bool is_constructor,
     483             :                            FixedArray parameters);
     484             : 
     485             :     void EnsureSourcePositionsAvailable();
     486             : 
     487             :     Handle<Object> receiver() const { return receiver_; }
     488             :     Handle<JSFunction> function() const { return function_; }
     489             :     Handle<AbstractCode> abstract_code() const { return abstract_code_; }
     490             :     int code_offset() const { return code_offset_; }
     491             :     bool is_constructor() const { return is_constructor_; }
     492             :     Handle<FixedArray> parameters() const { return parameters_; }
     493             :     bool is_subject_to_debugging() const;
     494             :     int SourcePosition() const;
     495             :     int SourceStatementPosition() const;
     496             :     Handle<Object> script() const;
     497             :     Handle<String> FunctionName() const;
     498             :     Handle<Context> native_context() const;
     499             : 
     500             :    private:
     501             :     Handle<Object> receiver_;
     502             :     Handle<JSFunction> function_;
     503             :     Handle<AbstractCode> abstract_code_;
     504             :     int code_offset_;
     505             :     bool is_constructor_;
     506             :     Handle<FixedArray> parameters_;
     507             :   };
     508             : 
     509             :   class WasmFrameSummary : public FrameSummaryBase {
     510             :    protected:
     511             :     WasmFrameSummary(Isolate*, Kind, Handle<WasmInstanceObject>,
     512             :                      bool at_to_number_conversion);
     513             : 
     514             :    public:
     515             :     Handle<Object> receiver() const;
     516             :     uint32_t function_index() const;
     517             :     int byte_offset() const;
     518             :     bool is_constructor() const { return false; }
     519             :     bool is_subject_to_debugging() const { return true; }
     520             :     int SourcePosition() const;
     521           0 :     int SourceStatementPosition() const { return SourcePosition(); }
     522             :     Handle<Script> script() const;
     523             :     Handle<WasmInstanceObject> wasm_instance() const { return wasm_instance_; }
     524             :     Handle<String> FunctionName() const;
     525             :     Handle<Context> native_context() const;
     526             :     bool at_to_number_conversion() const { return at_to_number_conversion_; }
     527             : 
     528             :    private:
     529             :     Handle<WasmInstanceObject> wasm_instance_;
     530             :     bool at_to_number_conversion_;
     531             :   };
     532             : 
     533             :   class WasmCompiledFrameSummary : public WasmFrameSummary {
     534             :    public:
     535             :     WasmCompiledFrameSummary(Isolate*, Handle<WasmInstanceObject>,
     536             :                              wasm::WasmCode*, int code_offset,
     537             :                              bool at_to_number_conversion);
     538             :     uint32_t function_index() const;
     539             :     wasm::WasmCode* code() const { return code_; }
     540             :     int code_offset() const { return code_offset_; }
     541             :     int byte_offset() const;
     542             :     static int GetWasmSourcePosition(const wasm::WasmCode* code, int offset);
     543             : 
     544             :    private:
     545             :     wasm::WasmCode* const code_;
     546             :     int code_offset_;
     547             :   };
     548             : 
     549             :   class WasmInterpretedFrameSummary : public WasmFrameSummary {
     550             :    public:
     551             :     WasmInterpretedFrameSummary(Isolate*, Handle<WasmInstanceObject>,
     552             :                                 uint32_t function_index, int byte_offset);
     553             :     uint32_t function_index() const { return function_index_; }
     554             :     int code_offset() const { return byte_offset_; }
     555             :     int byte_offset() const { return byte_offset_; }
     556             : 
     557             :    private:
     558             :     uint32_t function_index_;
     559             :     int byte_offset_;
     560             :   };
     561             : 
     562             : #define FRAME_SUMMARY_CONS(kind, type, field, desc) \
     563             :   FrameSummary(type summ) : field(summ) {}  // NOLINT
     564     8726386 :   FRAME_SUMMARY_VARIANTS(FRAME_SUMMARY_CONS)
     565             : #undef FRAME_SUMMARY_CONS
     566             : 
     567             :   ~FrameSummary();
     568             : 
     569             :   static FrameSummary GetTop(const StandardFrame* frame);
     570             :   static FrameSummary GetBottom(const StandardFrame* frame);
     571             :   static FrameSummary GetSingle(const StandardFrame* frame);
     572             :   static FrameSummary Get(const StandardFrame* frame, int index);
     573             : 
     574             :   void EnsureSourcePositionsAvailable();
     575             : 
     576             :   // Dispatched accessors.
     577             :   Handle<Object> receiver() const;
     578             :   int code_offset() const;
     579             :   bool is_constructor() const;
     580             :   bool is_subject_to_debugging() const;
     581             :   Handle<Object> script() const;
     582             :   int SourcePosition() const;
     583             :   int SourceStatementPosition() const;
     584             :   Handle<String> FunctionName() const;
     585             :   Handle<Context> native_context() const;
     586             : 
     587             : #define FRAME_SUMMARY_CAST(kind_, type, field, desc)      \
     588             :   bool Is##desc() const { return base_.kind() == kind_; } \
     589             :   const type& As##desc() const {                          \
     590             :     DCHECK_EQ(base_.kind(), kind_);                       \
     591             :     return field;                                         \
     592             :   }
     593     5141055 :   FRAME_SUMMARY_VARIANTS(FRAME_SUMMARY_CAST)
     594             : #undef FRAME_SUMMARY_CAST
     595             : 
     596             :   bool IsWasm() const { return IsWasmCompiled() || IsWasmInterpreted(); }
     597             :   const WasmFrameSummary& AsWasm() const {
     598             :     if (IsWasmCompiled()) return AsWasmCompiled();
     599             :     return AsWasmInterpreted();
     600             :   }
     601             : 
     602             :  private:
     603             : #define FRAME_SUMMARY_FIELD(kind, type, field, desc) type field;
     604             :   union {
     605             :     FrameSummaryBase base_;
     606             :     FRAME_SUMMARY_VARIANTS(FRAME_SUMMARY_FIELD)
     607             :   };
     608             : #undef FRAME_SUMMARY_FIELD
     609             : };
     610             : 
     611   295403136 : class StandardFrame : public StackFrame {
     612             :  public:
     613             :   // Testers.
     614           0 :   bool is_standard() const override { return true; }
     615             : 
     616             :   // Accessors.
     617             :   virtual Object receiver() const;
     618             :   virtual Script script() const;
     619             :   virtual Object context() const;
     620             :   virtual int position() const;
     621             : 
     622             :   // Access the expressions in the stack frame including locals.
     623             :   inline Object GetExpression(int index) const;
     624             :   inline void SetExpression(int index, Object value);
     625             :   int ComputeExpressionsCount() const;
     626             : 
     627             :   // Access the parameters.
     628             :   virtual Object GetParameter(int index) const;
     629             :   virtual int ComputeParametersCount() const;
     630             : 
     631             :   // Check if this frame is a constructor frame invoked through 'new'.
     632             :   virtual bool IsConstructor() const;
     633             : 
     634             :   // Build a list with summaries for this frame including all inlined frames.
     635             :   // The functions are ordered bottom-to-top (i.e. summaries.last() is the
     636             :   // top-most activation; caller comes before callee).
     637             :   virtual void Summarize(std::vector<FrameSummary>* frames) const;
     638             : 
     639             :   static StandardFrame* cast(StackFrame* frame) {
     640             :     DCHECK(frame->is_standard());
     641             :     return static_cast<StandardFrame*>(frame);
     642             :   }
     643             : 
     644             :  protected:
     645             :   inline explicit StandardFrame(StackFrameIteratorBase* iterator);
     646             : 
     647             :   void ComputeCallerState(State* state) const override;
     648             : 
     649             :   // Accessors.
     650             :   inline Address caller_fp() const;
     651             :   inline Address caller_pc() const;
     652             : 
     653             :   // Computes the address of the PC field in the standard frame given
     654             :   // by the provided frame pointer.
     655             :   static inline Address ComputePCAddress(Address fp);
     656             : 
     657             :   // Computes the address of the constant pool  field in the standard
     658             :   // frame given by the provided frame pointer.
     659             :   static inline Address ComputeConstantPoolAddress(Address fp);
     660             : 
     661             :   // Iterate over expression stack including stack handlers, locals,
     662             :   // and parts of the fixed part including context and code fields.
     663             :   void IterateExpressions(RootVisitor* v) const;
     664             : 
     665             :   // Returns the address of the n'th expression stack element.
     666             :   virtual Address GetExpressionAddress(int n) const;
     667             : 
     668             :   // Determines if the standard frame for the given frame pointer is
     669             :   // an arguments adaptor frame.
     670             :   static inline bool IsArgumentsAdaptorFrame(Address fp);
     671             : 
     672             :   // Determines if the standard frame for the given frame pointer is a
     673             :   // construct frame.
     674             :   static inline bool IsConstructFrame(Address fp);
     675             : 
     676             :   // Used by OptimizedFrames and StubFrames.
     677             :   void IterateCompiledFrame(RootVisitor* v) const;
     678             : 
     679             :  private:
     680             :   friend class StackFrame;
     681             :   friend class SafeStackFrameIterator;
     682             : };
     683             : 
     684   110776176 : class JavaScriptFrame : public StandardFrame {
     685             :  public:
     686             :   Type type() const override = 0;
     687             : 
     688             :   void Summarize(std::vector<FrameSummary>* frames) const override;
     689             : 
     690             :   // Accessors.
     691             :   virtual JSFunction function() const;
     692             :   Object unchecked_function() const;
     693             :   Object receiver() const override;
     694             :   Object context() const override;
     695             :   Script script() const override;
     696             : 
     697             :   inline void set_receiver(Object value);
     698             : 
     699             :   // Access the parameters.
     700             :   inline Address GetParameterSlot(int index) const;
     701             :   Object GetParameter(int index) const override;
     702             :   int ComputeParametersCount() const override;
     703             :   Handle<FixedArray> GetParameters() const;
     704             : 
     705             :   // Debugger access.
     706             :   void SetParameterValue(int index, Object value) const;
     707             : 
     708             :   // Check if this frame is a constructor frame invoked through 'new'.
     709             :   bool IsConstructor() const override;
     710             : 
     711             :   // Determines whether this frame includes inlined activations. To get details
     712             :   // about the inlined frames use {GetFunctions} and {Summarize}.
     713             :   bool HasInlinedFrames() const;
     714             : 
     715             :   // Check if this frame has "adapted" arguments in the sense that the
     716             :   // actual passed arguments are available in an arguments adaptor
     717             :   // frame below it on the stack.
     718             :   inline bool has_adapted_arguments() const;
     719             : 
     720             :   // Garbage collection support.
     721             :   void Iterate(RootVisitor* v) const override;
     722             : 
     723             :   // Printing support.
     724             :   void Print(StringStream* accumulator, PrintMode mode,
     725             :              int index) const override;
     726             : 
     727             :   // Determine the code for the frame.
     728             :   Code unchecked_code() const override;
     729             : 
     730             :   // Return a list with {SharedFunctionInfo} objects of this frame.
     731             :   virtual void GetFunctions(std::vector<SharedFunctionInfo>* functions) const;
     732             : 
     733             :   void GetFunctions(std::vector<Handle<SharedFunctionInfo>>* functions) const;
     734             : 
     735             :   // Lookup exception handler for current {pc}, returns -1 if none found. Also
     736             :   // returns data associated with the handler site specific to the frame type:
     737             :   //  - OptimizedFrame  : Data is the stack slot count of the entire frame.
     738             :   //  - InterpretedFrame: Data is the register index holding the context.
     739             :   virtual int LookupExceptionHandlerInTable(
     740             :       int* data, HandlerTable::CatchPrediction* prediction);
     741             : 
     742             :   // Architecture-specific register description.
     743             :   static Register fp_register();
     744             :   static Register context_register();
     745             :   static Register constant_pool_pointer_register();
     746             : 
     747             :   static JavaScriptFrame* cast(StackFrame* frame) {
     748             :     DCHECK(frame->is_java_script());
     749             :     return static_cast<JavaScriptFrame*>(frame);
     750             :   }
     751             : 
     752             :   static void PrintFunctionAndOffset(JSFunction function, AbstractCode code,
     753             :                                      int code_offset, FILE* file,
     754             :                                      bool print_line_number);
     755             : 
     756             :   static void PrintTop(Isolate* isolate, FILE* file, bool print_args,
     757             :                        bool print_line_number);
     758             : 
     759             :   static void CollectFunctionAndOffsetForICStats(JSFunction function,
     760             :                                                  AbstractCode code,
     761             :                                                  int code_offset);
     762             : 
     763             :  protected:
     764             :   inline explicit JavaScriptFrame(StackFrameIteratorBase* iterator);
     765             : 
     766             :   Address GetCallerStackPointer() const override;
     767             : 
     768          57 :   virtual void PrintFrameKind(StringStream* accumulator) const {}
     769             : 
     770             :  private:
     771             :   inline Object function_slot_object() const;
     772             : 
     773             :   friend class StackFrameIteratorBase;
     774             : };
     775             : 
     776             : 
     777    73850784 : class StubFrame : public StandardFrame {
     778             :  public:
     779     7127157 :   Type type() const override { return STUB; }
     780             : 
     781             :   // GC support.
     782             :   void Iterate(RootVisitor* v) const override;
     783             : 
     784             :   // Determine the code for the frame.
     785             :   Code unchecked_code() const override;
     786             : 
     787             :   // Lookup exception handler for current {pc}, returns -1 if none found. Only
     788             :   // TurboFan stub frames are supported. Also returns data associated with the
     789             :   // handler site:
     790             :   //  - TurboFan stub: Data is the stack slot count of the entire frame.
     791             :   int LookupExceptionHandlerInTable(int* data);
     792             : 
     793             :  protected:
     794             :   inline explicit StubFrame(StackFrameIteratorBase* iterator);
     795             : 
     796             :   Address GetCallerStackPointer() const override;
     797             : 
     798             :   friend class StackFrameIteratorBase;
     799             : };
     800             : 
     801             : 
     802    18462696 : class OptimizedFrame : public JavaScriptFrame {
     803             :  public:
     804     9279213 :   Type type() const override { return OPTIMIZED; }
     805             : 
     806             :   // GC support.
     807             :   void Iterate(RootVisitor* v) const override;
     808             : 
     809             :   // Return a list with {SharedFunctionInfo} objects of this frame.
     810             :   // The functions are ordered bottom-to-top (i.e. functions.last()
     811             :   // is the top-most activation)
     812             :   void GetFunctions(std::vector<SharedFunctionInfo>* functions) const override;
     813             : 
     814             :   void Summarize(std::vector<FrameSummary>* frames) const override;
     815             : 
     816             :   // Lookup exception handler for current {pc}, returns -1 if none found.
     817             :   int LookupExceptionHandlerInTable(
     818             :       int* data, HandlerTable::CatchPrediction* prediction) override;
     819             : 
     820             :   DeoptimizationData GetDeoptimizationData(int* deopt_index) const;
     821             : 
     822             :   Object receiver() const override;
     823             :   int ComputeParametersCount() const override;
     824             : 
     825             :   static int StackSlotOffsetRelativeToFp(int slot_index);
     826             : 
     827             :  protected:
     828             :   inline explicit OptimizedFrame(StackFrameIteratorBase* iterator);
     829             : 
     830             : 
     831             :  private:
     832             :   friend class StackFrameIteratorBase;
     833             : 
     834             :   Object StackSlotAt(int index) const;
     835             : };
     836             : 
     837             : 
     838    18462696 : class InterpretedFrame : public JavaScriptFrame {
     839             :  public:
     840    38605045 :   Type type() const override { return INTERPRETED; }
     841             : 
     842             :   // Accessors.
     843             :   int position() const override;
     844             : 
     845             :   // Lookup exception handler for current {pc}, returns -1 if none found.
     846             :   int LookupExceptionHandlerInTable(
     847             :       int* data, HandlerTable::CatchPrediction* prediction) override;
     848             : 
     849             :   // Returns the current offset into the bytecode stream.
     850             :   int GetBytecodeOffset() const;
     851             : 
     852             :   // Updates the current offset into the bytecode stream, mainly used for stack
     853             :   // unwinding to continue execution at a different bytecode offset.
     854             :   void PatchBytecodeOffset(int new_offset);
     855             : 
     856             :   // Returns the frame's current bytecode array.
     857             :   BytecodeArray GetBytecodeArray() const;
     858             : 
     859             :   // Updates the frame's BytecodeArray with |bytecode_array|. Used by the
     860             :   // debugger to swap execution onto a BytecodeArray patched with breakpoints.
     861             :   void PatchBytecodeArray(BytecodeArray bytecode_array);
     862             : 
     863             :   // Access to the interpreter register file for this frame.
     864             :   Object ReadInterpreterRegister(int register_index) const;
     865             :   void WriteInterpreterRegister(int register_index, Object value);
     866             : 
     867             :   // Build a list with summaries for this frame including all inlined frames.
     868             :   void Summarize(std::vector<FrameSummary>* frames) const override;
     869             : 
     870             :   static int GetBytecodeOffset(Address fp);
     871             : 
     872             :   static InterpretedFrame* cast(StackFrame* frame) {
     873             :     DCHECK(frame->is_interpreted());
     874             :     return static_cast<InterpretedFrame*>(frame);
     875             :   }
     876             : 
     877             :  protected:
     878             :   inline explicit InterpretedFrame(StackFrameIteratorBase* iterator);
     879             : 
     880             :   Address GetExpressionAddress(int n) const override;
     881             : 
     882             :  private:
     883             :   friend class StackFrameIteratorBase;
     884             : };
     885             : 
     886             : 
     887             : // Arguments adaptor frames are automatically inserted below
     888             : // JavaScript frames when the actual number of parameters does not
     889             : // match the formal number of parameters.
     890    18462696 : class ArgumentsAdaptorFrame: public JavaScriptFrame {
     891             :  public:
     892     2116199 :   Type type() const override { return ARGUMENTS_ADAPTOR; }
     893             : 
     894             :   // Determine the code for the frame.
     895             :   Code unchecked_code() const override;
     896             : 
     897             :   static ArgumentsAdaptorFrame* cast(StackFrame* frame) {
     898             :     DCHECK(frame->is_arguments_adaptor());
     899             :     return static_cast<ArgumentsAdaptorFrame*>(frame);
     900             :   }
     901             : 
     902             :   int ComputeParametersCount() const override;
     903             : 
     904             :   // Printing support.
     905             :   void Print(StringStream* accumulator, PrintMode mode,
     906             :              int index) const override;
     907             : 
     908             :  protected:
     909             :   inline explicit ArgumentsAdaptorFrame(StackFrameIteratorBase* iterator);
     910             : 
     911             : 
     912             :  private:
     913             :   friend class StackFrameIteratorBase;
     914             : };
     915             : 
     916             : // Builtin frames are built for builtins with JavaScript linkage, such as
     917             : // various standard library functions (i.e. Math.asin, Math.floor, etc.).
     918    18462696 : class BuiltinFrame final : public JavaScriptFrame {
     919             :  public:
     920           0 :   Type type() const final { return BUILTIN; }
     921             : 
     922             :   static BuiltinFrame* cast(StackFrame* frame) {
     923             :     DCHECK(frame->is_builtin());
     924             :     return static_cast<BuiltinFrame*>(frame);
     925             :   }
     926             :   int ComputeParametersCount() const final;
     927             : 
     928             :  protected:
     929             :   inline explicit BuiltinFrame(StackFrameIteratorBase* iterator);
     930             : 
     931             :   void PrintFrameKind(StringStream* accumulator) const override;
     932             : 
     933             :  private:
     934             :   friend class StackFrameIteratorBase;
     935             : };
     936             : 
     937    18462696 : class WasmCompiledFrame final : public StandardFrame {
     938             :  public:
     939     5686408 :   Type type() const override { return WASM_COMPILED; }
     940             : 
     941             :   // GC support.
     942             :   void Iterate(RootVisitor* v) const override;
     943             : 
     944             :   // Printing support.
     945             :   void Print(StringStream* accumulator, PrintMode mode,
     946             :              int index) const override;
     947             : 
     948             :   // Lookup exception handler for current {pc}, returns -1 if none found. Also
     949             :   // returns the stack slot count of the entire frame.
     950             :   int LookupExceptionHandlerInTable(int* data);
     951             : 
     952             :   // Determine the code for the frame.
     953             :   Code unchecked_code() const override;
     954             : 
     955             :   // Accessors.
     956             :   WasmInstanceObject wasm_instance() const;
     957             :   wasm::WasmCode* wasm_code() const;
     958             :   uint32_t function_index() const;
     959             :   Script script() const override;
     960             :   int position() const override;
     961             :   bool at_to_number_conversion() const;
     962             : 
     963             :   void Summarize(std::vector<FrameSummary>* frames) const override;
     964             : 
     965             :   static WasmCompiledFrame* cast(StackFrame* frame) {
     966             :     DCHECK(frame->is_wasm_compiled());
     967             :     return static_cast<WasmCompiledFrame*>(frame);
     968             :   }
     969             : 
     970             :  protected:
     971             :   inline explicit WasmCompiledFrame(StackFrameIteratorBase* iterator);
     972             : 
     973             :   Address GetCallerStackPointer() const override;
     974             : 
     975             :  private:
     976             :   friend class StackFrameIteratorBase;
     977             :   WasmModuleObject module_object() const;
     978             : };
     979             : 
     980    18462696 : class WasmInterpreterEntryFrame final : public StandardFrame {
     981             :  public:
     982       21925 :   Type type() const override { return WASM_INTERPRETER_ENTRY; }
     983             : 
     984             :   // GC support.
     985             :   void Iterate(RootVisitor* v) const override;
     986             : 
     987             :   // Printing support.
     988             :   void Print(StringStream* accumulator, PrintMode mode,
     989             :              int index) const override;
     990             : 
     991             :   void Summarize(std::vector<FrameSummary>* frames) const override;
     992             : 
     993             :   // Determine the code for the frame.
     994             :   Code unchecked_code() const override;
     995             : 
     996             :   // Accessors.
     997             :   WasmDebugInfo debug_info() const;
     998             :   WasmInstanceObject wasm_instance() const;
     999             : 
    1000             :   Script script() const override;
    1001             :   int position() const override;
    1002             :   Object context() const override;
    1003             : 
    1004             :   static WasmInterpreterEntryFrame* cast(StackFrame* frame) {
    1005             :     DCHECK(frame->is_wasm_interpreter_entry());
    1006             :     return static_cast<WasmInterpreterEntryFrame*>(frame);
    1007             :   }
    1008             : 
    1009             :  protected:
    1010             :   inline explicit WasmInterpreterEntryFrame(StackFrameIteratorBase* iterator);
    1011             : 
    1012             :   Address GetCallerStackPointer() const override;
    1013             : 
    1014             :  private:
    1015             :   friend class StackFrameIteratorBase;
    1016             :   WasmModuleObject module_object() const;
    1017             : };
    1018             : 
    1019    18462696 : class WasmToJsFrame : public StubFrame {
    1020             :  public:
    1021        7388 :   Type type() const override { return WASM_TO_JS; }
    1022             : 
    1023             :  protected:
    1024             :   inline explicit WasmToJsFrame(StackFrameIteratorBase* iterator);
    1025             : 
    1026             :  private:
    1027             :   friend class StackFrameIteratorBase;
    1028             : };
    1029             : 
    1030    18462696 : class JsToWasmFrame : public StubFrame {
    1031             :  public:
    1032      462240 :   Type type() const override { return JS_TO_WASM; }
    1033             : 
    1034             :  protected:
    1035             :   inline explicit JsToWasmFrame(StackFrameIteratorBase* iterator);
    1036             : 
    1037             :  private:
    1038             :   friend class StackFrameIteratorBase;
    1039             : };
    1040             : 
    1041    18462696 : class CWasmEntryFrame : public StubFrame {
    1042             :  public:
    1043        5124 :   Type type() const override { return C_WASM_ENTRY; }
    1044             : 
    1045             :  protected:
    1046             :   inline explicit CWasmEntryFrame(StackFrameIteratorBase* iterator);
    1047             : 
    1048             :  private:
    1049             :   friend class StackFrameIteratorBase;
    1050             : };
    1051             : 
    1052    18462696 : class WasmCompileLazyFrame : public StandardFrame {
    1053             :  public:
    1054          88 :   Type type() const override { return WASM_COMPILE_LAZY; }
    1055             : 
    1056             :   Code unchecked_code() const override;
    1057             :   WasmInstanceObject wasm_instance() const;
    1058             :   FullObjectSlot wasm_instance_slot() const;
    1059             : 
    1060             :   // Garbage collection support.
    1061             :   void Iterate(RootVisitor* v) const override;
    1062             : 
    1063             :   static WasmCompileLazyFrame* cast(StackFrame* frame) {
    1064             :     DCHECK(frame->is_wasm_compile_lazy());
    1065             :     return static_cast<WasmCompileLazyFrame*>(frame);
    1066             :   }
    1067             : 
    1068             :  protected:
    1069             :   inline explicit WasmCompileLazyFrame(StackFrameIteratorBase* iterator);
    1070             : 
    1071             :   Address GetCallerStackPointer() const override;
    1072             : 
    1073             :  private:
    1074             :   friend class StackFrameIteratorBase;
    1075             : };
    1076             : 
    1077    55388088 : class InternalFrame: public StandardFrame {
    1078             :  public:
    1079     2831795 :   Type type() const override { return INTERNAL; }
    1080             : 
    1081             :   // Garbage collection support.
    1082             :   void Iterate(RootVisitor* v) const override;
    1083             : 
    1084             :   // Determine the code for the frame.
    1085             :   Code unchecked_code() const override;
    1086             : 
    1087             :   static InternalFrame* cast(StackFrame* frame) {
    1088             :     DCHECK(frame->is_internal());
    1089             :     return static_cast<InternalFrame*>(frame);
    1090             :   }
    1091             : 
    1092             :  protected:
    1093             :   inline explicit InternalFrame(StackFrameIteratorBase* iterator);
    1094             : 
    1095             :   Address GetCallerStackPointer() const override;
    1096             : 
    1097             :  private:
    1098             :   friend class StackFrameIteratorBase;
    1099             : };
    1100             : 
    1101             : 
    1102             : // Construct frames are special trampoline frames introduced to handle
    1103             : // function invocations through 'new'.
    1104    18462696 : class ConstructFrame: public InternalFrame {
    1105             :  public:
    1106      461168 :   Type type() const override { return CONSTRUCT; }
    1107             : 
    1108             :   static ConstructFrame* cast(StackFrame* frame) {
    1109             :     DCHECK(frame->is_construct());
    1110             :     return static_cast<ConstructFrame*>(frame);
    1111             :   }
    1112             : 
    1113             :  protected:
    1114             :   inline explicit ConstructFrame(StackFrameIteratorBase* iterator);
    1115             : 
    1116             :  private:
    1117             :   friend class StackFrameIteratorBase;
    1118             : };
    1119             : 
    1120    18462696 : class BuiltinContinuationFrame : public InternalFrame {
    1121             :  public:
    1122           8 :   Type type() const override { return BUILTIN_CONTINUATION; }
    1123             : 
    1124             :   static BuiltinContinuationFrame* cast(StackFrame* frame) {
    1125             :     DCHECK(frame->is_builtin_continuation());
    1126             :     return static_cast<BuiltinContinuationFrame*>(frame);
    1127             :   }
    1128             : 
    1129             :  protected:
    1130             :   inline explicit BuiltinContinuationFrame(StackFrameIteratorBase* iterator);
    1131             : 
    1132             :  private:
    1133             :   friend class StackFrameIteratorBase;
    1134             : };
    1135             : 
    1136    36925392 : class JavaScriptBuiltinContinuationFrame : public JavaScriptFrame {
    1137             :  public:
    1138         707 :   Type type() const override { return JAVA_SCRIPT_BUILTIN_CONTINUATION; }
    1139             : 
    1140             :   static JavaScriptBuiltinContinuationFrame* cast(StackFrame* frame) {
    1141             :     DCHECK(frame->is_java_script_builtin_continuation());
    1142             :     return static_cast<JavaScriptBuiltinContinuationFrame*>(frame);
    1143             :   }
    1144             : 
    1145             :   int ComputeParametersCount() const override;
    1146             :   intptr_t GetSPToFPDelta() const;
    1147             : 
    1148             :   Object context() const override;
    1149             : 
    1150             :  protected:
    1151             :   inline explicit JavaScriptBuiltinContinuationFrame(
    1152             :       StackFrameIteratorBase* iterator);
    1153             : 
    1154             :  private:
    1155             :   friend class StackFrameIteratorBase;
    1156             : };
    1157             : 
    1158    18462696 : class JavaScriptBuiltinContinuationWithCatchFrame
    1159             :     : public JavaScriptBuiltinContinuationFrame {
    1160             :  public:
    1161          24 :   Type type() const override {
    1162          24 :     return JAVA_SCRIPT_BUILTIN_CONTINUATION_WITH_CATCH;
    1163             :   }
    1164             : 
    1165             :   static JavaScriptBuiltinContinuationWithCatchFrame* cast(StackFrame* frame) {
    1166             :     DCHECK(frame->is_java_script_builtin_with_catch_continuation());
    1167             :     return static_cast<JavaScriptBuiltinContinuationWithCatchFrame*>(frame);
    1168             :   }
    1169             : 
    1170             :   // Patch in the exception object at the appropriate location into the stack
    1171             :   // frame.
    1172             :   void SetException(Object exception);
    1173             : 
    1174             :  protected:
    1175             :   inline explicit JavaScriptBuiltinContinuationWithCatchFrame(
    1176             :       StackFrameIteratorBase* iterator);
    1177             : 
    1178             :  private:
    1179             :   friend class StackFrameIteratorBase;
    1180             : };
    1181             : 
    1182    18462696 : class StackFrameIteratorBase {
    1183             :  public:
    1184             :   Isolate* isolate() const { return isolate_; }
    1185             : 
    1186      258871 :   bool done() const { return frame_ == nullptr; }
    1187             : 
    1188             :  protected:
    1189             :   // An iterator that iterates over a given thread's stack.
    1190             :   StackFrameIteratorBase(Isolate* isolate, bool can_access_heap_objects);
    1191             : 
    1192             :   Isolate* isolate_;
    1193             : #define DECLARE_SINGLETON(ignore, type) type type##_;
    1194             :   STACK_FRAME_TYPE_LIST(DECLARE_SINGLETON)
    1195             : #undef DECLARE_SINGLETON
    1196             :   StackFrame* frame_;
    1197             :   StackHandler* handler_;
    1198             :   const bool can_access_heap_objects_;
    1199             : 
    1200             :   StackHandler* handler() const {
    1201             :     DCHECK(!done());
    1202             :     return handler_;
    1203             :   }
    1204             : 
    1205             :   // Get the type-specific frame singleton in a given state.
    1206             :   StackFrame* SingletonFor(StackFrame::Type type, StackFrame::State* state);
    1207             :   // A helper function, can return a nullptr pointer.
    1208             :   StackFrame* SingletonFor(StackFrame::Type type);
    1209             : 
    1210             :  private:
    1211             :   friend class StackFrame;
    1212             :   DISALLOW_COPY_AND_ASSIGN(StackFrameIteratorBase);
    1213             : };
    1214             : 
    1215             : 
    1216     9130037 : class StackFrameIterator: public StackFrameIteratorBase {
    1217             :  public:
    1218             :   // An iterator that iterates over the isolate's current thread's stack,
    1219             :   V8_EXPORT_PRIVATE explicit StackFrameIterator(Isolate* isolate);
    1220             :   // An iterator that iterates over a given thread's stack.
    1221             :   V8_EXPORT_PRIVATE StackFrameIterator(Isolate* isolate, ThreadLocalTop* t);
    1222             : 
    1223             :   StackFrame* frame() const {
    1224             :     DCHECK(!done());
    1225             :     return frame_;
    1226             :   }
    1227             :   V8_EXPORT_PRIVATE void Advance();
    1228             : 
    1229             :  private:
    1230             :   // Go back to the first frame.
    1231             :   void Reset(ThreadLocalTop* top);
    1232             : 
    1233             :   DISALLOW_COPY_AND_ASSIGN(StackFrameIterator);
    1234             : };
    1235             : 
    1236             : // Iterator that supports iterating through all JavaScript frames.
    1237      774181 : class JavaScriptFrameIterator {
    1238             :  public:
    1239             :   inline explicit JavaScriptFrameIterator(Isolate* isolate);
    1240             :   inline JavaScriptFrameIterator(Isolate* isolate, ThreadLocalTop* top);
    1241             : 
    1242             :   inline JavaScriptFrame* frame() const;
    1243             : 
    1244             :   bool done() const { return iterator_.done(); }
    1245             :   V8_EXPORT_PRIVATE void Advance();
    1246        4105 :   void AdvanceOneFrame() { iterator_.Advance(); }
    1247             : 
    1248             :  private:
    1249             :   StackFrameIterator iterator_;
    1250             : };
    1251             : 
    1252             : // NOTE: The stack trace frame iterator is an iterator that only traverse proper
    1253             : // JavaScript frames that have proper JavaScript functions and WebAssembly
    1254             : // frames.
    1255     1962061 : class V8_EXPORT_PRIVATE StackTraceFrameIterator {
    1256             :  public:
    1257             :   explicit StackTraceFrameIterator(Isolate* isolate);
    1258             :   // Skip frames until the frame with the given id is reached.
    1259             :   StackTraceFrameIterator(Isolate* isolate, StackFrame::Id id);
    1260             :   bool done() const { return iterator_.done(); }
    1261             :   void Advance();
    1262             :   void AdvanceOneFrame() { iterator_.Advance(); }
    1263             : 
    1264             :   inline StandardFrame* frame() const;
    1265             : 
    1266             :   inline bool is_javascript() const;
    1267             :   inline bool is_wasm() const;
    1268             :   inline JavaScriptFrame* javascript_frame() const;
    1269             : 
    1270             :  private:
    1271             :   StackFrameIterator iterator_;
    1272             :   bool IsValidFrame(StackFrame* frame) const;
    1273             : };
    1274             : 
    1275       60357 : class SafeStackFrameIterator: public StackFrameIteratorBase {
    1276             :  public:
    1277             :   SafeStackFrameIterator(Isolate* isolate,
    1278             :                          Address fp, Address sp,
    1279             :                          Address js_entry_sp);
    1280             : 
    1281             :   inline StackFrame* frame() const;
    1282             :   void Advance();
    1283             : 
    1284             :   StackFrame::Type top_frame_type() const { return top_frame_type_; }
    1285             : 
    1286             :  private:
    1287             :   void AdvanceOneFrame();
    1288             : 
    1289             :   bool IsValidStackAddress(Address addr) const {
    1290     1537185 :     return low_bound_ <= addr && addr <= high_bound_;
    1291             :   }
    1292             :   bool IsValidFrame(StackFrame* frame) const;
    1293             :   bool IsValidCaller(StackFrame* frame);
    1294             :   bool IsValidExitFrame(Address fp) const;
    1295             :   bool IsValidTop(ThreadLocalTop* top) const;
    1296             : 
    1297             :   const Address low_bound_;
    1298             :   const Address high_bound_;
    1299             :   StackFrame::Type top_frame_type_;
    1300             :   ExternalCallbackScope* external_callback_scope_;
    1301             : };
    1302             : }  // namespace internal
    1303             : }  // namespace v8
    1304             : 
    1305             : #endif  // V8_FRAMES_H_

Generated by: LCOV version 1.10