| 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 576 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 |
| OLD | NEW |