chromium/v8/src/execution/frames.h

// 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_