1// Copyright 2015 the V8 project authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#ifndef V8_COMPILER_FRAME_STATES_H_
6#define V8_COMPILER_FRAME_STATES_H_
7
8#include "src/builtins/builtins.h"
9#include "src/compiler/node.h"
10#include "src/handles/handles.h"
11#include "src/objects/shared-function-info.h"
12#include "src/utils/utils.h"
13
14namespace v8 {
15namespace internal {
16
17namespace wasm {
18class ValueType;
19using FunctionSig = Signature<ValueType>;
20}  // namespace wasm
21
22namespace compiler {
23
24class JSGraph;
25class Node;
26class SharedFunctionInfoRef;
27
28// Flag that describes how to combine the current environment with
29// the output of a node to obtain a framestate for lazy bailout.
30class OutputFrameStateCombine {
31 public:
32  static const size_t kInvalidIndex = SIZE_MAX;
33
34  static OutputFrameStateCombine Ignore() {
35    return OutputFrameStateCombine(kInvalidIndex);
36  }
37  static OutputFrameStateCombine PokeAt(size_t index) {
38    return OutputFrameStateCombine(index);
39  }
40
41  size_t GetOffsetToPokeAt() const {
42    DCHECK_NE(parameter_, kInvalidIndex);
43    return parameter_;
44  }
45
46  bool IsOutputIgnored() const { return parameter_ == kInvalidIndex; }
47
48  size_t ConsumedOutputCount() const { return IsOutputIgnored() ? 0 : 1; }
49
50  bool operator==(OutputFrameStateCombine const& other) const {
51    return parameter_ == other.parameter_;
52  }
53  bool operator!=(OutputFrameStateCombine const& other) const {
54    return !(*this == other);
55  }
56
57  friend size_t hash_value(OutputFrameStateCombine const&);
58  friend std::ostream& operator<<(std::ostream&,
59                                  OutputFrameStateCombine const&);
60
61 private:
62  explicit OutputFrameStateCombine(size_t parameter) : parameter_(parameter) {}
63
64  size_t const parameter_;
65};
66
67
68// The type of stack frame that a FrameState node represents.
69enum class FrameStateType {
70  kUnoptimizedFunction,            // Represents an UnoptimizedFrame.
71  kArgumentsAdaptor,               // Represents an ArgumentsAdaptorFrame.
72  kConstructStub,                  // Represents a ConstructStubFrame.
73  kBuiltinContinuation,            // Represents a continuation to a stub.
74#if V8_ENABLE_WEBASSEMBLY          // ↓ WebAssembly only
75  kJSToWasmBuiltinContinuation,    // Represents a lazy deopt continuation for a
76                                   // JS to Wasm call.
77#endif                             // ↑ WebAssembly only
78  kJavaScriptBuiltinContinuation,  // Represents a continuation to a JavaScipt
79                                   // builtin.
80  kJavaScriptBuiltinContinuationWithCatch  // Represents a continuation to a
81                                           // JavaScipt builtin with a catch
82                                           // handler.
83};
84
85class FrameStateFunctionInfo {
86 public:
87  FrameStateFunctionInfo(FrameStateType type, int parameter_count,
88                         int local_count,
89                         Handle<SharedFunctionInfo> shared_info)
90      : type_(type),
91        parameter_count_(parameter_count),
92        local_count_(local_count),
93        shared_info_(shared_info) {}
94
95  int local_count() const { return local_count_; }
96  int parameter_count() const { return parameter_count_; }
97  Handle<SharedFunctionInfo> shared_info() const { return shared_info_; }
98  FrameStateType type() const { return type_; }
99
100  static bool IsJSFunctionType(FrameStateType type) {
101    return type == FrameStateType::kUnoptimizedFunction ||
102           type == FrameStateType::kJavaScriptBuiltinContinuation ||
103           type == FrameStateType::kJavaScriptBuiltinContinuationWithCatch;
104  }
105
106 private:
107  FrameStateType const type_;
108  int const parameter_count_;
109  int const local_count_;
110  Handle<SharedFunctionInfo> const shared_info_;
111};
112
113#if V8_ENABLE_WEBASSEMBLY
114class JSToWasmFrameStateFunctionInfo : public FrameStateFunctionInfo {
115 public:
116  JSToWasmFrameStateFunctionInfo(FrameStateType type, int parameter_count,
117                                 int local_count,
118                                 Handle<SharedFunctionInfo> shared_info,
119                                 const wasm::FunctionSig* signature)
120      : FrameStateFunctionInfo(type, parameter_count, local_count, shared_info),
121        signature_(signature) {
122    DCHECK_NOT_NULL(signature);
123  }
124
125  const wasm::FunctionSig* signature() const { return signature_; }
126
127 private:
128  const wasm::FunctionSig* const signature_;
129};
130#endif  // V8_ENABLE_WEBASSEMBLY
131
132class FrameStateInfo final {
133 public:
134  FrameStateInfo(BytecodeOffset bailout_id,
135                 OutputFrameStateCombine state_combine,
136                 const FrameStateFunctionInfo* info)
137      : bailout_id_(bailout_id),
138        frame_state_combine_(state_combine),
139        info_(info) {}
140
141  FrameStateType type() const {
142    return info_ == nullptr ? FrameStateType::kUnoptimizedFunction
143                            : info_->type();
144  }
145  BytecodeOffset bailout_id() const { return bailout_id_; }
146  OutputFrameStateCombine state_combine() const { return frame_state_combine_; }
147  MaybeHandle<SharedFunctionInfo> shared_info() const {
148    return info_ == nullptr ? MaybeHandle<SharedFunctionInfo>()
149                            : info_->shared_info();
150  }
151  int parameter_count() const {
152    return info_ == nullptr ? 0 : info_->parameter_count();
153  }
154  int local_count() const {
155    return info_ == nullptr ? 0 : info_->local_count();
156  }
157  const FrameStateFunctionInfo* function_info() const { return info_; }
158
159 private:
160  BytecodeOffset const bailout_id_;
161  OutputFrameStateCombine const frame_state_combine_;
162  const FrameStateFunctionInfo* const info_;
163};
164
165bool operator==(FrameStateInfo const&, FrameStateInfo const&);
166bool operator!=(FrameStateInfo const&, FrameStateInfo const&);
167
168size_t hash_value(FrameStateInfo const&);
169
170std::ostream& operator<<(std::ostream&, FrameStateInfo const&);
171
172enum class ContinuationFrameStateMode { EAGER, LAZY, LAZY_WITH_CATCH };
173
174class FrameState;
175
176FrameState CreateStubBuiltinContinuationFrameState(
177    JSGraph* graph, Builtin name, Node* context, Node* const* parameters,
178    int parameter_count, Node* outer_frame_state,
179    ContinuationFrameStateMode mode,
180    const wasm::FunctionSig* signature = nullptr);
181
182#if V8_ENABLE_WEBASSEMBLY
183FrameState CreateJSWasmCallBuiltinContinuationFrameState(
184    JSGraph* jsgraph, Node* context, Node* outer_frame_state,
185    const wasm::FunctionSig* signature);
186#endif  // V8_ENABLE_WEBASSEMBLY
187
188FrameState CreateJavaScriptBuiltinContinuationFrameState(
189    JSGraph* graph, const SharedFunctionInfoRef& shared, Builtin name,
190    Node* target, Node* context, Node* const* stack_parameters,
191    int stack_parameter_count, Node* outer_frame_state,
192    ContinuationFrameStateMode mode);
193
194FrameState CreateGenericLazyDeoptContinuationFrameState(
195    JSGraph* graph, const SharedFunctionInfoRef& shared, Node* target,
196    Node* context, Node* receiver, Node* outer_frame_state);
197
198}  // namespace compiler
199}  // namespace internal
200}  // namespace v8
201
202#endif  // V8_COMPILER_FRAME_STATES_H_
203