OLD | NEW |
---|---|
1 // Copyright 2014 the V8 project authors. All rights reserved. | 1 // Copyright 2014 the V8 project authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "src/compiler/js-operator.h" | 5 #include "src/compiler/js-operator.h" |
6 #include "src/compiler/opcodes.h" | 6 #include "src/compiler/opcodes.h" |
7 #include "src/compiler/operator.h" | 7 #include "src/compiler/operator.h" |
8 #include "src/compiler/operator-properties.h" | 8 #include "src/compiler/operator-properties.h" |
9 #include "test/unittests/test-utils.h" | 9 #include "test/unittests/test-utils.h" |
10 | 10 |
11 namespace v8 { | 11 namespace v8 { |
12 namespace internal { | 12 namespace internal { |
13 namespace compiler { | 13 namespace compiler { |
14 | 14 |
15 // ----------------------------------------------------------------------------- | |
16 // Shared operators. | |
17 | |
18 | 15 |
19 namespace { | 16 namespace { |
20 | 17 |
18 typedef const Operator* (JSOperatorBuilder::*no_params_t) () ; | |
19 | |
20 typedef const Operator* (JSOperatorBuilder::*with_language_mode_t) | |
21 (LanguageMode language_mode) ; | |
22 | |
23 | |
24 template <typename T> | |
21 struct SharedOperator { | 25 struct SharedOperator { |
22 const Operator* (JSOperatorBuilder::*constructor)(); | 26 T constructor; |
23 IrOpcode::Value opcode; | 27 IrOpcode::Value opcode; |
24 Operator::Properties properties; | 28 Operator::Properties properties; |
25 int value_input_count; | 29 int value_input_count; |
26 int frame_state_input_count; | 30 int frame_state_input_count; |
27 int effect_input_count; | 31 int effect_input_count; |
28 int control_input_count; | 32 int control_input_count; |
29 int value_output_count; | 33 int value_output_count; |
30 int effect_output_count; | 34 int effect_output_count; |
31 int control_output_count; | 35 int control_output_count; |
32 }; | 36 }; |
33 | 37 |
34 | 38 |
35 std::ostream& operator<<(std::ostream& os, const SharedOperator& sop) { | 39 const SharedOperator<no_params_t> kSharedOperators[] = { |
36 return os << IrOpcode::Mnemonic(sop.opcode); | |
37 } | |
38 | |
39 | |
40 const SharedOperator kSharedOperators[] = { | |
41 #define SHARED(Name, properties, value_input_count, frame_state_input_count, \ | 40 #define SHARED(Name, properties, value_input_count, frame_state_input_count, \ |
42 effect_input_count, control_input_count, value_output_count, \ | 41 effect_input_count, control_input_count, value_output_count, \ |
43 effect_output_count, control_output_count) \ | 42 effect_output_count, control_output_count) \ |
44 { \ | 43 { \ |
45 &JSOperatorBuilder::Name, IrOpcode::kJS##Name, properties, \ | 44 &JSOperatorBuilder::Name, IrOpcode::kJS##Name, properties, \ |
46 value_input_count, frame_state_input_count, effect_input_count, \ | 45 value_input_count, frame_state_input_count, effect_input_count, \ |
47 control_input_count, value_output_count, effect_output_count, \ | 46 control_input_count, value_output_count, effect_output_count, \ |
48 control_output_count \ | 47 control_output_count \ |
49 } | 48 } |
50 SHARED(Equal, Operator::kNoProperties, 2, 1, 1, 1, 1, 1, 2), | 49 SHARED(Equal, Operator::kNoProperties, 2, 1, 1, 1, 1, 1, 2), |
51 SHARED(NotEqual, Operator::kNoProperties, 2, 1, 1, 1, 1, 1, 2), | 50 SHARED(NotEqual, Operator::kNoProperties, 2, 1, 1, 1, 1, 1, 2), |
52 SHARED(StrictEqual, Operator::kPure, 2, 0, 0, 0, 1, 0, 0), | 51 SHARED(StrictEqual, Operator::kPure, 2, 0, 0, 0, 1, 0, 0), |
53 SHARED(StrictNotEqual, Operator::kPure, 2, 0, 0, 0, 1, 0, 0), | 52 SHARED(StrictNotEqual, Operator::kPure, 2, 0, 0, 0, 1, 0, 0), |
54 SHARED(LessThan, Operator::kNoProperties, 2, 1, 1, 1, 1, 1, 2), | |
55 SHARED(GreaterThan, Operator::kNoProperties, 2, 1, 1, 1, 1, 1, 2), | |
56 SHARED(LessThanOrEqual, Operator::kNoProperties, 2, 1, 1, 1, 1, 1, 2), | |
57 SHARED(GreaterThanOrEqual, Operator::kNoProperties, 2, 1, 1, 1, 1, 1, 2), | |
58 SHARED(BitwiseOr, Operator::kNoProperties, 2, 2, 1, 1, 1, 1, 2), | |
59 SHARED(BitwiseXor, Operator::kNoProperties, 2, 2, 1, 1, 1, 1, 2), | |
60 SHARED(BitwiseAnd, Operator::kNoProperties, 2, 2, 1, 1, 1, 1, 2), | |
61 SHARED(ShiftLeft, Operator::kNoProperties, 2, 2, 1, 1, 1, 1, 2), | |
62 SHARED(ShiftRight, Operator::kNoProperties, 2, 2, 1, 1, 1, 1, 2), | |
63 SHARED(ShiftRightLogical, Operator::kNoProperties, 2, 2, 1, 1, 1, 1, 2), | |
64 SHARED(Add, Operator::kNoProperties, 2, 2, 1, 1, 1, 1, 2), | |
65 SHARED(Subtract, Operator::kNoProperties, 2, 2, 1, 1, 1, 1, 2), | |
66 SHARED(Multiply, Operator::kNoProperties, 2, 2, 1, 1, 1, 1, 2), | |
67 SHARED(Divide, Operator::kNoProperties, 2, 2, 1, 1, 1, 1, 2), | |
68 SHARED(Modulus, Operator::kNoProperties, 2, 2, 1, 1, 1, 1, 2), | |
69 SHARED(UnaryNot, Operator::kPure, 1, 0, 0, 0, 1, 0, 0), | 53 SHARED(UnaryNot, Operator::kPure, 1, 0, 0, 0, 1, 0, 0), |
70 SHARED(ToBoolean, Operator::kPure, 1, 0, 0, 0, 1, 0, 0), | 54 SHARED(ToBoolean, Operator::kPure, 1, 0, 0, 0, 1, 0, 0), |
71 SHARED(ToNumber, Operator::kNoProperties, 1, 1, 1, 1, 1, 1, 2), | 55 SHARED(ToNumber, Operator::kNoProperties, 1, 1, 1, 1, 1, 1, 2), |
72 SHARED(ToString, Operator::kNoProperties, 1, 0, 1, 1, 1, 1, 2), | 56 SHARED(ToString, Operator::kNoProperties, 1, 0, 1, 1, 1, 1, 2), |
73 SHARED(ToName, Operator::kNoProperties, 1, 1, 1, 1, 1, 1, 2), | 57 SHARED(ToName, Operator::kNoProperties, 1, 1, 1, 1, 1, 1, 2), |
74 SHARED(ToObject, Operator::kNoProperties, 1, 1, 1, 1, 1, 1, 2), | 58 SHARED(ToObject, Operator::kNoProperties, 1, 1, 1, 1, 1, 1, 2), |
75 SHARED(Yield, Operator::kNoProperties, 1, 0, 1, 1, 1, 1, 2), | 59 SHARED(Yield, Operator::kNoProperties, 1, 0, 1, 1, 1, 1, 2), |
76 SHARED(Create, Operator::kEliminatable, 0, 0, 1, 0, 1, 1, 0), | 60 SHARED(Create, Operator::kEliminatable, 0, 0, 1, 0, 1, 1, 0), |
77 SHARED(HasProperty, Operator::kNoProperties, 2, 1, 1, 1, 1, 1, 2), | 61 SHARED(HasProperty, Operator::kNoProperties, 2, 1, 1, 1, 1, 1, 2), |
78 SHARED(TypeOf, Operator::kPure, 1, 0, 0, 0, 1, 0, 0), | 62 SHARED(TypeOf, Operator::kPure, 1, 0, 0, 0, 1, 0, 0), |
79 SHARED(InstanceOf, Operator::kNoProperties, 2, 1, 1, 1, 1, 1, 2), | 63 SHARED(InstanceOf, Operator::kNoProperties, 2, 1, 1, 1, 1, 1, 2), |
80 SHARED(CreateFunctionContext, Operator::kNoProperties, 1, 0, 1, 1, 1, 1, 2), | 64 SHARED(CreateFunctionContext, Operator::kNoProperties, 1, 0, 1, 1, 1, 1, 2), |
81 SHARED(CreateWithContext, Operator::kNoProperties, 2, 1, 1, 1, 1, 1, 2), | 65 SHARED(CreateWithContext, Operator::kNoProperties, 2, 1, 1, 1, 1, 1, 2), |
82 SHARED(CreateBlockContext, Operator::kNoProperties, 2, 0, 1, 1, 1, 1, 2), | 66 SHARED(CreateBlockContext, Operator::kNoProperties, 2, 0, 1, 1, 1, 1, 2), |
83 SHARED(CreateModuleContext, Operator::kNoProperties, 2, 0, 1, 1, 1, 1, 2), | 67 SHARED(CreateModuleContext, Operator::kNoProperties, 2, 0, 1, 1, 1, 1, 2), |
84 SHARED(CreateScriptContext, Operator::kNoProperties, 2, 1, 1, 1, 1, 1, 2) | 68 SHARED(CreateScriptContext, Operator::kNoProperties, 2, 1, 1, 1, 1, 1, 2) |
85 #undef SHARED | 69 #undef SHARED |
86 }; | 70 }; |
87 | 71 |
88 } // namespace | 72 |
73 const SharedOperator<with_language_mode_t> | |
74 kSharedOperatorsWithlanguageMode[] = { | |
arv (Not doing code reviews)
2015/04/24 14:14:23
strange indentation
conradw
2015/04/24 14:42:32
I guess I was slightly religious in sticking to th
| |
75 #define SHARED(Name, properties, value_input_count, frame_state_input_count, \ | |
76 effect_input_count, control_input_count, value_output_count, \ | |
77 effect_output_count, control_output_count) \ | |
78 { \ | |
79 &JSOperatorBuilder::Name, IrOpcode::kJS##Name, properties, \ | |
80 value_input_count, frame_state_input_count, effect_input_count, \ | |
81 control_input_count, value_output_count, effect_output_count, \ | |
82 control_output_count \ | |
83 } | |
84 SHARED(LessThan, Operator::kNoProperties, 2, 1, 1, 1, 1, 1, 2), | |
85 SHARED(GreaterThan, Operator::kNoProperties, 2, 1, 1, 1, 1, 1, 2), | |
86 SHARED(LessThanOrEqual, Operator::kNoProperties, 2, 1, 1, 1, 1, 1, 2), | |
87 SHARED(GreaterThanOrEqual, Operator::kNoProperties, 2, 1, 1, 1, 1, 1, 2), | |
88 SHARED(BitwiseOr, Operator::kNoProperties, 2, 2, 1, 1, 1, 1, 2), | |
89 SHARED(BitwiseXor, Operator::kNoProperties, 2, 2, 1, 1, 1, 1, 2), | |
90 SHARED(BitwiseAnd, Operator::kNoProperties, 2, 2, 1, 1, 1, 1, 2), | |
91 SHARED(ShiftLeft, Operator::kNoProperties, 2, 2, 1, 1, 1, 1, 2), | |
92 SHARED(ShiftRight, Operator::kNoProperties, 2, 2, 1, 1, 1, 1, 2), | |
93 SHARED(ShiftRightLogical, Operator::kNoProperties, 2, 2, 1, 1, 1, 1, 2), | |
94 SHARED(Add, Operator::kNoProperties, 2, 2, 1, 1, 1, 1, 2), | |
95 SHARED(Subtract, Operator::kNoProperties, 2, 2, 1, 1, 1, 1, 2), | |
96 SHARED(Multiply, Operator::kNoProperties, 2, 2, 1, 1, 1, 1, 2), | |
97 SHARED(Divide, Operator::kNoProperties, 2, 2, 1, 1, 1, 1, 2), | |
98 SHARED(Modulus, Operator::kNoProperties, 2, 2, 1, 1, 1, 1, 2), | |
99 #undef SHARED | |
100 }; | |
89 | 101 |
90 | 102 |
91 class JSSharedOperatorTest | 103 template <typename T> |
92 : public TestWithZone, | 104 void testNumberOfInputsAndOutputs(const SharedOperator<T>& sop, |
93 public ::testing::WithParamInterface<SharedOperator> {}; | 105 const Operator* op) { |
94 | |
95 | |
96 TEST_P(JSSharedOperatorTest, InstancesAreGloballyShared) { | |
97 const SharedOperator& sop = GetParam(); | |
98 JSOperatorBuilder javascript1(zone()); | |
99 JSOperatorBuilder javascript2(zone()); | |
100 EXPECT_EQ((javascript1.*sop.constructor)(), (javascript2.*sop.constructor)()); | |
101 } | |
102 | |
103 | |
104 TEST_P(JSSharedOperatorTest, NumberOfInputsAndOutputs) { | |
105 JSOperatorBuilder javascript(zone()); | |
106 const SharedOperator& sop = GetParam(); | |
107 const Operator* op = (javascript.*sop.constructor)(); | |
108 | |
109 const int context_input_count = 1; | 106 const int context_input_count = 1; |
110 EXPECT_EQ(sop.value_input_count, op->ValueInputCount()); | 107 EXPECT_EQ(sop.value_input_count, op->ValueInputCount()); |
111 EXPECT_EQ(context_input_count, OperatorProperties::GetContextInputCount(op)); | 108 EXPECT_EQ(context_input_count, OperatorProperties::GetContextInputCount(op)); |
112 EXPECT_EQ(sop.frame_state_input_count, | 109 EXPECT_EQ(sop.frame_state_input_count, |
113 OperatorProperties::GetFrameStateInputCount(op)); | 110 OperatorProperties::GetFrameStateInputCount(op)); |
114 EXPECT_EQ(sop.effect_input_count, op->EffectInputCount()); | 111 EXPECT_EQ(sop.effect_input_count, op->EffectInputCount()); |
115 EXPECT_EQ(sop.control_input_count, op->ControlInputCount()); | 112 EXPECT_EQ(sop.control_input_count, op->ControlInputCount()); |
116 EXPECT_EQ(sop.value_input_count + context_input_count + | 113 EXPECT_EQ(sop.value_input_count + context_input_count + |
117 sop.frame_state_input_count + sop.effect_input_count + | 114 sop.frame_state_input_count + sop.effect_input_count + |
118 sop.control_input_count, | 115 sop.control_input_count, |
119 OperatorProperties::GetTotalInputCount(op)); | 116 OperatorProperties::GetTotalInputCount(op)); |
120 | 117 |
121 EXPECT_EQ(sop.value_output_count, op->ValueOutputCount()); | 118 EXPECT_EQ(sop.value_output_count, op->ValueOutputCount()); |
122 EXPECT_EQ(sop.effect_output_count, op->EffectOutputCount()); | 119 EXPECT_EQ(sop.effect_output_count, op->EffectOutputCount()); |
123 EXPECT_EQ(sop.control_output_count, op->ControlOutputCount()); | 120 EXPECT_EQ(sop.control_output_count, op->ControlOutputCount()); |
124 } | 121 } |
125 | 122 |
126 | 123 |
124 std::ostream& operator<<(std::ostream& os, | |
125 const SharedOperator<no_params_t>& sop) { | |
126 return os << IrOpcode::Mnemonic(sop.opcode); | |
127 } | |
128 | |
129 | |
130 std::ostream& operator<<(std::ostream& os, | |
131 const SharedOperator<with_language_mode_t>& sop) { | |
132 return os << IrOpcode::Mnemonic(sop.opcode); | |
133 } | |
134 | |
135 } // namespace | |
136 | |
137 | |
138 // ----------------------------------------------------------------------------- | |
139 // Shared operators. | |
140 | |
141 | |
142 class JSSharedOperatorTest | |
143 : public TestWithZone, | |
144 public ::testing::WithParamInterface<SharedOperator<no_params_t>> {}; | |
145 | |
146 | |
147 TEST_P(JSSharedOperatorTest, InstancesAreGloballyShared) { | |
148 const SharedOperator<no_params_t>& sop = GetParam(); | |
149 JSOperatorBuilder javascript1(zone()); | |
150 JSOperatorBuilder javascript2(zone()); | |
151 EXPECT_EQ((javascript1.*sop.constructor)(), (javascript2.*sop.constructor)()); | |
152 } | |
153 | |
154 | |
155 TEST_P(JSSharedOperatorTest, NumberOfInputsAndOutputs) { | |
156 JSOperatorBuilder javascript(zone()); | |
157 const SharedOperator<no_params_t>& sop = GetParam(); | |
158 const Operator* op = (javascript.*sop.constructor)(); | |
159 testNumberOfInputsAndOutputs(sop, op); | |
160 } | |
161 | |
162 | |
127 TEST_P(JSSharedOperatorTest, OpcodeIsCorrect) { | 163 TEST_P(JSSharedOperatorTest, OpcodeIsCorrect) { |
128 JSOperatorBuilder javascript(zone()); | 164 JSOperatorBuilder javascript(zone()); |
129 const SharedOperator& sop = GetParam(); | 165 const SharedOperator<no_params_t>& sop = GetParam(); |
130 const Operator* op = (javascript.*sop.constructor)(); | 166 const Operator* op = (javascript.*sop.constructor)(); |
131 EXPECT_EQ(sop.opcode, op->opcode()); | 167 EXPECT_EQ(sop.opcode, op->opcode()); |
132 } | 168 } |
133 | 169 |
134 | 170 |
135 TEST_P(JSSharedOperatorTest, Properties) { | 171 TEST_P(JSSharedOperatorTest, Properties) { |
136 JSOperatorBuilder javascript(zone()); | 172 JSOperatorBuilder javascript(zone()); |
137 const SharedOperator& sop = GetParam(); | 173 const SharedOperator<no_params_t>& sop = GetParam(); |
138 const Operator* op = (javascript.*sop.constructor)(); | 174 const Operator* op = (javascript.*sop.constructor)(); |
139 EXPECT_EQ(sop.properties, op->properties()); | 175 EXPECT_EQ(sop.properties, op->properties()); |
140 } | 176 } |
141 | 177 |
142 | 178 |
143 INSTANTIATE_TEST_CASE_P(JSOperatorTest, JSSharedOperatorTest, | 179 INSTANTIATE_TEST_CASE_P(JSOperatorTest, JSSharedOperatorTest, |
144 ::testing::ValuesIn(kSharedOperators)); | 180 ::testing::ValuesIn(kSharedOperators)); |
145 | 181 |
182 // ----------------------------------------------------------------------------- | |
183 // Shared operators which behave differently in strong mode | |
184 | |
185 | |
186 class JSSharedOperatorWithStrongTest | |
187 : public TestWithZone, | |
188 public ::testing::WithParamInterface< | |
189 SharedOperator<with_language_mode_t>>{}; | |
190 | |
191 | |
192 TEST_P(JSSharedOperatorWithStrongTest, InstancesAreGloballyShared) { | |
193 const SharedOperator<with_language_mode_t>& sop = GetParam(); | |
194 JSOperatorBuilder javascript1(zone()); | |
195 JSOperatorBuilder javascript2(zone()); | |
196 EXPECT_EQ((javascript1.*sop.constructor)(LanguageMode::SLOPPY), | |
197 (javascript2.*sop.constructor)(LanguageMode::SLOPPY)); | |
198 EXPECT_EQ((javascript1.*sop.constructor)(LanguageMode::STRONG), | |
199 (javascript2.*sop.constructor)(LanguageMode::STRONG)); | |
200 } | |
201 | |
202 | |
203 TEST_P(JSSharedOperatorWithStrongTest, NumberOfInputsAndOutputs) { | |
204 JSOperatorBuilder javascript(zone()); | |
205 const SharedOperator<with_language_mode_t>& sop = GetParam(); | |
206 const Operator* op_sloppy = (javascript.*sop.constructor) | |
207 (LanguageMode::SLOPPY); | |
208 testNumberOfInputsAndOutputs(sop, op_sloppy); | |
209 const Operator* op_strong = (javascript.*sop.constructor) | |
210 (LanguageMode::STRONG); | |
211 testNumberOfInputsAndOutputs(sop, op_strong); | |
212 } | |
213 | |
214 | |
215 TEST_P(JSSharedOperatorWithStrongTest, OpcodeIsCorrect) { | |
216 JSOperatorBuilder javascript(zone()); | |
217 const SharedOperator<with_language_mode_t>& sop = GetParam(); | |
218 const Operator* op_sloppy = (javascript.*sop.constructor) | |
219 (LanguageMode::SLOPPY); | |
220 EXPECT_EQ(sop.opcode, op_sloppy->opcode()); | |
221 const Operator* op_strong = (javascript.*sop.constructor) | |
222 (LanguageMode::STRONG); | |
223 EXPECT_EQ(sop.opcode, op_strong->opcode()); | |
224 } | |
225 | |
226 | |
227 TEST_P(JSSharedOperatorWithStrongTest, Properties) { | |
228 JSOperatorBuilder javascript(zone()); | |
229 const SharedOperator<with_language_mode_t>& sop = GetParam(); | |
230 const Operator* op_sloppy = (javascript.*sop.constructor) | |
231 (LanguageMode::SLOPPY); | |
232 EXPECT_EQ(sop.properties, op_sloppy->properties()); | |
233 const Operator* op_strong = (javascript.*sop.constructor) | |
234 (LanguageMode::STRONG); | |
235 EXPECT_EQ(sop.properties, op_strong->properties()); | |
236 } | |
237 | |
238 | |
239 INSTANTIATE_TEST_CASE_P(JSOperatorTest, JSSharedOperatorWithStrongTest, | |
240 ::testing::ValuesIn(kSharedOperatorsWithlanguageMode)); | |
146 | 241 |
147 // ----------------------------------------------------------------------------- | 242 // ----------------------------------------------------------------------------- |
148 // JSStoreProperty. | 243 // JSStoreProperty. |
149 | 244 |
150 | 245 |
151 class JSStorePropertyOperatorTest | 246 class JSStorePropertyOperatorTest |
152 : public TestWithZone, | 247 : public TestWithZone, |
153 public ::testing::WithParamInterface<LanguageMode> {}; | 248 public ::testing::WithParamInterface<LanguageMode> {}; |
154 | 249 |
155 | 250 |
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
202 EXPECT_EQ(Operator::kNoProperties, op->properties()); | 297 EXPECT_EQ(Operator::kNoProperties, op->properties()); |
203 } | 298 } |
204 | 299 |
205 | 300 |
206 INSTANTIATE_TEST_CASE_P(JSOperatorTest, JSStorePropertyOperatorTest, | 301 INSTANTIATE_TEST_CASE_P(JSOperatorTest, JSStorePropertyOperatorTest, |
207 ::testing::Values(SLOPPY, STRICT)); | 302 ::testing::Values(SLOPPY, STRICT)); |
208 | 303 |
209 } // namespace compiler | 304 } // namespace compiler |
210 } // namespace internal | 305 } // namespace internal |
211 } // namespace v8 | 306 } // namespace v8 |
OLD | NEW |