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. |
Ben Murdoch | da12d29 | 2016-06-02 14:46:10 +0100 | [diff] [blame] | 82 | kTailCallerFunction, // Represents a frame removed by tail call elimination. |
Ben Murdoch | 4a90d5f | 2016-03-22 12:00:34 +0000 | [diff] [blame] | 83 | kConstructStub // Represents a ConstructStubFrame. |
| 84 | }; |
| 85 | |
Ben Murdoch | 4a90d5f | 2016-03-22 12:00:34 +0000 | [diff] [blame] | 86 | class FrameStateFunctionInfo { |
| 87 | public: |
| 88 | FrameStateFunctionInfo(FrameStateType type, int parameter_count, |
| 89 | int local_count, |
Ben Murdoch | 097c5b2 | 2016-05-18 11:27:45 +0100 | [diff] [blame] | 90 | Handle<SharedFunctionInfo> shared_info) |
Ben Murdoch | 4a90d5f | 2016-03-22 12:00:34 +0000 | [diff] [blame] | 91 | : type_(type), |
| 92 | parameter_count_(parameter_count), |
| 93 | local_count_(local_count), |
Ben Murdoch | 097c5b2 | 2016-05-18 11:27:45 +0100 | [diff] [blame] | 94 | shared_info_(shared_info) {} |
Ben Murdoch | 4a90d5f | 2016-03-22 12:00:34 +0000 | [diff] [blame] | 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_; } |
Ben Murdoch | 4a90d5f | 2016-03-22 12:00:34 +0000 | [diff] [blame] | 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_; |
Ben Murdoch | 4a90d5f | 2016-03-22 12:00:34 +0000 | [diff] [blame] | 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_ |