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-context-specialization.h" | 5 #include "src/compiler/js-context-specialization.h" |
6 #include "src/compiler/js-graph.h" | 6 #include "src/compiler/js-graph.h" |
7 #include "src/compiler/js-operator.h" | 7 #include "src/compiler/js-operator.h" |
8 #include "src/compiler/node-matchers.h" | 8 #include "src/compiler/node-matchers.h" |
9 #include "src/compiler/node-properties.h" | 9 #include "src/compiler/node-properties.h" |
10 #include "src/compiler/source-position.h" | 10 #include "src/compiler/source-position.h" |
(...skipping 168 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
179 HeapObjectMatcher match(new_context_input); | 179 HeapObjectMatcher match(new_context_input); |
180 CHECK_EQ(*native, *match.Value()); | 180 CHECK_EQ(*native, *match.Value()); |
181 ContextAccess access = OpParameter<ContextAccess>(r.replacement()); | 181 ContextAccess access = OpParameter<ContextAccess>(r.replacement()); |
182 CHECK_EQ(Context::GLOBAL_EVAL_FUN_INDEX, static_cast<int>(access.index())); | 182 CHECK_EQ(Context::GLOBAL_EVAL_FUN_INDEX, static_cast<int>(access.index())); |
183 CHECK_EQ(0, static_cast<int>(access.depth())); | 183 CHECK_EQ(0, static_cast<int>(access.depth())); |
184 CHECK_EQ(false, access.immutable()); | 184 CHECK_EQ(false, access.immutable()); |
185 } | 185 } |
186 } | 186 } |
187 | 187 |
188 | 188 |
189 // TODO(titzer): factor out common code with effects checking in typed lowering. | |
190 static void CheckEffectInput(Node* effect, Node* use) { | |
191 CHECK_EQ(effect, NodeProperties::GetEffectInput(use)); | |
192 } | |
193 | |
194 | |
195 TEST(SpecializeToContext) { | |
196 ContextSpecializationTester t; | |
197 | |
198 Node* start = t.graph()->NewNode(t.common()->Start(0)); | |
199 t.graph()->SetStart(start); | |
200 | |
201 // Make a context and initialize it a bit for this test. | |
202 Handle<Context> native = t.factory()->NewNativeContext(); | |
203 Handle<Object> expected = t.factory()->InternalizeUtf8String("gboy!"); | |
204 const int slot = Context::NATIVE_CONTEXT_INDEX; | |
205 native->set(slot, *expected); | |
206 | |
207 Node* const_context = t.jsgraph()->Constant(native); | |
208 Node* param_context = t.graph()->NewNode(t.common()->Parameter(0), start); | |
209 | |
210 { | |
211 // Check that specialization replaces values and forwards effects | |
212 // correctly, and folds values from constant and non-constant contexts | |
213 Node* effect_in = start; | |
214 Node* load = t.graph()->NewNode(t.javascript()->LoadContext(0, slot, true), | |
215 const_context, const_context, effect_in); | |
216 | |
217 | |
218 Node* value_use = | |
219 t.graph()->NewNode(t.simplified()->ChangeTaggedToInt32(), load); | |
220 Node* other_load = | |
221 t.graph()->NewNode(t.javascript()->LoadContext(0, slot, true), | |
222 param_context, param_context, load); | |
223 Node* effect_use = other_load; | |
224 Node* other_use = | |
225 t.graph()->NewNode(t.simplified()->ChangeTaggedToInt32(), other_load); | |
226 | |
227 Node* add = t.graph()->NewNode( | |
228 t.javascript()->Add(BinaryOperationHints::Any()), value_use, other_use, | |
229 param_context, t.jsgraph()->EmptyFrameState(), | |
230 t.jsgraph()->EmptyFrameState(), other_load, start); | |
231 | |
232 Node* ret = | |
233 t.graph()->NewNode(t.common()->Return(), add, effect_use, start); | |
234 Node* end = t.graph()->NewNode(t.common()->End(1), ret); | |
235 USE(end); | |
236 t.graph()->SetEnd(end); | |
237 | |
238 // Double check the above graph is what we expect, or the test is broken. | |
239 CheckEffectInput(effect_in, load); | |
240 CheckEffectInput(load, effect_use); | |
241 | |
242 // Perform the reduction on the entire graph. | |
243 GraphReducer graph_reducer(t.main_zone(), t.graph()); | |
244 JSContextSpecialization spec(&graph_reducer, t.jsgraph(), | |
245 MaybeHandle<Context>()); | |
246 graph_reducer.AddReducer(&spec); | |
247 graph_reducer.ReduceGraph(); | |
248 | |
249 // Effects should have been forwarded (not replaced with a value). | |
250 CheckEffectInput(effect_in, effect_use); | |
251 | |
252 // Use of {other_load} should not have been replaced. | |
253 CHECK_EQ(other_load, other_use->InputAt(0)); | |
254 | |
255 Node* replacement = value_use->InputAt(0); | |
256 HeapObjectMatcher match(replacement); | |
257 CHECK(match.HasValue()); | |
258 CHECK_EQ(*expected, *match.Value()); | |
259 } | |
260 // TODO(titzer): clean up above test and test more complicated effects. | |
261 } | |
262 | |
263 | |
264 TEST(SpecializeJSFunction_ToConstant1) { | 189 TEST(SpecializeJSFunction_ToConstant1) { |
265 FunctionTester T( | 190 FunctionTester T( |
266 "(function() { var x = 1; function inc(a)" | 191 "(function() { var x = 1; function inc(a)" |
267 " { return a + x; } return inc; })()"); | 192 " { return a + x; } return inc; })()"); |
268 | 193 |
269 T.CheckCall(1.0, 0.0, 0.0); | 194 T.CheckCall(1.0, 0.0, 0.0); |
270 T.CheckCall(2.0, 1.0, 0.0); | 195 T.CheckCall(2.0, 1.0, 0.0); |
271 T.CheckCall(2.1, 1.1, 0.0); | 196 T.CheckCall(2.1, 1.1, 0.0); |
272 } | 197 } |
273 | 198 |
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
313 | 238 |
314 CHECK(T.Call(T.Val(0.0), T.Val(0.0)).ToHandleChecked()->IsNaN()); | 239 CHECK(T.Call(T.Val(0.0), T.Val(0.0)).ToHandleChecked()->IsNaN()); |
315 CHECK(T.Call(T.Val(2.0), T.Val(0.0)).ToHandleChecked()->IsNaN()); | 240 CHECK(T.Call(T.Val(2.0), T.Val(0.0)).ToHandleChecked()->IsNaN()); |
316 CHECK(T.Call(T.Val(-2.1), T.Val(0.0)).ToHandleChecked()->IsNaN()); | 241 CHECK(T.Call(T.Val(-2.1), T.Val(0.0)).ToHandleChecked()->IsNaN()); |
317 } | 242 } |
318 } | 243 } |
319 | 244 |
320 } // namespace compiler | 245 } // namespace compiler |
321 } // namespace internal | 246 } // namespace internal |
322 } // namespace v8 | 247 } // namespace v8 |
OLD | NEW |