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

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

Issue 2821273002: [turbofan] Inline Array constructor calls with multiple parameters. (Closed)
Patch Set: Created 3 years, 8 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') | test/mjsunit/array-constructor-feedback.js » ('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 576 matching lines...) Expand 10 before | Expand all | Expand 10 after
587 a.Allocate(JSArray::kSize, pretenure); 587 a.Allocate(JSArray::kSize, pretenure);
588 a.Store(AccessBuilder::ForMap(), js_array_map); 588 a.Store(AccessBuilder::ForMap(), js_array_map);
589 a.Store(AccessBuilder::ForJSObjectProperties(), properties); 589 a.Store(AccessBuilder::ForJSObjectProperties(), properties);
590 a.Store(AccessBuilder::ForJSObjectElements(), elements); 590 a.Store(AccessBuilder::ForJSObjectElements(), elements);
591 a.Store(AccessBuilder::ForJSArrayLength(elements_kind), length); 591 a.Store(AccessBuilder::ForJSArrayLength(elements_kind), length);
592 RelaxControls(node); 592 RelaxControls(node);
593 a.FinishAndChange(node); 593 a.FinishAndChange(node);
594 return Changed(node); 594 return Changed(node);
595 } 595 }
596 596
597 Reduction JSCreateLowering::ReduceNewArray(Node* node,
598 std::vector<Node*> values,
599 Handle<AllocationSite> site) {
600 DCHECK_EQ(IrOpcode::kJSCreateArray, node->opcode());
601 Node* effect = NodeProperties::GetEffectInput(node);
602 Node* control = NodeProperties::GetControlInput(node);
603
604 // Extract transition and tenuring feedback from the {site} and add
605 // appropriate code dependencies on the {site} if deoptimization is
606 // enabled.
607 PretenureFlag pretenure = site->GetPretenureMode();
608 ElementsKind elements_kind = site->GetElementsKind();
609 DCHECK(IsFastElementsKind(elements_kind));
610 dependencies()->AssumeTenuringDecision(site);
611 dependencies()->AssumeTransitionStable(site);
612
613 // Check {values} based on the {elements_kind}. These checks are guarded
614 // by the {elements_kind} feedback on the {site}, so it's safe to just
615 // deoptimize in this case.
616 if (IsFastSmiElementsKind(elements_kind)) {
617 for (auto& value : values) {
618 if (!NodeProperties::GetType(value)->Is(Type::SignedSmall())) {
619 value = effect =
620 graph()->NewNode(simplified()->CheckSmi(), value, effect, control);
621 }
622 }
623 } else if (IsFastDoubleElementsKind(elements_kind)) {
624 for (auto& value : values) {
625 if (!NodeProperties::GetType(value)->Is(Type::Number())) {
626 value = effect = graph()->NewNode(simplified()->CheckNumber(), value,
627 effect, control);
628 }
629 // Make sure we do not store signaling NaNs into double arrays.
630 value = graph()->NewNode(simplified()->NumberSilenceNaN(), value);
631 }
632 }
633
634 // Retrieve the initial map for the array.
635 int const array_map_index = Context::ArrayMapIndex(elements_kind);
636 Node* js_array_map = jsgraph()->HeapConstant(
637 handle(Map::cast(native_context()->get(array_map_index)), isolate()));
638
639 // Setup elements, properties and length.
640 Node* elements = effect =
641 AllocateElements(effect, control, elements_kind, values, pretenure);
642 Node* properties = jsgraph()->EmptyFixedArrayConstant();
643 Node* length = jsgraph()->Constant(static_cast<int>(values.size()));
644
645 // Perform the allocation of the actual JSArray object.
646 AllocationBuilder a(jsgraph(), effect, control);
647 a.Allocate(JSArray::kSize, pretenure);
648 a.Store(AccessBuilder::ForMap(), js_array_map);
649 a.Store(AccessBuilder::ForJSObjectProperties(), properties);
650 a.Store(AccessBuilder::ForJSObjectElements(), elements);
651 a.Store(AccessBuilder::ForJSArrayLength(elements_kind), length);
652 RelaxControls(node);
653 a.FinishAndChange(node);
654 return Changed(node);
655 }
656
597 Reduction JSCreateLowering::ReduceNewArrayToStubCall( 657 Reduction JSCreateLowering::ReduceNewArrayToStubCall(
598 Node* node, Handle<AllocationSite> site) { 658 Node* node, Handle<AllocationSite> site) {
599 CreateArrayParameters const& p = CreateArrayParametersOf(node->op()); 659 CreateArrayParameters const& p = CreateArrayParametersOf(node->op());
600 int const arity = static_cast<int>(p.arity()); 660 int const arity = static_cast<int>(p.arity());
601 Node* target = NodeProperties::GetValueInput(node, 0); 661 Node* target = NodeProperties::GetValueInput(node, 0);
602 Node* new_target = NodeProperties::GetValueInput(node, 1); 662 Node* new_target = NodeProperties::GetValueInput(node, 1);
603 Type* new_target_type = NodeProperties::GetType(new_target); 663 Type* new_target_type = NodeProperties::GetType(new_target);
604 664
605 ElementsKind elements_kind = site->GetElementsKind(); 665 ElementsKind elements_kind = site->GetElementsKind();
606 AllocationSiteOverrideMode override_mode = 666 AllocationSiteOverrideMode override_mode =
(...skipping 141 matching lines...) Expand 10 before | Expand all | Expand 10 after
748 // where either no arguments are provided, or exactly one unsigned number 808 // where either no arguments are provided, or exactly one unsigned number
749 // argument is given. 809 // argument is given.
750 if (site->CanInlineCall()) { 810 if (site->CanInlineCall()) {
751 if (p.arity() == 0) { 811 if (p.arity() == 0) {
752 Node* length = jsgraph()->ZeroConstant(); 812 Node* length = jsgraph()->ZeroConstant();
753 int capacity = JSArray::kPreallocatedArrayElements; 813 int capacity = JSArray::kPreallocatedArrayElements;
754 return ReduceNewArray(node, length, capacity, site); 814 return ReduceNewArray(node, length, capacity, site);
755 } else if (p.arity() == 1) { 815 } else if (p.arity() == 1) {
756 Node* length = NodeProperties::GetValueInput(node, 2); 816 Node* length = NodeProperties::GetValueInput(node, 2);
757 Type* length_type = NodeProperties::GetType(length); 817 Type* length_type = NodeProperties::GetType(length);
818 if (!length_type->Maybe(Type::Unsigned32())) {
819 // Handle the single argument case, where we know that the value
820 // cannot be a valid Array length.
821 return ReduceNewArray(node, {length}, site);
822 }
758 if (length_type->Is(Type::SignedSmall()) && length_type->Min() >= 0 && 823 if (length_type->Is(Type::SignedSmall()) && length_type->Min() >= 0 &&
759 length_type->Max() <= kElementLoopUnrollLimit && 824 length_type->Max() <= kElementLoopUnrollLimit &&
760 length_type->Min() == length_type->Max()) { 825 length_type->Min() == length_type->Max()) {
761 int capacity = static_cast<int>(length_type->Max()); 826 int capacity = static_cast<int>(length_type->Max());
762 return ReduceNewArray(node, length, capacity, site); 827 return ReduceNewArray(node, length, capacity, site);
763 } 828 }
829 } else if (p.arity() <= JSArray::kInitialMaxFastElementArray) {
830 std::vector<Node*> values;
831 values.reserve(p.arity());
832 for (size_t i = 0; i < p.arity(); ++i) {
833 values.push_back(
834 NodeProperties::GetValueInput(node, static_cast<int>(2 + i)));
835 }
836 return ReduceNewArray(node, values, site);
764 } 837 }
765 } 838 }
766 839
767 return ReduceNewArrayToStubCall(node, site); 840 return ReduceNewArrayToStubCall(node, site);
768 } 841 }
769 842
770 Reduction JSCreateLowering::ReduceJSCreateIterResultObject(Node* node) { 843 Reduction JSCreateLowering::ReduceJSCreateIterResultObject(Node* node) {
771 DCHECK_EQ(IrOpcode::kJSCreateIterResultObject, node->opcode()); 844 DCHECK_EQ(IrOpcode::kJSCreateIterResultObject, node->opcode());
772 Node* value = NodeProperties::GetValueInput(node, 0); 845 Node* value = NodeProperties::GetValueInput(node, 0);
773 Node* done = NodeProperties::GetValueInput(node, 1); 846 Node* done = NodeProperties::GetValueInput(node, 1);
(...skipping 344 matching lines...) Expand 10 before | Expand all | Expand 10 after
1118 // Actually allocate the backing store. 1191 // Actually allocate the backing store.
1119 AllocationBuilder a(jsgraph(), effect, control); 1192 AllocationBuilder a(jsgraph(), effect, control);
1120 a.AllocateArray(capacity, elements_map, pretenure); 1193 a.AllocateArray(capacity, elements_map, pretenure);
1121 for (int i = 0; i < capacity; ++i) { 1194 for (int i = 0; i < capacity; ++i) {
1122 Node* index = jsgraph()->Constant(i); 1195 Node* index = jsgraph()->Constant(i);
1123 a.Store(access, index, value); 1196 a.Store(access, index, value);
1124 } 1197 }
1125 return a.Finish(); 1198 return a.Finish();
1126 } 1199 }
1127 1200
1201 Node* JSCreateLowering::AllocateElements(Node* effect, Node* control,
1202 ElementsKind elements_kind,
1203 std::vector<Node*> const& values,
1204 PretenureFlag pretenure) {
1205 int const capacity = static_cast<int>(values.size());
1206 DCHECK_LE(1, capacity);
1207 DCHECK_LE(capacity, JSArray::kInitialMaxFastElementArray);
1208
1209 Handle<Map> elements_map = IsFastDoubleElementsKind(elements_kind)
1210 ? factory()->fixed_double_array_map()
1211 : factory()->fixed_array_map();
1212 ElementAccess access = IsFastDoubleElementsKind(elements_kind)
1213 ? AccessBuilder::ForFixedDoubleArrayElement()
1214 : AccessBuilder::ForFixedArrayElement();
1215
1216 // Actually allocate the backing store.
1217 AllocationBuilder a(jsgraph(), effect, control);
1218 a.AllocateArray(capacity, elements_map, pretenure);
1219 for (int i = 0; i < capacity; ++i) {
1220 Node* index = jsgraph()->Constant(i);
1221 a.Store(access, index, values[i]);
1222 }
1223 return a.Finish();
1224 }
1225
1128 Node* JSCreateLowering::AllocateFastLiteral( 1226 Node* JSCreateLowering::AllocateFastLiteral(
1129 Node* effect, Node* control, Handle<JSObject> boilerplate, 1227 Node* effect, Node* control, Handle<JSObject> boilerplate,
1130 AllocationSiteUsageContext* site_context) { 1228 AllocationSiteUsageContext* site_context) {
1131 Handle<AllocationSite> current_site(*site_context->current(), isolate()); 1229 Handle<AllocationSite> current_site(*site_context->current(), isolate());
1132 dependencies()->AssumeTransitionStable(current_site); 1230 dependencies()->AssumeTransitionStable(current_site);
1133 1231
1134 PretenureFlag pretenure = NOT_TENURED; 1232 PretenureFlag pretenure = NOT_TENURED;
1135 if (FLAG_allocation_site_pretenuring) { 1233 if (FLAG_allocation_site_pretenuring) {
1136 Handle<AllocationSite> top_site(*site_context->top(), isolate()); 1234 Handle<AllocationSite> top_site(*site_context->top(), isolate());
1137 pretenure = top_site->GetPretenureMode(); 1235 pretenure = top_site->GetPretenureMode();
(...skipping 207 matching lines...) Expand 10 before | Expand all | Expand 10 after
1345 return jsgraph()->simplified(); 1443 return jsgraph()->simplified();
1346 } 1444 }
1347 1445
1348 MachineOperatorBuilder* JSCreateLowering::machine() const { 1446 MachineOperatorBuilder* JSCreateLowering::machine() const {
1349 return jsgraph()->machine(); 1447 return jsgraph()->machine();
1350 } 1448 }
1351 1449
1352 } // namespace compiler 1450 } // namespace compiler
1353 } // namespace internal 1451 } // namespace internal
1354 } // namespace v8 1452 } // namespace v8
OLDNEW
« no previous file with comments | « src/compiler/js-create-lowering.h ('k') | test/mjsunit/array-constructor-feedback.js » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698