LCOV - code coverage report
Current view: top level - src - frames.h (source / functions) Hit Total Coverage
Test: app.info Lines: 100 108 92.6 %
Date: 2017-10-20 Functions: 38 86 44.2 %

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

Generated by: LCOV version 1.10