OLD | NEW |
---|---|
(Empty) | |
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 #include "src/compiler/access-builder.h" | |
6 #include "src/compiler/diamond.h" | |
Michael Starzinger
2015/07/20 08:09:49
nit: The diamond.h and the access-builder.h includ
| |
7 #include "src/compiler/js-context-relaxation.h" | |
8 #include "src/compiler/js-graph.h" | |
9 #include "test/unittests/compiler/graph-unittest.h" | |
10 #include "test/unittests/compiler/node-test-utils.h" | |
11 | |
12 namespace v8 { | |
13 namespace internal { | |
14 namespace compiler { | |
15 | |
16 class JSContextRelaxationTest : public GraphTest { | |
17 public: | |
18 JSContextRelaxationTest() : GraphTest(3), javascript_(zone()) {} | |
19 ~JSContextRelaxationTest() override {} | |
20 | |
21 protected: | |
22 Reduction Reduce(Node* node, MachineOperatorBuilder::Flags flags = | |
23 MachineOperatorBuilder::kNoFlags) { | |
24 MachineOperatorBuilder machine(zone(), kMachPtr, flags); | |
25 JSGraph jsgraph(isolate(), graph(), common(), javascript(), &machine); | |
26 // TODO(titzer): mock the GraphReducer here for better unit testing. | |
27 GraphReducer graph_reducer(zone(), graph()); | |
28 JSContextRelaxation reducer; | |
29 return reducer.Reduce(node); | |
30 } | |
31 | |
32 Node* EmptyFrameState() { | |
33 MachineOperatorBuilder machine(zone()); | |
34 JSGraph jsgraph(isolate(), graph(), common(), javascript(), &machine); | |
35 return jsgraph.EmptyFrameState(); | |
36 } | |
37 | |
38 Node* ShallowFrameStateChain(Node* outer_context, | |
39 ContextCallingMode context_calling_mode) { | |
40 const FrameStateFunctionInfo* const frame_state_function_info = | |
41 common()->CreateFrameStateFunctionInfo( | |
42 FrameStateType::kJavaScriptFunction, 3, 0, | |
43 Handle<SharedFunctionInfo>(), context_calling_mode); | |
44 const Operator* op = common()->FrameState(BailoutId::None(), | |
45 OutputFrameStateCombine::Ignore(), | |
46 frame_state_function_info); | |
47 return graph()->NewNode(op, graph()->start(), graph()->start(), | |
48 graph()->start(), outer_context, graph()->start(), | |
49 graph()->start()); | |
50 } | |
51 | |
52 Node* DeepFrameStateChain(Node* outer_context, | |
53 ContextCallingMode context_calling_mode) { | |
54 const FrameStateFunctionInfo* const frame_state_function_info = | |
55 common()->CreateFrameStateFunctionInfo( | |
56 FrameStateType::kJavaScriptFunction, 3, 0, | |
57 Handle<SharedFunctionInfo>(), context_calling_mode); | |
58 const Operator* op = common()->FrameState(BailoutId::None(), | |
59 OutputFrameStateCombine::Ignore(), | |
60 frame_state_function_info); | |
61 Node* shallow_frame_state = | |
62 ShallowFrameStateChain(outer_context, CALL_MAINTAINS_NATIVE_CONTEXT); | |
63 return graph()->NewNode(op, graph()->start(), graph()->start(), | |
64 graph()->start(), graph()->start(), | |
65 graph()->start(), shallow_frame_state); | |
66 } | |
67 | |
68 JSOperatorBuilder* javascript() { return &javascript_; } | |
69 | |
70 private: | |
71 JSOperatorBuilder javascript_; | |
72 }; | |
73 | |
74 | |
75 TEST_F(JSContextRelaxationTest, | |
76 RelaxJSCallFunctionShallowFrameStateChainNoCrossCtx) { | |
77 Node* const input0 = Parameter(0); | |
78 Node* const input1 = Parameter(1); | |
79 Node* const context = Parameter(2); | |
80 Node* const outer_context = Parameter(3); | |
81 Node* const frame_state = | |
82 ShallowFrameStateChain(outer_context, CALL_MAINTAINS_NATIVE_CONTEXT); | |
83 Node* const effect = graph()->start(); | |
84 Node* const control = graph()->start(); | |
85 Node* node = | |
86 graph()->NewNode(javascript()->CallFunction(2, NO_CALL_FUNCTION_FLAGS, | |
87 STRICT, VectorSlotPair()), | |
88 input0, input1, context, frame_state, effect, control); | |
89 Reduction const r = Reduce(node); | |
90 EXPECT_TRUE(r.Changed()); | |
91 EXPECT_EQ(outer_context, NodeProperties::GetContextInput(node)); | |
92 } | |
93 | |
94 TEST_F(JSContextRelaxationTest, | |
95 RelaxJSCallFunctionShallowFrameStateChainCrossCtx) { | |
96 Node* const input0 = Parameter(0); | |
97 Node* const input1 = Parameter(1); | |
98 Node* const context = Parameter(2); | |
99 Node* const outer_context = Parameter(3); | |
100 Node* const frame_state = | |
101 ShallowFrameStateChain(outer_context, CALL_CHANGES_NATIVE_CONTEXT); | |
102 Node* const effect = graph()->start(); | |
103 Node* const control = graph()->start(); | |
104 Node* node = | |
105 graph()->NewNode(javascript()->CallFunction(2, NO_CALL_FUNCTION_FLAGS, | |
106 STRICT, VectorSlotPair()), | |
107 input0, input1, context, frame_state, effect, control); | |
108 Reduction const r = Reduce(node); | |
109 EXPECT_FALSE(r.Changed()); | |
110 EXPECT_EQ(context, NodeProperties::GetContextInput(node)); | |
111 } | |
112 | |
113 TEST_F(JSContextRelaxationTest, | |
114 RelaxJSCallFunctionDeepFrameStateChainNoCrossCtx) { | |
115 Node* const input0 = Parameter(0); | |
116 Node* const input1 = Parameter(1); | |
117 Node* const context = Parameter(2); | |
118 Node* const outer_context = Parameter(3); | |
119 Node* const frame_state = | |
120 DeepFrameStateChain(outer_context, CALL_MAINTAINS_NATIVE_CONTEXT); | |
121 Node* const effect = graph()->start(); | |
122 Node* const control = graph()->start(); | |
123 Node* node = | |
124 graph()->NewNode(javascript()->CallFunction(2, NO_CALL_FUNCTION_FLAGS, | |
125 STRICT, VectorSlotPair()), | |
126 input0, input1, context, frame_state, effect, control); | |
127 Reduction const r = Reduce(node); | |
128 EXPECT_TRUE(r.Changed()); | |
129 EXPECT_EQ(outer_context, NodeProperties::GetContextInput(node)); | |
130 } | |
131 | |
132 TEST_F(JSContextRelaxationTest, | |
133 RelaxJSCallFunctionDeepFrameStateChainCrossCtx) { | |
134 Node* const input0 = Parameter(0); | |
135 Node* const input1 = Parameter(1); | |
136 Node* const context = Parameter(2); | |
137 Node* const outer_context = Parameter(3); | |
138 Node* const frame_state = | |
139 DeepFrameStateChain(outer_context, CALL_CHANGES_NATIVE_CONTEXT); | |
140 Node* const effect = graph()->start(); | |
141 Node* const control = graph()->start(); | |
142 Node* node = | |
143 graph()->NewNode(javascript()->CallFunction(2, NO_CALL_FUNCTION_FLAGS, | |
144 STRICT, VectorSlotPair()), | |
145 input0, input1, context, frame_state, effect, control); | |
146 Reduction const r = Reduce(node); | |
147 EXPECT_FALSE(r.Changed()); | |
148 EXPECT_EQ(context, NodeProperties::GetContextInput(node)); | |
149 } | |
150 | |
151 TEST_F(JSContextRelaxationTest, | |
152 RelaxJSCallFunctionDeepContextChainFullRelaxForCatch) { | |
153 Node* const input0 = Parameter(0); | |
154 Node* const input1 = Parameter(1); | |
155 Node* const context = Parameter(2); | |
156 Node* const outer_context = Parameter(3); | |
157 const Operator* op = javascript()->CreateCatchContext(Unique<String>()); | |
158 Node* const frame_state_1 = | |
159 ShallowFrameStateChain(outer_context, CALL_MAINTAINS_NATIVE_CONTEXT); | |
160 Node* const effect = graph()->start(); | |
161 Node* const control = graph()->start(); | |
162 Node* nested_context = | |
163 graph()->NewNode(op, graph()->start(), graph()->start(), outer_context, | |
164 frame_state_1, effect, control); | |
165 Node* const frame_state_2 = | |
166 ShallowFrameStateChain(nested_context, CALL_MAINTAINS_NATIVE_CONTEXT); | |
167 Node* node = | |
168 graph()->NewNode(javascript()->CallFunction(2, NO_CALL_FUNCTION_FLAGS, | |
169 STRICT, VectorSlotPair()), | |
170 input0, input1, context, frame_state_2, effect, control); | |
171 Reduction const r = Reduce(node); | |
172 EXPECT_TRUE(r.Changed()); | |
173 EXPECT_EQ(outer_context, NodeProperties::GetContextInput(node)); | |
174 } | |
175 | |
176 | |
177 TEST_F(JSContextRelaxationTest, | |
178 RelaxJSCallFunctionDeepContextChainFullRelaxForWith) { | |
179 Node* const input0 = Parameter(0); | |
180 Node* const input1 = Parameter(1); | |
181 Node* const context = Parameter(2); | |
182 Node* const outer_context = Parameter(3); | |
183 const Operator* op = javascript()->CreateWithContext(); | |
184 Node* const frame_state_1 = | |
185 ShallowFrameStateChain(outer_context, CALL_MAINTAINS_NATIVE_CONTEXT); | |
186 Node* const effect = graph()->start(); | |
187 Node* const control = graph()->start(); | |
188 Node* nested_context = | |
189 graph()->NewNode(op, graph()->start(), graph()->start(), outer_context, | |
190 frame_state_1, effect, control); | |
191 Node* const frame_state_2 = | |
192 ShallowFrameStateChain(nested_context, CALL_MAINTAINS_NATIVE_CONTEXT); | |
193 Node* node = | |
194 graph()->NewNode(javascript()->CallFunction(2, NO_CALL_FUNCTION_FLAGS, | |
195 STRICT, VectorSlotPair()), | |
196 input0, input1, context, frame_state_2, effect, control); | |
197 Reduction const r = Reduce(node); | |
198 EXPECT_TRUE(r.Changed()); | |
199 EXPECT_EQ(outer_context, NodeProperties::GetContextInput(node)); | |
200 } | |
201 | |
202 | |
203 TEST_F(JSContextRelaxationTest, | |
204 RelaxJSCallFunctionDeepContextChainFullRelaxForBlock) { | |
205 Node* const input0 = Parameter(0); | |
206 Node* const input1 = Parameter(1); | |
207 Node* const context = Parameter(2); | |
208 Node* const outer_context = Parameter(3); | |
209 const Operator* op = javascript()->CreateBlockContext(); | |
210 Node* const frame_state_1 = | |
211 ShallowFrameStateChain(outer_context, CALL_MAINTAINS_NATIVE_CONTEXT); | |
212 Node* const effect = graph()->start(); | |
213 Node* const control = graph()->start(); | |
214 Node* nested_context = | |
215 graph()->NewNode(op, graph()->start(), graph()->start(), outer_context, | |
216 frame_state_1, effect, control); | |
217 Node* const frame_state_2 = | |
218 ShallowFrameStateChain(nested_context, CALL_MAINTAINS_NATIVE_CONTEXT); | |
219 Node* node = | |
220 graph()->NewNode(javascript()->CallFunction(2, NO_CALL_FUNCTION_FLAGS, | |
221 STRICT, VectorSlotPair()), | |
222 input0, input1, context, frame_state_2, effect, control); | |
223 Reduction const r = Reduce(node); | |
224 EXPECT_TRUE(r.Changed()); | |
225 EXPECT_EQ(outer_context, NodeProperties::GetContextInput(node)); | |
226 } | |
227 | |
228 | |
229 TEST_F(JSContextRelaxationTest, | |
230 RelaxJSCallFunctionDeepContextChainPartialRelaxForScript) { | |
231 Node* const input0 = Parameter(0); | |
232 Node* const input1 = Parameter(1); | |
233 Node* const context = Parameter(2); | |
234 Node* const outer_context = Parameter(3); | |
235 const Operator* op = javascript()->CreateScriptContext(); | |
236 Node* const frame_state_1 = | |
237 ShallowFrameStateChain(outer_context, CALL_MAINTAINS_NATIVE_CONTEXT); | |
238 Node* const effect = graph()->start(); | |
239 Node* const control = graph()->start(); | |
240 Node* nested_context = | |
241 graph()->NewNode(op, graph()->start(), graph()->start(), outer_context, | |
242 frame_state_1, effect, control); | |
243 Node* const frame_state_2 = | |
244 ShallowFrameStateChain(nested_context, CALL_MAINTAINS_NATIVE_CONTEXT); | |
245 Node* node = | |
246 graph()->NewNode(javascript()->CallFunction(2, NO_CALL_FUNCTION_FLAGS, | |
247 STRICT, VectorSlotPair()), | |
248 input0, input1, context, frame_state_2, effect, control); | |
249 Reduction const r = Reduce(node); | |
250 EXPECT_TRUE(r.Changed()); | |
251 EXPECT_EQ(nested_context, NodeProperties::GetContextInput(node)); | |
252 } | |
253 | |
254 | |
255 TEST_F(JSContextRelaxationTest, | |
256 RelaxJSCallFunctionDeepContextChainPartialRelaxForModule) { | |
257 Node* const input0 = Parameter(0); | |
258 Node* const input1 = Parameter(1); | |
259 Node* const context = Parameter(2); | |
260 Node* const outer_context = Parameter(3); | |
261 const Operator* op = javascript()->CreateModuleContext(); | |
262 Node* const frame_state_1 = | |
263 ShallowFrameStateChain(outer_context, CALL_MAINTAINS_NATIVE_CONTEXT); | |
264 Node* const effect = graph()->start(); | |
265 Node* const control = graph()->start(); | |
266 Node* nested_context = | |
267 graph()->NewNode(op, graph()->start(), graph()->start(), outer_context, | |
268 frame_state_1, effect, control); | |
269 Node* const frame_state_2 = | |
270 ShallowFrameStateChain(nested_context, CALL_MAINTAINS_NATIVE_CONTEXT); | |
271 Node* node = | |
272 graph()->NewNode(javascript()->CallFunction(2, NO_CALL_FUNCTION_FLAGS, | |
273 STRICT, VectorSlotPair()), | |
274 input0, input1, context, frame_state_2, effect, control); | |
275 Reduction const r = Reduce(node); | |
276 EXPECT_TRUE(r.Changed()); | |
277 EXPECT_EQ(nested_context, NodeProperties::GetContextInput(node)); | |
278 } | |
279 | |
280 | |
281 TEST_F(JSContextRelaxationTest, | |
282 RelaxJSCallFunctionDeepContextChainPartialNoRelax) { | |
283 Node* const input0 = Parameter(0); | |
284 Node* const input1 = Parameter(1); | |
285 Node* const context = Parameter(2); | |
286 Node* const outer_context = Parameter(3); | |
287 const Operator* op = javascript()->CreateFunctionContext(); | |
288 Node* const frame_state_1 = | |
289 ShallowFrameStateChain(outer_context, CALL_MAINTAINS_NATIVE_CONTEXT); | |
290 Node* const effect = graph()->start(); | |
291 Node* const control = graph()->start(); | |
292 Node* nested_context = | |
293 graph()->NewNode(op, graph()->start(), graph()->start(), outer_context, | |
294 frame_state_1, effect, control); | |
295 Node* const frame_state_2 = | |
296 ShallowFrameStateChain(nested_context, CALL_MAINTAINS_NATIVE_CONTEXT); | |
297 Node* node = | |
298 graph()->NewNode(javascript()->CallFunction(2, NO_CALL_FUNCTION_FLAGS, | |
299 STRICT, VectorSlotPair()), | |
300 input0, input1, context, frame_state_2, effect, control); | |
301 Reduction const r = Reduce(node); | |
302 EXPECT_FALSE(r.Changed()); | |
303 EXPECT_EQ(context, NodeProperties::GetContextInput(node)); | |
304 } | |
305 | |
306 } // namespace compiler | |
307 } // namespace internal | |
308 } // namespace v8 | |
OLD | NEW |