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