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

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

Issue 1465203002: [turbofan] Initial support for inline allocations of arrays. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Fix unbounded inlining. Reduce code duplication. Add proper code dependencies. Created 5 years 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-typed-lowering.h ('k') | src/type-cache.h » ('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 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
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
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
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
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
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
OLDNEW
« no previous file with comments | « src/compiler/js-typed-lowering.h ('k') | src/type-cache.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698