11cb0ef41Sopenharmony_ci// Copyright 2015 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_COMPILER_FRAME_STATES_H_
61cb0ef41Sopenharmony_ci#define V8_COMPILER_FRAME_STATES_H_
71cb0ef41Sopenharmony_ci
81cb0ef41Sopenharmony_ci#include "src/builtins/builtins.h"
91cb0ef41Sopenharmony_ci#include "src/compiler/node.h"
101cb0ef41Sopenharmony_ci#include "src/handles/handles.h"
111cb0ef41Sopenharmony_ci#include "src/objects/shared-function-info.h"
121cb0ef41Sopenharmony_ci#include "src/utils/utils.h"
131cb0ef41Sopenharmony_ci
141cb0ef41Sopenharmony_cinamespace v8 {
151cb0ef41Sopenharmony_cinamespace internal {
161cb0ef41Sopenharmony_ci
171cb0ef41Sopenharmony_cinamespace wasm {
181cb0ef41Sopenharmony_ciclass ValueType;
191cb0ef41Sopenharmony_ciusing FunctionSig = Signature<ValueType>;
201cb0ef41Sopenharmony_ci}  // namespace wasm
211cb0ef41Sopenharmony_ci
221cb0ef41Sopenharmony_cinamespace compiler {
231cb0ef41Sopenharmony_ci
241cb0ef41Sopenharmony_ciclass JSGraph;
251cb0ef41Sopenharmony_ciclass Node;
261cb0ef41Sopenharmony_ciclass SharedFunctionInfoRef;
271cb0ef41Sopenharmony_ci
281cb0ef41Sopenharmony_ci// Flag that describes how to combine the current environment with
291cb0ef41Sopenharmony_ci// the output of a node to obtain a framestate for lazy bailout.
301cb0ef41Sopenharmony_ciclass OutputFrameStateCombine {
311cb0ef41Sopenharmony_ci public:
321cb0ef41Sopenharmony_ci  static const size_t kInvalidIndex = SIZE_MAX;
331cb0ef41Sopenharmony_ci
341cb0ef41Sopenharmony_ci  static OutputFrameStateCombine Ignore() {
351cb0ef41Sopenharmony_ci    return OutputFrameStateCombine(kInvalidIndex);
361cb0ef41Sopenharmony_ci  }
371cb0ef41Sopenharmony_ci  static OutputFrameStateCombine PokeAt(size_t index) {
381cb0ef41Sopenharmony_ci    return OutputFrameStateCombine(index);
391cb0ef41Sopenharmony_ci  }
401cb0ef41Sopenharmony_ci
411cb0ef41Sopenharmony_ci  size_t GetOffsetToPokeAt() const {
421cb0ef41Sopenharmony_ci    DCHECK_NE(parameter_, kInvalidIndex);
431cb0ef41Sopenharmony_ci    return parameter_;
441cb0ef41Sopenharmony_ci  }
451cb0ef41Sopenharmony_ci
461cb0ef41Sopenharmony_ci  bool IsOutputIgnored() const { return parameter_ == kInvalidIndex; }
471cb0ef41Sopenharmony_ci
481cb0ef41Sopenharmony_ci  size_t ConsumedOutputCount() const { return IsOutputIgnored() ? 0 : 1; }
491cb0ef41Sopenharmony_ci
501cb0ef41Sopenharmony_ci  bool operator==(OutputFrameStateCombine const& other) const {
511cb0ef41Sopenharmony_ci    return parameter_ == other.parameter_;
521cb0ef41Sopenharmony_ci  }
531cb0ef41Sopenharmony_ci  bool operator!=(OutputFrameStateCombine const& other) const {
541cb0ef41Sopenharmony_ci    return !(*this == other);
551cb0ef41Sopenharmony_ci  }
561cb0ef41Sopenharmony_ci
571cb0ef41Sopenharmony_ci  friend size_t hash_value(OutputFrameStateCombine const&);
581cb0ef41Sopenharmony_ci  friend std::ostream& operator<<(std::ostream&,
591cb0ef41Sopenharmony_ci                                  OutputFrameStateCombine const&);
601cb0ef41Sopenharmony_ci
611cb0ef41Sopenharmony_ci private:
621cb0ef41Sopenharmony_ci  explicit OutputFrameStateCombine(size_t parameter) : parameter_(parameter) {}
631cb0ef41Sopenharmony_ci
641cb0ef41Sopenharmony_ci  size_t const parameter_;
651cb0ef41Sopenharmony_ci};
661cb0ef41Sopenharmony_ci
671cb0ef41Sopenharmony_ci
681cb0ef41Sopenharmony_ci// The type of stack frame that a FrameState node represents.
691cb0ef41Sopenharmony_cienum class FrameStateType {
701cb0ef41Sopenharmony_ci  kUnoptimizedFunction,            // Represents an UnoptimizedFrame.
711cb0ef41Sopenharmony_ci  kArgumentsAdaptor,               // Represents an ArgumentsAdaptorFrame.
721cb0ef41Sopenharmony_ci  kConstructStub,                  // Represents a ConstructStubFrame.
731cb0ef41Sopenharmony_ci  kBuiltinContinuation,            // Represents a continuation to a stub.
741cb0ef41Sopenharmony_ci#if V8_ENABLE_WEBASSEMBLY          // ↓ WebAssembly only
751cb0ef41Sopenharmony_ci  kJSToWasmBuiltinContinuation,    // Represents a lazy deopt continuation for a
761cb0ef41Sopenharmony_ci                                   // JS to Wasm call.
771cb0ef41Sopenharmony_ci#endif                             // ↑ WebAssembly only
781cb0ef41Sopenharmony_ci  kJavaScriptBuiltinContinuation,  // Represents a continuation to a JavaScipt
791cb0ef41Sopenharmony_ci                                   // builtin.
801cb0ef41Sopenharmony_ci  kJavaScriptBuiltinContinuationWithCatch  // Represents a continuation to a
811cb0ef41Sopenharmony_ci                                           // JavaScipt builtin with a catch
821cb0ef41Sopenharmony_ci                                           // handler.
831cb0ef41Sopenharmony_ci};
841cb0ef41Sopenharmony_ci
851cb0ef41Sopenharmony_ciclass FrameStateFunctionInfo {
861cb0ef41Sopenharmony_ci public:
871cb0ef41Sopenharmony_ci  FrameStateFunctionInfo(FrameStateType type, int parameter_count,
881cb0ef41Sopenharmony_ci                         int local_count,
891cb0ef41Sopenharmony_ci                         Handle<SharedFunctionInfo> shared_info)
901cb0ef41Sopenharmony_ci      : type_(type),
911cb0ef41Sopenharmony_ci        parameter_count_(parameter_count),
921cb0ef41Sopenharmony_ci        local_count_(local_count),
931cb0ef41Sopenharmony_ci        shared_info_(shared_info) {}
941cb0ef41Sopenharmony_ci
951cb0ef41Sopenharmony_ci  int local_count() const { return local_count_; }
961cb0ef41Sopenharmony_ci  int parameter_count() const { return parameter_count_; }
971cb0ef41Sopenharmony_ci  Handle<SharedFunctionInfo> shared_info() const { return shared_info_; }
981cb0ef41Sopenharmony_ci  FrameStateType type() const { return type_; }
991cb0ef41Sopenharmony_ci
1001cb0ef41Sopenharmony_ci  static bool IsJSFunctionType(FrameStateType type) {
1011cb0ef41Sopenharmony_ci    return type == FrameStateType::kUnoptimizedFunction ||
1021cb0ef41Sopenharmony_ci           type == FrameStateType::kJavaScriptBuiltinContinuation ||
1031cb0ef41Sopenharmony_ci           type == FrameStateType::kJavaScriptBuiltinContinuationWithCatch;
1041cb0ef41Sopenharmony_ci  }
1051cb0ef41Sopenharmony_ci
1061cb0ef41Sopenharmony_ci private:
1071cb0ef41Sopenharmony_ci  FrameStateType const type_;
1081cb0ef41Sopenharmony_ci  int const parameter_count_;
1091cb0ef41Sopenharmony_ci  int const local_count_;
1101cb0ef41Sopenharmony_ci  Handle<SharedFunctionInfo> const shared_info_;
1111cb0ef41Sopenharmony_ci};
1121cb0ef41Sopenharmony_ci
1131cb0ef41Sopenharmony_ci#if V8_ENABLE_WEBASSEMBLY
1141cb0ef41Sopenharmony_ciclass JSToWasmFrameStateFunctionInfo : public FrameStateFunctionInfo {
1151cb0ef41Sopenharmony_ci public:
1161cb0ef41Sopenharmony_ci  JSToWasmFrameStateFunctionInfo(FrameStateType type, int parameter_count,
1171cb0ef41Sopenharmony_ci                                 int local_count,
1181cb0ef41Sopenharmony_ci                                 Handle<SharedFunctionInfo> shared_info,
1191cb0ef41Sopenharmony_ci                                 const wasm::FunctionSig* signature)
1201cb0ef41Sopenharmony_ci      : FrameStateFunctionInfo(type, parameter_count, local_count, shared_info),
1211cb0ef41Sopenharmony_ci        signature_(signature) {
1221cb0ef41Sopenharmony_ci    DCHECK_NOT_NULL(signature);
1231cb0ef41Sopenharmony_ci  }
1241cb0ef41Sopenharmony_ci
1251cb0ef41Sopenharmony_ci  const wasm::FunctionSig* signature() const { return signature_; }
1261cb0ef41Sopenharmony_ci
1271cb0ef41Sopenharmony_ci private:
1281cb0ef41Sopenharmony_ci  const wasm::FunctionSig* const signature_;
1291cb0ef41Sopenharmony_ci};
1301cb0ef41Sopenharmony_ci#endif  // V8_ENABLE_WEBASSEMBLY
1311cb0ef41Sopenharmony_ci
1321cb0ef41Sopenharmony_ciclass FrameStateInfo final {
1331cb0ef41Sopenharmony_ci public:
1341cb0ef41Sopenharmony_ci  FrameStateInfo(BytecodeOffset bailout_id,
1351cb0ef41Sopenharmony_ci                 OutputFrameStateCombine state_combine,
1361cb0ef41Sopenharmony_ci                 const FrameStateFunctionInfo* info)
1371cb0ef41Sopenharmony_ci      : bailout_id_(bailout_id),
1381cb0ef41Sopenharmony_ci        frame_state_combine_(state_combine),
1391cb0ef41Sopenharmony_ci        info_(info) {}
1401cb0ef41Sopenharmony_ci
1411cb0ef41Sopenharmony_ci  FrameStateType type() const {
1421cb0ef41Sopenharmony_ci    return info_ == nullptr ? FrameStateType::kUnoptimizedFunction
1431cb0ef41Sopenharmony_ci                            : info_->type();
1441cb0ef41Sopenharmony_ci  }
1451cb0ef41Sopenharmony_ci  BytecodeOffset bailout_id() const { return bailout_id_; }
1461cb0ef41Sopenharmony_ci  OutputFrameStateCombine state_combine() const { return frame_state_combine_; }
1471cb0ef41Sopenharmony_ci  MaybeHandle<SharedFunctionInfo> shared_info() const {
1481cb0ef41Sopenharmony_ci    return info_ == nullptr ? MaybeHandle<SharedFunctionInfo>()
1491cb0ef41Sopenharmony_ci                            : info_->shared_info();
1501cb0ef41Sopenharmony_ci  }
1511cb0ef41Sopenharmony_ci  int parameter_count() const {
1521cb0ef41Sopenharmony_ci    return info_ == nullptr ? 0 : info_->parameter_count();
1531cb0ef41Sopenharmony_ci  }
1541cb0ef41Sopenharmony_ci  int local_count() const {
1551cb0ef41Sopenharmony_ci    return info_ == nullptr ? 0 : info_->local_count();
1561cb0ef41Sopenharmony_ci  }
1571cb0ef41Sopenharmony_ci  const FrameStateFunctionInfo* function_info() const { return info_; }
1581cb0ef41Sopenharmony_ci
1591cb0ef41Sopenharmony_ci private:
1601cb0ef41Sopenharmony_ci  BytecodeOffset const bailout_id_;
1611cb0ef41Sopenharmony_ci  OutputFrameStateCombine const frame_state_combine_;
1621cb0ef41Sopenharmony_ci  const FrameStateFunctionInfo* const info_;
1631cb0ef41Sopenharmony_ci};
1641cb0ef41Sopenharmony_ci
1651cb0ef41Sopenharmony_cibool operator==(FrameStateInfo const&, FrameStateInfo const&);
1661cb0ef41Sopenharmony_cibool operator!=(FrameStateInfo const&, FrameStateInfo const&);
1671cb0ef41Sopenharmony_ci
1681cb0ef41Sopenharmony_cisize_t hash_value(FrameStateInfo const&);
1691cb0ef41Sopenharmony_ci
1701cb0ef41Sopenharmony_cistd::ostream& operator<<(std::ostream&, FrameStateInfo const&);
1711cb0ef41Sopenharmony_ci
1721cb0ef41Sopenharmony_cienum class ContinuationFrameStateMode { EAGER, LAZY, LAZY_WITH_CATCH };
1731cb0ef41Sopenharmony_ci
1741cb0ef41Sopenharmony_ciclass FrameState;
1751cb0ef41Sopenharmony_ci
1761cb0ef41Sopenharmony_ciFrameState CreateStubBuiltinContinuationFrameState(
1771cb0ef41Sopenharmony_ci    JSGraph* graph, Builtin name, Node* context, Node* const* parameters,
1781cb0ef41Sopenharmony_ci    int parameter_count, Node* outer_frame_state,
1791cb0ef41Sopenharmony_ci    ContinuationFrameStateMode mode,
1801cb0ef41Sopenharmony_ci    const wasm::FunctionSig* signature = nullptr);
1811cb0ef41Sopenharmony_ci
1821cb0ef41Sopenharmony_ci#if V8_ENABLE_WEBASSEMBLY
1831cb0ef41Sopenharmony_ciFrameState CreateJSWasmCallBuiltinContinuationFrameState(
1841cb0ef41Sopenharmony_ci    JSGraph* jsgraph, Node* context, Node* outer_frame_state,
1851cb0ef41Sopenharmony_ci    const wasm::FunctionSig* signature);
1861cb0ef41Sopenharmony_ci#endif  // V8_ENABLE_WEBASSEMBLY
1871cb0ef41Sopenharmony_ci
1881cb0ef41Sopenharmony_ciFrameState CreateJavaScriptBuiltinContinuationFrameState(
1891cb0ef41Sopenharmony_ci    JSGraph* graph, const SharedFunctionInfoRef& shared, Builtin name,
1901cb0ef41Sopenharmony_ci    Node* target, Node* context, Node* const* stack_parameters,
1911cb0ef41Sopenharmony_ci    int stack_parameter_count, Node* outer_frame_state,
1921cb0ef41Sopenharmony_ci    ContinuationFrameStateMode mode);
1931cb0ef41Sopenharmony_ci
1941cb0ef41Sopenharmony_ciFrameState CreateGenericLazyDeoptContinuationFrameState(
1951cb0ef41Sopenharmony_ci    JSGraph* graph, const SharedFunctionInfoRef& shared, Node* target,
1961cb0ef41Sopenharmony_ci    Node* context, Node* receiver, Node* outer_frame_state);
1971cb0ef41Sopenharmony_ci
1981cb0ef41Sopenharmony_ci}  // namespace compiler
1991cb0ef41Sopenharmony_ci}  // namespace internal
2001cb0ef41Sopenharmony_ci}  // namespace v8
2011cb0ef41Sopenharmony_ci
2021cb0ef41Sopenharmony_ci#endif  // V8_COMPILER_FRAME_STATES_H_
203