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/handles.h" 9 #include "src/utils.h" 10 11 namespace v8 { 12 namespace internal { 13 14 // Forward declarations. 15 class SharedFunctionInfo; 16 17 namespace compiler { 18 19 // Flag that describes how to combine the current environment with 20 // the output of a node to obtain a framestate for lazy bailout. 21 class OutputFrameStateCombine { 22 public: 23 enum Kind { 24 kPushOutput, // Push the output on the expression stack. 25 kPokeAt // Poke at the given environment location, 26 // counting from the top of the stack. 27 }; 28 29 static OutputFrameStateCombine Ignore() { 30 return OutputFrameStateCombine(kPushOutput, 0); 31 } 32 static OutputFrameStateCombine Push(size_t count = 1) { 33 return OutputFrameStateCombine(kPushOutput, count); 34 } 35 static OutputFrameStateCombine PokeAt(size_t index) { 36 return OutputFrameStateCombine(kPokeAt, index); 37 } 38 39 Kind kind() const { return kind_; } 40 size_t GetPushCount() const { 41 DCHECK_EQ(kPushOutput, kind()); 42 return parameter_; 43 } 44 size_t GetOffsetToPokeAt() const { 45 DCHECK_EQ(kPokeAt, kind()); 46 return parameter_; 47 } 48 49 bool IsOutputIgnored() const { 50 return kind_ == kPushOutput && parameter_ == 0; 51 } 52 53 size_t ConsumedOutputCount() const { 54 return kind_ == kPushOutput ? GetPushCount() : 1; 55 } 56 57 bool operator==(OutputFrameStateCombine const& other) const { 58 return kind_ == other.kind_ && parameter_ == other.parameter_; 59 } 60 bool operator!=(OutputFrameStateCombine const& other) const { 61 return !(*this == other); 62 } 63 64 friend size_t hash_value(OutputFrameStateCombine const&); 65 friend std::ostream& operator<<(std::ostream&, 66 OutputFrameStateCombine const&); 67 68 private: 69 OutputFrameStateCombine(Kind kind, size_t parameter) 70 : kind_(kind), parameter_(parameter) {} 71 72 Kind const kind_; 73 size_t const parameter_; 74 }; 75 76 77 // The type of stack frame that a FrameState node represents. 78 enum class FrameStateType { 79 kJavaScriptFunction, // Represents an unoptimized JavaScriptFrame. 80 kInterpretedFunction, // Represents an InterpretedFrame. 81 kArgumentsAdaptor, // Represents an ArgumentsAdaptorFrame. 82 kConstructStub // Represents a ConstructStubFrame. 83 }; 84 85 86 enum ContextCallingMode { 87 CALL_MAINTAINS_NATIVE_CONTEXT, 88 CALL_CHANGES_NATIVE_CONTEXT 89 }; 90 91 92 class FrameStateFunctionInfo { 93 public: 94 FrameStateFunctionInfo(FrameStateType type, int parameter_count, 95 int local_count, 96 Handle<SharedFunctionInfo> shared_info, 97 ContextCallingMode context_calling_mode) 98 : type_(type), 99 parameter_count_(parameter_count), 100 local_count_(local_count), 101 shared_info_(shared_info), 102 context_calling_mode_(context_calling_mode) {} 103 104 int local_count() const { return local_count_; } 105 int parameter_count() const { return parameter_count_; } 106 Handle<SharedFunctionInfo> shared_info() const { return shared_info_; } 107 FrameStateType type() const { return type_; } 108 ContextCallingMode context_calling_mode() const { 109 return context_calling_mode_; 110 } 111 112 static bool IsJSFunctionType(FrameStateType type) { 113 return type == FrameStateType::kJavaScriptFunction || 114 type == FrameStateType::kInterpretedFunction; 115 } 116 117 private: 118 FrameStateType const type_; 119 int const parameter_count_; 120 int const local_count_; 121 Handle<SharedFunctionInfo> const shared_info_; 122 ContextCallingMode context_calling_mode_; 123 }; 124 125 126 class FrameStateInfo final { 127 public: 128 FrameStateInfo(BailoutId bailout_id, OutputFrameStateCombine state_combine, 129 const FrameStateFunctionInfo* info) 130 : bailout_id_(bailout_id), 131 frame_state_combine_(state_combine), 132 info_(info) {} 133 134 FrameStateType type() const { 135 return info_ == nullptr ? FrameStateType::kJavaScriptFunction 136 : info_->type(); 137 } 138 BailoutId bailout_id() const { return bailout_id_; } 139 OutputFrameStateCombine state_combine() const { return frame_state_combine_; } 140 MaybeHandle<SharedFunctionInfo> shared_info() const { 141 return info_ == nullptr ? MaybeHandle<SharedFunctionInfo>() 142 : info_->shared_info(); 143 } 144 int parameter_count() const { 145 return info_ == nullptr ? 0 : info_->parameter_count(); 146 } 147 int local_count() const { 148 return info_ == nullptr ? 0 : info_->local_count(); 149 } 150 const FrameStateFunctionInfo* function_info() const { return info_; } 151 152 private: 153 BailoutId const bailout_id_; 154 OutputFrameStateCombine const frame_state_combine_; 155 const FrameStateFunctionInfo* const info_; 156 }; 157 158 bool operator==(FrameStateInfo const&, FrameStateInfo const&); 159 bool operator!=(FrameStateInfo const&, FrameStateInfo const&); 160 161 size_t hash_value(FrameStateInfo const&); 162 163 std::ostream& operator<<(std::ostream&, FrameStateInfo const&); 164 165 static const int kFrameStateParametersInput = 0; 166 static const int kFrameStateLocalsInput = 1; 167 static const int kFrameStateStackInput = 2; 168 static const int kFrameStateContextInput = 3; 169 static const int kFrameStateFunctionInput = 4; 170 static const int kFrameStateOuterStateInput = 5; 171 static const int kFrameStateInputCount = kFrameStateOuterStateInput + 1; 172 173 } // namespace compiler 174 } // namespace internal 175 } // namespace v8 176 177 #endif // V8_COMPILER_FRAME_STATES_H_ 178