Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(579)

Side by Side Diff: src/compiler/js-create-lowering.cc

Issue 2127713003: [TurboFan] Improve Array constructor optimization (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Test file fixes. Created 4 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « src/compiler/js-create-lowering.h ('k') | src/compiler/js-generic-lowering.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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
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
OLDNEW
« no previous file with comments | « src/compiler/js-create-lowering.h ('k') | src/compiler/js-generic-lowering.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698