Ben Murdoch | 4a90d5f | 2016-03-22 12:00:34 +0000 | [diff] [blame^] | 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_ |