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