OLD | NEW |
1 // Copyright 2014 the V8 project authors. All rights reserved. | 1 // Copyright 2014 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/code-factory.h" | 5 #include "src/code-factory.h" |
6 #include "src/compilation-dependencies.h" | 6 #include "src/compilation-dependencies.h" |
7 #include "src/compiler/access-builder.h" | 7 #include "src/compiler/access-builder.h" |
8 #include "src/compiler/js-graph.h" | 8 #include "src/compiler/js-graph.h" |
9 #include "src/compiler/js-typed-lowering.h" | 9 #include "src/compiler/js-typed-lowering.h" |
10 #include "src/compiler/linkage.h" | 10 #include "src/compiler/linkage.h" |
11 #include "src/compiler/node-matchers.h" | 11 #include "src/compiler/node-matchers.h" |
12 #include "src/compiler/node-properties.h" | 12 #include "src/compiler/node-properties.h" |
13 #include "src/compiler/operator-properties.h" | 13 #include "src/compiler/operator-properties.h" |
14 #include "src/compiler/state-values-utils.h" | 14 #include "src/compiler/state-values-utils.h" |
| 15 #include "src/type-cache.h" |
15 #include "src/types.h" | 16 #include "src/types.h" |
16 | 17 |
17 namespace v8 { | 18 namespace v8 { |
18 namespace internal { | 19 namespace internal { |
19 namespace compiler { | 20 namespace compiler { |
20 | 21 |
21 // TODO(turbofan): js-typed-lowering improvements possible | 22 namespace { |
22 // - immediately put in type bounds for all new nodes | |
23 // - relax effects from generic but not-side-effecting operations | |
24 | |
25 | |
26 JSTypedLowering::JSTypedLowering(Editor* editor, | |
27 CompilationDependencies* dependencies, | |
28 Flags flags, JSGraph* jsgraph, Zone* zone) | |
29 : AdvancedReducer(editor), | |
30 dependencies_(dependencies), | |
31 flags_(flags), | |
32 jsgraph_(jsgraph) { | |
33 for (size_t k = 0; k < arraysize(shifted_int32_ranges_); ++k) { | |
34 double min = kMinInt / (1 << k); | |
35 double max = kMaxInt / (1 << k); | |
36 shifted_int32_ranges_[k] = Type::Range(min, max, graph()->zone()); | |
37 } | |
38 } | |
39 | |
40 | 23 |
41 // A helper class to construct inline allocations on the simplified operator | 24 // A helper class to construct inline allocations on the simplified operator |
42 // level. This keeps track of the effect chain for initial stores on a newly | 25 // level. This keeps track of the effect chain for initial stores on a newly |
43 // allocated object and also provides helpers for commonly allocated objects. | 26 // allocated object and also provides helpers for commonly allocated objects. |
44 class AllocationBuilder final { | 27 class AllocationBuilder final { |
45 public: | 28 public: |
46 AllocationBuilder(JSGraph* jsgraph, Node* effect, Node* control) | 29 AllocationBuilder(JSGraph* jsgraph, Node* effect, Node* control) |
47 : jsgraph_(jsgraph), | 30 : jsgraph_(jsgraph), |
48 allocation_(nullptr), | 31 allocation_(nullptr), |
49 effect_(effect), | 32 effect_(effect), |
50 control_(control) {} | 33 control_(control) {} |
51 | 34 |
52 // Primitive allocation of static size. | 35 // Primitive allocation of static size. |
53 void Allocate(int size) { | 36 void Allocate(int size, PretenureFlag pretenure = NOT_TENURED) { |
54 effect_ = graph()->NewNode(common()->BeginRegion(), effect_); | 37 effect_ = graph()->NewNode(common()->BeginRegion(), effect_); |
55 allocation_ = graph()->NewNode( | 38 allocation_ = |
56 simplified()->Allocate(), jsgraph()->Constant(size), effect_, control_); | 39 graph()->NewNode(simplified()->Allocate(pretenure), |
| 40 jsgraph()->Constant(size), effect_, control_); |
57 effect_ = allocation_; | 41 effect_ = allocation_; |
58 } | 42 } |
59 | 43 |
60 // Primitive store into a field. | 44 // Primitive store into a field. |
61 void Store(const FieldAccess& access, Node* value) { | 45 void Store(const FieldAccess& access, Node* value) { |
62 effect_ = graph()->NewNode(simplified()->StoreField(access), allocation_, | 46 effect_ = graph()->NewNode(simplified()->StoreField(access), allocation_, |
63 value, effect_, control_); | 47 value, effect_, control_); |
64 } | 48 } |
65 | 49 |
| 50 // Primitive store into an element. |
| 51 void Store(ElementAccess const& access, Node* index, Node* value) { |
| 52 effect_ = graph()->NewNode(simplified()->StoreElement(access), allocation_, |
| 53 index, value, effect_, control_); |
| 54 } |
| 55 |
66 // Compound allocation of a FixedArray. | 56 // Compound allocation of a FixedArray. |
67 void AllocateArray(int length, Handle<Map> map) { | 57 void AllocateArray(int length, Handle<Map> map, |
68 Allocate(FixedArray::SizeFor(length)); | 58 PretenureFlag pretenure = NOT_TENURED) { |
| 59 DCHECK(map->instance_type() == FIXED_ARRAY_TYPE || |
| 60 map->instance_type() == FIXED_DOUBLE_ARRAY_TYPE); |
| 61 int size = (map->instance_type() == FIXED_ARRAY_TYPE) |
| 62 ? FixedArray::SizeFor(length) |
| 63 : FixedDoubleArray::SizeFor(length); |
| 64 Allocate(size, pretenure); |
69 Store(AccessBuilder::ForMap(), map); | 65 Store(AccessBuilder::ForMap(), map); |
70 Store(AccessBuilder::ForFixedArrayLength(), jsgraph()->Constant(length)); | 66 Store(AccessBuilder::ForFixedArrayLength(), jsgraph()->Constant(length)); |
71 } | 67 } |
72 | 68 |
73 // Compound store of a constant into a field. | 69 // Compound store of a constant into a field. |
74 void Store(const FieldAccess& access, Handle<Object> value) { | 70 void Store(const FieldAccess& access, Handle<Object> value) { |
75 Store(access, jsgraph()->Constant(value)); | 71 Store(access, jsgraph()->Constant(value)); |
76 } | 72 } |
77 | 73 |
78 void FinishAndChange(Node* node) { | 74 void FinishAndChange(Node* node) { |
(...skipping 14 matching lines...) Expand all Loading... |
93 CommonOperatorBuilder* common() { return jsgraph_->common(); } | 89 CommonOperatorBuilder* common() { return jsgraph_->common(); } |
94 SimplifiedOperatorBuilder* simplified() { return jsgraph_->simplified(); } | 90 SimplifiedOperatorBuilder* simplified() { return jsgraph_->simplified(); } |
95 | 91 |
96 private: | 92 private: |
97 JSGraph* const jsgraph_; | 93 JSGraph* const jsgraph_; |
98 Node* allocation_; | 94 Node* allocation_; |
99 Node* effect_; | 95 Node* effect_; |
100 Node* control_; | 96 Node* control_; |
101 }; | 97 }; |
102 | 98 |
| 99 } // namespace |
| 100 |
103 | 101 |
104 // A helper class to simplify the process of reducing a single binop node with a | 102 // A helper class to simplify the process of reducing a single binop node with a |
105 // JSOperator. This class manages the rewriting of context, control, and effect | 103 // JSOperator. This class manages the rewriting of context, control, and effect |
106 // dependencies during lowering of a binop and contains numerous helper | 104 // dependencies during lowering of a binop and contains numerous helper |
107 // functions for matching the types of inputs to an operation. | 105 // functions for matching the types of inputs to an operation. |
108 class JSBinopReduction final { | 106 class JSBinopReduction final { |
109 public: | 107 public: |
110 JSBinopReduction(JSTypedLowering* lowering, Node* node) | 108 JSBinopReduction(JSTypedLowering* lowering, Node* node) |
111 : lowering_(lowering), node_(node) {} | 109 : lowering_(lowering), node_(node) {} |
112 | 110 |
(...skipping 297 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
410 } | 408 } |
411 return node; | 409 return node; |
412 } | 410 } |
413 | 411 |
414 void update_effect(Node* effect) { | 412 void update_effect(Node* effect) { |
415 NodeProperties::ReplaceEffectInput(node_, effect); | 413 NodeProperties::ReplaceEffectInput(node_, effect); |
416 } | 414 } |
417 }; | 415 }; |
418 | 416 |
419 | 417 |
| 418 // TODO(turbofan): js-typed-lowering improvements possible |
| 419 // - immediately put in type bounds for all new nodes |
| 420 // - relax effects from generic but not-side-effecting operations |
| 421 |
| 422 |
| 423 JSTypedLowering::JSTypedLowering(Editor* editor, |
| 424 CompilationDependencies* dependencies, |
| 425 Flags flags, JSGraph* jsgraph, Zone* zone) |
| 426 : AdvancedReducer(editor), |
| 427 dependencies_(dependencies), |
| 428 flags_(flags), |
| 429 jsgraph_(jsgraph), |
| 430 type_cache_(TypeCache::Get()) { |
| 431 for (size_t k = 0; k < arraysize(shifted_int32_ranges_); ++k) { |
| 432 double min = kMinInt / (1 << k); |
| 433 double max = kMaxInt / (1 << k); |
| 434 shifted_int32_ranges_[k] = Type::Range(min, max, graph()->zone()); |
| 435 } |
| 436 } |
| 437 |
| 438 |
420 Reduction JSTypedLowering::ReduceJSAdd(Node* node) { | 439 Reduction JSTypedLowering::ReduceJSAdd(Node* node) { |
421 JSBinopReduction r(this, node); | 440 JSBinopReduction r(this, node); |
422 if (r.BothInputsAre(Type::Number())) { | 441 if (r.BothInputsAre(Type::Number())) { |
423 // JSAdd(x:number, y:number) => NumberAdd(x, y) | 442 // JSAdd(x:number, y:number) => NumberAdd(x, y) |
424 return r.ChangeToPureOperator(simplified()->NumberAdd(), Type::Number()); | 443 return r.ChangeToPureOperator(simplified()->NumberAdd(), Type::Number()); |
425 } | 444 } |
426 if (r.NeitherInputCanBe(Type::StringOrReceiver()) && !r.IsStrong()) { | 445 if (r.NeitherInputCanBe(Type::StringOrReceiver()) && !r.IsStrong()) { |
427 // JSAdd(x:-string, y:-string) => NumberAdd(ToNumber(x), ToNumber(y)) | 446 // JSAdd(x:-string, y:-string) => NumberAdd(ToNumber(x), ToNumber(y)) |
428 Node* frame_state = NodeProperties::GetFrameStateInput(node, 1); | 447 Node* frame_state = NodeProperties::GetFrameStateInput(node, 1); |
429 r.ConvertInputsToNumber(frame_state); | 448 r.ConvertInputsToNumber(frame_state); |
(...skipping 1124 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1554 a.Store(AccessBuilder::ForArgumentsLength(), jsgraph()->Constant(length)); | 1573 a.Store(AccessBuilder::ForArgumentsLength(), jsgraph()->Constant(length)); |
1555 RelaxControls(node); | 1574 RelaxControls(node); |
1556 a.FinishAndChange(node); | 1575 a.FinishAndChange(node); |
1557 return Changed(node); | 1576 return Changed(node); |
1558 } | 1577 } |
1559 | 1578 |
1560 return NoChange(); | 1579 return NoChange(); |
1561 } | 1580 } |
1562 | 1581 |
1563 | 1582 |
| 1583 Reduction JSTypedLowering::ReduceNewArray(Node* node, Node* length, |
| 1584 int capacity, |
| 1585 Handle<AllocationSite> site) { |
| 1586 DCHECK_EQ(IrOpcode::kJSCreateArray, node->opcode()); |
| 1587 Node* target = NodeProperties::GetValueInput(node, 0); |
| 1588 Type* target_type = NodeProperties::GetType(target); |
| 1589 Node* context = NodeProperties::GetContextInput(node); |
| 1590 Node* effect = NodeProperties::GetEffectInput(node); |
| 1591 Node* control = NodeProperties::GetControlInput(node); |
| 1592 |
| 1593 // Extract transition and tenuring feedback from the {site} and add |
| 1594 // appropriate code dependencies on the {site} if deoptimization is |
| 1595 // enabled. |
| 1596 PretenureFlag pretenure = site->GetPretenureMode(); |
| 1597 ElementsKind elements_kind = site->GetElementsKind(); |
| 1598 if (flags() & kDeoptimizationEnabled) { |
| 1599 dependencies()->AssumeTenuringDecision(site); |
| 1600 dependencies()->AssumeTransitionStable(site); |
| 1601 } |
| 1602 |
| 1603 // Retrieve the initial map for the array from the appropriate native context. |
| 1604 Node* js_array_map; |
| 1605 if (target_type->IsConstant()) { |
| 1606 Handle<JSFunction> target_function = |
| 1607 Handle<JSFunction>::cast(target_type->AsConstant()->Value()); |
| 1608 Handle<FixedArray> js_array_maps( |
| 1609 FixedArray::cast(target_function->native_context()->js_array_maps()), |
| 1610 isolate()); |
| 1611 js_array_map = jsgraph()->Constant( |
| 1612 handle(js_array_maps->get(elements_kind), isolate())); |
| 1613 } else { |
| 1614 Node* global_object = effect = graph()->NewNode( |
| 1615 javascript()->LoadContext(0, Context::GLOBAL_OBJECT_INDEX, true), |
| 1616 context, context, effect); |
| 1617 Node* native_context = effect = |
| 1618 graph()->NewNode(simplified()->LoadField( |
| 1619 AccessBuilder::ForJSGlobalObjectNativeContext()), |
| 1620 global_object, effect, control); |
| 1621 Node* js_array_maps = effect = graph()->NewNode( |
| 1622 javascript()->LoadContext(0, Context::JS_ARRAY_MAPS_INDEX, true), |
| 1623 native_context, native_context, effect); |
| 1624 js_array_map = effect = |
| 1625 graph()->NewNode(simplified()->LoadField( |
| 1626 AccessBuilder::ForFixedArraySlot(elements_kind)), |
| 1627 js_array_maps, effect, control); |
| 1628 } |
| 1629 |
| 1630 // Setup elements and properties. |
| 1631 Node* elements; |
| 1632 if (capacity == 0) { |
| 1633 elements = jsgraph()->EmptyFixedArrayConstant(); |
| 1634 } else { |
| 1635 elements = effect = |
| 1636 AllocateElements(effect, control, elements_kind, capacity, pretenure); |
| 1637 } |
| 1638 Node* properties = jsgraph()->EmptyFixedArrayConstant(); |
| 1639 |
| 1640 // Perform the allocation of the actual JSArray object. |
| 1641 AllocationBuilder a(jsgraph(), effect, control); |
| 1642 a.Allocate(JSArray::kSize, pretenure); |
| 1643 a.Store(AccessBuilder::ForMap(), js_array_map); |
| 1644 a.Store(AccessBuilder::ForJSObjectProperties(), properties); |
| 1645 a.Store(AccessBuilder::ForJSObjectElements(), elements); |
| 1646 a.Store(AccessBuilder::ForJSArrayLength(elements_kind), length); |
| 1647 RelaxControls(node); |
| 1648 a.FinishAndChange(node); |
| 1649 return Changed(node); |
| 1650 } |
| 1651 |
| 1652 |
1564 Reduction JSTypedLowering::ReduceJSCreateArray(Node* node) { | 1653 Reduction JSTypedLowering::ReduceJSCreateArray(Node* node) { |
1565 DCHECK_EQ(IrOpcode::kJSCreateArray, node->opcode()); | 1654 DCHECK_EQ(IrOpcode::kJSCreateArray, node->opcode()); |
1566 CreateArrayParameters const& p = CreateArrayParametersOf(node->op()); | 1655 CreateArrayParameters const& p = CreateArrayParametersOf(node->op()); |
1567 Node* const target = NodeProperties::GetValueInput(node, 0); | 1656 Node* target = NodeProperties::GetValueInput(node, 0); |
1568 Node* const new_target = NodeProperties::GetValueInput(node, 1); | 1657 Node* new_target = NodeProperties::GetValueInput(node, 1); |
1569 | 1658 |
1570 // TODO(bmeurer): Optimize the subclassing case. | 1659 // TODO(bmeurer): Optimize the subclassing case. |
1571 if (target != new_target) return NoChange(); | 1660 if (target != new_target) return NoChange(); |
1572 | 1661 |
1573 // Check if we have a feedback {site} on the {node}. | 1662 // Check if we have a feedback {site} on the {node}. |
1574 Handle<AllocationSite> site = p.site(); | 1663 Handle<AllocationSite> site = p.site(); |
1575 if (p.site().is_null()) return NoChange(); | 1664 if (p.site().is_null()) return NoChange(); |
1576 ElementsKind const elements_kind = site->GetElementsKind(); | 1665 |
1577 AllocationSiteOverrideMode override_mode = | 1666 // Attempt to inline calls to the Array constructor for the relevant cases |
1578 (AllocationSite::GetMode(elements_kind) == TRACK_ALLOCATION_SITE) | 1667 // where either no arguments are provided, or exactly one unsigned number |
1579 ? DISABLE_ALLOCATION_SITES | 1668 // argument is given. |
1580 : DONT_OVERRIDE; | 1669 if (site->CanInlineCall()) { |
| 1670 if (p.arity() == 0) { |
| 1671 Node* length = jsgraph()->ZeroConstant(); |
| 1672 int capacity = JSArray::kPreallocatedArrayElements; |
| 1673 return ReduceNewArray(node, length, capacity, site); |
| 1674 } else if (p.arity() == 1) { |
| 1675 Node* length = NodeProperties::GetValueInput(node, 2); |
| 1676 Type* length_type = NodeProperties::GetType(length); |
| 1677 if (length_type->Is(type_cache_.kElementLoopUnrollType)) { |
| 1678 int capacity = static_cast<int>(length_type->Max()); |
| 1679 return ReduceNewArray(node, length, capacity, site); |
| 1680 } |
| 1681 } |
| 1682 } |
1581 | 1683 |
1582 // Reduce {node} to the appropriate ArrayConstructorStub backend. | 1684 // Reduce {node} to the appropriate ArrayConstructorStub backend. |
1583 // Note that these stubs "behave" like JSFunctions, which means they | 1685 // Note that these stubs "behave" like JSFunctions, which means they |
1584 // expect a receiver on the stack, which they remove. We just push | 1686 // expect a receiver on the stack, which they remove. We just push |
1585 // undefined for the receiver. | 1687 // undefined for the receiver. |
| 1688 ElementsKind elements_kind = site->GetElementsKind(); |
| 1689 AllocationSiteOverrideMode override_mode = |
| 1690 (AllocationSite::GetMode(elements_kind) == TRACK_ALLOCATION_SITE) |
| 1691 ? DISABLE_ALLOCATION_SITES |
| 1692 : DONT_OVERRIDE; |
1586 if (p.arity() == 0) { | 1693 if (p.arity() == 0) { |
1587 ArrayNoArgumentConstructorStub stub(isolate(), elements_kind, | 1694 ArrayNoArgumentConstructorStub stub(isolate(), elements_kind, |
1588 override_mode); | 1695 override_mode); |
1589 CallDescriptor* desc = Linkage::GetStubCallDescriptor( | 1696 CallDescriptor* desc = Linkage::GetStubCallDescriptor( |
1590 isolate(), graph()->zone(), stub.GetCallInterfaceDescriptor(), 1, | 1697 isolate(), graph()->zone(), stub.GetCallInterfaceDescriptor(), 1, |
1591 CallDescriptor::kNeedsFrameState); | 1698 CallDescriptor::kNeedsFrameState); |
1592 node->ReplaceInput(0, jsgraph()->HeapConstant(stub.GetCode())); | 1699 node->ReplaceInput(0, jsgraph()->HeapConstant(stub.GetCode())); |
1593 node->InsertInput(graph()->zone(), 2, jsgraph()->UndefinedConstant()); | 1700 node->InsertInput(graph()->zone(), 2, jsgraph()->HeapConstant(site)); |
1594 node->InsertInput(graph()->zone(), 3, jsgraph()->UndefinedConstant()); | 1701 node->InsertInput(graph()->zone(), 3, jsgraph()->UndefinedConstant()); |
1595 NodeProperties::ChangeOp(node, common()->Call(desc)); | 1702 NodeProperties::ChangeOp(node, common()->Call(desc)); |
1596 return Changed(node); | 1703 return Changed(node); |
1597 } else if (p.arity() == 1) { | 1704 } else if (p.arity() == 1) { |
1598 // TODO(bmeurer): Optimize for the 0 length non-holey case? | 1705 // TODO(bmeurer): Optimize for the 0 length non-holey case? |
1599 ArraySingleArgumentConstructorStub stub( | 1706 ArraySingleArgumentConstructorStub stub( |
1600 isolate(), GetHoleyElementsKind(elements_kind), override_mode); | 1707 isolate(), GetHoleyElementsKind(elements_kind), override_mode); |
1601 CallDescriptor* desc = Linkage::GetStubCallDescriptor( | 1708 CallDescriptor* desc = Linkage::GetStubCallDescriptor( |
1602 isolate(), graph()->zone(), stub.GetCallInterfaceDescriptor(), 2, | 1709 isolate(), graph()->zone(), stub.GetCallInterfaceDescriptor(), 2, |
1603 CallDescriptor::kNeedsFrameState); | 1710 CallDescriptor::kNeedsFrameState); |
1604 node->ReplaceInput(0, jsgraph()->HeapConstant(stub.GetCode())); | 1711 node->ReplaceInput(0, jsgraph()->HeapConstant(stub.GetCode())); |
1605 node->InsertInput(graph()->zone(), 2, jsgraph()->HeapConstant(site)); | 1712 node->InsertInput(graph()->zone(), 2, jsgraph()->HeapConstant(site)); |
1606 node->InsertInput(graph()->zone(), 3, jsgraph()->Int32Constant(1)); | 1713 node->InsertInput(graph()->zone(), 3, jsgraph()->Int32Constant(1)); |
1607 node->InsertInput(graph()->zone(), 4, jsgraph()->UndefinedConstant()); | 1714 node->InsertInput(graph()->zone(), 4, jsgraph()->UndefinedConstant()); |
1608 NodeProperties::ChangeOp(node, common()->Call(desc)); | 1715 NodeProperties::ChangeOp(node, common()->Call(desc)); |
1609 return Changed(node); | 1716 return Changed(node); |
1610 } else { | 1717 } else { |
1611 int const arity = static_cast<int>(p.arity()); | 1718 int const arity = static_cast<int>(p.arity()); |
1612 ArrayNArgumentsConstructorStub stub(isolate(), elements_kind, | 1719 ArrayNArgumentsConstructorStub stub(isolate(), elements_kind, |
1613 override_mode); | 1720 override_mode); |
1614 CallDescriptor* desc = Linkage::GetStubCallDescriptor( | 1721 CallDescriptor* desc = Linkage::GetStubCallDescriptor( |
1615 isolate(), graph()->zone(), stub.GetCallInterfaceDescriptor(), | 1722 isolate(), graph()->zone(), stub.GetCallInterfaceDescriptor(), |
1616 arity + 1, CallDescriptor::kNeedsFrameState); | 1723 arity + 1, CallDescriptor::kNeedsFrameState); |
1617 node->ReplaceInput(0, jsgraph()->HeapConstant(stub.GetCode())); | 1724 node->ReplaceInput(0, jsgraph()->HeapConstant(stub.GetCode())); |
1618 node->InsertInput(graph()->zone(), 2, jsgraph()->UndefinedConstant()); | 1725 node->InsertInput(graph()->zone(), 2, jsgraph()->HeapConstant(site)); |
1619 node->InsertInput(graph()->zone(), 3, jsgraph()->Int32Constant(arity)); | 1726 node->InsertInput(graph()->zone(), 3, jsgraph()->Int32Constant(arity)); |
1620 node->InsertInput(graph()->zone(), 4, jsgraph()->UndefinedConstant()); | 1727 node->InsertInput(graph()->zone(), 4, jsgraph()->UndefinedConstant()); |
1621 NodeProperties::ChangeOp(node, common()->Call(desc)); | 1728 NodeProperties::ChangeOp(node, common()->Call(desc)); |
1622 return Changed(node); | 1729 return Changed(node); |
1623 } | 1730 } |
1624 } | 1731 } |
1625 | 1732 |
1626 | 1733 |
1627 Reduction JSTypedLowering::ReduceJSCreateClosure(Node* node) { | 1734 Reduction JSTypedLowering::ReduceJSCreateClosure(Node* node) { |
1628 DCHECK_EQ(IrOpcode::kJSCreateClosure, node->opcode()); | 1735 DCHECK_EQ(IrOpcode::kJSCreateClosure, node->opcode()); |
(...skipping 805 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2434 a.Store(AccessBuilder::ForFixedArraySlot(0), context); | 2541 a.Store(AccessBuilder::ForFixedArraySlot(0), context); |
2435 a.Store(AccessBuilder::ForFixedArraySlot(1), arguments); | 2542 a.Store(AccessBuilder::ForFixedArraySlot(1), arguments); |
2436 for (int i = 0; i < mapped_count; ++i) { | 2543 for (int i = 0; i < mapped_count; ++i) { |
2437 int idx = Context::MIN_CONTEXT_SLOTS + parameter_count - 1 - i; | 2544 int idx = Context::MIN_CONTEXT_SLOTS + parameter_count - 1 - i; |
2438 a.Store(AccessBuilder::ForFixedArraySlot(i + 2), jsgraph()->Constant(idx)); | 2545 a.Store(AccessBuilder::ForFixedArraySlot(i + 2), jsgraph()->Constant(idx)); |
2439 } | 2546 } |
2440 return a.Finish(); | 2547 return a.Finish(); |
2441 } | 2548 } |
2442 | 2549 |
2443 | 2550 |
| 2551 Node* JSTypedLowering::AllocateElements(Node* effect, Node* control, |
| 2552 ElementsKind elements_kind, |
| 2553 int capacity, PretenureFlag pretenure) { |
| 2554 DCHECK_LE(1, capacity); |
| 2555 DCHECK_LE(capacity, JSArray::kInitialMaxFastElementArray); |
| 2556 |
| 2557 Handle<Map> elements_map = IsFastDoubleElementsKind(elements_kind) |
| 2558 ? factory()->fixed_double_array_map() |
| 2559 : factory()->fixed_array_map(); |
| 2560 ElementAccess access = IsFastDoubleElementsKind(elements_kind) |
| 2561 ? AccessBuilder::ForFixedDoubleArrayElement() |
| 2562 : AccessBuilder::ForFixedArrayElement(); |
| 2563 Node* value = |
| 2564 IsFastDoubleElementsKind(elements_kind) |
| 2565 ? jsgraph()->Float64Constant(bit_cast<double>(kHoleNanInt64)) |
| 2566 : jsgraph()->TheHoleConstant(); |
| 2567 |
| 2568 // Actually allocate the backing store. |
| 2569 AllocationBuilder a(jsgraph(), effect, control); |
| 2570 a.AllocateArray(capacity, elements_map, pretenure); |
| 2571 for (int i = 0; i < capacity; ++i) { |
| 2572 Node* index = jsgraph()->Int32Constant(i); |
| 2573 a.Store(access, index, value); |
| 2574 } |
| 2575 return a.Finish(); |
| 2576 } |
| 2577 |
| 2578 |
2444 Factory* JSTypedLowering::factory() const { return jsgraph()->factory(); } | 2579 Factory* JSTypedLowering::factory() const { return jsgraph()->factory(); } |
2445 | 2580 |
2446 | 2581 |
2447 Graph* JSTypedLowering::graph() const { return jsgraph()->graph(); } | 2582 Graph* JSTypedLowering::graph() const { return jsgraph()->graph(); } |
2448 | 2583 |
2449 | 2584 |
2450 Isolate* JSTypedLowering::isolate() const { return jsgraph()->isolate(); } | 2585 Isolate* JSTypedLowering::isolate() const { return jsgraph()->isolate(); } |
2451 | 2586 |
2452 | 2587 |
2453 JSOperatorBuilder* JSTypedLowering::javascript() const { | 2588 JSOperatorBuilder* JSTypedLowering::javascript() const { |
(...skipping 16 matching lines...) Expand all Loading... |
2470 } | 2605 } |
2471 | 2606 |
2472 | 2607 |
2473 CompilationDependencies* JSTypedLowering::dependencies() const { | 2608 CompilationDependencies* JSTypedLowering::dependencies() const { |
2474 return dependencies_; | 2609 return dependencies_; |
2475 } | 2610 } |
2476 | 2611 |
2477 } // namespace compiler | 2612 } // namespace compiler |
2478 } // namespace internal | 2613 } // namespace internal |
2479 } // namespace v8 | 2614 } // namespace v8 |
OLD | NEW |