11cb0ef41Sopenharmony_ci// Copyright 2012 the V8 project authors. All rights reserved.
21cb0ef41Sopenharmony_ci// Use of this source code is governed by a BSD-style license that can be
31cb0ef41Sopenharmony_ci// found in the LICENSE file.
41cb0ef41Sopenharmony_ci
51cb0ef41Sopenharmony_ci#ifndef V8_EXECUTION_FRAMES_H_
61cb0ef41Sopenharmony_ci#define V8_EXECUTION_FRAMES_H_
71cb0ef41Sopenharmony_ci
81cb0ef41Sopenharmony_ci#include "include/v8-initialization.h"
91cb0ef41Sopenharmony_ci#include "src/base/bounds.h"
101cb0ef41Sopenharmony_ci#include "src/codegen/safepoint-table.h"
111cb0ef41Sopenharmony_ci#include "src/common/globals.h"
121cb0ef41Sopenharmony_ci#include "src/handles/handles.h"
131cb0ef41Sopenharmony_ci#include "src/objects/code.h"
141cb0ef41Sopenharmony_ci#include "src/objects/objects.h"
151cb0ef41Sopenharmony_ci
161cb0ef41Sopenharmony_ci//
171cb0ef41Sopenharmony_ci// Frame inheritance hierarchy (please keep in sync with frame-constants.h):
181cb0ef41Sopenharmony_ci// - CommonFrame
191cb0ef41Sopenharmony_ci//   - CommonFrameWithJSLinkage
201cb0ef41Sopenharmony_ci//     - JavaScriptFrame (aka StandardFrame)
211cb0ef41Sopenharmony_ci//       - UnoptimizedFrame
221cb0ef41Sopenharmony_ci//         - InterpretedFrame
231cb0ef41Sopenharmony_ci//         - BaselineFrame
241cb0ef41Sopenharmony_ci//       - OptimizedFrame
251cb0ef41Sopenharmony_ci//     - TypedFrameWithJSLinkage
261cb0ef41Sopenharmony_ci//       - BuiltinFrame
271cb0ef41Sopenharmony_ci//       - JavaScriptBuiltinContinuationFrame
281cb0ef41Sopenharmony_ci//         - JavaScriptBuiltinContinuationWithCatchFrame
291cb0ef41Sopenharmony_ci//   - TypedFrame
301cb0ef41Sopenharmony_ci//     - NativeFrame
311cb0ef41Sopenharmony_ci//     - EntryFrame
321cb0ef41Sopenharmony_ci//       - ConstructEntryFrame
331cb0ef41Sopenharmony_ci//     - ExitFrame
341cb0ef41Sopenharmony_ci//       - BuiltinExitFrame
351cb0ef41Sopenharmony_ci//     - StubFrame
361cb0ef41Sopenharmony_ci//       - JsToWasmFrame
371cb0ef41Sopenharmony_ci//       - CWasmEntryFrame
381cb0ef41Sopenharmony_ci//     - Internal
391cb0ef41Sopenharmony_ci//       - ConstructFrame
401cb0ef41Sopenharmony_ci//       - BuiltinContinuationFrame
411cb0ef41Sopenharmony_ci//     - WasmFrame
421cb0ef41Sopenharmony_ci//       - WasmExitFrame
431cb0ef41Sopenharmony_ci//     - WasmDebugBreakFrame
441cb0ef41Sopenharmony_ci//     - WasmCompileLazyFrame
451cb0ef41Sopenharmony_ci//
461cb0ef41Sopenharmony_ci
471cb0ef41Sopenharmony_cinamespace v8 {
481cb0ef41Sopenharmony_cinamespace internal {
491cb0ef41Sopenharmony_cinamespace wasm {
501cb0ef41Sopenharmony_ciclass WasmCode;
511cb0ef41Sopenharmony_cistruct JumpBuffer;
521cb0ef41Sopenharmony_ciclass StackMemory;
531cb0ef41Sopenharmony_ci}  // namespace wasm
541cb0ef41Sopenharmony_ci
551cb0ef41Sopenharmony_ciclass AbstractCode;
561cb0ef41Sopenharmony_ciclass Debug;
571cb0ef41Sopenharmony_ciclass ExternalCallbackScope;
581cb0ef41Sopenharmony_ciclass InnerPointerToCodeCache;
591cb0ef41Sopenharmony_ciclass Isolate;
601cb0ef41Sopenharmony_ciclass ObjectVisitor;
611cb0ef41Sopenharmony_ciclass Register;
621cb0ef41Sopenharmony_ciclass RootVisitor;
631cb0ef41Sopenharmony_ciclass StackFrameInfo;
641cb0ef41Sopenharmony_ciclass StackFrameIteratorBase;
651cb0ef41Sopenharmony_ciclass StringStream;
661cb0ef41Sopenharmony_ciclass ThreadLocalTop;
671cb0ef41Sopenharmony_ciclass WasmInstanceObject;
681cb0ef41Sopenharmony_ciclass WasmModuleObject;
691cb0ef41Sopenharmony_ci
701cb0ef41Sopenharmony_ciclass StackHandlerConstants : public AllStatic {
711cb0ef41Sopenharmony_ci public:
721cb0ef41Sopenharmony_ci  static const int kNextOffset = 0 * kSystemPointerSize;
731cb0ef41Sopenharmony_ci  static const int kPaddingOffset = 1 * kSystemPointerSize;
741cb0ef41Sopenharmony_ci
751cb0ef41Sopenharmony_ci  static const int kSize = kPaddingOffset + kSystemPointerSize;
761cb0ef41Sopenharmony_ci  static const int kSlotCount = kSize >> kSystemPointerSizeLog2;
771cb0ef41Sopenharmony_ci};
781cb0ef41Sopenharmony_ci
791cb0ef41Sopenharmony_ciclass StackHandler {
801cb0ef41Sopenharmony_ci public:
811cb0ef41Sopenharmony_ci  // Get the address of this stack handler.
821cb0ef41Sopenharmony_ci  inline Address address() const;
831cb0ef41Sopenharmony_ci
841cb0ef41Sopenharmony_ci  // Get the next stack handler in the chain.
851cb0ef41Sopenharmony_ci  inline StackHandler* next() const;
861cb0ef41Sopenharmony_ci
871cb0ef41Sopenharmony_ci  // Get the next stack handler, as an Address. This is safe to use even
881cb0ef41Sopenharmony_ci  // when the next handler is null.
891cb0ef41Sopenharmony_ci  inline Address next_address() const;
901cb0ef41Sopenharmony_ci
911cb0ef41Sopenharmony_ci  // Conversion support.
921cb0ef41Sopenharmony_ci  static inline StackHandler* FromAddress(Address address);
931cb0ef41Sopenharmony_ci
941cb0ef41Sopenharmony_ci private:
951cb0ef41Sopenharmony_ci  DISALLOW_IMPLICIT_CONSTRUCTORS(StackHandler);
961cb0ef41Sopenharmony_ci};
971cb0ef41Sopenharmony_ci
981cb0ef41Sopenharmony_ci#define STACK_FRAME_TYPE_LIST(V)                                          \
991cb0ef41Sopenharmony_ci  V(ENTRY, EntryFrame)                                                    \
1001cb0ef41Sopenharmony_ci  V(CONSTRUCT_ENTRY, ConstructEntryFrame)                                 \
1011cb0ef41Sopenharmony_ci  V(EXIT, ExitFrame)                                                      \
1021cb0ef41Sopenharmony_ci  IF_WASM(V, WASM, WasmFrame)                                             \
1031cb0ef41Sopenharmony_ci  IF_WASM(V, WASM_TO_JS, WasmToJsFrame)                                   \
1041cb0ef41Sopenharmony_ci  IF_WASM(V, JS_TO_WASM, JsToWasmFrame)                                   \
1051cb0ef41Sopenharmony_ci  IF_WASM(V, STACK_SWITCH, StackSwitchFrame)                              \
1061cb0ef41Sopenharmony_ci  IF_WASM(V, WASM_DEBUG_BREAK, WasmDebugBreakFrame)                       \
1071cb0ef41Sopenharmony_ci  IF_WASM(V, C_WASM_ENTRY, CWasmEntryFrame)                               \
1081cb0ef41Sopenharmony_ci  IF_WASM(V, WASM_EXIT, WasmExitFrame)                                    \
1091cb0ef41Sopenharmony_ci  IF_WASM(V, WASM_COMPILE_LAZY, WasmCompileLazyFrame)                     \
1101cb0ef41Sopenharmony_ci  V(INTERPRETED, InterpretedFrame)                                        \
1111cb0ef41Sopenharmony_ci  V(BASELINE, BaselineFrame)                                              \
1121cb0ef41Sopenharmony_ci  V(OPTIMIZED, OptimizedFrame)                                            \
1131cb0ef41Sopenharmony_ci  V(STUB, StubFrame)                                                      \
1141cb0ef41Sopenharmony_ci  V(BUILTIN_CONTINUATION, BuiltinContinuationFrame)                       \
1151cb0ef41Sopenharmony_ci  V(JAVA_SCRIPT_BUILTIN_CONTINUATION, JavaScriptBuiltinContinuationFrame) \
1161cb0ef41Sopenharmony_ci  V(JAVA_SCRIPT_BUILTIN_CONTINUATION_WITH_CATCH,                          \
1171cb0ef41Sopenharmony_ci    JavaScriptBuiltinContinuationWithCatchFrame)                          \
1181cb0ef41Sopenharmony_ci  V(INTERNAL, InternalFrame)                                              \
1191cb0ef41Sopenharmony_ci  V(CONSTRUCT, ConstructFrame)                                            \
1201cb0ef41Sopenharmony_ci  V(BUILTIN, BuiltinFrame)                                                \
1211cb0ef41Sopenharmony_ci  V(BUILTIN_EXIT, BuiltinExitFrame)                                       \
1221cb0ef41Sopenharmony_ci  V(NATIVE, NativeFrame)
1231cb0ef41Sopenharmony_ci
1241cb0ef41Sopenharmony_ci// Abstract base class for all stack frames.
1251cb0ef41Sopenharmony_ciclass StackFrame {
1261cb0ef41Sopenharmony_ci public:
1271cb0ef41Sopenharmony_ci#define DECLARE_TYPE(type, ignore) type,
1281cb0ef41Sopenharmony_ci  enum Type {
1291cb0ef41Sopenharmony_ci    NO_FRAME_TYPE = 0,
1301cb0ef41Sopenharmony_ci    STACK_FRAME_TYPE_LIST(DECLARE_TYPE) NUMBER_OF_TYPES,
1311cb0ef41Sopenharmony_ci    // Used by FrameScope to indicate that the stack frame is constructed
1321cb0ef41Sopenharmony_ci    // manually and the FrameScope does not need to emit code.
1331cb0ef41Sopenharmony_ci    MANUAL
1341cb0ef41Sopenharmony_ci  };
1351cb0ef41Sopenharmony_ci#undef DECLARE_TYPE
1361cb0ef41Sopenharmony_ci
1371cb0ef41Sopenharmony_ci  // Used to mark the outermost JS entry frame.
1381cb0ef41Sopenharmony_ci  //
1391cb0ef41Sopenharmony_ci  // The mark is an opaque value that should be pushed onto the stack directly,
1401cb0ef41Sopenharmony_ci  // carefully crafted to not be interpreted as a tagged pointer.
1411cb0ef41Sopenharmony_ci  enum JsFrameMarker {
1421cb0ef41Sopenharmony_ci    INNER_JSENTRY_FRAME = (0 << kSmiTagSize) | kSmiTag,
1431cb0ef41Sopenharmony_ci    OUTERMOST_JSENTRY_FRAME = (1 << kSmiTagSize) | kSmiTag
1441cb0ef41Sopenharmony_ci  };
1451cb0ef41Sopenharmony_ci  STATIC_ASSERT((INNER_JSENTRY_FRAME & kHeapObjectTagMask) != kHeapObjectTag);
1461cb0ef41Sopenharmony_ci  STATIC_ASSERT((OUTERMOST_JSENTRY_FRAME & kHeapObjectTagMask) !=
1471cb0ef41Sopenharmony_ci                kHeapObjectTag);
1481cb0ef41Sopenharmony_ci
1491cb0ef41Sopenharmony_ci  struct State {
1501cb0ef41Sopenharmony_ci    Address sp = kNullAddress;
1511cb0ef41Sopenharmony_ci    Address fp = kNullAddress;
1521cb0ef41Sopenharmony_ci    Address* pc_address = nullptr;
1531cb0ef41Sopenharmony_ci    Address callee_fp = kNullAddress;
1541cb0ef41Sopenharmony_ci    Address* callee_pc_address = nullptr;
1551cb0ef41Sopenharmony_ci    Address* constant_pool_address = nullptr;
1561cb0ef41Sopenharmony_ci  };
1571cb0ef41Sopenharmony_ci
1581cb0ef41Sopenharmony_ci  // Convert a stack frame type to a marker that can be stored on the stack.
1591cb0ef41Sopenharmony_ci  //
1601cb0ef41Sopenharmony_ci  // The marker is an opaque value, not intended to be interpreted in any way
1611cb0ef41Sopenharmony_ci  // except being checked by IsTypeMarker or converted by MarkerToType.
1621cb0ef41Sopenharmony_ci  // It has the same tagging as Smis, so any marker value that does not pass
1631cb0ef41Sopenharmony_ci  // IsTypeMarker can instead be interpreted as a tagged pointer.
1641cb0ef41Sopenharmony_ci  //
1651cb0ef41Sopenharmony_ci  // Note that the marker is not a Smi: Smis on 64-bit architectures are stored
1661cb0ef41Sopenharmony_ci  // in the top 32 bits of a 64-bit value, which in turn makes them expensive
1671cb0ef41Sopenharmony_ci  // (in terms of code/instruction size) to push as immediates onto the stack.
1681cb0ef41Sopenharmony_ci  static int32_t TypeToMarker(Type type) {
1691cb0ef41Sopenharmony_ci    DCHECK_GE(type, 0);
1701cb0ef41Sopenharmony_ci    return (type << kSmiTagSize) | kSmiTag;
1711cb0ef41Sopenharmony_ci  }
1721cb0ef41Sopenharmony_ci
1731cb0ef41Sopenharmony_ci  // Convert a marker back to a stack frame type.
1741cb0ef41Sopenharmony_ci  //
1751cb0ef41Sopenharmony_ci  // Unlike the return value of TypeToMarker, this takes an intptr_t, as that is
1761cb0ef41Sopenharmony_ci  // the type of the value on the stack.
1771cb0ef41Sopenharmony_ci  static Type MarkerToType(intptr_t marker) {
1781cb0ef41Sopenharmony_ci    DCHECK(IsTypeMarker(marker));
1791cb0ef41Sopenharmony_ci    intptr_t type = marker >> kSmiTagSize;
1801cb0ef41Sopenharmony_ci    // TODO(petermarshall): There is a bug in the arm simulators that causes
1811cb0ef41Sopenharmony_ci    // invalid frame markers.
1821cb0ef41Sopenharmony_ci#if (defined(USE_SIMULATOR) &&                        \
1831cb0ef41Sopenharmony_ci     (V8_TARGET_ARCH_ARM64 || V8_TARGET_ARCH_ARM)) || \
1841cb0ef41Sopenharmony_ci    V8_TARGET_ARCH_RISCV64
1851cb0ef41Sopenharmony_ci    if (static_cast<uintptr_t>(type) >= Type::NUMBER_OF_TYPES) {
1861cb0ef41Sopenharmony_ci      // Appease UBSan.
1871cb0ef41Sopenharmony_ci      return Type::NUMBER_OF_TYPES;
1881cb0ef41Sopenharmony_ci    }
1891cb0ef41Sopenharmony_ci#else
1901cb0ef41Sopenharmony_ci    DCHECK_LT(static_cast<uintptr_t>(type), Type::NUMBER_OF_TYPES);
1911cb0ef41Sopenharmony_ci#endif
1921cb0ef41Sopenharmony_ci    return static_cast<Type>(type);
1931cb0ef41Sopenharmony_ci  }
1941cb0ef41Sopenharmony_ci
1951cb0ef41Sopenharmony_ci  // Check if a marker is a stack frame type marker or a tagged pointer.
1961cb0ef41Sopenharmony_ci  //
1971cb0ef41Sopenharmony_ci  // Returns true if the given marker is tagged as a stack frame type marker,
1981cb0ef41Sopenharmony_ci  // and should be converted back to a stack frame type using MarkerToType.
1991cb0ef41Sopenharmony_ci  // Otherwise, the value is a tagged function pointer.
2001cb0ef41Sopenharmony_ci  static bool IsTypeMarker(intptr_t function_or_marker) {
2011cb0ef41Sopenharmony_ci    return (function_or_marker & kSmiTagMask) == kSmiTag;
2021cb0ef41Sopenharmony_ci  }
2031cb0ef41Sopenharmony_ci
2041cb0ef41Sopenharmony_ci  // Copy constructor; it breaks the connection to host iterator
2051cb0ef41Sopenharmony_ci  // (as an iterator usually lives on stack).
2061cb0ef41Sopenharmony_ci  StackFrame(const StackFrame& original) V8_NOEXCEPT {
2071cb0ef41Sopenharmony_ci    this->state_ = original.state_;
2081cb0ef41Sopenharmony_ci    this->iterator_ = nullptr;
2091cb0ef41Sopenharmony_ci    this->isolate_ = original.isolate_;
2101cb0ef41Sopenharmony_ci  }
2111cb0ef41Sopenharmony_ci
2121cb0ef41Sopenharmony_ci  // Type testers.
2131cb0ef41Sopenharmony_ci  bool is_entry() const { return type() == ENTRY; }
2141cb0ef41Sopenharmony_ci  bool is_construct_entry() const { return type() == CONSTRUCT_ENTRY; }
2151cb0ef41Sopenharmony_ci  bool is_exit() const { return type() == EXIT; }
2161cb0ef41Sopenharmony_ci  bool is_optimized() const { return type() == OPTIMIZED; }
2171cb0ef41Sopenharmony_ci  bool is_unoptimized() const {
2181cb0ef41Sopenharmony_ci    STATIC_ASSERT(BASELINE == INTERPRETED + 1);
2191cb0ef41Sopenharmony_ci    return base::IsInRange(type(), INTERPRETED, BASELINE);
2201cb0ef41Sopenharmony_ci  }
2211cb0ef41Sopenharmony_ci  bool is_interpreted() const { return type() == INTERPRETED; }
2221cb0ef41Sopenharmony_ci  bool is_baseline() const { return type() == BASELINE; }
2231cb0ef41Sopenharmony_ci#if V8_ENABLE_WEBASSEMBLY
2241cb0ef41Sopenharmony_ci  bool is_wasm() const { return this->type() == WASM; }
2251cb0ef41Sopenharmony_ci  bool is_c_wasm_entry() const { return type() == C_WASM_ENTRY; }
2261cb0ef41Sopenharmony_ci  bool is_wasm_compile_lazy() const { return type() == WASM_COMPILE_LAZY; }
2271cb0ef41Sopenharmony_ci  bool is_wasm_debug_break() const { return type() == WASM_DEBUG_BREAK; }
2281cb0ef41Sopenharmony_ci  bool is_wasm_to_js() const { return type() == WASM_TO_JS; }
2291cb0ef41Sopenharmony_ci  bool is_js_to_wasm() const { return type() == JS_TO_WASM; }
2301cb0ef41Sopenharmony_ci#endif  // V8_ENABLE_WEBASSEMBLY
2311cb0ef41Sopenharmony_ci  bool is_builtin() const { return type() == BUILTIN; }
2321cb0ef41Sopenharmony_ci  bool is_internal() const { return type() == INTERNAL; }
2331cb0ef41Sopenharmony_ci  bool is_builtin_continuation() const {
2341cb0ef41Sopenharmony_ci    return type() == BUILTIN_CONTINUATION;
2351cb0ef41Sopenharmony_ci  }
2361cb0ef41Sopenharmony_ci  bool is_java_script_builtin_continuation() const {
2371cb0ef41Sopenharmony_ci    return type() == JAVA_SCRIPT_BUILTIN_CONTINUATION;
2381cb0ef41Sopenharmony_ci  }
2391cb0ef41Sopenharmony_ci  bool is_java_script_builtin_with_catch_continuation() const {
2401cb0ef41Sopenharmony_ci    return type() == JAVA_SCRIPT_BUILTIN_CONTINUATION_WITH_CATCH;
2411cb0ef41Sopenharmony_ci  }
2421cb0ef41Sopenharmony_ci  bool is_construct() const { return type() == CONSTRUCT; }
2431cb0ef41Sopenharmony_ci  bool is_builtin_exit() const { return type() == BUILTIN_EXIT; }
2441cb0ef41Sopenharmony_ci
2451cb0ef41Sopenharmony_ci  static bool IsJavaScript(Type t) {
2461cb0ef41Sopenharmony_ci    STATIC_ASSERT(INTERPRETED + 1 == BASELINE);
2471cb0ef41Sopenharmony_ci    STATIC_ASSERT(BASELINE + 1 == OPTIMIZED);
2481cb0ef41Sopenharmony_ci    return t >= INTERPRETED && t <= OPTIMIZED;
2491cb0ef41Sopenharmony_ci  }
2501cb0ef41Sopenharmony_ci  bool is_java_script() const { return IsJavaScript(type()); }
2511cb0ef41Sopenharmony_ci
2521cb0ef41Sopenharmony_ci  // Accessors.
2531cb0ef41Sopenharmony_ci  Address sp() const { return state_.sp; }
2541cb0ef41Sopenharmony_ci  Address fp() const { return state_.fp; }
2551cb0ef41Sopenharmony_ci  Address callee_fp() const { return state_.callee_fp; }
2561cb0ef41Sopenharmony_ci  inline Address callee_pc() const;
2571cb0ef41Sopenharmony_ci  Address caller_sp() const { return GetCallerStackPointer(); }
2581cb0ef41Sopenharmony_ci  inline Address pc() const;
2591cb0ef41Sopenharmony_ci
2601cb0ef41Sopenharmony_ci  // Skip authentication of the PC, when using CFI. Used in the profiler, where
2611cb0ef41Sopenharmony_ci  // in certain corner-cases we do not use an address on the stack, which would
2621cb0ef41Sopenharmony_ci  // be signed, as the PC of the frame.
2631cb0ef41Sopenharmony_ci  inline Address unauthenticated_pc() const;
2641cb0ef41Sopenharmony_ci
2651cb0ef41Sopenharmony_ci  Address constant_pool() const { return *constant_pool_address(); }
2661cb0ef41Sopenharmony_ci  void set_constant_pool(Address constant_pool) {
2671cb0ef41Sopenharmony_ci    *constant_pool_address() = constant_pool;
2681cb0ef41Sopenharmony_ci  }
2691cb0ef41Sopenharmony_ci
2701cb0ef41Sopenharmony_ci  Address* pc_address() const { return state_.pc_address; }
2711cb0ef41Sopenharmony_ci
2721cb0ef41Sopenharmony_ci  Address* constant_pool_address() const {
2731cb0ef41Sopenharmony_ci    return state_.constant_pool_address;
2741cb0ef41Sopenharmony_ci  }
2751cb0ef41Sopenharmony_ci
2761cb0ef41Sopenharmony_ci  // Get the id of this stack frame.
2771cb0ef41Sopenharmony_ci  StackFrameId id() const { return static_cast<StackFrameId>(caller_sp()); }
2781cb0ef41Sopenharmony_ci
2791cb0ef41Sopenharmony_ci  // Get the top handler from the current stack iterator.
2801cb0ef41Sopenharmony_ci  inline StackHandler* top_handler() const;
2811cb0ef41Sopenharmony_ci
2821cb0ef41Sopenharmony_ci  // Get the type of this frame.
2831cb0ef41Sopenharmony_ci  virtual Type type() const = 0;
2841cb0ef41Sopenharmony_ci
2851cb0ef41Sopenharmony_ci  // Get the code associated with this frame.
2861cb0ef41Sopenharmony_ci  // This method could be called during marking phase of GC.
2871cb0ef41Sopenharmony_ci  virtual Code unchecked_code() const = 0;
2881cb0ef41Sopenharmony_ci
2891cb0ef41Sopenharmony_ci  // Search for the code associated with this frame.
2901cb0ef41Sopenharmony_ci  V8_EXPORT_PRIVATE Code LookupCode() const;
2911cb0ef41Sopenharmony_ci
2921cb0ef41Sopenharmony_ci  virtual void Iterate(RootVisitor* v) const = 0;
2931cb0ef41Sopenharmony_ci  void IteratePc(RootVisitor* v, Address* pc_address,
2941cb0ef41Sopenharmony_ci                 Address* constant_pool_address, Code holder) const;
2951cb0ef41Sopenharmony_ci
2961cb0ef41Sopenharmony_ci  // Sets a callback function for return-address rewriting profilers
2971cb0ef41Sopenharmony_ci  // to resolve the location of a return address to the location of the
2981cb0ef41Sopenharmony_ci  // profiler's stashed return address.
2991cb0ef41Sopenharmony_ci  static void SetReturnAddressLocationResolver(
3001cb0ef41Sopenharmony_ci      ReturnAddressLocationResolver resolver);
3011cb0ef41Sopenharmony_ci
3021cb0ef41Sopenharmony_ci  static inline Address ReadPC(Address* pc_address);
3031cb0ef41Sopenharmony_ci
3041cb0ef41Sopenharmony_ci  // Resolves pc_address through the resolution address function if one is set.
3051cb0ef41Sopenharmony_ci  static inline Address* ResolveReturnAddressLocation(Address* pc_address);
3061cb0ef41Sopenharmony_ci
3071cb0ef41Sopenharmony_ci  // Printing support.
3081cb0ef41Sopenharmony_ci  enum PrintMode { OVERVIEW, DETAILS };
3091cb0ef41Sopenharmony_ci  virtual void Print(StringStream* accumulator, PrintMode mode,
3101cb0ef41Sopenharmony_ci                     int index) const;
3111cb0ef41Sopenharmony_ci
3121cb0ef41Sopenharmony_ci  Isolate* isolate() const { return isolate_; }
3131cb0ef41Sopenharmony_ci
3141cb0ef41Sopenharmony_ci  void operator=(const StackFrame& original) = delete;
3151cb0ef41Sopenharmony_ci
3161cb0ef41Sopenharmony_ci protected:
3171cb0ef41Sopenharmony_ci  inline explicit StackFrame(StackFrameIteratorBase* iterator);
3181cb0ef41Sopenharmony_ci  virtual ~StackFrame() = default;
3191cb0ef41Sopenharmony_ci
3201cb0ef41Sopenharmony_ci  // Compute the stack pointer for the calling frame.
3211cb0ef41Sopenharmony_ci  virtual Address GetCallerStackPointer() const = 0;
3221cb0ef41Sopenharmony_ci
3231cb0ef41Sopenharmony_ci  // Compute the stack frame type for the given state.
3241cb0ef41Sopenharmony_ci  static Type ComputeType(const StackFrameIteratorBase* iterator, State* state);
3251cb0ef41Sopenharmony_ci
3261cb0ef41Sopenharmony_ci#ifdef DEBUG
3271cb0ef41Sopenharmony_ci  bool can_access_heap_objects() const;
3281cb0ef41Sopenharmony_ci#endif
3291cb0ef41Sopenharmony_ci
3301cb0ef41Sopenharmony_ci private:
3311cb0ef41Sopenharmony_ci  const StackFrameIteratorBase* iterator_;
3321cb0ef41Sopenharmony_ci  Isolate* isolate_;
3331cb0ef41Sopenharmony_ci  State state_;
3341cb0ef41Sopenharmony_ci
3351cb0ef41Sopenharmony_ci  static ReturnAddressLocationResolver return_address_location_resolver_;
3361cb0ef41Sopenharmony_ci
3371cb0ef41Sopenharmony_ci  // Fill in the state of the calling frame.
3381cb0ef41Sopenharmony_ci  virtual void ComputeCallerState(State* state) const = 0;
3391cb0ef41Sopenharmony_ci
3401cb0ef41Sopenharmony_ci  // Get the type and the state of the calling frame.
3411cb0ef41Sopenharmony_ci  virtual Type GetCallerState(State* state) const;
3421cb0ef41Sopenharmony_ci
3431cb0ef41Sopenharmony_ci  static const intptr_t kIsolateTag = 1;
3441cb0ef41Sopenharmony_ci
3451cb0ef41Sopenharmony_ci  friend class StackFrameIterator;
3461cb0ef41Sopenharmony_ci  friend class StackFrameIteratorBase;
3471cb0ef41Sopenharmony_ci  friend class StackHandlerIterator;
3481cb0ef41Sopenharmony_ci  friend class SafeStackFrameIterator;
3491cb0ef41Sopenharmony_ci};
3501cb0ef41Sopenharmony_ci
3511cb0ef41Sopenharmony_ciclass CommonFrame;
3521cb0ef41Sopenharmony_ci
3531cb0ef41Sopenharmony_ciclass V8_EXPORT_PRIVATE FrameSummary {
3541cb0ef41Sopenharmony_ci public:
3551cb0ef41Sopenharmony_ci// Subclasses for the different summary kinds:
3561cb0ef41Sopenharmony_ci#define FRAME_SUMMARY_VARIANTS(F)                                          \
3571cb0ef41Sopenharmony_ci  F(JAVA_SCRIPT, JavaScriptFrameSummary, java_script_summary_, JavaScript) \
3581cb0ef41Sopenharmony_ci  IF_WASM(F, WASM, WasmFrameSummary, wasm_summary_, Wasm)
3591cb0ef41Sopenharmony_ci
3601cb0ef41Sopenharmony_ci#define FRAME_SUMMARY_KIND(kind, type, field, desc) kind,
3611cb0ef41Sopenharmony_ci  enum Kind { FRAME_SUMMARY_VARIANTS(FRAME_SUMMARY_KIND) };
3621cb0ef41Sopenharmony_ci#undef FRAME_SUMMARY_KIND
3631cb0ef41Sopenharmony_ci
3641cb0ef41Sopenharmony_ci  class FrameSummaryBase {
3651cb0ef41Sopenharmony_ci   public:
3661cb0ef41Sopenharmony_ci    FrameSummaryBase(Isolate* isolate, Kind kind)
3671cb0ef41Sopenharmony_ci        : isolate_(isolate), kind_(kind) {}
3681cb0ef41Sopenharmony_ci    Isolate* isolate() const { return isolate_; }
3691cb0ef41Sopenharmony_ci    Kind kind() const { return kind_; }
3701cb0ef41Sopenharmony_ci
3711cb0ef41Sopenharmony_ci   private:
3721cb0ef41Sopenharmony_ci    Isolate* isolate_;
3731cb0ef41Sopenharmony_ci    Kind kind_;
3741cb0ef41Sopenharmony_ci  };
3751cb0ef41Sopenharmony_ci
3761cb0ef41Sopenharmony_ci  class JavaScriptFrameSummary : public FrameSummaryBase {
3771cb0ef41Sopenharmony_ci   public:
3781cb0ef41Sopenharmony_ci    JavaScriptFrameSummary(Isolate* isolate, Object receiver,
3791cb0ef41Sopenharmony_ci                           JSFunction function, AbstractCode abstract_code,
3801cb0ef41Sopenharmony_ci                           int code_offset, bool is_constructor,
3811cb0ef41Sopenharmony_ci                           FixedArray parameters);
3821cb0ef41Sopenharmony_ci
3831cb0ef41Sopenharmony_ci    void EnsureSourcePositionsAvailable();
3841cb0ef41Sopenharmony_ci    bool AreSourcePositionsAvailable() const;
3851cb0ef41Sopenharmony_ci
3861cb0ef41Sopenharmony_ci    Handle<Object> receiver() const { return receiver_; }
3871cb0ef41Sopenharmony_ci    Handle<JSFunction> function() const { return function_; }
3881cb0ef41Sopenharmony_ci    Handle<AbstractCode> abstract_code() const { return abstract_code_; }
3891cb0ef41Sopenharmony_ci    int code_offset() const { return code_offset_; }
3901cb0ef41Sopenharmony_ci    bool is_constructor() const { return is_constructor_; }
3911cb0ef41Sopenharmony_ci    Handle<FixedArray> parameters() const { return parameters_; }
3921cb0ef41Sopenharmony_ci    bool is_subject_to_debugging() const;
3931cb0ef41Sopenharmony_ci    int SourcePosition() const;
3941cb0ef41Sopenharmony_ci    int SourceStatementPosition() const;
3951cb0ef41Sopenharmony_ci    Handle<Object> script() const;
3961cb0ef41Sopenharmony_ci    Handle<Context> native_context() const;
3971cb0ef41Sopenharmony_ci    Handle<StackFrameInfo> CreateStackFrameInfo() const;
3981cb0ef41Sopenharmony_ci
3991cb0ef41Sopenharmony_ci   private:
4001cb0ef41Sopenharmony_ci    Handle<Object> receiver_;
4011cb0ef41Sopenharmony_ci    Handle<JSFunction> function_;
4021cb0ef41Sopenharmony_ci    Handle<AbstractCode> abstract_code_;
4031cb0ef41Sopenharmony_ci    int code_offset_;
4041cb0ef41Sopenharmony_ci    bool is_constructor_;
4051cb0ef41Sopenharmony_ci    Handle<FixedArray> parameters_;
4061cb0ef41Sopenharmony_ci  };
4071cb0ef41Sopenharmony_ci
4081cb0ef41Sopenharmony_ci#if V8_ENABLE_WEBASSEMBLY
4091cb0ef41Sopenharmony_ci  class WasmFrameSummary : public FrameSummaryBase {
4101cb0ef41Sopenharmony_ci   public:
4111cb0ef41Sopenharmony_ci    WasmFrameSummary(Isolate*, Handle<WasmInstanceObject>, wasm::WasmCode*,
4121cb0ef41Sopenharmony_ci                     int code_offset, bool at_to_number_conversion);
4131cb0ef41Sopenharmony_ci
4141cb0ef41Sopenharmony_ci    Handle<Object> receiver() const;
4151cb0ef41Sopenharmony_ci    uint32_t function_index() const;
4161cb0ef41Sopenharmony_ci    wasm::WasmCode* code() const { return code_; }
4171cb0ef41Sopenharmony_ci    int code_offset() const { return code_offset_; }
4181cb0ef41Sopenharmony_ci    V8_EXPORT_PRIVATE int byte_offset() const;
4191cb0ef41Sopenharmony_ci    bool is_constructor() const { return false; }
4201cb0ef41Sopenharmony_ci    bool is_subject_to_debugging() const { return true; }
4211cb0ef41Sopenharmony_ci    int SourcePosition() const;
4221cb0ef41Sopenharmony_ci    int SourceStatementPosition() const { return SourcePosition(); }
4231cb0ef41Sopenharmony_ci    Handle<Script> script() const;
4241cb0ef41Sopenharmony_ci    Handle<WasmInstanceObject> wasm_instance() const { return wasm_instance_; }
4251cb0ef41Sopenharmony_ci    Handle<Context> native_context() const;
4261cb0ef41Sopenharmony_ci    bool at_to_number_conversion() const { return at_to_number_conversion_; }
4271cb0ef41Sopenharmony_ci    Handle<StackFrameInfo> CreateStackFrameInfo() const;
4281cb0ef41Sopenharmony_ci
4291cb0ef41Sopenharmony_ci   private:
4301cb0ef41Sopenharmony_ci    Handle<WasmInstanceObject> wasm_instance_;
4311cb0ef41Sopenharmony_ci    bool at_to_number_conversion_;
4321cb0ef41Sopenharmony_ci    wasm::WasmCode* const code_;
4331cb0ef41Sopenharmony_ci    int code_offset_;
4341cb0ef41Sopenharmony_ci  };
4351cb0ef41Sopenharmony_ci#endif  // V8_ENABLE_WEBASSEMBLY
4361cb0ef41Sopenharmony_ci
4371cb0ef41Sopenharmony_ci#define FRAME_SUMMARY_CONS(kind, type, field, desc) \
4381cb0ef41Sopenharmony_ci  FrameSummary(type summ) : field(summ) {}  // NOLINT
4391cb0ef41Sopenharmony_ci  FRAME_SUMMARY_VARIANTS(FRAME_SUMMARY_CONS)
4401cb0ef41Sopenharmony_ci#undef FRAME_SUMMARY_CONS
4411cb0ef41Sopenharmony_ci
4421cb0ef41Sopenharmony_ci  ~FrameSummary();
4431cb0ef41Sopenharmony_ci
4441cb0ef41Sopenharmony_ci  static FrameSummary GetTop(const CommonFrame* frame);
4451cb0ef41Sopenharmony_ci  static FrameSummary GetBottom(const CommonFrame* frame);
4461cb0ef41Sopenharmony_ci  static FrameSummary GetSingle(const CommonFrame* frame);
4471cb0ef41Sopenharmony_ci  static FrameSummary Get(const CommonFrame* frame, int index);
4481cb0ef41Sopenharmony_ci
4491cb0ef41Sopenharmony_ci  void EnsureSourcePositionsAvailable();
4501cb0ef41Sopenharmony_ci  bool AreSourcePositionsAvailable() const;
4511cb0ef41Sopenharmony_ci
4521cb0ef41Sopenharmony_ci  // Dispatched accessors.
4531cb0ef41Sopenharmony_ci  Handle<Object> receiver() const;
4541cb0ef41Sopenharmony_ci  int code_offset() const;
4551cb0ef41Sopenharmony_ci  bool is_constructor() const;
4561cb0ef41Sopenharmony_ci  bool is_subject_to_debugging() const;
4571cb0ef41Sopenharmony_ci  Handle<Object> script() const;
4581cb0ef41Sopenharmony_ci  int SourcePosition() const;
4591cb0ef41Sopenharmony_ci  int SourceStatementPosition() const;
4601cb0ef41Sopenharmony_ci  Handle<Context> native_context() const;
4611cb0ef41Sopenharmony_ci  Handle<StackFrameInfo> CreateStackFrameInfo() const;
4621cb0ef41Sopenharmony_ci
4631cb0ef41Sopenharmony_ci#define FRAME_SUMMARY_CAST(kind_, type, field, desc)      \
4641cb0ef41Sopenharmony_ci  bool Is##desc() const { return base_.kind() == kind_; } \
4651cb0ef41Sopenharmony_ci  const type& As##desc() const {                          \
4661cb0ef41Sopenharmony_ci    DCHECK_EQ(base_.kind(), kind_);                       \
4671cb0ef41Sopenharmony_ci    return field;                                         \
4681cb0ef41Sopenharmony_ci  }
4691cb0ef41Sopenharmony_ci  FRAME_SUMMARY_VARIANTS(FRAME_SUMMARY_CAST)
4701cb0ef41Sopenharmony_ci#undef FRAME_SUMMARY_CAST
4711cb0ef41Sopenharmony_ci
4721cb0ef41Sopenharmony_ci private:
4731cb0ef41Sopenharmony_ci#define FRAME_SUMMARY_FIELD(kind, type, field, desc) type field;
4741cb0ef41Sopenharmony_ci  union {
4751cb0ef41Sopenharmony_ci    FrameSummaryBase base_;
4761cb0ef41Sopenharmony_ci    FRAME_SUMMARY_VARIANTS(FRAME_SUMMARY_FIELD)
4771cb0ef41Sopenharmony_ci  };
4781cb0ef41Sopenharmony_ci#undef FRAME_SUMMARY_FIELD
4791cb0ef41Sopenharmony_ci};
4801cb0ef41Sopenharmony_ci
4811cb0ef41Sopenharmony_ciclass CommonFrame : public StackFrame {
4821cb0ef41Sopenharmony_ci public:
4831cb0ef41Sopenharmony_ci  // Accessors.
4841cb0ef41Sopenharmony_ci  virtual Object context()
4851cb0ef41Sopenharmony_ci      const;  // TODO(victorgomes): CommonFrames don't have context.
4861cb0ef41Sopenharmony_ci  virtual int position() const;
4871cb0ef41Sopenharmony_ci
4881cb0ef41Sopenharmony_ci  // Access the expressions in the stack frame including locals.
4891cb0ef41Sopenharmony_ci  inline Object GetExpression(int index) const;
4901cb0ef41Sopenharmony_ci  inline void SetExpression(int index, Object value);
4911cb0ef41Sopenharmony_ci  int ComputeExpressionsCount() const;
4921cb0ef41Sopenharmony_ci
4931cb0ef41Sopenharmony_ci  Address GetCallerStackPointer() const override;
4941cb0ef41Sopenharmony_ci
4951cb0ef41Sopenharmony_ci  // Build a list with summaries for this frame including all inlined frames.
4961cb0ef41Sopenharmony_ci  // The functions are ordered bottom-to-top (i.e. summaries.last() is the
4971cb0ef41Sopenharmony_ci  // top-most activation; caller comes before callee).
4981cb0ef41Sopenharmony_ci  virtual void Summarize(std::vector<FrameSummary>* frames) const;
4991cb0ef41Sopenharmony_ci
5001cb0ef41Sopenharmony_ci  static CommonFrame* cast(StackFrame* frame) {
5011cb0ef41Sopenharmony_ci    // It is always safe to cast to common.
5021cb0ef41Sopenharmony_ci    return static_cast<CommonFrame*>(frame);
5031cb0ef41Sopenharmony_ci  }
5041cb0ef41Sopenharmony_ci
5051cb0ef41Sopenharmony_ci protected:
5061cb0ef41Sopenharmony_ci  inline explicit CommonFrame(StackFrameIteratorBase* iterator);
5071cb0ef41Sopenharmony_ci
5081cb0ef41Sopenharmony_ci  void ComputeCallerState(State* state) const override;
5091cb0ef41Sopenharmony_ci
5101cb0ef41Sopenharmony_ci  // Accessors.
5111cb0ef41Sopenharmony_ci  inline Address caller_fp() const;
5121cb0ef41Sopenharmony_ci  inline Address caller_pc() const;
5131cb0ef41Sopenharmony_ci
5141cb0ef41Sopenharmony_ci  // Computes the address of the PC field in the standard frame given
5151cb0ef41Sopenharmony_ci  // by the provided frame pointer.
5161cb0ef41Sopenharmony_ci  static inline Address ComputePCAddress(Address fp);
5171cb0ef41Sopenharmony_ci
5181cb0ef41Sopenharmony_ci  // Computes the address of the constant pool  field in the standard
5191cb0ef41Sopenharmony_ci  // frame given by the provided frame pointer.
5201cb0ef41Sopenharmony_ci  static inline Address ComputeConstantPoolAddress(Address fp);
5211cb0ef41Sopenharmony_ci
5221cb0ef41Sopenharmony_ci  // Iterate over expression stack including stack handlers, locals,
5231cb0ef41Sopenharmony_ci  // and parts of the fixed part including context and code fields.
5241cb0ef41Sopenharmony_ci  void IterateExpressions(RootVisitor* v) const;
5251cb0ef41Sopenharmony_ci
5261cb0ef41Sopenharmony_ci  // Returns the address of the n'th expression stack element.
5271cb0ef41Sopenharmony_ci  virtual Address GetExpressionAddress(int n) const;
5281cb0ef41Sopenharmony_ci
5291cb0ef41Sopenharmony_ci  // Used by OptimizedFrames and StubFrames.
5301cb0ef41Sopenharmony_ci  void IterateCompiledFrame(RootVisitor* v) const;
5311cb0ef41Sopenharmony_ci
5321cb0ef41Sopenharmony_ci private:
5331cb0ef41Sopenharmony_ci  friend class StackFrame;
5341cb0ef41Sopenharmony_ci  friend class SafeStackFrameIterator;
5351cb0ef41Sopenharmony_ci};
5361cb0ef41Sopenharmony_ci
5371cb0ef41Sopenharmony_ciclass TypedFrame : public CommonFrame {
5381cb0ef41Sopenharmony_ci public:
5391cb0ef41Sopenharmony_ci  Code unchecked_code() const override { return {}; }
5401cb0ef41Sopenharmony_ci  void Iterate(RootVisitor* v) const override { IterateCompiledFrame(v); }
5411cb0ef41Sopenharmony_ci
5421cb0ef41Sopenharmony_ci protected:
5431cb0ef41Sopenharmony_ci  inline explicit TypedFrame(StackFrameIteratorBase* iterator);
5441cb0ef41Sopenharmony_ci};
5451cb0ef41Sopenharmony_ci
5461cb0ef41Sopenharmony_ciclass CommonFrameWithJSLinkage : public CommonFrame {
5471cb0ef41Sopenharmony_ci public:
5481cb0ef41Sopenharmony_ci  // Accessors.
5491cb0ef41Sopenharmony_ci  virtual JSFunction function() const = 0;
5501cb0ef41Sopenharmony_ci
5511cb0ef41Sopenharmony_ci  // Access the parameters.
5521cb0ef41Sopenharmony_ci  virtual Object receiver() const;
5531cb0ef41Sopenharmony_ci  virtual Object GetParameter(int index) const;
5541cb0ef41Sopenharmony_ci  virtual int ComputeParametersCount() const;
5551cb0ef41Sopenharmony_ci  Handle<FixedArray> GetParameters() const;
5561cb0ef41Sopenharmony_ci  virtual int GetActualArgumentCount() const;
5571cb0ef41Sopenharmony_ci
5581cb0ef41Sopenharmony_ci  // Determine the code for the frame.
5591cb0ef41Sopenharmony_ci  Code unchecked_code() const override;
5601cb0ef41Sopenharmony_ci
5611cb0ef41Sopenharmony_ci  // Lookup exception handler for current {pc}, returns -1 if none found. Also
5621cb0ef41Sopenharmony_ci  // returns data associated with the handler site specific to the frame type:
5631cb0ef41Sopenharmony_ci  //  - OptimizedFrame  : Data is not used and will not return a value.
5641cb0ef41Sopenharmony_ci  //  - UnoptimizedFrame: Data is the register index holding the context.
5651cb0ef41Sopenharmony_ci  virtual int LookupExceptionHandlerInTable(
5661cb0ef41Sopenharmony_ci      int* data, HandlerTable::CatchPrediction* prediction);
5671cb0ef41Sopenharmony_ci
5681cb0ef41Sopenharmony_ci  // Check if this frame is a constructor frame invoked through 'new'.
5691cb0ef41Sopenharmony_ci  virtual bool IsConstructor() const;
5701cb0ef41Sopenharmony_ci
5711cb0ef41Sopenharmony_ci  // Summarize Frame
5721cb0ef41Sopenharmony_ci  void Summarize(std::vector<FrameSummary>* frames) const override;
5731cb0ef41Sopenharmony_ci
5741cb0ef41Sopenharmony_ci protected:
5751cb0ef41Sopenharmony_ci  inline explicit CommonFrameWithJSLinkage(StackFrameIteratorBase* iterator);
5761cb0ef41Sopenharmony_ci
5771cb0ef41Sopenharmony_ci  // Determines if the standard frame for the given frame pointer is a
5781cb0ef41Sopenharmony_ci  // construct frame.
5791cb0ef41Sopenharmony_ci  static inline bool IsConstructFrame(Address fp);
5801cb0ef41Sopenharmony_ci  inline Address GetParameterSlot(int index) const;
5811cb0ef41Sopenharmony_ci};
5821cb0ef41Sopenharmony_ci
5831cb0ef41Sopenharmony_ciclass TypedFrameWithJSLinkage : public CommonFrameWithJSLinkage {
5841cb0ef41Sopenharmony_ci public:
5851cb0ef41Sopenharmony_ci  void Iterate(RootVisitor* v) const override;
5861cb0ef41Sopenharmony_ci
5871cb0ef41Sopenharmony_ci protected:
5881cb0ef41Sopenharmony_ci  inline explicit TypedFrameWithJSLinkage(StackFrameIteratorBase* iterator);
5891cb0ef41Sopenharmony_ci};
5901cb0ef41Sopenharmony_ci
5911cb0ef41Sopenharmony_ciclass JavaScriptFrame : public CommonFrameWithJSLinkage {
5921cb0ef41Sopenharmony_ci public:
5931cb0ef41Sopenharmony_ci  Type type() const override = 0;
5941cb0ef41Sopenharmony_ci
5951cb0ef41Sopenharmony_ci  // Accessors.
5961cb0ef41Sopenharmony_ci  JSFunction function() const override;
5971cb0ef41Sopenharmony_ci  Object unchecked_function() const;
5981cb0ef41Sopenharmony_ci  Script script() const;
5991cb0ef41Sopenharmony_ci  Object context() const override;
6001cb0ef41Sopenharmony_ci  int GetActualArgumentCount() const override;
6011cb0ef41Sopenharmony_ci
6021cb0ef41Sopenharmony_ci  inline void set_receiver(Object value);
6031cb0ef41Sopenharmony_ci
6041cb0ef41Sopenharmony_ci  // Debugger access.
6051cb0ef41Sopenharmony_ci  void SetParameterValue(int index, Object value) const;
6061cb0ef41Sopenharmony_ci
6071cb0ef41Sopenharmony_ci  // Check if this frame is a constructor frame invoked through 'new'.
6081cb0ef41Sopenharmony_ci  bool IsConstructor() const override;
6091cb0ef41Sopenharmony_ci
6101cb0ef41Sopenharmony_ci  // Determines whether this frame includes inlined activations. To get details
6111cb0ef41Sopenharmony_ci  // about the inlined frames use {GetFunctions} and {Summarize}.
6121cb0ef41Sopenharmony_ci  bool HasInlinedFrames() const;
6131cb0ef41Sopenharmony_ci
6141cb0ef41Sopenharmony_ci  // Garbage collection support.
6151cb0ef41Sopenharmony_ci  void Iterate(RootVisitor* v) const override;
6161cb0ef41Sopenharmony_ci
6171cb0ef41Sopenharmony_ci  // Printing support.
6181cb0ef41Sopenharmony_ci  void Print(StringStream* accumulator, PrintMode mode,
6191cb0ef41Sopenharmony_ci             int index) const override;
6201cb0ef41Sopenharmony_ci
6211cb0ef41Sopenharmony_ci  // Return a list with {SharedFunctionInfo} objects of this frame.
6221cb0ef41Sopenharmony_ci  virtual void GetFunctions(std::vector<SharedFunctionInfo>* functions) const;
6231cb0ef41Sopenharmony_ci
6241cb0ef41Sopenharmony_ci  void GetFunctions(std::vector<Handle<SharedFunctionInfo>>* functions) const;
6251cb0ef41Sopenharmony_ci
6261cb0ef41Sopenharmony_ci  // Architecture-specific register description.
6271cb0ef41Sopenharmony_ci  static Register fp_register();
6281cb0ef41Sopenharmony_ci  static Register context_register();
6291cb0ef41Sopenharmony_ci  static Register constant_pool_pointer_register();
6301cb0ef41Sopenharmony_ci
6311cb0ef41Sopenharmony_ci  static JavaScriptFrame* cast(StackFrame* frame) {
6321cb0ef41Sopenharmony_ci    DCHECK(frame->is_java_script());
6331cb0ef41Sopenharmony_ci    return static_cast<JavaScriptFrame*>(frame);
6341cb0ef41Sopenharmony_ci  }
6351cb0ef41Sopenharmony_ci
6361cb0ef41Sopenharmony_ci  static void PrintFunctionAndOffset(JSFunction function, AbstractCode code,
6371cb0ef41Sopenharmony_ci                                     int code_offset, FILE* file,
6381cb0ef41Sopenharmony_ci                                     bool print_line_number);
6391cb0ef41Sopenharmony_ci
6401cb0ef41Sopenharmony_ci  static void PrintTop(Isolate* isolate, FILE* file, bool print_args,
6411cb0ef41Sopenharmony_ci                       bool print_line_number);
6421cb0ef41Sopenharmony_ci
6431cb0ef41Sopenharmony_ci  static void CollectFunctionAndOffsetForICStats(JSFunction function,
6441cb0ef41Sopenharmony_ci                                                 AbstractCode code,
6451cb0ef41Sopenharmony_ci                                                 int code_offset);
6461cb0ef41Sopenharmony_ci
6471cb0ef41Sopenharmony_ci protected:
6481cb0ef41Sopenharmony_ci  inline explicit JavaScriptFrame(StackFrameIteratorBase* iterator);
6491cb0ef41Sopenharmony_ci
6501cb0ef41Sopenharmony_ci  Address GetCallerStackPointer() const override;
6511cb0ef41Sopenharmony_ci
6521cb0ef41Sopenharmony_ci  virtual void PrintFrameKind(StringStream* accumulator) const {}
6531cb0ef41Sopenharmony_ci
6541cb0ef41Sopenharmony_ci private:
6551cb0ef41Sopenharmony_ci  inline Object function_slot_object() const;
6561cb0ef41Sopenharmony_ci
6571cb0ef41Sopenharmony_ci  friend class StackFrameIteratorBase;
6581cb0ef41Sopenharmony_ci};
6591cb0ef41Sopenharmony_ci
6601cb0ef41Sopenharmony_ciclass NativeFrame : public TypedFrame {
6611cb0ef41Sopenharmony_ci public:
6621cb0ef41Sopenharmony_ci  Type type() const override { return NATIVE; }
6631cb0ef41Sopenharmony_ci
6641cb0ef41Sopenharmony_ci  // Garbage collection support.
6651cb0ef41Sopenharmony_ci  void Iterate(RootVisitor* v) const override {}
6661cb0ef41Sopenharmony_ci
6671cb0ef41Sopenharmony_ci protected:
6681cb0ef41Sopenharmony_ci  inline explicit NativeFrame(StackFrameIteratorBase* iterator);
6691cb0ef41Sopenharmony_ci
6701cb0ef41Sopenharmony_ci private:
6711cb0ef41Sopenharmony_ci  void ComputeCallerState(State* state) const override;
6721cb0ef41Sopenharmony_ci
6731cb0ef41Sopenharmony_ci  friend class StackFrameIteratorBase;
6741cb0ef41Sopenharmony_ci};
6751cb0ef41Sopenharmony_ci
6761cb0ef41Sopenharmony_ci// Entry frames are used to enter JavaScript execution from C.
6771cb0ef41Sopenharmony_ciclass EntryFrame : public TypedFrame {
6781cb0ef41Sopenharmony_ci public:
6791cb0ef41Sopenharmony_ci  Type type() const override { return ENTRY; }
6801cb0ef41Sopenharmony_ci
6811cb0ef41Sopenharmony_ci  Code unchecked_code() const override;
6821cb0ef41Sopenharmony_ci
6831cb0ef41Sopenharmony_ci  // Garbage collection support.
6841cb0ef41Sopenharmony_ci  void Iterate(RootVisitor* v) const override;
6851cb0ef41Sopenharmony_ci
6861cb0ef41Sopenharmony_ci  static EntryFrame* cast(StackFrame* frame) {
6871cb0ef41Sopenharmony_ci    DCHECK(frame->is_entry());
6881cb0ef41Sopenharmony_ci    return static_cast<EntryFrame*>(frame);
6891cb0ef41Sopenharmony_ci  }
6901cb0ef41Sopenharmony_ci
6911cb0ef41Sopenharmony_ci protected:
6921cb0ef41Sopenharmony_ci  inline explicit EntryFrame(StackFrameIteratorBase* iterator);
6931cb0ef41Sopenharmony_ci
6941cb0ef41Sopenharmony_ci  // The caller stack pointer for entry frames is always zero. The
6951cb0ef41Sopenharmony_ci  // real information about the caller frame is available through the
6961cb0ef41Sopenharmony_ci  // link to the top exit frame.
6971cb0ef41Sopenharmony_ci  Address GetCallerStackPointer() const override { return 0; }
6981cb0ef41Sopenharmony_ci
6991cb0ef41Sopenharmony_ci private:
7001cb0ef41Sopenharmony_ci  void ComputeCallerState(State* state) const override;
7011cb0ef41Sopenharmony_ci  Type GetCallerState(State* state) const override;
7021cb0ef41Sopenharmony_ci
7031cb0ef41Sopenharmony_ci  friend class StackFrameIteratorBase;
7041cb0ef41Sopenharmony_ci};
7051cb0ef41Sopenharmony_ci
7061cb0ef41Sopenharmony_ciclass ConstructEntryFrame : public EntryFrame {
7071cb0ef41Sopenharmony_ci public:
7081cb0ef41Sopenharmony_ci  Type type() const override { return CONSTRUCT_ENTRY; }
7091cb0ef41Sopenharmony_ci
7101cb0ef41Sopenharmony_ci  Code unchecked_code() const override;
7111cb0ef41Sopenharmony_ci
7121cb0ef41Sopenharmony_ci  static ConstructEntryFrame* cast(StackFrame* frame) {
7131cb0ef41Sopenharmony_ci    DCHECK(frame->is_construct_entry());
7141cb0ef41Sopenharmony_ci    return static_cast<ConstructEntryFrame*>(frame);
7151cb0ef41Sopenharmony_ci  }
7161cb0ef41Sopenharmony_ci
7171cb0ef41Sopenharmony_ci protected:
7181cb0ef41Sopenharmony_ci  inline explicit ConstructEntryFrame(StackFrameIteratorBase* iterator);
7191cb0ef41Sopenharmony_ci
7201cb0ef41Sopenharmony_ci private:
7211cb0ef41Sopenharmony_ci  friend class StackFrameIteratorBase;
7221cb0ef41Sopenharmony_ci};
7231cb0ef41Sopenharmony_ci
7241cb0ef41Sopenharmony_ci// Exit frames are used to exit JavaScript execution and go to C, or to switch
7251cb0ef41Sopenharmony_ci// out of the current stack for wasm stack-switching.
7261cb0ef41Sopenharmony_ciclass ExitFrame : public TypedFrame {
7271cb0ef41Sopenharmony_ci public:
7281cb0ef41Sopenharmony_ci  Type type() const override { return EXIT; }
7291cb0ef41Sopenharmony_ci
7301cb0ef41Sopenharmony_ci  // Garbage collection support.
7311cb0ef41Sopenharmony_ci  void Iterate(RootVisitor* v) const override;
7321cb0ef41Sopenharmony_ci
7331cb0ef41Sopenharmony_ci  static ExitFrame* cast(StackFrame* frame) {
7341cb0ef41Sopenharmony_ci    DCHECK(frame->is_exit());
7351cb0ef41Sopenharmony_ci    return static_cast<ExitFrame*>(frame);
7361cb0ef41Sopenharmony_ci  }
7371cb0ef41Sopenharmony_ci
7381cb0ef41Sopenharmony_ci  // Compute the state and type of an exit frame given a frame
7391cb0ef41Sopenharmony_ci  // pointer. Used when constructing the first stack frame seen by an
7401cb0ef41Sopenharmony_ci  // iterator and the frames following entry frames.
7411cb0ef41Sopenharmony_ci  static Type GetStateForFramePointer(Address fp, State* state);
7421cb0ef41Sopenharmony_ci  static Address ComputeStackPointer(Address fp);
7431cb0ef41Sopenharmony_ci  static StackFrame::Type ComputeFrameType(Address fp);
7441cb0ef41Sopenharmony_ci  static void FillState(Address fp, Address sp, State* state);
7451cb0ef41Sopenharmony_ci
7461cb0ef41Sopenharmony_ci protected:
7471cb0ef41Sopenharmony_ci  inline explicit ExitFrame(StackFrameIteratorBase* iterator);
7481cb0ef41Sopenharmony_ci
7491cb0ef41Sopenharmony_ci private:
7501cb0ef41Sopenharmony_ci  void ComputeCallerState(State* state) const override;
7511cb0ef41Sopenharmony_ci
7521cb0ef41Sopenharmony_ci  friend class StackFrameIteratorBase;
7531cb0ef41Sopenharmony_ci};
7541cb0ef41Sopenharmony_ci
7551cb0ef41Sopenharmony_ci// Builtin exit frames are a special case of exit frames, which are used
7561cb0ef41Sopenharmony_ci// whenever C++ builtins (e.g., Math.acos) are called. Their main purpose is
7571cb0ef41Sopenharmony_ci// to allow such builtins to appear in stack traces.
7581cb0ef41Sopenharmony_ciclass BuiltinExitFrame : public ExitFrame {
7591cb0ef41Sopenharmony_ci public:
7601cb0ef41Sopenharmony_ci  Type type() const override { return BUILTIN_EXIT; }
7611cb0ef41Sopenharmony_ci
7621cb0ef41Sopenharmony_ci  JSFunction function() const;
7631cb0ef41Sopenharmony_ci
7641cb0ef41Sopenharmony_ci  Object receiver() const;
7651cb0ef41Sopenharmony_ci  Object GetParameter(int i) const;
7661cb0ef41Sopenharmony_ci  int ComputeParametersCount() const;
7671cb0ef41Sopenharmony_ci  Handle<FixedArray> GetParameters() const;
7681cb0ef41Sopenharmony_ci
7691cb0ef41Sopenharmony_ci  // Check if this frame is a constructor frame invoked through 'new'.
7701cb0ef41Sopenharmony_ci  bool IsConstructor() const;
7711cb0ef41Sopenharmony_ci
7721cb0ef41Sopenharmony_ci  void Print(StringStream* accumulator, PrintMode mode,
7731cb0ef41Sopenharmony_ci             int index) const override;
7741cb0ef41Sopenharmony_ci
7751cb0ef41Sopenharmony_ci  // Summarize Frame
7761cb0ef41Sopenharmony_ci  void Summarize(std::vector<FrameSummary>* frames) const override;
7771cb0ef41Sopenharmony_ci
7781cb0ef41Sopenharmony_ci protected:
7791cb0ef41Sopenharmony_ci  inline explicit BuiltinExitFrame(StackFrameIteratorBase* iterator);
7801cb0ef41Sopenharmony_ci
7811cb0ef41Sopenharmony_ci private:
7821cb0ef41Sopenharmony_ci  inline Object receiver_slot_object() const;
7831cb0ef41Sopenharmony_ci  inline Object argc_slot_object() const;
7841cb0ef41Sopenharmony_ci  inline Object target_slot_object() const;
7851cb0ef41Sopenharmony_ci  inline Object new_target_slot_object() const;
7861cb0ef41Sopenharmony_ci
7871cb0ef41Sopenharmony_ci  friend class StackFrameIteratorBase;
7881cb0ef41Sopenharmony_ci};
7891cb0ef41Sopenharmony_ci
7901cb0ef41Sopenharmony_ciclass StubFrame : public TypedFrame {
7911cb0ef41Sopenharmony_ci public:
7921cb0ef41Sopenharmony_ci  Type type() const override { return STUB; }
7931cb0ef41Sopenharmony_ci
7941cb0ef41Sopenharmony_ci  // Determine the code for the frame.
7951cb0ef41Sopenharmony_ci  Code unchecked_code() const override;
7961cb0ef41Sopenharmony_ci
7971cb0ef41Sopenharmony_ci  // Lookup exception handler for current {pc}, returns -1 if none found. Only
7981cb0ef41Sopenharmony_ci  // TurboFan stub frames are supported.
7991cb0ef41Sopenharmony_ci  int LookupExceptionHandlerInTable();
8001cb0ef41Sopenharmony_ci
8011cb0ef41Sopenharmony_ci protected:
8021cb0ef41Sopenharmony_ci  inline explicit StubFrame(StackFrameIteratorBase* iterator);
8031cb0ef41Sopenharmony_ci
8041cb0ef41Sopenharmony_ci private:
8051cb0ef41Sopenharmony_ci  friend class StackFrameIteratorBase;
8061cb0ef41Sopenharmony_ci};
8071cb0ef41Sopenharmony_ci
8081cb0ef41Sopenharmony_ciclass OptimizedFrame : public JavaScriptFrame {
8091cb0ef41Sopenharmony_ci public:
8101cb0ef41Sopenharmony_ci  Type type() const override { return OPTIMIZED; }
8111cb0ef41Sopenharmony_ci
8121cb0ef41Sopenharmony_ci  // GC support.
8131cb0ef41Sopenharmony_ci  void Iterate(RootVisitor* v) const override;
8141cb0ef41Sopenharmony_ci
8151cb0ef41Sopenharmony_ci  // Return a list with {SharedFunctionInfo} objects of this frame.
8161cb0ef41Sopenharmony_ci  // The functions are ordered bottom-to-top (i.e. functions.last()
8171cb0ef41Sopenharmony_ci  // is the top-most activation)
8181cb0ef41Sopenharmony_ci  void GetFunctions(std::vector<SharedFunctionInfo>* functions) const override;
8191cb0ef41Sopenharmony_ci
8201cb0ef41Sopenharmony_ci  void Summarize(std::vector<FrameSummary>* frames) const override;
8211cb0ef41Sopenharmony_ci
8221cb0ef41Sopenharmony_ci  // Lookup exception handler for current {pc}, returns -1 if none found.
8231cb0ef41Sopenharmony_ci  int LookupExceptionHandlerInTable(
8241cb0ef41Sopenharmony_ci      int* data, HandlerTable::CatchPrediction* prediction) override;
8251cb0ef41Sopenharmony_ci
8261cb0ef41Sopenharmony_ci  DeoptimizationData GetDeoptimizationData(int* deopt_index) const;
8271cb0ef41Sopenharmony_ci
8281cb0ef41Sopenharmony_ci  int ComputeParametersCount() const override;
8291cb0ef41Sopenharmony_ci
8301cb0ef41Sopenharmony_ci  static int StackSlotOffsetRelativeToFp(int slot_index);
8311cb0ef41Sopenharmony_ci
8321cb0ef41Sopenharmony_ci protected:
8331cb0ef41Sopenharmony_ci  inline explicit OptimizedFrame(StackFrameIteratorBase* iterator);
8341cb0ef41Sopenharmony_ci
8351cb0ef41Sopenharmony_ci private:
8361cb0ef41Sopenharmony_ci  friend class StackFrameIteratorBase;
8371cb0ef41Sopenharmony_ci
8381cb0ef41Sopenharmony_ci  Object StackSlotAt(int index) const;
8391cb0ef41Sopenharmony_ci};
8401cb0ef41Sopenharmony_ci
8411cb0ef41Sopenharmony_ci// An unoptimized frame is a JavaScript frame that is executing bytecode. It
8421cb0ef41Sopenharmony_ci// may be executing it using the interpreter, or via baseline code compiled from
8431cb0ef41Sopenharmony_ci// the bytecode.
8441cb0ef41Sopenharmony_ciclass UnoptimizedFrame : public JavaScriptFrame {
8451cb0ef41Sopenharmony_ci public:
8461cb0ef41Sopenharmony_ci  // Accessors.
8471cb0ef41Sopenharmony_ci  int position() const override;
8481cb0ef41Sopenharmony_ci
8491cb0ef41Sopenharmony_ci  // Lookup exception handler for current {pc}, returns -1 if none found.
8501cb0ef41Sopenharmony_ci  int LookupExceptionHandlerInTable(
8511cb0ef41Sopenharmony_ci      int* data, HandlerTable::CatchPrediction* prediction) override;
8521cb0ef41Sopenharmony_ci
8531cb0ef41Sopenharmony_ci  // Returns the current offset into the bytecode stream.
8541cb0ef41Sopenharmony_ci  virtual int GetBytecodeOffset() const = 0;
8551cb0ef41Sopenharmony_ci
8561cb0ef41Sopenharmony_ci  // Returns the frame's current bytecode array.
8571cb0ef41Sopenharmony_ci  BytecodeArray GetBytecodeArray() const;
8581cb0ef41Sopenharmony_ci
8591cb0ef41Sopenharmony_ci  // Access to the interpreter register file for this frame.
8601cb0ef41Sopenharmony_ci  Object ReadInterpreterRegister(int register_index) const;
8611cb0ef41Sopenharmony_ci
8621cb0ef41Sopenharmony_ci  // Build a list with summaries for this frame including all inlined frames.
8631cb0ef41Sopenharmony_ci  void Summarize(std::vector<FrameSummary>* frames) const override;
8641cb0ef41Sopenharmony_ci
8651cb0ef41Sopenharmony_ci  static UnoptimizedFrame* cast(StackFrame* frame) {
8661cb0ef41Sopenharmony_ci    DCHECK(frame->is_unoptimized());
8671cb0ef41Sopenharmony_ci    return static_cast<UnoptimizedFrame*>(frame);
8681cb0ef41Sopenharmony_ci  }
8691cb0ef41Sopenharmony_ci
8701cb0ef41Sopenharmony_ci protected:
8711cb0ef41Sopenharmony_ci  inline explicit UnoptimizedFrame(StackFrameIteratorBase* iterator);
8721cb0ef41Sopenharmony_ci
8731cb0ef41Sopenharmony_ci  Address GetExpressionAddress(int n) const override;
8741cb0ef41Sopenharmony_ci
8751cb0ef41Sopenharmony_ci private:
8761cb0ef41Sopenharmony_ci  friend class StackFrameIteratorBase;
8771cb0ef41Sopenharmony_ci};
8781cb0ef41Sopenharmony_ci
8791cb0ef41Sopenharmony_ciclass InterpretedFrame : public UnoptimizedFrame {
8801cb0ef41Sopenharmony_ci public:
8811cb0ef41Sopenharmony_ci  Type type() const override { return INTERPRETED; }
8821cb0ef41Sopenharmony_ci
8831cb0ef41Sopenharmony_ci  // Returns the current offset into the bytecode stream.
8841cb0ef41Sopenharmony_ci  int GetBytecodeOffset() const override;
8851cb0ef41Sopenharmony_ci
8861cb0ef41Sopenharmony_ci  // Updates the current offset into the bytecode stream, mainly used for stack
8871cb0ef41Sopenharmony_ci  // unwinding to continue execution at a different bytecode offset.
8881cb0ef41Sopenharmony_ci  void PatchBytecodeOffset(int new_offset);
8891cb0ef41Sopenharmony_ci
8901cb0ef41Sopenharmony_ci  // Updates the frame's BytecodeArray with |bytecode_array|. Used by the
8911cb0ef41Sopenharmony_ci  // debugger to swap execution onto a BytecodeArray patched with breakpoints.
8921cb0ef41Sopenharmony_ci  void PatchBytecodeArray(BytecodeArray bytecode_array);
8931cb0ef41Sopenharmony_ci
8941cb0ef41Sopenharmony_ci  static InterpretedFrame* cast(StackFrame* frame) {
8951cb0ef41Sopenharmony_ci    DCHECK(frame->is_interpreted());
8961cb0ef41Sopenharmony_ci    return static_cast<InterpretedFrame*>(frame);
8971cb0ef41Sopenharmony_ci  }
8981cb0ef41Sopenharmony_ci  static const InterpretedFrame* cast(const StackFrame* frame) {
8991cb0ef41Sopenharmony_ci    DCHECK(frame->is_interpreted());
9001cb0ef41Sopenharmony_ci    return static_cast<const InterpretedFrame*>(frame);
9011cb0ef41Sopenharmony_ci  }
9021cb0ef41Sopenharmony_ci
9031cb0ef41Sopenharmony_ci  static int GetBytecodeOffset(Address fp);
9041cb0ef41Sopenharmony_ci
9051cb0ef41Sopenharmony_ci protected:
9061cb0ef41Sopenharmony_ci  inline explicit InterpretedFrame(StackFrameIteratorBase* iterator);
9071cb0ef41Sopenharmony_ci
9081cb0ef41Sopenharmony_ci private:
9091cb0ef41Sopenharmony_ci  friend class StackFrameIteratorBase;
9101cb0ef41Sopenharmony_ci};
9111cb0ef41Sopenharmony_ci
9121cb0ef41Sopenharmony_ciclass BaselineFrame : public UnoptimizedFrame {
9131cb0ef41Sopenharmony_ci public:
9141cb0ef41Sopenharmony_ci  Type type() const override { return BASELINE; }
9151cb0ef41Sopenharmony_ci
9161cb0ef41Sopenharmony_ci  // Returns the current offset into the bytecode stream.
9171cb0ef41Sopenharmony_ci  int GetBytecodeOffset() const override;
9181cb0ef41Sopenharmony_ci
9191cb0ef41Sopenharmony_ci  intptr_t GetPCForBytecodeOffset(int lookup_offset) const;
9201cb0ef41Sopenharmony_ci
9211cb0ef41Sopenharmony_ci  void PatchContext(Context value);
9221cb0ef41Sopenharmony_ci
9231cb0ef41Sopenharmony_ci  static BaselineFrame* cast(StackFrame* frame) {
9241cb0ef41Sopenharmony_ci    DCHECK(frame->is_baseline());
9251cb0ef41Sopenharmony_ci    return static_cast<BaselineFrame*>(frame);
9261cb0ef41Sopenharmony_ci  }
9271cb0ef41Sopenharmony_ci
9281cb0ef41Sopenharmony_ci protected:
9291cb0ef41Sopenharmony_ci  inline explicit BaselineFrame(StackFrameIteratorBase* iterator);
9301cb0ef41Sopenharmony_ci
9311cb0ef41Sopenharmony_ci private:
9321cb0ef41Sopenharmony_ci  friend class StackFrameIteratorBase;
9331cb0ef41Sopenharmony_ci};
9341cb0ef41Sopenharmony_ci
9351cb0ef41Sopenharmony_ci// Builtin frames are built for builtins with JavaScript linkage, such as
9361cb0ef41Sopenharmony_ci// various standard library functions (i.e. Math.asin, Math.floor, etc.).
9371cb0ef41Sopenharmony_ciclass BuiltinFrame final : public TypedFrameWithJSLinkage {
9381cb0ef41Sopenharmony_ci public:
9391cb0ef41Sopenharmony_ci  Type type() const final { return BUILTIN; }
9401cb0ef41Sopenharmony_ci
9411cb0ef41Sopenharmony_ci  static BuiltinFrame* cast(StackFrame* frame) {
9421cb0ef41Sopenharmony_ci    DCHECK(frame->is_builtin());
9431cb0ef41Sopenharmony_ci    return static_cast<BuiltinFrame*>(frame);
9441cb0ef41Sopenharmony_ci  }
9451cb0ef41Sopenharmony_ci
9461cb0ef41Sopenharmony_ci  JSFunction function() const override;
9471cb0ef41Sopenharmony_ci  int ComputeParametersCount() const override;
9481cb0ef41Sopenharmony_ci
9491cb0ef41Sopenharmony_ci protected:
9501cb0ef41Sopenharmony_ci  inline explicit BuiltinFrame(StackFrameIteratorBase* iterator);
9511cb0ef41Sopenharmony_ci
9521cb0ef41Sopenharmony_ci private:
9531cb0ef41Sopenharmony_ci  friend class StackFrameIteratorBase;
9541cb0ef41Sopenharmony_ci};
9551cb0ef41Sopenharmony_ci
9561cb0ef41Sopenharmony_ci#if V8_ENABLE_WEBASSEMBLY
9571cb0ef41Sopenharmony_ciclass WasmFrame : public TypedFrame {
9581cb0ef41Sopenharmony_ci public:
9591cb0ef41Sopenharmony_ci  Type type() const override { return WASM; }
9601cb0ef41Sopenharmony_ci
9611cb0ef41Sopenharmony_ci  // Printing support.
9621cb0ef41Sopenharmony_ci  void Print(StringStream* accumulator, PrintMode mode,
9631cb0ef41Sopenharmony_ci             int index) const override;
9641cb0ef41Sopenharmony_ci
9651cb0ef41Sopenharmony_ci  // Lookup exception handler for current {pc}, returns -1 if none found.
9661cb0ef41Sopenharmony_ci  int LookupExceptionHandlerInTable();
9671cb0ef41Sopenharmony_ci
9681cb0ef41Sopenharmony_ci  // Accessors.
9691cb0ef41Sopenharmony_ci  V8_EXPORT_PRIVATE WasmInstanceObject wasm_instance() const;
9701cb0ef41Sopenharmony_ci  V8_EXPORT_PRIVATE wasm::NativeModule* native_module() const;
9711cb0ef41Sopenharmony_ci  wasm::WasmCode* wasm_code() const;
9721cb0ef41Sopenharmony_ci  int function_index() const;
9731cb0ef41Sopenharmony_ci  Script script() const;
9741cb0ef41Sopenharmony_ci  // Byte position in the module, or asm.js source position.
9751cb0ef41Sopenharmony_ci  int position() const override;
9761cb0ef41Sopenharmony_ci  Object context() const override;
9771cb0ef41Sopenharmony_ci  bool at_to_number_conversion() const;
9781cb0ef41Sopenharmony_ci  // Byte offset in the function.
9791cb0ef41Sopenharmony_ci  int byte_offset() const;
9801cb0ef41Sopenharmony_ci  bool is_inspectable() const;
9811cb0ef41Sopenharmony_ci
9821cb0ef41Sopenharmony_ci  void Summarize(std::vector<FrameSummary>* frames) const override;
9831cb0ef41Sopenharmony_ci
9841cb0ef41Sopenharmony_ci  static WasmFrame* cast(StackFrame* frame) {
9851cb0ef41Sopenharmony_ci    DCHECK(frame->is_wasm());
9861cb0ef41Sopenharmony_ci    return static_cast<WasmFrame*>(frame);
9871cb0ef41Sopenharmony_ci  }
9881cb0ef41Sopenharmony_ci
9891cb0ef41Sopenharmony_ci protected:
9901cb0ef41Sopenharmony_ci  inline explicit WasmFrame(StackFrameIteratorBase* iterator);
9911cb0ef41Sopenharmony_ci
9921cb0ef41Sopenharmony_ci private:
9931cb0ef41Sopenharmony_ci  friend class StackFrameIteratorBase;
9941cb0ef41Sopenharmony_ci  WasmModuleObject module_object() const;
9951cb0ef41Sopenharmony_ci};
9961cb0ef41Sopenharmony_ci
9971cb0ef41Sopenharmony_ciclass WasmExitFrame : public WasmFrame {
9981cb0ef41Sopenharmony_ci public:
9991cb0ef41Sopenharmony_ci  Type type() const override { return WASM_EXIT; }
10001cb0ef41Sopenharmony_ci  static Address ComputeStackPointer(Address fp);
10011cb0ef41Sopenharmony_ci
10021cb0ef41Sopenharmony_ci protected:
10031cb0ef41Sopenharmony_ci  inline explicit WasmExitFrame(StackFrameIteratorBase* iterator);
10041cb0ef41Sopenharmony_ci
10051cb0ef41Sopenharmony_ci private:
10061cb0ef41Sopenharmony_ci  friend class StackFrameIteratorBase;
10071cb0ef41Sopenharmony_ci};
10081cb0ef41Sopenharmony_ci
10091cb0ef41Sopenharmony_ciclass WasmDebugBreakFrame final : public TypedFrame {
10101cb0ef41Sopenharmony_ci public:
10111cb0ef41Sopenharmony_ci  Type type() const override { return WASM_DEBUG_BREAK; }
10121cb0ef41Sopenharmony_ci
10131cb0ef41Sopenharmony_ci  // GC support.
10141cb0ef41Sopenharmony_ci  void Iterate(RootVisitor* v) const override;
10151cb0ef41Sopenharmony_ci
10161cb0ef41Sopenharmony_ci  void Print(StringStream* accumulator, PrintMode mode,
10171cb0ef41Sopenharmony_ci             int index) const override;
10181cb0ef41Sopenharmony_ci
10191cb0ef41Sopenharmony_ci  static WasmDebugBreakFrame* cast(StackFrame* frame) {
10201cb0ef41Sopenharmony_ci    DCHECK(frame->is_wasm_debug_break());
10211cb0ef41Sopenharmony_ci    return static_cast<WasmDebugBreakFrame*>(frame);
10221cb0ef41Sopenharmony_ci  }
10231cb0ef41Sopenharmony_ci
10241cb0ef41Sopenharmony_ci protected:
10251cb0ef41Sopenharmony_ci  inline explicit WasmDebugBreakFrame(StackFrameIteratorBase*);
10261cb0ef41Sopenharmony_ci
10271cb0ef41Sopenharmony_ci private:
10281cb0ef41Sopenharmony_ci  friend class StackFrameIteratorBase;
10291cb0ef41Sopenharmony_ci};
10301cb0ef41Sopenharmony_ci
10311cb0ef41Sopenharmony_ciclass WasmToJsFrame : public StubFrame {
10321cb0ef41Sopenharmony_ci public:
10331cb0ef41Sopenharmony_ci  Type type() const override { return WASM_TO_JS; }
10341cb0ef41Sopenharmony_ci
10351cb0ef41Sopenharmony_ci protected:
10361cb0ef41Sopenharmony_ci  inline explicit WasmToJsFrame(StackFrameIteratorBase* iterator);
10371cb0ef41Sopenharmony_ci
10381cb0ef41Sopenharmony_ci private:
10391cb0ef41Sopenharmony_ci  friend class StackFrameIteratorBase;
10401cb0ef41Sopenharmony_ci};
10411cb0ef41Sopenharmony_ci
10421cb0ef41Sopenharmony_ciclass JsToWasmFrame : public StubFrame {
10431cb0ef41Sopenharmony_ci public:
10441cb0ef41Sopenharmony_ci  Type type() const override { return JS_TO_WASM; }
10451cb0ef41Sopenharmony_ci
10461cb0ef41Sopenharmony_ci  void Iterate(RootVisitor* v) const override;
10471cb0ef41Sopenharmony_ci
10481cb0ef41Sopenharmony_ci protected:
10491cb0ef41Sopenharmony_ci  inline explicit JsToWasmFrame(StackFrameIteratorBase* iterator);
10501cb0ef41Sopenharmony_ci
10511cb0ef41Sopenharmony_ci private:
10521cb0ef41Sopenharmony_ci  friend class StackFrameIteratorBase;
10531cb0ef41Sopenharmony_ci};
10541cb0ef41Sopenharmony_ci
10551cb0ef41Sopenharmony_ciclass StackSwitchFrame : public ExitFrame {
10561cb0ef41Sopenharmony_ci public:
10571cb0ef41Sopenharmony_ci  Type type() const override { return STACK_SWITCH; }
10581cb0ef41Sopenharmony_ci  void Iterate(RootVisitor* v) const override;
10591cb0ef41Sopenharmony_ci  static void GetStateForJumpBuffer(wasm::JumpBuffer* jmpbuf, State* state);
10601cb0ef41Sopenharmony_ci
10611cb0ef41Sopenharmony_ci protected:
10621cb0ef41Sopenharmony_ci  inline explicit StackSwitchFrame(StackFrameIteratorBase* iterator);
10631cb0ef41Sopenharmony_ci
10641cb0ef41Sopenharmony_ci private:
10651cb0ef41Sopenharmony_ci  friend class StackFrameIteratorBase;
10661cb0ef41Sopenharmony_ci};
10671cb0ef41Sopenharmony_ci
10681cb0ef41Sopenharmony_ciclass CWasmEntryFrame : public StubFrame {
10691cb0ef41Sopenharmony_ci public:
10701cb0ef41Sopenharmony_ci  Type type() const override { return C_WASM_ENTRY; }
10711cb0ef41Sopenharmony_ci
10721cb0ef41Sopenharmony_ci protected:
10731cb0ef41Sopenharmony_ci  inline explicit CWasmEntryFrame(StackFrameIteratorBase* iterator);
10741cb0ef41Sopenharmony_ci
10751cb0ef41Sopenharmony_ci private:
10761cb0ef41Sopenharmony_ci  friend class StackFrameIteratorBase;
10771cb0ef41Sopenharmony_ci  Type GetCallerState(State* state) const override;
10781cb0ef41Sopenharmony_ci};
10791cb0ef41Sopenharmony_ci
10801cb0ef41Sopenharmony_ciclass WasmCompileLazyFrame : public TypedFrame {
10811cb0ef41Sopenharmony_ci public:
10821cb0ef41Sopenharmony_ci  Type type() const override { return WASM_COMPILE_LAZY; }
10831cb0ef41Sopenharmony_ci
10841cb0ef41Sopenharmony_ci  WasmInstanceObject wasm_instance() const;
10851cb0ef41Sopenharmony_ci  FullObjectSlot wasm_instance_slot() const;
10861cb0ef41Sopenharmony_ci
10871cb0ef41Sopenharmony_ci  // Garbage collection support.
10881cb0ef41Sopenharmony_ci  void Iterate(RootVisitor* v) const override;
10891cb0ef41Sopenharmony_ci
10901cb0ef41Sopenharmony_ci  static WasmCompileLazyFrame* cast(StackFrame* frame) {
10911cb0ef41Sopenharmony_ci    DCHECK(frame->is_wasm_compile_lazy());
10921cb0ef41Sopenharmony_ci    return static_cast<WasmCompileLazyFrame*>(frame);
10931cb0ef41Sopenharmony_ci  }
10941cb0ef41Sopenharmony_ci
10951cb0ef41Sopenharmony_ci protected:
10961cb0ef41Sopenharmony_ci  inline explicit WasmCompileLazyFrame(StackFrameIteratorBase* iterator);
10971cb0ef41Sopenharmony_ci
10981cb0ef41Sopenharmony_ci private:
10991cb0ef41Sopenharmony_ci  friend class StackFrameIteratorBase;
11001cb0ef41Sopenharmony_ci};
11011cb0ef41Sopenharmony_ci#endif  // V8_ENABLE_WEBASSEMBLY
11021cb0ef41Sopenharmony_ci
11031cb0ef41Sopenharmony_ciclass InternalFrame : public TypedFrame {
11041cb0ef41Sopenharmony_ci public:
11051cb0ef41Sopenharmony_ci  Type type() const override { return INTERNAL; }
11061cb0ef41Sopenharmony_ci
11071cb0ef41Sopenharmony_ci  // Garbage collection support.
11081cb0ef41Sopenharmony_ci  void Iterate(RootVisitor* v) const override;
11091cb0ef41Sopenharmony_ci
11101cb0ef41Sopenharmony_ci  static InternalFrame* cast(StackFrame* frame) {
11111cb0ef41Sopenharmony_ci    DCHECK(frame->is_internal());
11121cb0ef41Sopenharmony_ci    return static_cast<InternalFrame*>(frame);
11131cb0ef41Sopenharmony_ci  }
11141cb0ef41Sopenharmony_ci
11151cb0ef41Sopenharmony_ci protected:
11161cb0ef41Sopenharmony_ci  inline explicit InternalFrame(StackFrameIteratorBase* iterator);
11171cb0ef41Sopenharmony_ci
11181cb0ef41Sopenharmony_ci private:
11191cb0ef41Sopenharmony_ci  friend class StackFrameIteratorBase;
11201cb0ef41Sopenharmony_ci};
11211cb0ef41Sopenharmony_ci
11221cb0ef41Sopenharmony_ci// Construct frames are special trampoline frames introduced to handle
11231cb0ef41Sopenharmony_ci// function invocations through 'new'.
11241cb0ef41Sopenharmony_ciclass ConstructFrame : public InternalFrame {
11251cb0ef41Sopenharmony_ci public:
11261cb0ef41Sopenharmony_ci  Type type() const override { return CONSTRUCT; }
11271cb0ef41Sopenharmony_ci
11281cb0ef41Sopenharmony_ci  static ConstructFrame* cast(StackFrame* frame) {
11291cb0ef41Sopenharmony_ci    DCHECK(frame->is_construct());
11301cb0ef41Sopenharmony_ci    return static_cast<ConstructFrame*>(frame);
11311cb0ef41Sopenharmony_ci  }
11321cb0ef41Sopenharmony_ci
11331cb0ef41Sopenharmony_ci protected:
11341cb0ef41Sopenharmony_ci  inline explicit ConstructFrame(StackFrameIteratorBase* iterator);
11351cb0ef41Sopenharmony_ci
11361cb0ef41Sopenharmony_ci private:
11371cb0ef41Sopenharmony_ci  friend class StackFrameIteratorBase;
11381cb0ef41Sopenharmony_ci};
11391cb0ef41Sopenharmony_ci
11401cb0ef41Sopenharmony_ciclass BuiltinContinuationFrame : public InternalFrame {
11411cb0ef41Sopenharmony_ci public:
11421cb0ef41Sopenharmony_ci  Type type() const override { return BUILTIN_CONTINUATION; }
11431cb0ef41Sopenharmony_ci
11441cb0ef41Sopenharmony_ci  static BuiltinContinuationFrame* cast(StackFrame* frame) {
11451cb0ef41Sopenharmony_ci    DCHECK(frame->is_builtin_continuation());
11461cb0ef41Sopenharmony_ci    return static_cast<BuiltinContinuationFrame*>(frame);
11471cb0ef41Sopenharmony_ci  }
11481cb0ef41Sopenharmony_ci
11491cb0ef41Sopenharmony_ci protected:
11501cb0ef41Sopenharmony_ci  inline explicit BuiltinContinuationFrame(StackFrameIteratorBase* iterator);
11511cb0ef41Sopenharmony_ci
11521cb0ef41Sopenharmony_ci private:
11531cb0ef41Sopenharmony_ci  friend class StackFrameIteratorBase;
11541cb0ef41Sopenharmony_ci};
11551cb0ef41Sopenharmony_ci
11561cb0ef41Sopenharmony_ciclass JavaScriptBuiltinContinuationFrame : public TypedFrameWithJSLinkage {
11571cb0ef41Sopenharmony_ci public:
11581cb0ef41Sopenharmony_ci  Type type() const override { return JAVA_SCRIPT_BUILTIN_CONTINUATION; }
11591cb0ef41Sopenharmony_ci
11601cb0ef41Sopenharmony_ci  static JavaScriptBuiltinContinuationFrame* cast(StackFrame* frame) {
11611cb0ef41Sopenharmony_ci    DCHECK(frame->is_java_script_builtin_continuation());
11621cb0ef41Sopenharmony_ci    return static_cast<JavaScriptBuiltinContinuationFrame*>(frame);
11631cb0ef41Sopenharmony_ci  }
11641cb0ef41Sopenharmony_ci
11651cb0ef41Sopenharmony_ci  JSFunction function() const override;
11661cb0ef41Sopenharmony_ci  int ComputeParametersCount() const override;
11671cb0ef41Sopenharmony_ci  intptr_t GetSPToFPDelta() const;
11681cb0ef41Sopenharmony_ci
11691cb0ef41Sopenharmony_ci  Object context() const override;
11701cb0ef41Sopenharmony_ci
11711cb0ef41Sopenharmony_ci protected:
11721cb0ef41Sopenharmony_ci  inline explicit JavaScriptBuiltinContinuationFrame(
11731cb0ef41Sopenharmony_ci      StackFrameIteratorBase* iterator);
11741cb0ef41Sopenharmony_ci
11751cb0ef41Sopenharmony_ci private:
11761cb0ef41Sopenharmony_ci  friend class StackFrameIteratorBase;
11771cb0ef41Sopenharmony_ci};
11781cb0ef41Sopenharmony_ci
11791cb0ef41Sopenharmony_ciclass JavaScriptBuiltinContinuationWithCatchFrame
11801cb0ef41Sopenharmony_ci    : public JavaScriptBuiltinContinuationFrame {
11811cb0ef41Sopenharmony_ci public:
11821cb0ef41Sopenharmony_ci  Type type() const override {
11831cb0ef41Sopenharmony_ci    return JAVA_SCRIPT_BUILTIN_CONTINUATION_WITH_CATCH;
11841cb0ef41Sopenharmony_ci  }
11851cb0ef41Sopenharmony_ci
11861cb0ef41Sopenharmony_ci  static JavaScriptBuiltinContinuationWithCatchFrame* cast(StackFrame* frame) {
11871cb0ef41Sopenharmony_ci    DCHECK(frame->is_java_script_builtin_with_catch_continuation());
11881cb0ef41Sopenharmony_ci    return static_cast<JavaScriptBuiltinContinuationWithCatchFrame*>(frame);
11891cb0ef41Sopenharmony_ci  }
11901cb0ef41Sopenharmony_ci
11911cb0ef41Sopenharmony_ci  // Patch in the exception object at the appropriate location into the stack
11921cb0ef41Sopenharmony_ci  // frame.
11931cb0ef41Sopenharmony_ci  void SetException(Object exception);
11941cb0ef41Sopenharmony_ci
11951cb0ef41Sopenharmony_ci protected:
11961cb0ef41Sopenharmony_ci  inline explicit JavaScriptBuiltinContinuationWithCatchFrame(
11971cb0ef41Sopenharmony_ci      StackFrameIteratorBase* iterator);
11981cb0ef41Sopenharmony_ci
11991cb0ef41Sopenharmony_ci private:
12001cb0ef41Sopenharmony_ci  friend class StackFrameIteratorBase;
12011cb0ef41Sopenharmony_ci};
12021cb0ef41Sopenharmony_ci
12031cb0ef41Sopenharmony_ciclass StackFrameIteratorBase {
12041cb0ef41Sopenharmony_ci public:
12051cb0ef41Sopenharmony_ci  StackFrameIteratorBase(const StackFrameIteratorBase&) = delete;
12061cb0ef41Sopenharmony_ci  StackFrameIteratorBase& operator=(const StackFrameIteratorBase&) = delete;
12071cb0ef41Sopenharmony_ci
12081cb0ef41Sopenharmony_ci  Isolate* isolate() const { return isolate_; }
12091cb0ef41Sopenharmony_ci
12101cb0ef41Sopenharmony_ci  bool done() const { return frame_ == nullptr; }
12111cb0ef41Sopenharmony_ci
12121cb0ef41Sopenharmony_ci protected:
12131cb0ef41Sopenharmony_ci  // An iterator that iterates over a given thread's stack.
12141cb0ef41Sopenharmony_ci  StackFrameIteratorBase(Isolate* isolate, bool can_access_heap_objects);
12151cb0ef41Sopenharmony_ci
12161cb0ef41Sopenharmony_ci  Isolate* isolate_;
12171cb0ef41Sopenharmony_ci#define DECLARE_SINGLETON(ignore, type) type type##_;
12181cb0ef41Sopenharmony_ci  STACK_FRAME_TYPE_LIST(DECLARE_SINGLETON)
12191cb0ef41Sopenharmony_ci#undef DECLARE_SINGLETON
12201cb0ef41Sopenharmony_ci  StackFrame* frame_;
12211cb0ef41Sopenharmony_ci  StackHandler* handler_;
12221cb0ef41Sopenharmony_ci  const bool can_access_heap_objects_;
12231cb0ef41Sopenharmony_ci
12241cb0ef41Sopenharmony_ci  StackHandler* handler() const {
12251cb0ef41Sopenharmony_ci    DCHECK(!done());
12261cb0ef41Sopenharmony_ci    return handler_;
12271cb0ef41Sopenharmony_ci  }
12281cb0ef41Sopenharmony_ci
12291cb0ef41Sopenharmony_ci  // Get the type-specific frame singleton in a given state.
12301cb0ef41Sopenharmony_ci  StackFrame* SingletonFor(StackFrame::Type type, StackFrame::State* state);
12311cb0ef41Sopenharmony_ci  // A helper function, can return a nullptr pointer.
12321cb0ef41Sopenharmony_ci  StackFrame* SingletonFor(StackFrame::Type type);
12331cb0ef41Sopenharmony_ci
12341cb0ef41Sopenharmony_ci private:
12351cb0ef41Sopenharmony_ci  friend class StackFrame;
12361cb0ef41Sopenharmony_ci};
12371cb0ef41Sopenharmony_ci
12381cb0ef41Sopenharmony_ciclass StackFrameIterator : public StackFrameIteratorBase {
12391cb0ef41Sopenharmony_ci public:
12401cb0ef41Sopenharmony_ci  // An iterator that iterates over the isolate's current thread's stack,
12411cb0ef41Sopenharmony_ci  V8_EXPORT_PRIVATE explicit StackFrameIterator(Isolate* isolate);
12421cb0ef41Sopenharmony_ci  // An iterator that iterates over a given thread's stack.
12431cb0ef41Sopenharmony_ci  V8_EXPORT_PRIVATE StackFrameIterator(Isolate* isolate, ThreadLocalTop* t);
12441cb0ef41Sopenharmony_ci#if V8_ENABLE_WEBASSEMBLY
12451cb0ef41Sopenharmony_ci  // An iterator that iterates over a given wasm stack segment.
12461cb0ef41Sopenharmony_ci  V8_EXPORT_PRIVATE StackFrameIterator(Isolate* isolate,
12471cb0ef41Sopenharmony_ci                                       wasm::StackMemory* stack);
12481cb0ef41Sopenharmony_ci#endif
12491cb0ef41Sopenharmony_ci
12501cb0ef41Sopenharmony_ci  StackFrameIterator(const StackFrameIterator&) = delete;
12511cb0ef41Sopenharmony_ci  StackFrameIterator& operator=(const StackFrameIterator&) = delete;
12521cb0ef41Sopenharmony_ci
12531cb0ef41Sopenharmony_ci  StackFrame* frame() const {
12541cb0ef41Sopenharmony_ci    DCHECK(!done());
12551cb0ef41Sopenharmony_ci    return frame_;
12561cb0ef41Sopenharmony_ci  }
12571cb0ef41Sopenharmony_ci  V8_EXPORT_PRIVATE void Advance();
12581cb0ef41Sopenharmony_ci  StackFrame* Reframe();
12591cb0ef41Sopenharmony_ci
12601cb0ef41Sopenharmony_ci private:
12611cb0ef41Sopenharmony_ci  // Go back to the first frame.
12621cb0ef41Sopenharmony_ci  void Reset(ThreadLocalTop* top);
12631cb0ef41Sopenharmony_ci#if V8_ENABLE_WEBASSEMBLY
12641cb0ef41Sopenharmony_ci  void Reset(ThreadLocalTop* top, wasm::StackMemory* stack);
12651cb0ef41Sopenharmony_ci#endif
12661cb0ef41Sopenharmony_ci};
12671cb0ef41Sopenharmony_ci
12681cb0ef41Sopenharmony_ci// Iterator that supports iterating through all JavaScript frames.
12691cb0ef41Sopenharmony_ciclass JavaScriptFrameIterator {
12701cb0ef41Sopenharmony_ci public:
12711cb0ef41Sopenharmony_ci  inline explicit JavaScriptFrameIterator(Isolate* isolate);
12721cb0ef41Sopenharmony_ci  inline JavaScriptFrameIterator(Isolate* isolate, ThreadLocalTop* top);
12731cb0ef41Sopenharmony_ci
12741cb0ef41Sopenharmony_ci  inline JavaScriptFrame* frame() const;
12751cb0ef41Sopenharmony_ci
12761cb0ef41Sopenharmony_ci  bool done() const { return iterator_.done(); }
12771cb0ef41Sopenharmony_ci  V8_EXPORT_PRIVATE void Advance();
12781cb0ef41Sopenharmony_ci  void AdvanceOneFrame() { iterator_.Advance(); }
12791cb0ef41Sopenharmony_ci  inline JavaScriptFrame* Reframe();
12801cb0ef41Sopenharmony_ci
12811cb0ef41Sopenharmony_ci private:
12821cb0ef41Sopenharmony_ci  StackFrameIterator iterator_;
12831cb0ef41Sopenharmony_ci};
12841cb0ef41Sopenharmony_ci
12851cb0ef41Sopenharmony_ci// NOTE: The stack trace frame iterator is an iterator that only traverse proper
12861cb0ef41Sopenharmony_ci// JavaScript frames that have proper JavaScript functions and WebAssembly
12871cb0ef41Sopenharmony_ci// frames.
12881cb0ef41Sopenharmony_ciclass V8_EXPORT_PRIVATE StackTraceFrameIterator {
12891cb0ef41Sopenharmony_ci public:
12901cb0ef41Sopenharmony_ci  explicit StackTraceFrameIterator(Isolate* isolate);
12911cb0ef41Sopenharmony_ci  // Skip frames until the frame with the given id is reached.
12921cb0ef41Sopenharmony_ci  StackTraceFrameIterator(Isolate* isolate, StackFrameId id);
12931cb0ef41Sopenharmony_ci  bool done() const { return iterator_.done(); }
12941cb0ef41Sopenharmony_ci  void Advance();
12951cb0ef41Sopenharmony_ci  void AdvanceOneFrame() { iterator_.Advance(); }
12961cb0ef41Sopenharmony_ci  int FrameFunctionCount() const;
12971cb0ef41Sopenharmony_ci
12981cb0ef41Sopenharmony_ci  inline CommonFrame* frame() const;
12991cb0ef41Sopenharmony_ci  inline CommonFrame* Reframe();
13001cb0ef41Sopenharmony_ci
13011cb0ef41Sopenharmony_ci  inline bool is_javascript() const;
13021cb0ef41Sopenharmony_ci#if V8_ENABLE_WEBASSEMBLY
13031cb0ef41Sopenharmony_ci  inline bool is_wasm() const;
13041cb0ef41Sopenharmony_ci#endif  // V8_ENABLE_WEBASSEMBLY
13051cb0ef41Sopenharmony_ci  inline JavaScriptFrame* javascript_frame() const;
13061cb0ef41Sopenharmony_ci
13071cb0ef41Sopenharmony_ci  // Use this instead of FrameSummary::GetTop(javascript_frame) to keep
13081cb0ef41Sopenharmony_ci  // filtering behavior consistent with the rest of StackTraceFrameIterator.
13091cb0ef41Sopenharmony_ci  FrameSummary GetTopValidFrame() const;
13101cb0ef41Sopenharmony_ci
13111cb0ef41Sopenharmony_ci private:
13121cb0ef41Sopenharmony_ci  StackFrameIterator iterator_;
13131cb0ef41Sopenharmony_ci  static bool IsValidFrame(StackFrame* frame);
13141cb0ef41Sopenharmony_ci  static bool IsValidJSFunction(JSFunction f);
13151cb0ef41Sopenharmony_ci};
13161cb0ef41Sopenharmony_ci
13171cb0ef41Sopenharmony_ciclass SafeStackFrameIterator : public StackFrameIteratorBase {
13181cb0ef41Sopenharmony_ci public:
13191cb0ef41Sopenharmony_ci  SafeStackFrameIterator(Isolate* isolate, Address pc, Address fp, Address sp,
13201cb0ef41Sopenharmony_ci                         Address lr, Address js_entry_sp);
13211cb0ef41Sopenharmony_ci
13221cb0ef41Sopenharmony_ci  inline StackFrame* frame() const;
13231cb0ef41Sopenharmony_ci  void Advance();
13241cb0ef41Sopenharmony_ci
13251cb0ef41Sopenharmony_ci  StackFrame::Type top_frame_type() const { return top_frame_type_; }
13261cb0ef41Sopenharmony_ci  Address top_context_address() const { return top_context_address_; }
13271cb0ef41Sopenharmony_ci
13281cb0ef41Sopenharmony_ci private:
13291cb0ef41Sopenharmony_ci  void AdvanceOneFrame();
13301cb0ef41Sopenharmony_ci
13311cb0ef41Sopenharmony_ci  bool IsValidStackAddress(Address addr) const {
13321cb0ef41Sopenharmony_ci    return low_bound_ <= addr && addr <= high_bound_;
13331cb0ef41Sopenharmony_ci  }
13341cb0ef41Sopenharmony_ci  bool IsValidFrame(StackFrame* frame) const;
13351cb0ef41Sopenharmony_ci  bool IsValidCaller(StackFrame* frame);
13361cb0ef41Sopenharmony_ci  bool IsValidExitFrame(Address fp) const;
13371cb0ef41Sopenharmony_ci  bool IsValidTop(ThreadLocalTop* top) const;
13381cb0ef41Sopenharmony_ci
13391cb0ef41Sopenharmony_ci  // Returns true if the pc points to a bytecode handler and the frame pointer
13401cb0ef41Sopenharmony_ci  // doesn't seem to be a bytecode handler's frame, which implies that the
13411cb0ef41Sopenharmony_ci  // bytecode handler has an elided frame. This is not precise and might give
13421cb0ef41Sopenharmony_ci  // false negatives since it relies on checks to the frame's type marker,
13431cb0ef41Sopenharmony_ci  // which might be uninitialized.
13441cb0ef41Sopenharmony_ci  bool IsNoFrameBytecodeHandlerPc(Isolate* isolate, Address pc,
13451cb0ef41Sopenharmony_ci                                  Address fp) const;
13461cb0ef41Sopenharmony_ci
13471cb0ef41Sopenharmony_ci  const Address low_bound_;
13481cb0ef41Sopenharmony_ci  const Address high_bound_;
13491cb0ef41Sopenharmony_ci  StackFrame::Type top_frame_type_;
13501cb0ef41Sopenharmony_ci  Address top_context_address_;
13511cb0ef41Sopenharmony_ci  ExternalCallbackScope* external_callback_scope_;
13521cb0ef41Sopenharmony_ci  Address top_link_register_;
13531cb0ef41Sopenharmony_ci};
13541cb0ef41Sopenharmony_ci
13551cb0ef41Sopenharmony_ci// Frame layout helper classes. Used by the deoptimizer and instruction
13561cb0ef41Sopenharmony_ci// selector.
13571cb0ef41Sopenharmony_ci// -------------------------------------------------------------------------
13581cb0ef41Sopenharmony_ci
13591cb0ef41Sopenharmony_ci// How to calculate the frame layout information. Precise, when all information
13601cb0ef41Sopenharmony_ci// is available during deoptimization. Conservative, when an overapproximation
13611cb0ef41Sopenharmony_ci// is fine.
13621cb0ef41Sopenharmony_ci// TODO(jgruber): Investigate whether the conservative kind can be removed. It
13631cb0ef41Sopenharmony_ci// seems possible: 1. is_topmost should be known through the outer_state chain
13641cb0ef41Sopenharmony_ci// of FrameStateDescriptor; 2. the deopt_kind may be a property of the bailout
13651cb0ef41Sopenharmony_ci// id; 3. for continuation_mode, we only care whether it is a mode with catch,
13661cb0ef41Sopenharmony_ci// and that is likewise known at compile-time.
13671cb0ef41Sopenharmony_ci// There is nothing specific blocking this, the investigation just requires time
13681cb0ef41Sopenharmony_ci// and it is not that important to get the exact frame height at compile-time.
13691cb0ef41Sopenharmony_cienum class FrameInfoKind {
13701cb0ef41Sopenharmony_ci  kPrecise,
13711cb0ef41Sopenharmony_ci  kConservative,
13721cb0ef41Sopenharmony_ci};
13731cb0ef41Sopenharmony_ci
13741cb0ef41Sopenharmony_ci// Used by the deoptimizer. Corresponds to frame kinds:
13751cb0ef41Sopenharmony_cienum class BuiltinContinuationMode {
13761cb0ef41Sopenharmony_ci  STUB,                        // BuiltinContinuationFrame
13771cb0ef41Sopenharmony_ci  JAVASCRIPT,                  // JavaScriptBuiltinContinuationFrame
13781cb0ef41Sopenharmony_ci  JAVASCRIPT_WITH_CATCH,       // JavaScriptBuiltinContinuationWithCatchFrame
13791cb0ef41Sopenharmony_ci  JAVASCRIPT_HANDLE_EXCEPTION  // JavaScriptBuiltinContinuationWithCatchFrame
13801cb0ef41Sopenharmony_ci};
13811cb0ef41Sopenharmony_ci
13821cb0ef41Sopenharmony_ciclass UnoptimizedFrameInfo {
13831cb0ef41Sopenharmony_ci public:
13841cb0ef41Sopenharmony_ci  static UnoptimizedFrameInfo Precise(int parameters_count_with_receiver,
13851cb0ef41Sopenharmony_ci                                      int translation_height, bool is_topmost,
13861cb0ef41Sopenharmony_ci                                      bool pad_arguments) {
13871cb0ef41Sopenharmony_ci    return {parameters_count_with_receiver, translation_height, is_topmost,
13881cb0ef41Sopenharmony_ci            pad_arguments, FrameInfoKind::kPrecise};
13891cb0ef41Sopenharmony_ci  }
13901cb0ef41Sopenharmony_ci
13911cb0ef41Sopenharmony_ci  static UnoptimizedFrameInfo Conservative(int parameters_count_with_receiver,
13921cb0ef41Sopenharmony_ci                                           int locals_count) {
13931cb0ef41Sopenharmony_ci    return {parameters_count_with_receiver, locals_count, false, true,
13941cb0ef41Sopenharmony_ci            FrameInfoKind::kConservative};
13951cb0ef41Sopenharmony_ci  }
13961cb0ef41Sopenharmony_ci
13971cb0ef41Sopenharmony_ci  static uint32_t GetStackSizeForAdditionalArguments(int parameters_count);
13981cb0ef41Sopenharmony_ci
13991cb0ef41Sopenharmony_ci  uint32_t register_stack_slot_count() const {
14001cb0ef41Sopenharmony_ci    return register_stack_slot_count_;
14011cb0ef41Sopenharmony_ci  }
14021cb0ef41Sopenharmony_ci  uint32_t frame_size_in_bytes_without_fixed() const {
14031cb0ef41Sopenharmony_ci    return frame_size_in_bytes_without_fixed_;
14041cb0ef41Sopenharmony_ci  }
14051cb0ef41Sopenharmony_ci  uint32_t frame_size_in_bytes() const { return frame_size_in_bytes_; }
14061cb0ef41Sopenharmony_ci
14071cb0ef41Sopenharmony_ci private:
14081cb0ef41Sopenharmony_ci  UnoptimizedFrameInfo(int parameters_count_with_receiver,
14091cb0ef41Sopenharmony_ci                       int translation_height, bool is_topmost,
14101cb0ef41Sopenharmony_ci                       bool pad_arguments, FrameInfoKind frame_info_kind);
14111cb0ef41Sopenharmony_ci
14121cb0ef41Sopenharmony_ci  uint32_t register_stack_slot_count_;
14131cb0ef41Sopenharmony_ci  uint32_t frame_size_in_bytes_without_fixed_;
14141cb0ef41Sopenharmony_ci  uint32_t frame_size_in_bytes_;
14151cb0ef41Sopenharmony_ci};
14161cb0ef41Sopenharmony_ci
14171cb0ef41Sopenharmony_ciclass ConstructStubFrameInfo {
14181cb0ef41Sopenharmony_ci public:
14191cb0ef41Sopenharmony_ci  static ConstructStubFrameInfo Precise(int translation_height,
14201cb0ef41Sopenharmony_ci                                        bool is_topmost) {
14211cb0ef41Sopenharmony_ci    return {translation_height, is_topmost, FrameInfoKind::kPrecise};
14221cb0ef41Sopenharmony_ci  }
14231cb0ef41Sopenharmony_ci
14241cb0ef41Sopenharmony_ci  static ConstructStubFrameInfo Conservative(int parameters_count) {
14251cb0ef41Sopenharmony_ci    return {parameters_count, false, FrameInfoKind::kConservative};
14261cb0ef41Sopenharmony_ci  }
14271cb0ef41Sopenharmony_ci
14281cb0ef41Sopenharmony_ci  uint32_t frame_size_in_bytes_without_fixed() const {
14291cb0ef41Sopenharmony_ci    return frame_size_in_bytes_without_fixed_;
14301cb0ef41Sopenharmony_ci  }
14311cb0ef41Sopenharmony_ci  uint32_t frame_size_in_bytes() const { return frame_size_in_bytes_; }
14321cb0ef41Sopenharmony_ci
14331cb0ef41Sopenharmony_ci private:
14341cb0ef41Sopenharmony_ci  ConstructStubFrameInfo(int translation_height, bool is_topmost,
14351cb0ef41Sopenharmony_ci                         FrameInfoKind frame_info_kind);
14361cb0ef41Sopenharmony_ci
14371cb0ef41Sopenharmony_ci  uint32_t frame_size_in_bytes_without_fixed_;
14381cb0ef41Sopenharmony_ci  uint32_t frame_size_in_bytes_;
14391cb0ef41Sopenharmony_ci};
14401cb0ef41Sopenharmony_ci
14411cb0ef41Sopenharmony_ci// Used by BuiltinContinuationFrameInfo.
14421cb0ef41Sopenharmony_ciclass CallInterfaceDescriptor;
14431cb0ef41Sopenharmony_ciclass RegisterConfiguration;
14441cb0ef41Sopenharmony_ci
14451cb0ef41Sopenharmony_ciclass BuiltinContinuationFrameInfo {
14461cb0ef41Sopenharmony_ci public:
14471cb0ef41Sopenharmony_ci  static BuiltinContinuationFrameInfo Precise(
14481cb0ef41Sopenharmony_ci      int translation_height,
14491cb0ef41Sopenharmony_ci      const CallInterfaceDescriptor& continuation_descriptor,
14501cb0ef41Sopenharmony_ci      const RegisterConfiguration* register_config, bool is_topmost,
14511cb0ef41Sopenharmony_ci      DeoptimizeKind deopt_kind, BuiltinContinuationMode continuation_mode) {
14521cb0ef41Sopenharmony_ci    return {translation_height,
14531cb0ef41Sopenharmony_ci            continuation_descriptor,
14541cb0ef41Sopenharmony_ci            register_config,
14551cb0ef41Sopenharmony_ci            is_topmost,
14561cb0ef41Sopenharmony_ci            deopt_kind,
14571cb0ef41Sopenharmony_ci            continuation_mode,
14581cb0ef41Sopenharmony_ci            FrameInfoKind::kPrecise};
14591cb0ef41Sopenharmony_ci  }
14601cb0ef41Sopenharmony_ci
14611cb0ef41Sopenharmony_ci  static BuiltinContinuationFrameInfo Conservative(
14621cb0ef41Sopenharmony_ci      int parameters_count,
14631cb0ef41Sopenharmony_ci      const CallInterfaceDescriptor& continuation_descriptor,
14641cb0ef41Sopenharmony_ci      const RegisterConfiguration* register_config) {
14651cb0ef41Sopenharmony_ci    // It doesn't matter what we pass as is_topmost, deopt_kind and
14661cb0ef41Sopenharmony_ci    // continuation_mode; these values are ignored in conservative mode.
14671cb0ef41Sopenharmony_ci    return {parameters_count,
14681cb0ef41Sopenharmony_ci            continuation_descriptor,
14691cb0ef41Sopenharmony_ci            register_config,
14701cb0ef41Sopenharmony_ci            false,
14711cb0ef41Sopenharmony_ci            DeoptimizeKind::kEager,
14721cb0ef41Sopenharmony_ci            BuiltinContinuationMode::STUB,
14731cb0ef41Sopenharmony_ci            FrameInfoKind::kConservative};
14741cb0ef41Sopenharmony_ci  }
14751cb0ef41Sopenharmony_ci
14761cb0ef41Sopenharmony_ci  bool frame_has_result_stack_slot() const {
14771cb0ef41Sopenharmony_ci    return frame_has_result_stack_slot_;
14781cb0ef41Sopenharmony_ci  }
14791cb0ef41Sopenharmony_ci  uint32_t translated_stack_parameter_count() const {
14801cb0ef41Sopenharmony_ci    return translated_stack_parameter_count_;
14811cb0ef41Sopenharmony_ci  }
14821cb0ef41Sopenharmony_ci  uint32_t stack_parameter_count() const { return stack_parameter_count_; }
14831cb0ef41Sopenharmony_ci  uint32_t frame_size_in_bytes() const { return frame_size_in_bytes_; }
14841cb0ef41Sopenharmony_ci  uint32_t frame_size_in_bytes_above_fp() const {
14851cb0ef41Sopenharmony_ci    return frame_size_in_bytes_above_fp_;
14861cb0ef41Sopenharmony_ci  }
14871cb0ef41Sopenharmony_ci
14881cb0ef41Sopenharmony_ci private:
14891cb0ef41Sopenharmony_ci  BuiltinContinuationFrameInfo(
14901cb0ef41Sopenharmony_ci      int translation_height,
14911cb0ef41Sopenharmony_ci      const CallInterfaceDescriptor& continuation_descriptor,
14921cb0ef41Sopenharmony_ci      const RegisterConfiguration* register_config, bool is_topmost,
14931cb0ef41Sopenharmony_ci      DeoptimizeKind deopt_kind, BuiltinContinuationMode continuation_mode,
14941cb0ef41Sopenharmony_ci      FrameInfoKind frame_info_kind);
14951cb0ef41Sopenharmony_ci
14961cb0ef41Sopenharmony_ci  bool frame_has_result_stack_slot_;
14971cb0ef41Sopenharmony_ci  uint32_t translated_stack_parameter_count_;
14981cb0ef41Sopenharmony_ci  uint32_t stack_parameter_count_;
14991cb0ef41Sopenharmony_ci  uint32_t frame_size_in_bytes_;
15001cb0ef41Sopenharmony_ci  uint32_t frame_size_in_bytes_above_fp_;
15011cb0ef41Sopenharmony_ci};
15021cb0ef41Sopenharmony_ci
15031cb0ef41Sopenharmony_ci}  // namespace internal
15041cb0ef41Sopenharmony_ci}  // namespace v8
15051cb0ef41Sopenharmony_ci
15061cb0ef41Sopenharmony_ci#endif  // V8_EXECUTION_FRAMES_H_
1507