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