| 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 |
| 628 DCHECK(arity > 1); |
| 629 ArrayNArgumentsConstructorStub stub(isolate()); |
| 630 CallDescriptor* desc = Linkage::GetStubCallDescriptor( |
| 631 isolate(), graph()->zone(), stub.GetCallInterfaceDescriptor(), arity + 1, |
| 632 CallDescriptor::kNeedsFrameState); |
| 633 node->ReplaceInput(0, jsgraph()->HeapConstant(stub.GetCode())); |
| 634 node->InsertInput(graph()->zone(), 2, jsgraph()->HeapConstant(site)); |
| 635 node->InsertInput(graph()->zone(), 3, jsgraph()->Int32Constant(arity)); |
| 636 node->InsertInput(graph()->zone(), 4, jsgraph()->UndefinedConstant()); |
| 637 NodeProperties::ChangeOp(node, common()->Call(desc)); |
| 638 return Changed(node); |
| 639 } |
| 640 |
| 512 Reduction JSCreateLowering::ReduceJSCreateArray(Node* node) { | 641 Reduction JSCreateLowering::ReduceJSCreateArray(Node* node) { |
| 513 DCHECK_EQ(IrOpcode::kJSCreateArray, node->opcode()); | 642 DCHECK_EQ(IrOpcode::kJSCreateArray, node->opcode()); |
| 514 CreateArrayParameters const& p = CreateArrayParametersOf(node->op()); | 643 CreateArrayParameters const& p = CreateArrayParametersOf(node->op()); |
| 515 Node* target = NodeProperties::GetValueInput(node, 0); | 644 Node* target = NodeProperties::GetValueInput(node, 0); |
| 516 Node* new_target = NodeProperties::GetValueInput(node, 1); | 645 Node* new_target = NodeProperties::GetValueInput(node, 1); |
| 517 | 646 |
| 647 // TODO(mstarzinger): Array constructor can throw. Hook up exceptional edges. |
| 648 if (NodeProperties::IsExceptionalCall(node)) return NoChange(); |
| 649 |
| 518 // TODO(bmeurer): Optimize the subclassing case. | 650 // TODO(bmeurer): Optimize the subclassing case. |
| 519 if (target != new_target) return NoChange(); | 651 if (target != new_target) return NoChange(); |
| 520 | 652 |
| 521 // Check if we have a feedback {site} on the {node}. | 653 // Check if we have a feedback {site} on the {node}. |
| 522 Handle<AllocationSite> site = p.site(); | 654 Handle<AllocationSite> site = p.site(); |
| 523 if (p.site().is_null()) return NoChange(); | 655 if (p.site().is_null()) return NoChange(); |
| 524 | 656 |
| 525 // Attempt to inline calls to the Array constructor for the relevant cases | 657 // Attempt to inline calls to the Array constructor for the relevant cases |
| 526 // where either no arguments are provided, or exactly one unsigned number | 658 // where either no arguments are provided, or exactly one unsigned number |
| 527 // argument is given. | 659 // argument is given. |
| 528 if (site->CanInlineCall()) { | 660 if (site->CanInlineCall()) { |
| 529 if (p.arity() == 0) { | 661 if (p.arity() == 0) { |
| 530 Node* length = jsgraph()->ZeroConstant(); | 662 Node* length = jsgraph()->ZeroConstant(); |
| 531 int capacity = JSArray::kPreallocatedArrayElements; | 663 int capacity = JSArray::kPreallocatedArrayElements; |
| 532 return ReduceNewArray(node, length, capacity, site); | 664 return ReduceNewArray(node, length, capacity, site); |
| 533 } else if (p.arity() == 1) { | 665 } else if (p.arity() == 1) { |
| 534 Node* length = NodeProperties::GetValueInput(node, 2); | 666 Node* length = NodeProperties::GetValueInput(node, 2); |
| 535 Type* length_type = NodeProperties::GetType(length); | 667 Type* length_type = NodeProperties::GetType(length); |
| 536 if (length_type->Is(Type::SignedSmall()) && | 668 if (length_type->Is(Type::SignedSmall()) && length_type->Min() >= 0 && |
| 537 length_type->Min() >= 0 && | 669 length_type->Max() <= kElementLoopUnrollLimit && |
| 538 length_type->Max() <= kElementLoopUnrollLimit) { | 670 length_type->Min() == length_type->Max()) { |
| 539 int capacity = static_cast<int>(length_type->Max()); | 671 int capacity = static_cast<int>(length_type->Max()); |
| 540 return ReduceNewArray(node, length, capacity, site); | 672 return ReduceNewArray(node, length, capacity, site); |
| 541 } | 673 } |
| 542 } | 674 } |
| 543 } | 675 } |
| 544 | 676 |
| 545 return NoChange(); | 677 return ReduceNewArrayToStubCall(node, site); |
| 546 } | 678 } |
| 547 | 679 |
| 548 Reduction JSCreateLowering::ReduceJSCreateClosure(Node* node) { | 680 Reduction JSCreateLowering::ReduceJSCreateClosure(Node* node) { |
| 549 DCHECK_EQ(IrOpcode::kJSCreateClosure, node->opcode()); | 681 DCHECK_EQ(IrOpcode::kJSCreateClosure, node->opcode()); |
| 550 CreateClosureParameters const& p = CreateClosureParametersOf(node->op()); | 682 CreateClosureParameters const& p = CreateClosureParametersOf(node->op()); |
| 551 Handle<SharedFunctionInfo> shared = p.shared_info(); | 683 Handle<SharedFunctionInfo> shared = p.shared_info(); |
| 552 | 684 |
| 553 Node* effect = NodeProperties::GetEffectInput(node); | 685 Node* effect = NodeProperties::GetEffectInput(node); |
| 554 Node* control = NodeProperties::GetControlInput(node); | 686 Node* control = NodeProperties::GetControlInput(node); |
| 555 Node* context = NodeProperties::GetContextInput(node); | 687 Node* context = NodeProperties::GetContextInput(node); |
| (...skipping 574 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1130 return jsgraph()->simplified(); | 1262 return jsgraph()->simplified(); |
| 1131 } | 1263 } |
| 1132 | 1264 |
| 1133 MachineOperatorBuilder* JSCreateLowering::machine() const { | 1265 MachineOperatorBuilder* JSCreateLowering::machine() const { |
| 1134 return jsgraph()->machine(); | 1266 return jsgraph()->machine(); |
| 1135 } | 1267 } |
| 1136 | 1268 |
| 1137 } // namespace compiler | 1269 } // namespace compiler |
| 1138 } // namespace internal | 1270 } // namespace internal |
| 1139 } // namespace v8 | 1271 } // namespace v8 |
| OLD | NEW |