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