LCOV - code coverage report
Current view: top level - src - frames.h (source / functions) Hit Total Coverage
Test: app.info Lines: 97 105 92.4 %
Date: 2019-02-19 Functions: 37 91 40.7 %

          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         504 :   static int32_t TypeToMarker(Type type) {
     141             :     DCHECK_GE(type, 0);
     142     1208482 :     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    13113556 :     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    37129754 :     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      127205 :   bool is_entry() const { return type() == ENTRY; }
     173      101210 :   bool is_construct_entry() const { return type() == CONSTRUCT_ENTRY; }
     174       61115 :   bool is_exit() const { return type() == EXIT; }
     175    23287718 :   bool is_optimized() const { return type() == OPTIMIZED; }
     176     1054667 :   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      382711 :     return type() == WASM_INTERPRETER_ENTRY;
     183             :   }
     184      525385 :   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       60830 :   bool is_builtin_exit() const { return type() == BUILTIN_EXIT; }
     198           0 :   virtual bool is_standard() const { return false; }
     199             : 
     200    12652853 :   bool is_java_script() const {
     201    12652853 :     Type type = this->type();
     202    25311721 :     return (type == OPTIMIZED) || (type == INTERPRETED) || (type == BUILTIN) ||
     203    25311515 :            (type == JAVA_SCRIPT_BUILTIN_CONTINUATION) ||
     204    12652853 :            (type == JAVA_SCRIPT_BUILTIN_CONTINUATION_WITH_CATCH);
     205             :   }
     206             :   bool is_wasm() const {
     207     5215435 :     Type type = this->type();
     208     5215435 :     return type == WASM_COMPILED || type == WASM_INTERPRETER_ENTRY;
     209             :   }
     210             : 
     211             :   // Accessors.
     212             :   Address sp() const { return state_.sp; }
     213       33470 :   Address fp() const { return state_.fp; }
     214             :   Address callee_pc() const {
     215      311298 :     return state_.callee_pc_address ? *state_.callee_pc_address : kNullAddress;
     216             :   }
     217    59936713 :   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    24191688 :   Address pc() const { return *pc_address(); }
     225       26168 :   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     1982318 :   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   185657787 :   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     8840847 : 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    17681694 : class EntryFrame: public StackFrame {
     333             :  public:
     334     2053626 :   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     8840847 : class ConstructEntryFrame : public EntryFrame {
     362             :  public:
     363          44 :   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    17681694 : class ExitFrame: public StackFrame {
     382             :  public:
     383     7390911 :   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     8840847 : class BuiltinExitFrame : public ExitFrame {
     420             :  public:
     421     1156913 :   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             :   friend class FrameArrayBuilder;
     450             : };
     451             : 
     452             : class StandardFrame;
     453             : 
     454             : class FrameSummary {
     455             :  public:
     456             : // Subclasses for the different summary kinds:
     457             : #define FRAME_SUMMARY_VARIANTS(F)                                             \
     458             :   F(JAVA_SCRIPT, JavaScriptFrameSummary, java_script_summary_, JavaScript)    \
     459             :   F(WASM_COMPILED, WasmCompiledFrameSummary, wasm_compiled_summary_,          \
     460             :     WasmCompiled)                                                             \
     461             :   F(WASM_INTERPRETED, WasmInterpretedFrameSummary, wasm_interpreted_summary_, \
     462             :     WasmInterpreted)
     463             : 
     464             : #define FRAME_SUMMARY_KIND(kind, type, field, desc) kind,
     465             :   enum Kind { FRAME_SUMMARY_VARIANTS(FRAME_SUMMARY_KIND) };
     466             : #undef FRAME_SUMMARY_KIND
     467             : 
     468             :   class FrameSummaryBase {
     469             :    public:
     470             :     FrameSummaryBase(Isolate* isolate, Kind kind)
     471     7725609 :         : isolate_(isolate), kind_(kind) {}
     472             :     Isolate* isolate() const { return isolate_; }
     473             :     Kind kind() const { return kind_; }
     474             : 
     475             :    private:
     476             :     Isolate* isolate_;
     477             :     Kind kind_;
     478             :   };
     479             : 
     480             :   class JavaScriptFrameSummary : public FrameSummaryBase {
     481             :    public:
     482             :     JavaScriptFrameSummary(Isolate* isolate, Object receiver,
     483             :                            JSFunction function, AbstractCode abstract_code,
     484             :                            int code_offset, bool is_constructor,
     485             :                            FixedArray parameters);
     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             : #undef FRAME_SUMMARY_FIELD
     563             : #define FRAME_SUMMARY_CONS(kind, type, field, desc) \
     564             :   FrameSummary(type summ) : field(summ) {}  // NOLINT
     565     8708055 :   FRAME_SUMMARY_VARIANTS(FRAME_SUMMARY_CONS)
     566             : #undef FRAME_SUMMARY_CONS
     567             : 
     568             :   ~FrameSummary();
     569             : 
     570             :   static FrameSummary GetTop(const StandardFrame* frame);
     571             :   static FrameSummary GetBottom(const StandardFrame* frame);
     572             :   static FrameSummary GetSingle(const StandardFrame* frame);
     573             :   static FrameSummary Get(const StandardFrame* frame, int index);
     574             : 
     575             :   // Dispatched accessors.
     576             :   Handle<Object> receiver() const;
     577             :   int code_offset() const;
     578             :   bool is_constructor() const;
     579             :   bool is_subject_to_debugging() const;
     580             :   Handle<Object> script() const;
     581             :   int SourcePosition() const;
     582             :   int SourceStatementPosition() const;
     583             :   Handle<String> FunctionName() const;
     584             :   Handle<Context> native_context() const;
     585             : 
     586             : #define FRAME_SUMMARY_CAST(kind_, type, field, desc)      \
     587             :   bool Is##desc() const { return base_.kind() == kind_; } \
     588             :   const type& As##desc() const {                          \
     589             :     DCHECK_EQ(base_.kind(), kind_);                       \
     590             :     return field;                                         \
     591             :   }
     592     6363133 :   FRAME_SUMMARY_VARIANTS(FRAME_SUMMARY_CAST)
     593             : #undef FRAME_SUMMARY_CAST
     594             : 
     595             :   bool IsWasm() const { return IsWasmCompiled() || IsWasmInterpreted(); }
     596             :   const WasmFrameSummary& AsWasm() const {
     597             :     if (IsWasmCompiled()) return AsWasmCompiled();
     598             :     return AsWasmInterpreted();
     599             :   }
     600             : 
     601             :  private:
     602             : #define FRAME_SUMMARY_FIELD(kind, type, field, desc) type field;
     603             :   union {
     604             :     FrameSummaryBase base_;
     605             :     FRAME_SUMMARY_VARIANTS(FRAME_SUMMARY_FIELD)
     606             :   };
     607             : };
     608             : 
     609   141453552 : class StandardFrame : public StackFrame {
     610             :  public:
     611             :   // Testers.
     612           0 :   bool is_standard() const override { return true; }
     613             : 
     614             :   // Accessors.
     615             :   virtual Object receiver() const;
     616             :   virtual Script script() const;
     617             :   virtual Object context() const;
     618             :   virtual int position() const;
     619             : 
     620             :   // Access the expressions in the stack frame including locals.
     621             :   inline Object GetExpression(int index) const;
     622             :   inline void SetExpression(int index, Object value);
     623             :   int ComputeExpressionsCount() const;
     624             : 
     625             :   // Access the parameters.
     626             :   virtual Object GetParameter(int index) const;
     627             :   virtual int ComputeParametersCount() const;
     628             : 
     629             :   // Check if this frame is a constructor frame invoked through 'new'.
     630             :   virtual bool IsConstructor() const;
     631             : 
     632             :   // Build a list with summaries for this frame including all inlined frames.
     633             :   // The functions are ordered bottom-to-top (i.e. summaries.last() is the
     634             :   // top-most activation; caller comes before callee).
     635             :   virtual void Summarize(std::vector<FrameSummary>* frames) const;
     636             : 
     637             :   static StandardFrame* cast(StackFrame* frame) {
     638             :     DCHECK(frame->is_standard());
     639             :     return static_cast<StandardFrame*>(frame);
     640             :   }
     641             : 
     642             :  protected:
     643             :   inline explicit StandardFrame(StackFrameIteratorBase* iterator);
     644             : 
     645             :   void ComputeCallerState(State* state) const override;
     646             : 
     647             :   // Accessors.
     648             :   inline Address caller_fp() const;
     649             :   inline Address caller_pc() const;
     650             : 
     651             :   // Computes the address of the PC field in the standard frame given
     652             :   // by the provided frame pointer.
     653             :   static inline Address ComputePCAddress(Address fp);
     654             : 
     655             :   // Computes the address of the constant pool  field in the standard
     656             :   // frame given by the provided frame pointer.
     657             :   static inline Address ComputeConstantPoolAddress(Address fp);
     658             : 
     659             :   // Iterate over expression stack including stack handlers, locals,
     660             :   // and parts of the fixed part including context and code fields.
     661             :   void IterateExpressions(RootVisitor* v) const;
     662             : 
     663             :   // Returns the address of the n'th expression stack element.
     664             :   virtual Address GetExpressionAddress(int n) const;
     665             : 
     666             :   // Determines if the standard frame for the given frame pointer is
     667             :   // an arguments adaptor frame.
     668             :   static inline bool IsArgumentsAdaptorFrame(Address fp);
     669             : 
     670             :   // Determines if the standard frame for the given frame pointer is a
     671             :   // construct frame.
     672             :   static inline bool IsConstructFrame(Address fp);
     673             : 
     674             :   // Used by OptimizedFrames and StubFrames.
     675             :   void IterateCompiledFrame(RootVisitor* v) const;
     676             : 
     677             :  private:
     678             :   friend class StackFrame;
     679             :   friend class SafeStackFrameIterator;
     680             : };
     681             : 
     682    53045082 : class JavaScriptFrame : public StandardFrame {
     683             :  public:
     684             :   Type type() const override = 0;
     685             : 
     686             :   void Summarize(std::vector<FrameSummary>* frames) const override;
     687             : 
     688             :   // Accessors.
     689             :   virtual JSFunction function() const;
     690             :   Object unchecked_function() const;
     691             :   Object receiver() const override;
     692             :   Object context() const override;
     693             :   Script script() const override;
     694             : 
     695             :   inline void set_receiver(Object value);
     696             : 
     697             :   // Access the parameters.
     698             :   inline Address GetParameterSlot(int index) const;
     699             :   Object GetParameter(int index) const override;
     700             :   int ComputeParametersCount() const override;
     701             :   Handle<FixedArray> GetParameters() const;
     702             : 
     703             :   // Debugger access.
     704             :   void SetParameterValue(int index, Object value) const;
     705             : 
     706             :   // Check if this frame is a constructor frame invoked through 'new'.
     707             :   bool IsConstructor() const override;
     708             : 
     709             :   // Determines whether this frame includes inlined activations. To get details
     710             :   // about the inlined frames use {GetFunctions} and {Summarize}.
     711             :   bool HasInlinedFrames() const;
     712             : 
     713             :   // Check if this frame has "adapted" arguments in the sense that the
     714             :   // actual passed arguments are available in an arguments adaptor
     715             :   // frame below it on the stack.
     716             :   inline bool has_adapted_arguments() const;
     717             : 
     718             :   // Garbage collection support.
     719             :   void Iterate(RootVisitor* v) const override;
     720             : 
     721             :   // Printing support.
     722             :   void Print(StringStream* accumulator, PrintMode mode,
     723             :              int index) const override;
     724             : 
     725             :   // Determine the code for the frame.
     726             :   Code unchecked_code() const override;
     727             : 
     728             :   // Return a list with {SharedFunctionInfo} objects of this frame.
     729             :   virtual void GetFunctions(std::vector<SharedFunctionInfo>* functions) const;
     730             : 
     731             :   void GetFunctions(std::vector<Handle<SharedFunctionInfo>>* functions) const;
     732             : 
     733             :   // Lookup exception handler for current {pc}, returns -1 if none found. Also
     734             :   // returns data associated with the handler site specific to the frame type:
     735             :   //  - OptimizedFrame  : Data is the stack slot count of the entire frame.
     736             :   //  - InterpretedFrame: Data is the register index holding the context.
     737             :   virtual int LookupExceptionHandlerInTable(
     738             :       int* data, HandlerTable::CatchPrediction* prediction);
     739             : 
     740             :   // Architecture-specific register description.
     741             :   static Register fp_register();
     742             :   static Register context_register();
     743             :   static Register constant_pool_pointer_register();
     744             : 
     745           9 :   static JavaScriptFrame* cast(StackFrame* frame) {
     746             :     DCHECK(frame->is_java_script());
     747           9 :     return static_cast<JavaScriptFrame*>(frame);
     748             :   }
     749             : 
     750             :   static void PrintFunctionAndOffset(JSFunction function, AbstractCode code,
     751             :                                      int code_offset, FILE* file,
     752             :                                      bool print_line_number);
     753             : 
     754             :   static void PrintTop(Isolate* isolate, FILE* file, bool print_args,
     755             :                        bool print_line_number);
     756             : 
     757             :   static void CollectFunctionAndOffsetForICStats(JSFunction function,
     758             :                                                  AbstractCode code,
     759             :                                                  int code_offset);
     760             :   static void CollectTopFrameForICStats(Isolate* isolate);
     761             : 
     762             :  protected:
     763             :   inline explicit JavaScriptFrame(StackFrameIteratorBase* iterator);
     764             : 
     765             :   Address GetCallerStackPointer() const override;
     766             : 
     767          57 :   virtual void PrintFrameKind(StringStream* accumulator) const {}
     768             : 
     769             :  private:
     770             :   inline Object function_slot_object() const;
     771             : 
     772             :   friend class StackFrameIteratorBase;
     773             : };
     774             : 
     775             : 
     776    35363388 : class StubFrame : public StandardFrame {
     777             :  public:
     778     6637742 :   Type type() const override { return STUB; }
     779             : 
     780             :   // GC support.
     781             :   void Iterate(RootVisitor* v) const override;
     782             : 
     783             :   // Determine the code for the frame.
     784             :   Code unchecked_code() const override;
     785             : 
     786             :   // Lookup exception handler for current {pc}, returns -1 if none found. Only
     787             :   // TurboFan stub frames are supported. Also returns data associated with the
     788             :   // handler site:
     789             :   //  - TurboFan stub: Data is the stack slot count of the entire frame.
     790             :   int LookupExceptionHandlerInTable(int* data);
     791             : 
     792             :  protected:
     793             :   inline explicit StubFrame(StackFrameIteratorBase* iterator);
     794             : 
     795             :   Address GetCallerStackPointer() const override;
     796             : 
     797             :   friend class StackFrameIteratorBase;
     798             : };
     799             : 
     800             : 
     801     8840847 : class OptimizedFrame : public JavaScriptFrame {
     802             :  public:
     803     9382747 :   Type type() const override { return OPTIMIZED; }
     804             : 
     805             :   // GC support.
     806             :   void Iterate(RootVisitor* v) const override;
     807             : 
     808             :   // Return a list with {SharedFunctionInfo} objects of this frame.
     809             :   // The functions are ordered bottom-to-top (i.e. functions.last()
     810             :   // is the top-most activation)
     811             :   void GetFunctions(std::vector<SharedFunctionInfo>* functions) const override;
     812             : 
     813             :   void Summarize(std::vector<FrameSummary>* frames) const override;
     814             : 
     815             :   // Lookup exception handler for current {pc}, returns -1 if none found.
     816             :   int LookupExceptionHandlerInTable(
     817             :       int* data, HandlerTable::CatchPrediction* prediction) override;
     818             : 
     819             :   DeoptimizationData GetDeoptimizationData(int* deopt_index) const;
     820             : 
     821             :   Object receiver() const override;
     822             :   int ComputeParametersCount() const override;
     823             : 
     824             :   static int StackSlotOffsetRelativeToFp(int slot_index);
     825             : 
     826             :  protected:
     827             :   inline explicit OptimizedFrame(StackFrameIteratorBase* iterator);
     828             : 
     829             : 
     830             :  private:
     831             :   friend class StackFrameIteratorBase;
     832             : 
     833             :   Object StackSlotAt(int index) const;
     834             : };
     835             : 
     836             : 
     837     8840847 : class InterpretedFrame : public JavaScriptFrame {
     838             :  public:
     839    37834369 :   Type type() const override { return INTERPRETED; }
     840             : 
     841             :   // Accessors.
     842             :   int position() const override;
     843             : 
     844             :   // Lookup exception handler for current {pc}, returns -1 if none found.
     845             :   int LookupExceptionHandlerInTable(
     846             :       int* data, HandlerTable::CatchPrediction* prediction) override;
     847             : 
     848             :   // Returns the current offset into the bytecode stream.
     849             :   int GetBytecodeOffset() const;
     850             : 
     851             :   // Updates the current offset into the bytecode stream, mainly used for stack
     852             :   // unwinding to continue execution at a different bytecode offset.
     853             :   void PatchBytecodeOffset(int new_offset);
     854             : 
     855             :   // Returns the frame's current bytecode array.
     856             :   BytecodeArray GetBytecodeArray() const;
     857             : 
     858             :   // Updates the frame's BytecodeArray with |bytecode_array|. Used by the
     859             :   // debugger to swap execution onto a BytecodeArray patched with breakpoints.
     860             :   void PatchBytecodeArray(BytecodeArray bytecode_array);
     861             : 
     862             :   // Access to the interpreter register file for this frame.
     863             :   Object ReadInterpreterRegister(int register_index) const;
     864             :   void WriteInterpreterRegister(int register_index, Object value);
     865             : 
     866             :   // Build a list with summaries for this frame including all inlined frames.
     867             :   void Summarize(std::vector<FrameSummary>* frames) const override;
     868             : 
     869             :   static int GetBytecodeOffset(Address fp);
     870             : 
     871        6588 :   static InterpretedFrame* cast(StackFrame* frame) {
     872             :     DCHECK(frame->is_interpreted());
     873        6588 :     return static_cast<InterpretedFrame*>(frame);
     874             :   }
     875             : 
     876             :  protected:
     877             :   inline explicit InterpretedFrame(StackFrameIteratorBase* iterator);
     878             : 
     879             :   Address GetExpressionAddress(int n) const override;
     880             : 
     881             :  private:
     882             :   friend class StackFrameIteratorBase;
     883             : };
     884             : 
     885             : 
     886             : // Arguments adaptor frames are automatically inserted below
     887             : // JavaScript frames when the actual number of parameters does not
     888             : // match the formal number of parameters.
     889     8840847 : class ArgumentsAdaptorFrame: public JavaScriptFrame {
     890             :  public:
     891     2946030 :   Type type() const override { return ARGUMENTS_ADAPTOR; }
     892             : 
     893             :   // Determine the code for the frame.
     894             :   Code unchecked_code() const override;
     895             : 
     896           9 :   static ArgumentsAdaptorFrame* cast(StackFrame* frame) {
     897             :     DCHECK(frame->is_arguments_adaptor());
     898           9 :     return static_cast<ArgumentsAdaptorFrame*>(frame);
     899             :   }
     900             : 
     901             :   int ComputeParametersCount() const override;
     902             : 
     903             :   // Printing support.
     904             :   void Print(StringStream* accumulator, PrintMode mode,
     905             :              int index) const override;
     906             : 
     907             :  protected:
     908             :   inline explicit ArgumentsAdaptorFrame(StackFrameIteratorBase* iterator);
     909             : 
     910             : 
     911             :  private:
     912             :   friend class StackFrameIteratorBase;
     913             : };
     914             : 
     915             : // Builtin frames are built for builtins with JavaScript linkage, such as
     916             : // various standard library functions (i.e. Math.asin, Math.floor, etc.).
     917     8840847 : class BuiltinFrame final : public JavaScriptFrame {
     918             :  public:
     919           0 :   Type type() const final { return BUILTIN; }
     920             : 
     921             :   static BuiltinFrame* cast(StackFrame* frame) {
     922             :     DCHECK(frame->is_builtin());
     923             :     return static_cast<BuiltinFrame*>(frame);
     924             :   }
     925             :   int ComputeParametersCount() const final;
     926             : 
     927             :  protected:
     928             :   inline explicit BuiltinFrame(StackFrameIteratorBase* iterator);
     929             : 
     930             :   void PrintFrameKind(StringStream* accumulator) const override;
     931             : 
     932             :  private:
     933             :   friend class StackFrameIteratorBase;
     934             : };
     935             : 
     936     8840847 : class WasmCompiledFrame final : public StandardFrame {
     937             :  public:
     938     5479391 :   Type type() const override { return WASM_COMPILED; }
     939             : 
     940             :   // GC support.
     941             :   void Iterate(RootVisitor* v) const override;
     942             : 
     943             :   // Printing support.
     944             :   void Print(StringStream* accumulator, PrintMode mode,
     945             :              int index) const override;
     946             : 
     947             :   // Lookup exception handler for current {pc}, returns -1 if none found. Also
     948             :   // returns the stack slot count of the entire frame.
     949             :   int LookupExceptionHandlerInTable(int* data);
     950             : 
     951             :   // Determine the code for the frame.
     952             :   Code unchecked_code() const override;
     953             : 
     954             :   // Accessors.
     955             :   WasmInstanceObject wasm_instance() const;
     956             :   wasm::WasmCode* wasm_code() const;
     957             :   uint32_t function_index() const;
     958             :   Script script() const override;
     959             :   int position() const override;
     960             :   bool at_to_number_conversion() const;
     961             : 
     962             :   void Summarize(std::vector<FrameSummary>* frames) const override;
     963             : 
     964          72 :   static WasmCompiledFrame* cast(StackFrame* frame) {
     965             :     DCHECK(frame->is_wasm_compiled());
     966          72 :     return static_cast<WasmCompiledFrame*>(frame);
     967             :   }
     968             : 
     969             :  protected:
     970             :   inline explicit WasmCompiledFrame(StackFrameIteratorBase* iterator);
     971             : 
     972             :   Address GetCallerStackPointer() const override;
     973             : 
     974             :  private:
     975             :   friend class StackFrameIteratorBase;
     976             :   WasmModuleObject module_object() const;
     977             : };
     978             : 
     979     8840847 : class WasmInterpreterEntryFrame final : public StandardFrame {
     980             :  public:
     981       14658 :   Type type() const override { return WASM_INTERPRETER_ENTRY; }
     982             : 
     983             :   // GC support.
     984             :   void Iterate(RootVisitor* v) const override;
     985             : 
     986             :   // Printing support.
     987             :   void Print(StringStream* accumulator, PrintMode mode,
     988             :              int index) const override;
     989             : 
     990             :   void Summarize(std::vector<FrameSummary>* frames) const override;
     991             : 
     992             :   // Determine the code for the frame.
     993             :   Code unchecked_code() const override;
     994             : 
     995             :   // Accessors.
     996             :   WasmDebugInfo debug_info() const;
     997             :   WasmInstanceObject wasm_instance() const;
     998             : 
     999             :   Script script() const override;
    1000             :   int position() const override;
    1001             :   Object context() const override;
    1002             : 
    1003       33452 :   static WasmInterpreterEntryFrame* cast(StackFrame* frame) {
    1004             :     DCHECK(frame->is_wasm_interpreter_entry());
    1005       33452 :     return static_cast<WasmInterpreterEntryFrame*>(frame);
    1006             :   }
    1007             : 
    1008             :  protected:
    1009             :   inline explicit WasmInterpreterEntryFrame(StackFrameIteratorBase* iterator);
    1010             : 
    1011             :   Address GetCallerStackPointer() const override;
    1012             : 
    1013             :  private:
    1014             :   friend class StackFrameIteratorBase;
    1015             :   WasmModuleObject module_object() const;
    1016             : };
    1017             : 
    1018     8840847 : class WasmToJsFrame : public StubFrame {
    1019             :  public:
    1020        4533 :   Type type() const override { return WASM_TO_JS; }
    1021             : 
    1022             :  protected:
    1023             :   inline explicit WasmToJsFrame(StackFrameIteratorBase* iterator);
    1024             : 
    1025             :  private:
    1026             :   friend class StackFrameIteratorBase;
    1027             : };
    1028             : 
    1029     8840847 : class JsToWasmFrame : public StubFrame {
    1030             :  public:
    1031      458360 :   Type type() const override { return JS_TO_WASM; }
    1032             : 
    1033             :  protected:
    1034             :   inline explicit JsToWasmFrame(StackFrameIteratorBase* iterator);
    1035             : 
    1036             :  private:
    1037             :   friend class StackFrameIteratorBase;
    1038             : };
    1039             : 
    1040     8840847 : class CWasmEntryFrame : public StubFrame {
    1041             :  public:
    1042        2326 :   Type type() const override { return C_WASM_ENTRY; }
    1043             : 
    1044             :  protected:
    1045             :   inline explicit CWasmEntryFrame(StackFrameIteratorBase* iterator);
    1046             : 
    1047             :  private:
    1048             :   friend class StackFrameIteratorBase;
    1049             : };
    1050             : 
    1051     8840847 : class WasmCompileLazyFrame : public StandardFrame {
    1052             :  public:
    1053           0 :   Type type() const override { return WASM_COMPILE_LAZY; }
    1054             : 
    1055             :   Code unchecked_code() const override;
    1056             :   WasmInstanceObject wasm_instance() const;
    1057             :   FullObjectSlot wasm_instance_slot() const;
    1058             : 
    1059             :   // Garbage collection support.
    1060             :   void Iterate(RootVisitor* v) const override;
    1061             : 
    1062             :   static WasmCompileLazyFrame* cast(StackFrame* frame) {
    1063             :     DCHECK(frame->is_wasm_compile_lazy());
    1064             :     return static_cast<WasmCompileLazyFrame*>(frame);
    1065             :   }
    1066             : 
    1067             :  protected:
    1068             :   inline explicit WasmCompileLazyFrame(StackFrameIteratorBase* iterator);
    1069             : 
    1070             :   Address GetCallerStackPointer() const override;
    1071             : 
    1072             :  private:
    1073             :   friend class StackFrameIteratorBase;
    1074             : };
    1075             : 
    1076    26522541 : class InternalFrame: public StandardFrame {
    1077             :  public:
    1078     2562490 :   Type type() const override { return INTERNAL; }
    1079             : 
    1080             :   // Garbage collection support.
    1081             :   void Iterate(RootVisitor* v) const override;
    1082             : 
    1083             :   // Determine the code for the frame.
    1084             :   Code unchecked_code() const override;
    1085             : 
    1086             :   static InternalFrame* cast(StackFrame* frame) {
    1087             :     DCHECK(frame->is_internal());
    1088             :     return static_cast<InternalFrame*>(frame);
    1089             :   }
    1090             : 
    1091             :  protected:
    1092             :   inline explicit InternalFrame(StackFrameIteratorBase* iterator);
    1093             : 
    1094             :   Address GetCallerStackPointer() const override;
    1095             : 
    1096             :  private:
    1097             :   friend class StackFrameIteratorBase;
    1098             : };
    1099             : 
    1100             : 
    1101             : // Construct frames are special trampoline frames introduced to handle
    1102             : // function invocations through 'new'.
    1103     8840847 : class ConstructFrame: public InternalFrame {
    1104             :  public:
    1105      466487 :   Type type() const override { return CONSTRUCT; }
    1106             : 
    1107             :   static ConstructFrame* cast(StackFrame* frame) {
    1108             :     DCHECK(frame->is_construct());
    1109             :     return static_cast<ConstructFrame*>(frame);
    1110             :   }
    1111             : 
    1112             :  protected:
    1113             :   inline explicit ConstructFrame(StackFrameIteratorBase* iterator);
    1114             : 
    1115             :  private:
    1116             :   friend class StackFrameIteratorBase;
    1117             : };
    1118             : 
    1119     8840847 : class BuiltinContinuationFrame : public InternalFrame {
    1120             :  public:
    1121           8 :   Type type() const override { return BUILTIN_CONTINUATION; }
    1122             : 
    1123             :   static BuiltinContinuationFrame* cast(StackFrame* frame) {
    1124             :     DCHECK(frame->is_builtin_continuation());
    1125             :     return static_cast<BuiltinContinuationFrame*>(frame);
    1126             :   }
    1127             : 
    1128             :  protected:
    1129             :   inline explicit BuiltinContinuationFrame(StackFrameIteratorBase* iterator);
    1130             : 
    1131             :  private:
    1132             :   friend class StackFrameIteratorBase;
    1133             : };
    1134             : 
    1135    17681694 : class JavaScriptBuiltinContinuationFrame : public JavaScriptFrame {
    1136             :  public:
    1137         666 :   Type type() const override { return JAVA_SCRIPT_BUILTIN_CONTINUATION; }
    1138             : 
    1139             :   static JavaScriptBuiltinContinuationFrame* cast(StackFrame* frame) {
    1140             :     DCHECK(frame->is_java_script_builtin_continuation());
    1141             :     return static_cast<JavaScriptBuiltinContinuationFrame*>(frame);
    1142             :   }
    1143             : 
    1144             :   int ComputeParametersCount() const override;
    1145             :   intptr_t GetSPToFPDelta() const;
    1146             : 
    1147             :   Object context() const override;
    1148             : 
    1149             :  protected:
    1150             :   inline explicit JavaScriptBuiltinContinuationFrame(
    1151             :       StackFrameIteratorBase* iterator);
    1152             : 
    1153             :  private:
    1154             :   friend class StackFrameIteratorBase;
    1155             : };
    1156             : 
    1157     8840847 : class JavaScriptBuiltinContinuationWithCatchFrame
    1158             :     : public JavaScriptBuiltinContinuationFrame {
    1159             :  public:
    1160          24 :   Type type() const override {
    1161          24 :     return JAVA_SCRIPT_BUILTIN_CONTINUATION_WITH_CATCH;
    1162             :   }
    1163             : 
    1164             :   static JavaScriptBuiltinContinuationWithCatchFrame* cast(StackFrame* frame) {
    1165             :     DCHECK(frame->is_java_script_builtin_with_catch_continuation());
    1166             :     return static_cast<JavaScriptBuiltinContinuationWithCatchFrame*>(frame);
    1167             :   }
    1168             : 
    1169             :   // Patch in the exception object at the appropriate location into the stack
    1170             :   // frame.
    1171             :   void SetException(Object exception);
    1172             : 
    1173             :  protected:
    1174             :   inline explicit JavaScriptBuiltinContinuationWithCatchFrame(
    1175             :       StackFrameIteratorBase* iterator);
    1176             : 
    1177             :  private:
    1178             :   friend class StackFrameIteratorBase;
    1179             : };
    1180             : 
    1181    17681694 : class StackFrameIteratorBase {
    1182             :  public:
    1183             :   Isolate* isolate() const { return isolate_; }
    1184             : 
    1185      321369 :   bool done() const { return frame_ == nullptr; }
    1186             : 
    1187             :  protected:
    1188             :   // An iterator that iterates over a given thread's stack.
    1189             :   StackFrameIteratorBase(Isolate* isolate, bool can_access_heap_objects);
    1190             : 
    1191             :   Isolate* isolate_;
    1192             : #define DECLARE_SINGLETON(ignore, type) type type##_;
    1193             :   STACK_FRAME_TYPE_LIST(DECLARE_SINGLETON)
    1194             : #undef DECLARE_SINGLETON
    1195             :   StackFrame* frame_;
    1196             :   StackHandler* handler_;
    1197             :   const bool can_access_heap_objects_;
    1198             : 
    1199             :   StackHandler* handler() const {
    1200             :     DCHECK(!done());
    1201             :     return handler_;
    1202             :   }
    1203             : 
    1204             :   // Get the type-specific frame singleton in a given state.
    1205             :   StackFrame* SingletonFor(StackFrame::Type type, StackFrame::State* state);
    1206             :   // A helper function, can return a nullptr pointer.
    1207             :   StackFrame* SingletonFor(StackFrame::Type type);
    1208             : 
    1209             :  private:
    1210             :   friend class StackFrame;
    1211             :   DISALLOW_COPY_AND_ASSIGN(StackFrameIteratorBase);
    1212             : };
    1213             : 
    1214             : 
    1215     8699633 : class StackFrameIterator: public StackFrameIteratorBase {
    1216             :  public:
    1217             :   // An iterator that iterates over the isolate's current thread's stack,
    1218             :   explicit StackFrameIterator(Isolate* isolate);
    1219             :   // An iterator that iterates over a given thread's stack.
    1220             :   StackFrameIterator(Isolate* isolate, ThreadLocalTop* t);
    1221             : 
    1222       66922 :   StackFrame* frame() const {
    1223             :     DCHECK(!done());
    1224       66922 :     return frame_;
    1225             :   }
    1226             :   void Advance();
    1227             : 
    1228             :  private:
    1229             :   // Go back to the first frame.
    1230             :   void Reset(ThreadLocalTop* top);
    1231             : 
    1232             :   DISALLOW_COPY_AND_ASSIGN(StackFrameIterator);
    1233             : };
    1234             : 
    1235             : // Iterator that supports iterating through all JavaScript frames.
    1236      315976 : class JavaScriptFrameIterator {
    1237             :  public:
    1238             :   inline explicit JavaScriptFrameIterator(Isolate* isolate);
    1239             :   inline JavaScriptFrameIterator(Isolate* isolate, ThreadLocalTop* top);
    1240             : 
    1241             :   inline JavaScriptFrame* frame() const;
    1242             : 
    1243     1863908 :   bool done() const { return iterator_.done(); }
    1244             :   void Advance();
    1245        3554 :   void AdvanceOneFrame() { iterator_.Advance(); }
    1246             : 
    1247             :  private:
    1248             :   StackFrameIterator iterator_;
    1249             : };
    1250             : 
    1251             : // NOTE: The stack trace frame iterator is an iterator that only traverse proper
    1252             : // JavaScript frames that have proper JavaScript functions and WebAssembly
    1253             : // frames.
    1254         144 : class StackTraceFrameIterator {
    1255             :  public:
    1256             :   explicit StackTraceFrameIterator(Isolate* isolate);
    1257             :   // Skip frames until the frame with the given id is reached.
    1258             :   StackTraceFrameIterator(Isolate* isolate, StackFrame::Id id);
    1259    13687962 :   bool done() const { return iterator_.done(); }
    1260             :   void Advance();
    1261             :   void AdvanceOneFrame() { iterator_.Advance(); }
    1262             : 
    1263             :   inline StandardFrame* frame() const;
    1264             : 
    1265             :   inline bool is_javascript() const;
    1266             :   inline bool is_wasm() const;
    1267             :   inline JavaScriptFrame* javascript_frame() const;
    1268             : 
    1269             :  private:
    1270             :   StackFrameIterator iterator_;
    1271             :   bool IsValidFrame(StackFrame* frame) const;
    1272             : };
    1273             : 
    1274             : 
    1275       25906 : 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      560165 :     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