Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright 2016 the V8 project authors. All rights reserved. | 1 // Copyright 2016 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-create-lowering.h" | 5 #include "src/compiler/js-create-lowering.h" |
| 6 | 6 |
| 7 #include "src/allocation-site-scopes.h" | 7 #include "src/allocation-site-scopes.h" |
| 8 #include "src/code-factory.h" | 8 #include "src/code-factory.h" |
| 9 #include "src/compilation-dependencies.h" | 9 #include "src/compilation-dependencies.h" |
| 10 #include "src/compiler/access-builder.h" | 10 #include "src/compiler/access-builder.h" |
| (...skipping 491 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 502 a.Allocate(JSArray::kSize, pretenure); | 502 a.Allocate(JSArray::kSize, pretenure); |
| 503 a.Store(AccessBuilder::ForMap(), js_array_map); | 503 a.Store(AccessBuilder::ForMap(), js_array_map); |
| 504 a.Store(AccessBuilder::ForJSObjectProperties(), properties); | 504 a.Store(AccessBuilder::ForJSObjectProperties(), properties); |
| 505 a.Store(AccessBuilder::ForJSObjectElements(), elements); | 505 a.Store(AccessBuilder::ForJSObjectElements(), elements); |
| 506 a.Store(AccessBuilder::ForJSArrayLength(elements_kind), length); | 506 a.Store(AccessBuilder::ForJSArrayLength(elements_kind), length); |
| 507 RelaxControls(node); | 507 RelaxControls(node); |
| 508 a.FinishAndChange(node); | 508 a.FinishAndChange(node); |
| 509 return Changed(node); | 509 return Changed(node); |
| 510 } | 510 } |
| 511 | 511 |
| 512 Reduction JSCreateLowering::ReduceNewArrayToStubCall( | |
| 513 Node* node, Handle<AllocationSite> site) { | |
| 514 CreateArrayParameters const& p = CreateArrayParametersOf(node->op()); | |
| 515 int const arity = static_cast<int>(p.arity()); | |
| 516 | |
| 517 ElementsKind elements_kind = site->GetElementsKind(); | |
| 518 AllocationSiteOverrideMode override_mode = | |
| 519 (AllocationSite::GetMode(elements_kind) == TRACK_ALLOCATION_SITE) | |
| 520 ? DISABLE_ALLOCATION_SITES | |
| 521 : DONT_OVERRIDE; | |
| 522 | |
| 523 if (arity == 0) { | |
| 524 ArrayNoArgumentConstructorStub stub(isolate(), elements_kind, | |
| 525 override_mode); | |
| 526 CallDescriptor* desc = Linkage::GetStubCallDescriptor( | |
| 527 isolate(), graph()->zone(), stub.GetCallInterfaceDescriptor(), 1, | |
| 528 CallDescriptor::kNeedsFrameState); | |
| 529 node->ReplaceInput(0, jsgraph()->HeapConstant(stub.GetCode())); | |
| 530 node->InsertInput(graph()->zone(), 2, jsgraph()->HeapConstant(site)); | |
| 531 node->InsertInput(graph()->zone(), 3, jsgraph()->Int32Constant(0)); | |
| 532 node->InsertInput(graph()->zone(), 4, jsgraph()->UndefinedConstant()); | |
| 533 NodeProperties::ChangeOp(node, common()->Call(desc)); | |
| 534 return Changed(node); | |
| 535 } else if (arity == 1) { | |
| 536 AllocationSiteOverrideMode override_mode = | |
| 537 (AllocationSite::GetMode(elements_kind) == TRACK_ALLOCATION_SITE) | |
| 538 ? DISABLE_ALLOCATION_SITES | |
| 539 : DONT_OVERRIDE; | |
| 540 | |
| 541 if (IsHoleyElementsKind(elements_kind)) { | |
| 542 ArraySingleArgumentConstructorStub stub(isolate(), elements_kind, | |
| 543 override_mode); | |
| 544 CallDescriptor* desc = Linkage::GetStubCallDescriptor( | |
| 545 isolate(), graph()->zone(), stub.GetCallInterfaceDescriptor(), 2, | |
| 546 CallDescriptor::kNeedsFrameState); | |
| 547 node->ReplaceInput(0, jsgraph()->HeapConstant(stub.GetCode())); | |
| 548 node->InsertInput(graph()->zone(), 2, jsgraph()->HeapConstant(site)); | |
| 549 node->InsertInput(graph()->zone(), 3, jsgraph()->Int32Constant(1)); | |
| 550 node->InsertInput(graph()->zone(), 4, jsgraph()->UndefinedConstant()); | |
| 551 NodeProperties::ChangeOp(node, common()->Call(desc)); | |
| 552 return Changed(node); | |
| 553 } | |
| 554 | |
| 555 Node* effect = NodeProperties::GetEffectInput(node); | |
| 556 Node* control = NodeProperties::GetControlInput(node); | |
| 557 Node* length = NodeProperties::GetValueInput(node, 2); | |
| 558 Node* equal = graph()->NewNode(simplified()->ReferenceEqual(Type::Any()), | |
| 559 length, jsgraph()->ZeroConstant()); | |
| 560 | |
| 561 Node* branch = | |
| 562 graph()->NewNode(common()->Branch(BranchHint::kFalse), equal, control); | |
| 563 Node* call_holey; | |
| 564 Node* call_packed; | |
| 565 Node* if_success_packed; | |
| 566 Node* if_success_holey; | |
| 567 Node* context = NodeProperties::GetContextInput(node); | |
| 568 Node* frame_state = NodeProperties::GetFrameStateInput(node, 0); | |
| 569 Node* if_equal = graph()->NewNode(common()->IfTrue(), branch); | |
| 570 { | |
| 571 ArraySingleArgumentConstructorStub stub(isolate(), elements_kind, | |
| 572 override_mode); | |
| 573 CallDescriptor* desc = Linkage::GetStubCallDescriptor( | |
| 574 isolate(), graph()->zone(), stub.GetCallInterfaceDescriptor(), 2, | |
| 575 CallDescriptor::kNeedsFrameState); | |
| 576 | |
| 577 Node* inputs[] = {jsgraph()->HeapConstant(stub.GetCode()), | |
| 578 node->InputAt(1), | |
| 579 jsgraph()->HeapConstant(site), | |
| 580 jsgraph()->Int32Constant(1), | |
| 581 jsgraph()->UndefinedConstant(), | |
| 582 length, | |
| 583 context, | |
| 584 frame_state, | |
| 585 effect, | |
| 586 if_equal}; | |
| 587 | |
| 588 call_holey = | |
| 589 graph()->NewNode(common()->Call(desc), arraysize(inputs), inputs); | |
| 590 if_success_holey = graph()->NewNode(common()->IfSuccess(), call_holey); | |
| 591 } | |
| 592 Node* if_not_equal = graph()->NewNode(common()->IfFalse(), branch); | |
| 593 { | |
| 594 // Require elements kind to "go holey." | |
| 595 ArraySingleArgumentConstructorStub stub( | |
| 596 isolate(), GetHoleyElementsKind(elements_kind), override_mode); | |
| 597 CallDescriptor* desc = Linkage::GetStubCallDescriptor( | |
| 598 isolate(), graph()->zone(), stub.GetCallInterfaceDescriptor(), 2, | |
| 599 CallDescriptor::kNeedsFrameState); | |
| 600 | |
| 601 Node* inputs[] = {jsgraph()->HeapConstant(stub.GetCode()), | |
| 602 node->InputAt(1), | |
| 603 jsgraph()->HeapConstant(site), | |
| 604 jsgraph()->Int32Constant(1), | |
| 605 jsgraph()->UndefinedConstant(), | |
| 606 length, | |
| 607 context, | |
| 608 frame_state, | |
| 609 effect, | |
| 610 if_not_equal}; | |
| 611 | |
| 612 call_packed = | |
| 613 graph()->NewNode(common()->Call(desc), arraysize(inputs), inputs); | |
| 614 if_success_packed = graph()->NewNode(common()->IfSuccess(), call_packed); | |
| 615 } | |
| 616 Node* merge = graph()->NewNode(common()->Merge(2), if_success_holey, | |
| 617 if_success_packed); | |
| 618 Node* effect_phi = graph()->NewNode(common()->EffectPhi(2), call_holey, | |
| 619 call_packed, merge); | |
| 620 Node* phi = | |
| 621 graph()->NewNode(common()->Phi(MachineRepresentation::kTagged, 2), | |
| 622 call_holey, call_packed, merge); | |
| 623 | |
| 624 ReplaceWithValue(node, phi, effect_phi, merge); | |
| 625 return Changed(node); | |
| 626 } | |
| 627 | |
|
Michael Starzinger
2016/07/06 14:34:00
nit: We could DCHECK(arity > 1) here.
mvstanton
2016/07/06 14:48:45
Done.
| |
| 628 ArrayNArgumentsConstructorStub stub(isolate()); | |
| 629 CallDescriptor* desc = Linkage::GetStubCallDescriptor( | |
| 630 isolate(), graph()->zone(), stub.GetCallInterfaceDescriptor(), arity + 1, | |
| 631 CallDescriptor::kNeedsFrameState); | |
| 632 node->ReplaceInput(0, jsgraph()->HeapConstant(stub.GetCode())); | |
| 633 node->InsertInput(graph()->zone(), 2, jsgraph()->HeapConstant(site)); | |
| 634 node->InsertInput(graph()->zone(), 3, jsgraph()->Int32Constant(arity)); | |
| 635 node->InsertInput(graph()->zone(), 4, jsgraph()->UndefinedConstant()); | |
| 636 NodeProperties::ChangeOp(node, common()->Call(desc)); | |
| 637 return Changed(node); | |
| 638 } | |
| 639 | |
| 512 Reduction JSCreateLowering::ReduceJSCreateArray(Node* node) { | 640 Reduction JSCreateLowering::ReduceJSCreateArray(Node* node) { |
| 513 DCHECK_EQ(IrOpcode::kJSCreateArray, node->opcode()); | 641 DCHECK_EQ(IrOpcode::kJSCreateArray, node->opcode()); |
| 514 CreateArrayParameters const& p = CreateArrayParametersOf(node->op()); | 642 CreateArrayParameters const& p = CreateArrayParametersOf(node->op()); |
| 515 Node* target = NodeProperties::GetValueInput(node, 0); | 643 Node* target = NodeProperties::GetValueInput(node, 0); |
| 516 Node* new_target = NodeProperties::GetValueInput(node, 1); | 644 Node* new_target = NodeProperties::GetValueInput(node, 1); |
| 517 | 645 |
| 646 // TODO(mstarzinger): Array constructor can throw. Hook up exceptional edges. | |
| 647 if (NodeProperties::IsExceptionalCall(node)) return NoChange(); | |
| 648 | |
| 518 // TODO(bmeurer): Optimize the subclassing case. | 649 // TODO(bmeurer): Optimize the subclassing case. |
| 519 if (target != new_target) return NoChange(); | 650 if (target != new_target) return NoChange(); |
| 520 | 651 |
| 521 // Check if we have a feedback {site} on the {node}. | 652 // Check if we have a feedback {site} on the {node}. |
| 522 Handle<AllocationSite> site = p.site(); | 653 Handle<AllocationSite> site = p.site(); |
| 523 if (p.site().is_null()) return NoChange(); | 654 if (p.site().is_null()) return NoChange(); |
| 524 | 655 |
| 525 // Attempt to inline calls to the Array constructor for the relevant cases | 656 // Attempt to inline calls to the Array constructor for the relevant cases |
| 526 // where either no arguments are provided, or exactly one unsigned number | 657 // where either no arguments are provided, or exactly one unsigned number |
| 527 // argument is given. | 658 // argument is given. |
| 528 if (site->CanInlineCall()) { | 659 if (site->CanInlineCall()) { |
| 529 if (p.arity() == 0) { | 660 if (p.arity() == 0) { |
| 530 Node* length = jsgraph()->ZeroConstant(); | 661 Node* length = jsgraph()->ZeroConstant(); |
| 531 int capacity = JSArray::kPreallocatedArrayElements; | 662 int capacity = JSArray::kPreallocatedArrayElements; |
| 532 return ReduceNewArray(node, length, capacity, site); | 663 return ReduceNewArray(node, length, capacity, site); |
| 533 } else if (p.arity() == 1) { | 664 } else if (p.arity() == 1) { |
| 534 Node* length = NodeProperties::GetValueInput(node, 2); | 665 Node* length = NodeProperties::GetValueInput(node, 2); |
| 535 Type* length_type = NodeProperties::GetType(length); | 666 Type* length_type = NodeProperties::GetType(length); |
| 536 if (length_type->Is(Type::SignedSmall()) && | 667 if (length_type->Is(Type::SignedSmall()) && length_type->Min() >= 0 && |
| 537 length_type->Min() >= 0 && | 668 length_type->Max() <= kElementLoopUnrollLimit && |
| 538 length_type->Max() <= kElementLoopUnrollLimit) { | 669 length_type->Min() == length_type->Max()) { |
| 539 int capacity = static_cast<int>(length_type->Max()); | 670 int capacity = static_cast<int>(length_type->Max()); |
| 540 return ReduceNewArray(node, length, capacity, site); | 671 return ReduceNewArray(node, length, capacity, site); |
| 541 } | 672 } |
| 542 } | 673 } |
| 543 } | 674 } |
| 544 | 675 |
| 545 return NoChange(); | 676 return ReduceNewArrayToStubCall(node, site); |
| 546 } | 677 } |
| 547 | 678 |
| 548 Reduction JSCreateLowering::ReduceJSCreateClosure(Node* node) { | 679 Reduction JSCreateLowering::ReduceJSCreateClosure(Node* node) { |
| 549 DCHECK_EQ(IrOpcode::kJSCreateClosure, node->opcode()); | 680 DCHECK_EQ(IrOpcode::kJSCreateClosure, node->opcode()); |
| 550 CreateClosureParameters const& p = CreateClosureParametersOf(node->op()); | 681 CreateClosureParameters const& p = CreateClosureParametersOf(node->op()); |
| 551 Handle<SharedFunctionInfo> shared = p.shared_info(); | 682 Handle<SharedFunctionInfo> shared = p.shared_info(); |
| 552 | 683 |
| 553 Node* effect = NodeProperties::GetEffectInput(node); | 684 Node* effect = NodeProperties::GetEffectInput(node); |
| 554 Node* control = NodeProperties::GetControlInput(node); | 685 Node* control = NodeProperties::GetControlInput(node); |
| 555 Node* context = NodeProperties::GetContextInput(node); | 686 Node* context = NodeProperties::GetContextInput(node); |
| (...skipping 574 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1130 return jsgraph()->simplified(); | 1261 return jsgraph()->simplified(); |
| 1131 } | 1262 } |
| 1132 | 1263 |
| 1133 MachineOperatorBuilder* JSCreateLowering::machine() const { | 1264 MachineOperatorBuilder* JSCreateLowering::machine() const { |
| 1134 return jsgraph()->machine(); | 1265 return jsgraph()->machine(); |
| 1135 } | 1266 } |
| 1136 | 1267 |
| 1137 } // namespace compiler | 1268 } // namespace compiler |
| 1138 } // namespace internal | 1269 } // namespace internal |
| 1139 } // namespace v8 | 1270 } // namespace v8 |
| OLD | NEW |