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 kTailCallerFunction, // Represents a frame removed by tail call elimination. 83 kConstructStub, // Represents a ConstructStubFrame. 84 kGetterStub, // Represents a GetterStubFrame. 85 kSetterStub // Represents a SetterStubFrame. 86 }; 87 88 class FrameStateFunctionInfo { 89 public: 90 FrameStateFunctionInfo(FrameStateType type, int parameter_count, 91 int local_count, 92 Handle<SharedFunctionInfo> shared_info) 93 : type_(type), 94 parameter_count_(parameter_count), 95 local_count_(local_count), 96 shared_info_(shared_info) {} 97 98 int local_count() const { return local_count_; } 99 int parameter_count() const { return parameter_count_; } 100 Handle<SharedFunctionInfo> shared_info() const { return shared_info_; } 101 FrameStateType type() const { return type_; } 102 103 static bool IsJSFunctionType(FrameStateType type) { 104 return type == FrameStateType::kJavaScriptFunction || 105 type == FrameStateType::kInterpretedFunction; 106 } 107 108 private: 109 FrameStateType const type_; 110 int const parameter_count_; 111 int const local_count_; 112 Handle<SharedFunctionInfo> const shared_info_; 113 }; 114 115 116 class FrameStateInfo final { 117 public: 118 FrameStateInfo(BailoutId bailout_id, OutputFrameStateCombine state_combine, 119 const FrameStateFunctionInfo* info) 120 : bailout_id_(bailout_id), 121 frame_state_combine_(state_combine), 122 info_(info) {} 123 124 FrameStateType type() const { 125 return info_ == nullptr ? FrameStateType::kJavaScriptFunction 126 : info_->type(); 127 } 128 BailoutId bailout_id() const { return bailout_id_; } 129 OutputFrameStateCombine state_combine() const { return frame_state_combine_; } 130 MaybeHandle<SharedFunctionInfo> shared_info() const { 131 return info_ == nullptr ? MaybeHandle<SharedFunctionInfo>() 132 : info_->shared_info(); 133 } 134 int parameter_count() const { 135 return info_ == nullptr ? 0 : info_->parameter_count(); 136 } 137 int local_count() const { 138 return info_ == nullptr ? 0 : info_->local_count(); 139 } 140 const FrameStateFunctionInfo* function_info() const { return info_; } 141 142 private: 143 BailoutId const bailout_id_; 144 OutputFrameStateCombine const frame_state_combine_; 145 const FrameStateFunctionInfo* const info_; 146 }; 147 148 bool operator==(FrameStateInfo const&, FrameStateInfo const&); 149 bool operator!=(FrameStateInfo const&, FrameStateInfo const&); 150 151 size_t hash_value(FrameStateInfo const&); 152 153 std::ostream& operator<<(std::ostream&, FrameStateInfo const&); 154 155 static const int kFrameStateParametersInput = 0; 156 static const int kFrameStateLocalsInput = 1; 157 static const int kFrameStateStackInput = 2; 158 static const int kFrameStateContextInput = 3; 159 static const int kFrameStateFunctionInput = 4; 160 static const int kFrameStateOuterStateInput = 5; 161 static const int kFrameStateInputCount = kFrameStateOuterStateInput + 1; 162 163 } // namespace compiler 164 } // namespace internal 165 } // namespace v8 166 167 #endif // V8_COMPILER_FRAME_STATES_H_ 168