OLD | NEW |
1 // Copyright 2015 the V8 project authors. All rights reserved. | 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 | 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-call-reducer.h" | 5 #include "src/compiler/js-call-reducer.h" |
6 | 6 |
7 #include "src/compiler/js-graph.h" | 7 #include "src/compiler/js-graph.h" |
8 #include "src/compiler/node-matchers.h" | 8 #include "src/compiler/node-matchers.h" |
9 #include "src/compiler/simplified-operator.h" | 9 #include "src/compiler/simplified-operator.h" |
10 #include "src/objects-inl.h" | 10 #include "src/objects-inl.h" |
(...skipping 176 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
187 // Try to further reduce the JSCallFunction {node}. | 187 // Try to further reduce the JSCallFunction {node}. |
188 Reduction const reduction = ReduceJSCallFunction(node); | 188 Reduction const reduction = ReduceJSCallFunction(node); |
189 return reduction.Changed() ? reduction : Changed(node); | 189 return reduction.Changed() ? reduction : Changed(node); |
190 } | 190 } |
191 | 191 |
192 | 192 |
193 Reduction JSCallReducer::ReduceJSCallFunction(Node* node) { | 193 Reduction JSCallReducer::ReduceJSCallFunction(Node* node) { |
194 DCHECK_EQ(IrOpcode::kJSCallFunction, node->opcode()); | 194 DCHECK_EQ(IrOpcode::kJSCallFunction, node->opcode()); |
195 CallFunctionParameters const& p = CallFunctionParametersOf(node->op()); | 195 CallFunctionParameters const& p = CallFunctionParametersOf(node->op()); |
196 Node* target = NodeProperties::GetValueInput(node, 0); | 196 Node* target = NodeProperties::GetValueInput(node, 0); |
197 Node* context = NodeProperties::GetContextInput(node); | |
198 Node* control = NodeProperties::GetControlInput(node); | 197 Node* control = NodeProperties::GetControlInput(node); |
199 Node* effect = NodeProperties::GetEffectInput(node); | 198 Node* effect = NodeProperties::GetEffectInput(node); |
200 | 199 |
201 // Try to specialize JSCallFunction {node}s with constant {target}s. | 200 // Try to specialize JSCallFunction {node}s with constant {target}s. |
202 HeapObjectMatcher m(target); | 201 HeapObjectMatcher m(target); |
203 if (m.HasValue()) { | 202 if (m.HasValue()) { |
204 if (m.Value()->IsJSFunction()) { | 203 if (m.Value()->IsJSFunction()) { |
205 Handle<JSFunction> function = Handle<JSFunction>::cast(m.Value()); | 204 Handle<JSFunction> function = Handle<JSFunction>::cast(m.Value()); |
206 Handle<SharedFunctionInfo> shared(function->shared(), isolate()); | 205 Handle<SharedFunctionInfo> shared(function->shared(), isolate()); |
207 | 206 |
(...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
291 // TODO(bmeurer): This should be on the AdvancedReducer somehow. | 290 // TODO(bmeurer): This should be on the AdvancedReducer somehow. |
292 NodeProperties::MergeControlToEnd(graph(), common(), deoptimize); | 291 NodeProperties::MergeControlToEnd(graph(), common(), deoptimize); |
293 Revisit(graph()->end()); | 292 Revisit(graph()->end()); |
294 node->TrimInputCount(0); | 293 node->TrimInputCount(0); |
295 NodeProperties::ChangeOp(node, common()->Dead()); | 294 NodeProperties::ChangeOp(node, common()->Dead()); |
296 return Changed(node); | 295 return Changed(node); |
297 } | 296 } |
298 Handle<Object> feedback(nexus.GetFeedback(), isolate()); | 297 Handle<Object> feedback(nexus.GetFeedback(), isolate()); |
299 if (feedback->IsAllocationSite()) { | 298 if (feedback->IsAllocationSite()) { |
300 // Retrieve the Array function from the {node}. | 299 // Retrieve the Array function from the {node}. |
301 Node* array_function; | 300 Node* array_function = jsgraph()->HeapConstant( |
302 Handle<Context> native_context; | 301 handle(native_context()->array_function(), isolate())); |
303 if (GetNativeContext(node).ToHandle(&native_context)) { | |
304 array_function = jsgraph()->HeapConstant( | |
305 handle(native_context->array_function(), isolate())); | |
306 } else { | |
307 Node* native_context = effect = graph()->NewNode( | |
308 javascript()->LoadContext(0, Context::NATIVE_CONTEXT_INDEX, true), | |
309 context, context, effect); | |
310 array_function = effect = graph()->NewNode( | |
311 javascript()->LoadContext(0, Context::ARRAY_FUNCTION_INDEX, true), | |
312 native_context, native_context, effect); | |
313 } | |
314 | 302 |
315 // Check that the {target} is still the {array_function}. | 303 // Check that the {target} is still the {array_function}. |
316 Node* check = graph()->NewNode(simplified()->ReferenceEqual(), target, | 304 Node* check = graph()->NewNode(simplified()->ReferenceEqual(), target, |
317 array_function); | 305 array_function); |
318 effect = graph()->NewNode(simplified()->CheckIf(), check, effect, control); | 306 effect = graph()->NewNode(simplified()->CheckIf(), check, effect, control); |
319 | 307 |
320 // Turn the {node} into a {JSCreateArray} call. | 308 // Turn the {node} into a {JSCreateArray} call. |
321 NodeProperties::ReplaceValueInput(node, array_function, 0); | 309 NodeProperties::ReplaceValueInput(node, array_function, 0); |
322 NodeProperties::ReplaceEffectInput(node, effect); | 310 NodeProperties::ReplaceEffectInput(node, effect); |
323 return ReduceArrayConstructor(node); | 311 return ReduceArrayConstructor(node); |
(...skipping 22 matching lines...) Expand all Loading... |
346 } | 334 } |
347 | 335 |
348 | 336 |
349 Reduction JSCallReducer::ReduceJSCallConstruct(Node* node) { | 337 Reduction JSCallReducer::ReduceJSCallConstruct(Node* node) { |
350 DCHECK_EQ(IrOpcode::kJSCallConstruct, node->opcode()); | 338 DCHECK_EQ(IrOpcode::kJSCallConstruct, node->opcode()); |
351 CallConstructParameters const& p = CallConstructParametersOf(node->op()); | 339 CallConstructParameters const& p = CallConstructParametersOf(node->op()); |
352 DCHECK_LE(2u, p.arity()); | 340 DCHECK_LE(2u, p.arity()); |
353 int const arity = static_cast<int>(p.arity() - 2); | 341 int const arity = static_cast<int>(p.arity() - 2); |
354 Node* target = NodeProperties::GetValueInput(node, 0); | 342 Node* target = NodeProperties::GetValueInput(node, 0); |
355 Node* new_target = NodeProperties::GetValueInput(node, arity + 1); | 343 Node* new_target = NodeProperties::GetValueInput(node, arity + 1); |
356 Node* context = NodeProperties::GetContextInput(node); | |
357 Node* effect = NodeProperties::GetEffectInput(node); | 344 Node* effect = NodeProperties::GetEffectInput(node); |
358 Node* control = NodeProperties::GetControlInput(node); | 345 Node* control = NodeProperties::GetControlInput(node); |
359 | 346 |
360 // Try to specialize JSCallConstruct {node}s with constant {target}s. | 347 // Try to specialize JSCallConstruct {node}s with constant {target}s. |
361 HeapObjectMatcher m(target); | 348 HeapObjectMatcher m(target); |
362 if (m.HasValue()) { | 349 if (m.HasValue()) { |
363 if (m.Value()->IsJSFunction()) { | 350 if (m.Value()->IsJSFunction()) { |
364 Handle<JSFunction> function = Handle<JSFunction>::cast(m.Value()); | 351 Handle<JSFunction> function = Handle<JSFunction>::cast(m.Value()); |
365 | 352 |
366 // Raise a TypeError if the {target} is not a constructor. | 353 // Raise a TypeError if the {target} is not a constructor. |
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
406 CallICNexus nexus(p.feedback().vector(), p.feedback().slot()); | 393 CallICNexus nexus(p.feedback().vector(), p.feedback().slot()); |
407 Handle<Object> feedback(nexus.GetFeedback(), isolate()); | 394 Handle<Object> feedback(nexus.GetFeedback(), isolate()); |
408 if (feedback->IsAllocationSite()) { | 395 if (feedback->IsAllocationSite()) { |
409 // The feedback is an AllocationSite, which means we have called the | 396 // The feedback is an AllocationSite, which means we have called the |
410 // Array function and collected transition (and pretenuring) feedback | 397 // Array function and collected transition (and pretenuring) feedback |
411 // for the resulting arrays. This has to be kept in sync with the | 398 // for the resulting arrays. This has to be kept in sync with the |
412 // implementation of the CallConstructStub. | 399 // implementation of the CallConstructStub. |
413 Handle<AllocationSite> site = Handle<AllocationSite>::cast(feedback); | 400 Handle<AllocationSite> site = Handle<AllocationSite>::cast(feedback); |
414 | 401 |
415 // Retrieve the Array function from the {node}. | 402 // Retrieve the Array function from the {node}. |
416 Node* array_function; | 403 Node* array_function = jsgraph()->HeapConstant( |
417 Handle<Context> native_context; | 404 handle(native_context()->array_function(), isolate())); |
418 if (GetNativeContext(node).ToHandle(&native_context)) { | |
419 array_function = jsgraph()->HeapConstant( | |
420 handle(native_context->array_function(), isolate())); | |
421 } else { | |
422 Node* native_context = effect = graph()->NewNode( | |
423 javascript()->LoadContext(0, Context::NATIVE_CONTEXT_INDEX, true), | |
424 context, context, effect); | |
425 array_function = effect = graph()->NewNode( | |
426 javascript()->LoadContext(0, Context::ARRAY_FUNCTION_INDEX, true), | |
427 native_context, native_context, effect); | |
428 } | |
429 | 405 |
430 // Check that the {target} is still the {array_function}. | 406 // Check that the {target} is still the {array_function}. |
431 Node* check = graph()->NewNode(simplified()->ReferenceEqual(), target, | 407 Node* check = graph()->NewNode(simplified()->ReferenceEqual(), target, |
432 array_function); | 408 array_function); |
433 effect = graph()->NewNode(simplified()->CheckIf(), check, effect, control); | 409 effect = graph()->NewNode(simplified()->CheckIf(), check, effect, control); |
434 | 410 |
435 // Turn the {node} into a {JSCreateArray} call. | 411 // Turn the {node} into a {JSCreateArray} call. |
436 NodeProperties::ReplaceEffectInput(node, effect); | 412 NodeProperties::ReplaceEffectInput(node, effect); |
437 for (int i = arity; i > 0; --i) { | 413 for (int i = arity; i > 0; --i) { |
438 NodeProperties::ReplaceValueInput( | 414 NodeProperties::ReplaceValueInput( |
(...skipping 23 matching lines...) Expand all Loading... |
462 | 438 |
463 // Try to further reduce the JSCallConstruct {node}. | 439 // Try to further reduce the JSCallConstruct {node}. |
464 Reduction const reduction = ReduceJSCallConstruct(node); | 440 Reduction const reduction = ReduceJSCallConstruct(node); |
465 return reduction.Changed() ? reduction : Changed(node); | 441 return reduction.Changed() ? reduction : Changed(node); |
466 } | 442 } |
467 } | 443 } |
468 | 444 |
469 return NoChange(); | 445 return NoChange(); |
470 } | 446 } |
471 | 447 |
472 | |
473 MaybeHandle<Context> JSCallReducer::GetNativeContext(Node* node) { | |
474 Node* const context = NodeProperties::GetContextInput(node); | |
475 return NodeProperties::GetSpecializationNativeContext(context, | |
476 native_context()); | |
477 } | |
478 | |
479 | |
480 Graph* JSCallReducer::graph() const { return jsgraph()->graph(); } | 448 Graph* JSCallReducer::graph() const { return jsgraph()->graph(); } |
481 | 449 |
482 | |
483 Isolate* JSCallReducer::isolate() const { return jsgraph()->isolate(); } | 450 Isolate* JSCallReducer::isolate() const { return jsgraph()->isolate(); } |
484 | 451 |
485 | |
486 CommonOperatorBuilder* JSCallReducer::common() const { | 452 CommonOperatorBuilder* JSCallReducer::common() const { |
487 return jsgraph()->common(); | 453 return jsgraph()->common(); |
488 } | 454 } |
489 | 455 |
490 | |
491 JSOperatorBuilder* JSCallReducer::javascript() const { | 456 JSOperatorBuilder* JSCallReducer::javascript() const { |
492 return jsgraph()->javascript(); | 457 return jsgraph()->javascript(); |
493 } | 458 } |
494 | 459 |
495 SimplifiedOperatorBuilder* JSCallReducer::simplified() const { | 460 SimplifiedOperatorBuilder* JSCallReducer::simplified() const { |
496 return jsgraph()->simplified(); | 461 return jsgraph()->simplified(); |
497 } | 462 } |
498 | 463 |
499 } // namespace compiler | 464 } // namespace compiler |
500 } // namespace internal | 465 } // namespace internal |
501 } // namespace v8 | 466 } // namespace v8 |
OLD | NEW |