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 14 namespace v8 { 15 namespace internal { 16 17 namespace wasm { 18 class ValueType; 19 using FunctionSig = Signature<ValueType>; 20 } // namespace wasm 21 22 namespace compiler { 23 24 class JSGraph; 25 class Node; 26 class 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. 30 class OutputFrameStateCombine { 31 public: 32 static const size_t kInvalidIndex = SIZE_MAX; 33 Ignore()34 static OutputFrameStateCombine Ignore() { 35 return OutputFrameStateCombine(kInvalidIndex); 36 } PokeAt(size_t index)37 static OutputFrameStateCombine PokeAt(size_t index) { 38 return OutputFrameStateCombine(index); 39 } 40 GetOffsetToPokeAt()41 size_t GetOffsetToPokeAt() const { 42 DCHECK_NE(parameter_, kInvalidIndex); 43 return parameter_; 44 } 45 IsOutputIgnored()46 bool IsOutputIgnored() const { return parameter_ == kInvalidIndex; } 47 ConsumedOutputCount()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: OutputFrameStateCombine(size_t parameter)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. 69 enum 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 85 class FrameStateFunctionInfo { 86 public: FrameStateFunctionInfo(FrameStateType type,int parameter_count,int local_count,Handle<SharedFunctionInfo> shared_info)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 local_count()95 int local_count() const { return local_count_; } parameter_count()96 int parameter_count() const { return parameter_count_; } shared_info()97 Handle<SharedFunctionInfo> shared_info() const { return shared_info_; } type()98 FrameStateType type() const { return type_; } 99 IsJSFunctionType(FrameStateType type)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 114 class JSToWasmFrameStateFunctionInfo : public FrameStateFunctionInfo { 115 public: JSToWasmFrameStateFunctionInfo(FrameStateType type,int parameter_count,int local_count,Handle<SharedFunctionInfo> shared_info,const wasm::FunctionSig * signature)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 signature()125 const wasm::FunctionSig* signature() const { return signature_; } 126 127 private: 128 const wasm::FunctionSig* const signature_; 129 }; 130 #endif // V8_ENABLE_WEBASSEMBLY 131 132 class FrameStateInfo final { 133 public: FrameStateInfo(BytecodeOffset bailout_id,OutputFrameStateCombine state_combine,const FrameStateFunctionInfo * info)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 type()141 FrameStateType type() const { 142 return info_ == nullptr ? FrameStateType::kUnoptimizedFunction 143 : info_->type(); 144 } bailout_id()145 BytecodeOffset bailout_id() const { return bailout_id_; } state_combine()146 OutputFrameStateCombine state_combine() const { return frame_state_combine_; } shared_info()147 MaybeHandle<SharedFunctionInfo> shared_info() const { 148 return info_ == nullptr ? MaybeHandle<SharedFunctionInfo>() 149 : info_->shared_info(); 150 } parameter_count()151 int parameter_count() const { 152 return info_ == nullptr ? 0 : info_->parameter_count(); 153 } local_count()154 int local_count() const { 155 return info_ == nullptr ? 0 : info_->local_count(); 156 } function_info()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 165 bool operator==(FrameStateInfo const&, FrameStateInfo const&); 166 bool operator!=(FrameStateInfo const&, FrameStateInfo const&); 167 168 size_t hash_value(FrameStateInfo const&); 169 170 std::ostream& operator<<(std::ostream&, FrameStateInfo const&); 171 172 enum class ContinuationFrameStateMode { EAGER, LAZY, LAZY_WITH_CATCH }; 173 174 class FrameState; 175 176 FrameState 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 183 FrameState CreateJSWasmCallBuiltinContinuationFrameState( 184 JSGraph* jsgraph, Node* context, Node* outer_frame_state, 185 const wasm::FunctionSig* signature); 186 #endif // V8_ENABLE_WEBASSEMBLY 187 188 FrameState 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 194 FrameState 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