// Copyright 2012 the V8 project authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. #ifndef V8_EXECUTION_FRAMES_H_ #define V8_EXECUTION_FRAMES_H_ #include "include/v8-initialization.h" #include "src/base/bounds.h" #include "src/codegen/handler-table.h" #include "src/codegen/safepoint-table.h" #include "src/common/globals.h" #include "src/handles/handles.h" #include "src/objects/code.h" #include "src/objects/deoptimization-data.h" #include "src/objects/objects.h" #if V8_ENABLE_WEBASSEMBLY #include "src/wasm/stacks.h" #include "src/wasm/wasm-code-manager.h" #endif // V8_ENABLE_WEBASSEMBLY // // Frame inheritance hierarchy (please keep in sync with frame-constants.h): // - CommonFrame // - CommonFrameWithJSLinkage // - JavaScriptFrame (aka StandardFrame) // - UnoptimizedFrame // - InterpretedFrame // - BaselineFrame // - OptimizedFrame // - MaglevFrame // - TurboFanFrame // - TypedFrameWithJSLinkage // - BuiltinFrame // - JavaScriptBuiltinContinuationFrame // - JavaScriptBuiltinContinuationWithCatchFrame // - TurbofanStubWithContextFrame // - TypedFrame // - NativeFrame // - EntryFrame // - ConstructEntryFrame // - ExitFrame // - BuiltinExitFrame // - StubFrame // - JsToWasmFrame // - CWasmEntryFrame // - Internal // - ConstructFrame // - FastConstructFrame // - BuiltinContinuationFrame // - WasmFrame // - WasmExitFrame // - WasmToJsFrame // - WasmInterpreterEntryFrame (#if V8_ENABLE_DRUMBRAKE) // - WasmDebugBreakFrame // - WasmLiftoffSetupFrame // - IrregexpFrame namespace v8 { namespace internal { namespace wasm { class WasmCode; struct JumpBuffer; class StackMemory; } // namespace wasm class AbstractCode; class Debug; class ExternalCallbackScope; class InnerPointerToCodeCache; class Isolate; class ObjectVisitor; class Register; class RootVisitor; class StackFrameInfo; class StackFrameIteratorBase; class StringStream; class ThreadLocalTop; class WasmInstanceObject; class WasmModuleObject; #if V8_ENABLE_DRUMBRAKE class Tuple2; #endif // V8_ENABLE_DRUMBRAKE class StackHandlerConstants : public AllStatic { … }; class StackHandler { … }; #define STACK_FRAME_TYPE_LIST(V) … // Abstract base class for all stack frames. class StackFrame { … }; class CommonFrame; class V8_EXPORT_PRIVATE FrameSummary { … }; class CommonFrame : public StackFrame { … }; // This frame is used for TF-optimized code without JS linkage, but // contains the context instead of a type marker. class TurbofanStubWithContextFrame : public CommonFrame { … }; class TypedFrame : public CommonFrame { … }; class CommonFrameWithJSLinkage : public CommonFrame { … }; class TypedFrameWithJSLinkage : public CommonFrameWithJSLinkage { … }; class JavaScriptFrame : public CommonFrameWithJSLinkage { … }; class NativeFrame : public TypedFrame { … }; // Entry frames are used to enter JavaScript execution from C. class EntryFrame : public TypedFrame { … }; class ConstructEntryFrame : public EntryFrame { … }; // Exit frames are used to exit JavaScript execution and go to C, or to switch // out of the current stack for wasm stack-switching. class ExitFrame : public TypedFrame { … }; // Builtin exit frames are a special case of exit frames, which are used // whenever C++ builtins (e.g., Math.acos) are called. Their main purpose is // to allow such builtins to appear in stack traces. class BuiltinExitFrame : public ExitFrame { … }; // Api callback exit frames are a special case of exit frames, which are used // whenever an Api functions (such as v8::Function or v8::FunctionTemplate) are // called. Their main purpose is to support preprocessing of exceptions thrown // from Api functions and as a bonus it allows these functions to appear in // stack traces (see v8_flags.experimental_stack_trace_frames). class ApiCallbackExitFrame : public ExitFrame { … }; // Api accessor exit frames are a special case of exit frames, which are used // whenever an Api property accessor callbacks (v8::AccessorGetterCallback or // v8::AccessorSetterCallback) are called. Their main purpose is to support // preprocessing of exceptions thrown from these callbacks. class ApiAccessorExitFrame : public ExitFrame { … }; class StubFrame : public TypedFrame { … }; class OptimizedFrame : public JavaScriptFrame { … }; // An unoptimized frame is a JavaScript frame that is executing bytecode. It // may be executing it using the interpreter, or via baseline code compiled from // the bytecode. class UnoptimizedFrame : public JavaScriptFrame { … }; class InterpretedFrame : public UnoptimizedFrame { … }; class BaselineFrame : public UnoptimizedFrame { … }; class MaglevFrame : public OptimizedFrame { … }; class TurbofanFrame : public OptimizedFrame { … }; // Builtin frames are built for builtins with JavaScript linkage, such as // various standard library functions (i.e. Math.asin, Math.floor, etc.). class BuiltinFrame final : public TypedFrameWithJSLinkage { … }; #if V8_ENABLE_WEBASSEMBLY class WasmFrame : public TypedFrame { … }; // WasmSegmentStartFrame is a regular Wasm frame moved to the // beginning of a new stack segment allocated for growable stack. // It requires special handling on return. To indicate that, the WASM frame type // is replaced by WASM_SEGMENT_START. class WasmSegmentStartFrame : public WasmFrame { … }; // Wasm to C-API exit frame. class WasmExitFrame : public WasmFrame { … }; #if V8_ENABLE_DRUMBRAKE class WasmInterpreterEntryFrame final : public WasmFrame { public: Type type() const override { return WASM_INTERPRETER_ENTRY; } // GC support. void Iterate(RootVisitor* v) const override; // Printing support. void Print(StringStream* accumulator, PrintMode mode, int index) const override; void Summarize(std::vector<FrameSummary>* frames) const override; // Determine the code for the frame. Tagged<HeapObject> unchecked_code() const override; // Accessors. Tagged<Tuple2> interpreter_object() const; V8_EXPORT_PRIVATE Tagged<WasmInstanceObject> wasm_instance() const override; Tagged<WasmTrustedInstanceData> trusted_instance_data() const override; wasm::WasmCode* wasm_code() const override { UNREACHABLE(); } int function_index(int inlined_function_index) const; int position() const override; Tagged<Object> context() const override; static WasmInterpreterEntryFrame* cast(StackFrame* frame) { DCHECK(frame->is_wasm_interpreter_entry()); return static_cast<WasmInterpreterEntryFrame*>(frame); } protected: inline explicit WasmInterpreterEntryFrame(StackFrameIteratorBase* iterator); Address GetCallerStackPointer() const override; private: friend class StackFrameIteratorBase; Tagged<WasmModuleObject> module_object() const; }; #endif // V8_ENABLE_DRUMBRAKE class WasmDebugBreakFrame final : public TypedFrame { … }; class WasmToJsFrame : public WasmFrame { … }; class WasmToJsFunctionFrame : public TypedFrame { … }; class JsToWasmFrame : public StubFrame { … }; class StackSwitchFrame : public ExitFrame { … }; class CWasmEntryFrame : public StubFrame { … }; class WasmLiftoffSetupFrame : public TypedFrame { … }; #endif // V8_ENABLE_WEBASSEMBLY class InternalFrame : public TypedFrame { … }; // Construct frames are special trampoline frames introduced to handle // function invocations through 'new'. class ConstructFrame : public InternalFrame { … }; // Fast construct frames are special construct trampoline frames that avoid // pushing arguments to the stack twice. class FastConstructFrame : public InternalFrame { … }; class BuiltinContinuationFrame : public InternalFrame { … }; class JavaScriptBuiltinContinuationFrame : public TypedFrameWithJSLinkage { … }; class JavaScriptBuiltinContinuationWithCatchFrame : public JavaScriptBuiltinContinuationFrame { … }; class IrregexpFrame : public TypedFrame { … }; class StackFrameIteratorBase { … }; class StackFrameIterator : public StackFrameIteratorBase { … }; // A wrapper around StackFrameIterator that skips over all non-JS frames. class JavaScriptStackFrameIterator final { … }; // A wrapper around StackFrameIterator that skips over all non-debuggable // frames (i.e. it iterates over Wasm and debuggable JS frames). class V8_EXPORT_PRIVATE DebuggableStackFrameIterator { … }; // Similar to StackFrameIterator, but can be created and used at any time and // any stack state. Currently, the only user is the profiler; if this ever // changes, find another name for this class. // IMPORTANT: Do not mark this class as V8_EXPORT_PRIVATE. The profiler creates // instances of this class from a signal handler. If we use V8_EXPORT_PRIVATE // "ld" inserts a symbol stub for the constructor call that may crash with // a stackoverflow when called from a signal handler. class StackFrameIteratorForProfiler : public StackFrameIteratorBase { … }; // We cannot export 'StackFrameIteratorForProfiler' for cctests since the // linker inserted symbol stub may cuase a stack overflow // (https://crbug.com/1449195). // We subclass it and export the subclass instead. class V8_EXPORT_PRIVATE StackFrameIteratorForProfilerForTesting : public StackFrameIteratorForProfiler { … }; // Frame layout helper classes. Used by the deoptimizer and instruction // selector. // ------------------------------------------------------------------------- // How to calculate the frame layout information. Precise, when all information // is available during deoptimization. Conservative, when an overapproximation // is fine. // TODO(jgruber): Investigate whether the conservative kind can be removed. It // seems possible: 1. is_topmost should be known through the outer_state chain // of FrameStateDescriptor; 2. the deopt_kind may be a property of the bailout // id; 3. for continuation_mode, we only care whether it is a mode with catch, // and that is likewise known at compile-time. // There is nothing specific blocking this, the investigation just requires time // and it is not that important to get the exact frame height at compile-time. enum class FrameInfoKind { … }; // Used by the deoptimizer. Corresponds to frame kinds: enum class BuiltinContinuationMode { … }; class UnoptimizedFrameInfo { … }; class ConstructStubFrameInfo { … }; class FastConstructStubFrameInfo { … }; // Used by BuiltinContinuationFrameInfo. class CallInterfaceDescriptor; class RegisterConfiguration; class BuiltinContinuationFrameInfo { … }; } // namespace internal } // namespace v8 #endif // V8_EXECUTION_FRAMES_H_