| 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 #include "src/code-stub-assembler.h" | 4 #include "src/code-stub-assembler.h" |
| 5 #include "src/code-factory.h" | 5 #include "src/code-factory.h" |
| 6 #include "src/frames-inl.h" | 6 #include "src/frames-inl.h" |
| 7 #include "src/frames.h" | 7 #include "src/frames.h" |
| 8 | 8 |
| 9 namespace v8 { | 9 namespace v8 { |
| 10 namespace internal { | 10 namespace internal { |
| (...skipping 553 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 564 // Check if the multiplication overflowed. | 564 // Check if the multiplication overflowed. |
| 565 Label if_overflow(this, Label::kDeferred), if_notoverflow(this); | 565 Label if_overflow(this, Label::kDeferred), if_notoverflow(this); |
| 566 Branch(overflow, &if_overflow, &if_notoverflow); | 566 Branch(overflow, &if_overflow, &if_notoverflow); |
| 567 Bind(&if_notoverflow); | 567 Bind(&if_notoverflow); |
| 568 { | 568 { |
| 569 // If the answer is zero, we may need to return -0.0, depending on the | 569 // If the answer is zero, we may need to return -0.0, depending on the |
| 570 // input. | 570 // input. |
| 571 Label answer_zero(this), answer_not_zero(this); | 571 Label answer_zero(this), answer_not_zero(this); |
| 572 Node* answer = Projection(0, pair); | 572 Node* answer = Projection(0, pair); |
| 573 Node* zero = Int32Constant(0); | 573 Node* zero = Int32Constant(0); |
| 574 Branch(WordEqual(answer, zero), &answer_zero, &answer_not_zero); | 574 Branch(Word32Equal(answer, zero), &answer_zero, &answer_not_zero); |
| 575 Bind(&answer_not_zero); | 575 Bind(&answer_not_zero); |
| 576 { | 576 { |
| 577 var_result.Bind(ChangeInt32ToTagged(answer)); | 577 var_result.Bind(ChangeInt32ToTagged(answer)); |
| 578 Goto(&return_result); | 578 Goto(&return_result); |
| 579 } | 579 } |
| 580 Bind(&answer_zero); | 580 Bind(&answer_zero); |
| 581 { | 581 { |
| 582 Node* or_result = Word32Or(lhs32, rhs32); | 582 Node* or_result = Word32Or(lhs32, rhs32); |
| 583 Label if_should_be_negative_zero(this), if_should_be_zero(this); | 583 Label if_should_be_negative_zero(this), if_should_be_zero(this); |
| 584 Branch(Int32LessThan(or_result, zero), &if_should_be_negative_zero, | 584 Branch(Int32LessThan(or_result, zero), &if_should_be_negative_zero, |
| 585 &if_should_be_zero); | 585 &if_should_be_zero); |
| 586 Bind(&if_should_be_negative_zero); | 586 Bind(&if_should_be_negative_zero); |
| 587 { | 587 { |
| 588 var_result.Bind(MinusZeroConstant()); | 588 var_result.Bind(MinusZeroConstant()); |
| 589 Goto(&return_result); | 589 Goto(&return_result); |
| 590 } | 590 } |
| 591 Bind(&if_should_be_zero); | 591 Bind(&if_should_be_zero); |
| 592 { | 592 { |
| 593 var_result.Bind(zero); | 593 var_result.Bind(SmiConstant(0)); |
| 594 Goto(&return_result); | 594 Goto(&return_result); |
| 595 } | 595 } |
| 596 } | 596 } |
| 597 } | 597 } |
| 598 Bind(&if_overflow); | 598 Bind(&if_overflow); |
| 599 { | 599 { |
| 600 var_lhs_float64.Bind(SmiToFloat64(a)); | 600 var_lhs_float64.Bind(SmiToFloat64(a)); |
| 601 var_rhs_float64.Bind(SmiToFloat64(b)); | 601 var_rhs_float64.Bind(SmiToFloat64(b)); |
| 602 Node* value = Float64Mul(var_lhs_float64.value(), var_rhs_float64.value()); | 602 Node* value = Float64Mul(var_lhs_float64.value(), var_rhs_float64.value()); |
| 603 Node* result = AllocateHeapNumberWithValue(value); | 603 Node* result = AllocateHeapNumberWithValue(value); |
| (...skipping 16 matching lines...) Expand all Loading... |
| 620 return WordEqual(WordAnd(BitcastTaggedToWord(a), IntPtrConstant(kSmiTagMask)), | 620 return WordEqual(WordAnd(BitcastTaggedToWord(a), IntPtrConstant(kSmiTagMask)), |
| 621 IntPtrConstant(0)); | 621 IntPtrConstant(0)); |
| 622 } | 622 } |
| 623 | 623 |
| 624 Node* CodeStubAssembler::TaggedIsNotSmi(Node* a) { | 624 Node* CodeStubAssembler::TaggedIsNotSmi(Node* a) { |
| 625 return WordNotEqual( | 625 return WordNotEqual( |
| 626 WordAnd(BitcastTaggedToWord(a), IntPtrConstant(kSmiTagMask)), | 626 WordAnd(BitcastTaggedToWord(a), IntPtrConstant(kSmiTagMask)), |
| 627 IntPtrConstant(0)); | 627 IntPtrConstant(0)); |
| 628 } | 628 } |
| 629 | 629 |
| 630 Node* CodeStubAssembler::WordIsPositiveSmi(Node* a) { | 630 Node* CodeStubAssembler::TaggedIsPositiveSmi(Node* a) { |
| 631 return WordEqual(WordAnd(a, IntPtrConstant(kSmiTagMask | kSmiSignMask)), | 631 return WordEqual(WordAnd(BitcastTaggedToWord(a), |
| 632 IntPtrConstant(kSmiTagMask | kSmiSignMask)), |
| 632 IntPtrConstant(0)); | 633 IntPtrConstant(0)); |
| 633 } | 634 } |
| 634 | 635 |
| 635 Node* CodeStubAssembler::WordIsWordAligned(Node* word) { | 636 Node* CodeStubAssembler::WordIsWordAligned(Node* word) { |
| 636 return WordEqual(IntPtrConstant(0), | 637 return WordEqual(IntPtrConstant(0), |
| 637 WordAnd(word, IntPtrConstant((1 << kPointerSizeLog2) - 1))); | 638 WordAnd(word, IntPtrConstant((1 << kPointerSizeLog2) - 1))); |
| 638 } | 639 } |
| 639 | 640 |
| 640 void CodeStubAssembler::BranchIfSimd128Equal(Node* lhs, Node* lhs_map, | 641 void CodeStubAssembler::BranchIfSimd128Equal(Node* lhs, Node* lhs_map, |
| 641 Node* rhs, Node* rhs_map, | 642 Node* rhs, Node* rhs_map, |
| (...skipping 272 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 914 #endif | 915 #endif |
| 915 | 916 |
| 916 return AllocateRawUnaligned(size_in_bytes, flags, top_address, limit_address); | 917 return AllocateRawUnaligned(size_in_bytes, flags, top_address, limit_address); |
| 917 } | 918 } |
| 918 | 919 |
| 919 Node* CodeStubAssembler::Allocate(int size_in_bytes, AllocationFlags flags) { | 920 Node* CodeStubAssembler::Allocate(int size_in_bytes, AllocationFlags flags) { |
| 920 return CodeStubAssembler::Allocate(IntPtrConstant(size_in_bytes), flags); | 921 return CodeStubAssembler::Allocate(IntPtrConstant(size_in_bytes), flags); |
| 921 } | 922 } |
| 922 | 923 |
| 923 Node* CodeStubAssembler::InnerAllocate(Node* previous, Node* offset) { | 924 Node* CodeStubAssembler::InnerAllocate(Node* previous, Node* offset) { |
| 924 return BitcastWordToTagged(IntPtrAdd(previous, offset)); | 925 return BitcastWordToTagged(IntPtrAdd(BitcastTaggedToWord(previous), offset)); |
| 925 } | 926 } |
| 926 | 927 |
| 927 Node* CodeStubAssembler::InnerAllocate(Node* previous, int offset) { | 928 Node* CodeStubAssembler::InnerAllocate(Node* previous, int offset) { |
| 928 return InnerAllocate(previous, IntPtrConstant(offset)); | 929 return InnerAllocate(previous, IntPtrConstant(offset)); |
| 929 } | 930 } |
| 930 | 931 |
| 931 Node* CodeStubAssembler::IsRegularHeapObjectSize(Node* size) { | 932 Node* CodeStubAssembler::IsRegularHeapObjectSize(Node* size) { |
| 932 return UintPtrLessThanOrEqual(size, | 933 return UintPtrLessThanOrEqual(size, |
| 933 IntPtrConstant(kMaxRegularHeapObjectSize)); | 934 IntPtrConstant(kMaxRegularHeapObjectSize)); |
| 934 } | 935 } |
| (...skipping 644 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1579 } | 1580 } |
| 1580 | 1581 |
| 1581 Node* CodeStubAssembler::AllocateSeqOneByteString(int length, | 1582 Node* CodeStubAssembler::AllocateSeqOneByteString(int length, |
| 1582 AllocationFlags flags) { | 1583 AllocationFlags flags) { |
| 1583 Comment("AllocateSeqOneByteString"); | 1584 Comment("AllocateSeqOneByteString"); |
| 1584 Node* result = Allocate(SeqOneByteString::SizeFor(length), flags); | 1585 Node* result = Allocate(SeqOneByteString::SizeFor(length), flags); |
| 1585 DCHECK(Heap::RootIsImmortalImmovable(Heap::kOneByteStringMapRootIndex)); | 1586 DCHECK(Heap::RootIsImmortalImmovable(Heap::kOneByteStringMapRootIndex)); |
| 1586 StoreMapNoWriteBarrier(result, Heap::kOneByteStringMapRootIndex); | 1587 StoreMapNoWriteBarrier(result, Heap::kOneByteStringMapRootIndex); |
| 1587 StoreObjectFieldNoWriteBarrier(result, SeqOneByteString::kLengthOffset, | 1588 StoreObjectFieldNoWriteBarrier(result, SeqOneByteString::kLengthOffset, |
| 1588 SmiConstant(Smi::FromInt(length))); | 1589 SmiConstant(Smi::FromInt(length))); |
| 1589 StoreObjectFieldNoWriteBarrier(result, SeqOneByteString::kHashFieldOffset, | 1590 // Initialize both used and unused parts of hash field slot at once. |
| 1591 StoreObjectFieldNoWriteBarrier(result, SeqOneByteString::kHashFieldSlot, |
| 1590 IntPtrConstant(String::kEmptyHashField), | 1592 IntPtrConstant(String::kEmptyHashField), |
| 1591 MachineRepresentation::kWord32); | 1593 MachineType::PointerRepresentation()); |
| 1592 return result; | 1594 return result; |
| 1593 } | 1595 } |
| 1594 | 1596 |
| 1595 Node* CodeStubAssembler::AllocateSeqOneByteString(Node* context, Node* length, | 1597 Node* CodeStubAssembler::AllocateSeqOneByteString(Node* context, Node* length, |
| 1596 ParameterMode mode, | 1598 ParameterMode mode, |
| 1597 AllocationFlags flags) { | 1599 AllocationFlags flags) { |
| 1598 Comment("AllocateSeqOneByteString"); | 1600 Comment("AllocateSeqOneByteString"); |
| 1599 Variable var_result(this, MachineRepresentation::kTagged); | 1601 Variable var_result(this, MachineRepresentation::kTagged); |
| 1600 | 1602 |
| 1601 // Compute the SeqOneByteString size and check if it fits into new space. | 1603 // Compute the SeqOneByteString size and check if it fits into new space. |
| 1602 Label if_sizeissmall(this), if_notsizeissmall(this, Label::kDeferred), | 1604 Label if_sizeissmall(this), if_notsizeissmall(this, Label::kDeferred), |
| 1603 if_join(this); | 1605 if_join(this); |
| 1604 Node* raw_size = GetArrayAllocationSize( | 1606 Node* raw_size = GetArrayAllocationSize( |
| 1605 length, UINT8_ELEMENTS, mode, | 1607 length, UINT8_ELEMENTS, mode, |
| 1606 SeqOneByteString::kHeaderSize + kObjectAlignmentMask); | 1608 SeqOneByteString::kHeaderSize + kObjectAlignmentMask); |
| 1607 Node* size = WordAnd(raw_size, IntPtrConstant(~kObjectAlignmentMask)); | 1609 Node* size = WordAnd(raw_size, IntPtrConstant(~kObjectAlignmentMask)); |
| 1608 Branch(IntPtrLessThanOrEqual(size, IntPtrConstant(kMaxRegularHeapObjectSize)), | 1610 Branch(IntPtrLessThanOrEqual(size, IntPtrConstant(kMaxRegularHeapObjectSize)), |
| 1609 &if_sizeissmall, &if_notsizeissmall); | 1611 &if_sizeissmall, &if_notsizeissmall); |
| 1610 | 1612 |
| 1611 Bind(&if_sizeissmall); | 1613 Bind(&if_sizeissmall); |
| 1612 { | 1614 { |
| 1613 // Just allocate the SeqOneByteString in new space. | 1615 // Just allocate the SeqOneByteString in new space. |
| 1614 Node* result = Allocate(size, flags); | 1616 Node* result = Allocate(size, flags); |
| 1615 DCHECK(Heap::RootIsImmortalImmovable(Heap::kOneByteStringMapRootIndex)); | 1617 DCHECK(Heap::RootIsImmortalImmovable(Heap::kOneByteStringMapRootIndex)); |
| 1616 StoreMapNoWriteBarrier(result, Heap::kOneByteStringMapRootIndex); | 1618 StoreMapNoWriteBarrier(result, Heap::kOneByteStringMapRootIndex); |
| 1617 StoreObjectFieldNoWriteBarrier( | 1619 StoreObjectFieldNoWriteBarrier(result, SeqOneByteString::kLengthOffset, |
| 1618 result, SeqOneByteString::kLengthOffset, | 1620 TagParameter(length, mode)); |
| 1619 mode == SMI_PARAMETERS ? length : SmiFromWord(length)); | 1621 // Initialize both used and unused parts of hash field slot at once. |
| 1620 StoreObjectFieldNoWriteBarrier(result, SeqOneByteString::kHashFieldOffset, | 1622 StoreObjectFieldNoWriteBarrier(result, SeqOneByteString::kHashFieldSlot, |
| 1621 IntPtrConstant(String::kEmptyHashField), | 1623 IntPtrConstant(String::kEmptyHashField), |
| 1622 MachineRepresentation::kWord32); | 1624 MachineType::PointerRepresentation()); |
| 1623 var_result.Bind(result); | 1625 var_result.Bind(result); |
| 1624 Goto(&if_join); | 1626 Goto(&if_join); |
| 1625 } | 1627 } |
| 1626 | 1628 |
| 1627 Bind(&if_notsizeissmall); | 1629 Bind(&if_notsizeissmall); |
| 1628 { | 1630 { |
| 1629 // We might need to allocate in large object space, go to the runtime. | 1631 // We might need to allocate in large object space, go to the runtime. |
| 1630 Node* result = | 1632 Node* result = CallRuntime(Runtime::kAllocateSeqOneByteString, context, |
| 1631 CallRuntime(Runtime::kAllocateSeqOneByteString, context, | 1633 TagParameter(length, mode)); |
| 1632 mode == SMI_PARAMETERS ? length : SmiFromWord(length)); | |
| 1633 var_result.Bind(result); | 1634 var_result.Bind(result); |
| 1634 Goto(&if_join); | 1635 Goto(&if_join); |
| 1635 } | 1636 } |
| 1636 | 1637 |
| 1637 Bind(&if_join); | 1638 Bind(&if_join); |
| 1638 return var_result.value(); | 1639 return var_result.value(); |
| 1639 } | 1640 } |
| 1640 | 1641 |
| 1641 Node* CodeStubAssembler::AllocateSeqTwoByteString(int length, | 1642 Node* CodeStubAssembler::AllocateSeqTwoByteString(int length, |
| 1642 AllocationFlags flags) { | 1643 AllocationFlags flags) { |
| 1643 Comment("AllocateSeqTwoByteString"); | 1644 Comment("AllocateSeqTwoByteString"); |
| 1644 Node* result = Allocate(SeqTwoByteString::SizeFor(length), flags); | 1645 Node* result = Allocate(SeqTwoByteString::SizeFor(length), flags); |
| 1645 DCHECK(Heap::RootIsImmortalImmovable(Heap::kStringMapRootIndex)); | 1646 DCHECK(Heap::RootIsImmortalImmovable(Heap::kStringMapRootIndex)); |
| 1646 StoreMapNoWriteBarrier(result, Heap::kStringMapRootIndex); | 1647 StoreMapNoWriteBarrier(result, Heap::kStringMapRootIndex); |
| 1647 StoreObjectFieldNoWriteBarrier(result, SeqTwoByteString::kLengthOffset, | 1648 StoreObjectFieldNoWriteBarrier(result, SeqTwoByteString::kLengthOffset, |
| 1648 SmiConstant(Smi::FromInt(length))); | 1649 SmiConstant(Smi::FromInt(length))); |
| 1649 StoreObjectFieldNoWriteBarrier(result, SeqTwoByteString::kHashFieldOffset, | 1650 // Initialize both used and unused parts of hash field slot at once. |
| 1651 StoreObjectFieldNoWriteBarrier(result, SeqTwoByteString::kHashFieldSlot, |
| 1650 IntPtrConstant(String::kEmptyHashField), | 1652 IntPtrConstant(String::kEmptyHashField), |
| 1651 MachineRepresentation::kWord32); | 1653 MachineType::PointerRepresentation()); |
| 1652 return result; | 1654 return result; |
| 1653 } | 1655 } |
| 1654 | 1656 |
| 1655 Node* CodeStubAssembler::AllocateSeqTwoByteString(Node* context, Node* length, | 1657 Node* CodeStubAssembler::AllocateSeqTwoByteString(Node* context, Node* length, |
| 1656 ParameterMode mode, | 1658 ParameterMode mode, |
| 1657 AllocationFlags flags) { | 1659 AllocationFlags flags) { |
| 1658 Comment("AllocateSeqTwoByteString"); | 1660 Comment("AllocateSeqTwoByteString"); |
| 1659 Variable var_result(this, MachineRepresentation::kTagged); | 1661 Variable var_result(this, MachineRepresentation::kTagged); |
| 1660 | 1662 |
| 1661 // Compute the SeqTwoByteString size and check if it fits into new space. | 1663 // Compute the SeqTwoByteString size and check if it fits into new space. |
| 1662 Label if_sizeissmall(this), if_notsizeissmall(this, Label::kDeferred), | 1664 Label if_sizeissmall(this), if_notsizeissmall(this, Label::kDeferred), |
| 1663 if_join(this); | 1665 if_join(this); |
| 1664 Node* raw_size = GetArrayAllocationSize( | 1666 Node* raw_size = GetArrayAllocationSize( |
| 1665 length, UINT16_ELEMENTS, mode, | 1667 length, UINT16_ELEMENTS, mode, |
| 1666 SeqOneByteString::kHeaderSize + kObjectAlignmentMask); | 1668 SeqOneByteString::kHeaderSize + kObjectAlignmentMask); |
| 1667 Node* size = WordAnd(raw_size, IntPtrConstant(~kObjectAlignmentMask)); | 1669 Node* size = WordAnd(raw_size, IntPtrConstant(~kObjectAlignmentMask)); |
| 1668 Branch(IntPtrLessThanOrEqual(size, IntPtrConstant(kMaxRegularHeapObjectSize)), | 1670 Branch(IntPtrLessThanOrEqual(size, IntPtrConstant(kMaxRegularHeapObjectSize)), |
| 1669 &if_sizeissmall, &if_notsizeissmall); | 1671 &if_sizeissmall, &if_notsizeissmall); |
| 1670 | 1672 |
| 1671 Bind(&if_sizeissmall); | 1673 Bind(&if_sizeissmall); |
| 1672 { | 1674 { |
| 1673 // Just allocate the SeqTwoByteString in new space. | 1675 // Just allocate the SeqTwoByteString in new space. |
| 1674 Node* result = Allocate(size, flags); | 1676 Node* result = Allocate(size, flags); |
| 1675 DCHECK(Heap::RootIsImmortalImmovable(Heap::kStringMapRootIndex)); | 1677 DCHECK(Heap::RootIsImmortalImmovable(Heap::kStringMapRootIndex)); |
| 1676 StoreMapNoWriteBarrier(result, Heap::kStringMapRootIndex); | 1678 StoreMapNoWriteBarrier(result, Heap::kStringMapRootIndex); |
| 1677 StoreObjectFieldNoWriteBarrier( | 1679 StoreObjectFieldNoWriteBarrier( |
| 1678 result, SeqTwoByteString::kLengthOffset, | 1680 result, SeqTwoByteString::kLengthOffset, |
| 1679 mode == SMI_PARAMETERS ? length : SmiFromWord(length)); | 1681 mode == SMI_PARAMETERS ? length : SmiFromWord(length)); |
| 1680 StoreObjectFieldNoWriteBarrier(result, SeqTwoByteString::kHashFieldOffset, | 1682 // Initialize both used and unused parts of hash field slot at once. |
| 1683 StoreObjectFieldNoWriteBarrier(result, SeqTwoByteString::kHashFieldSlot, |
| 1681 IntPtrConstant(String::kEmptyHashField), | 1684 IntPtrConstant(String::kEmptyHashField), |
| 1682 MachineRepresentation::kWord32); | 1685 MachineType::PointerRepresentation()); |
| 1683 var_result.Bind(result); | 1686 var_result.Bind(result); |
| 1684 Goto(&if_join); | 1687 Goto(&if_join); |
| 1685 } | 1688 } |
| 1686 | 1689 |
| 1687 Bind(&if_notsizeissmall); | 1690 Bind(&if_notsizeissmall); |
| 1688 { | 1691 { |
| 1689 // We might need to allocate in large object space, go to the runtime. | 1692 // We might need to allocate in large object space, go to the runtime. |
| 1690 Node* result = | 1693 Node* result = |
| 1691 CallRuntime(Runtime::kAllocateSeqTwoByteString, context, | 1694 CallRuntime(Runtime::kAllocateSeqTwoByteString, context, |
| 1692 mode == SMI_PARAMETERS ? length : SmiFromWord(length)); | 1695 mode == SMI_PARAMETERS ? length : SmiFromWord(length)); |
| 1693 var_result.Bind(result); | 1696 var_result.Bind(result); |
| 1694 Goto(&if_join); | 1697 Goto(&if_join); |
| 1695 } | 1698 } |
| 1696 | 1699 |
| 1697 Bind(&if_join); | 1700 Bind(&if_join); |
| 1698 return var_result.value(); | 1701 return var_result.value(); |
| 1699 } | 1702 } |
| 1700 | 1703 |
| 1701 Node* CodeStubAssembler::AllocateSlicedString( | 1704 Node* CodeStubAssembler::AllocateSlicedString( |
| 1702 Heap::RootListIndex map_root_index, Node* length, Node* parent, | 1705 Heap::RootListIndex map_root_index, Node* length, Node* parent, |
| 1703 Node* offset) { | 1706 Node* offset) { |
| 1704 CSA_ASSERT(this, TaggedIsSmi(length)); | 1707 CSA_ASSERT(this, TaggedIsSmi(length)); |
| 1705 Node* result = Allocate(SlicedString::kSize); | 1708 Node* result = Allocate(SlicedString::kSize); |
| 1706 DCHECK(Heap::RootIsImmortalImmovable(map_root_index)); | 1709 DCHECK(Heap::RootIsImmortalImmovable(map_root_index)); |
| 1707 StoreMapNoWriteBarrier(result, map_root_index); | 1710 StoreMapNoWriteBarrier(result, map_root_index); |
| 1708 StoreObjectFieldNoWriteBarrier(result, SlicedString::kLengthOffset, length, | 1711 StoreObjectFieldNoWriteBarrier(result, SlicedString::kLengthOffset, length, |
| 1709 MachineRepresentation::kTagged); | 1712 MachineRepresentation::kTagged); |
| 1710 StoreObjectFieldNoWriteBarrier(result, SlicedString::kHashFieldOffset, | 1713 // Initialize both used and unused parts of hash field slot at once. |
| 1711 Int32Constant(String::kEmptyHashField), | 1714 StoreObjectFieldNoWriteBarrier(result, SlicedString::kHashFieldSlot, |
| 1712 MachineRepresentation::kWord32); | 1715 IntPtrConstant(String::kEmptyHashField), |
| 1716 MachineType::PointerRepresentation()); |
| 1713 StoreObjectFieldNoWriteBarrier(result, SlicedString::kParentOffset, parent, | 1717 StoreObjectFieldNoWriteBarrier(result, SlicedString::kParentOffset, parent, |
| 1714 MachineRepresentation::kTagged); | 1718 MachineRepresentation::kTagged); |
| 1715 StoreObjectFieldNoWriteBarrier(result, SlicedString::kOffsetOffset, offset, | 1719 StoreObjectFieldNoWriteBarrier(result, SlicedString::kOffsetOffset, offset, |
| 1716 MachineRepresentation::kTagged); | 1720 MachineRepresentation::kTagged); |
| 1717 return result; | 1721 return result; |
| 1718 } | 1722 } |
| 1719 | 1723 |
| 1720 Node* CodeStubAssembler::AllocateSlicedOneByteString(Node* length, Node* parent, | 1724 Node* CodeStubAssembler::AllocateSlicedOneByteString(Node* length, Node* parent, |
| 1721 Node* offset) { | 1725 Node* offset) { |
| 1722 return AllocateSlicedString(Heap::kSlicedOneByteStringMapRootIndex, length, | 1726 return AllocateSlicedString(Heap::kSlicedOneByteStringMapRootIndex, length, |
| 1723 parent, offset); | 1727 parent, offset); |
| 1724 } | 1728 } |
| 1725 | 1729 |
| 1726 Node* CodeStubAssembler::AllocateSlicedTwoByteString(Node* length, Node* parent, | 1730 Node* CodeStubAssembler::AllocateSlicedTwoByteString(Node* length, Node* parent, |
| 1727 Node* offset) { | 1731 Node* offset) { |
| 1728 return AllocateSlicedString(Heap::kSlicedStringMapRootIndex, length, parent, | 1732 return AllocateSlicedString(Heap::kSlicedStringMapRootIndex, length, parent, |
| 1729 offset); | 1733 offset); |
| 1730 } | 1734 } |
| 1731 | 1735 |
| 1732 Node* CodeStubAssembler::AllocateConsString(Heap::RootListIndex map_root_index, | 1736 Node* CodeStubAssembler::AllocateConsString(Heap::RootListIndex map_root_index, |
| 1733 Node* length, Node* first, | 1737 Node* length, Node* first, |
| 1734 Node* second, | 1738 Node* second, |
| 1735 AllocationFlags flags) { | 1739 AllocationFlags flags) { |
| 1736 CSA_ASSERT(this, TaggedIsSmi(length)); | 1740 CSA_ASSERT(this, TaggedIsSmi(length)); |
| 1737 Node* result = Allocate(ConsString::kSize, flags); | 1741 Node* result = Allocate(ConsString::kSize, flags); |
| 1738 DCHECK(Heap::RootIsImmortalImmovable(map_root_index)); | 1742 DCHECK(Heap::RootIsImmortalImmovable(map_root_index)); |
| 1739 StoreMapNoWriteBarrier(result, map_root_index); | 1743 StoreMapNoWriteBarrier(result, map_root_index); |
| 1740 StoreObjectFieldNoWriteBarrier(result, ConsString::kLengthOffset, length, | 1744 StoreObjectFieldNoWriteBarrier(result, ConsString::kLengthOffset, length, |
| 1741 MachineRepresentation::kTagged); | 1745 MachineRepresentation::kTagged); |
| 1742 StoreObjectFieldNoWriteBarrier(result, ConsString::kHashFieldOffset, | 1746 // Initialize both used and unused parts of hash field slot at once. |
| 1743 Int32Constant(String::kEmptyHashField), | 1747 StoreObjectFieldNoWriteBarrier(result, ConsString::kHashFieldSlot, |
| 1744 MachineRepresentation::kWord32); | 1748 IntPtrConstant(String::kEmptyHashField), |
| 1749 MachineType::PointerRepresentation()); |
| 1745 bool const new_space = !(flags & kPretenured); | 1750 bool const new_space = !(flags & kPretenured); |
| 1746 if (new_space) { | 1751 if (new_space) { |
| 1747 StoreObjectFieldNoWriteBarrier(result, ConsString::kFirstOffset, first, | 1752 StoreObjectFieldNoWriteBarrier(result, ConsString::kFirstOffset, first, |
| 1748 MachineRepresentation::kTagged); | 1753 MachineRepresentation::kTagged); |
| 1749 StoreObjectFieldNoWriteBarrier(result, ConsString::kSecondOffset, second, | 1754 StoreObjectFieldNoWriteBarrier(result, ConsString::kSecondOffset, second, |
| 1750 MachineRepresentation::kTagged); | 1755 MachineRepresentation::kTagged); |
| 1751 } else { | 1756 } else { |
| 1752 StoreObjectField(result, ConsString::kFirstOffset, first); | 1757 StoreObjectField(result, ConsString::kFirstOffset, first); |
| 1753 StoreObjectField(result, ConsString::kSecondOffset, second); | 1758 StoreObjectField(result, ConsString::kSecondOffset, second); |
| 1754 } | 1759 } |
| (...skipping 253 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2008 | 2013 |
| 2009 int elements_offset = base_size; | 2014 int elements_offset = base_size; |
| 2010 | 2015 |
| 2011 // Compute space for elements | 2016 // Compute space for elements |
| 2012 base_size += FixedArray::kHeaderSize; | 2017 base_size += FixedArray::kHeaderSize; |
| 2013 Node* size = ElementOffsetFromIndex(capacity, kind, capacity_mode, base_size); | 2018 Node* size = ElementOffsetFromIndex(capacity, kind, capacity_mode, base_size); |
| 2014 | 2019 |
| 2015 Node* array = AllocateUninitializedJSArray(kind, array_map, length, | 2020 Node* array = AllocateUninitializedJSArray(kind, array_map, length, |
| 2016 allocation_site, size); | 2021 allocation_site, size); |
| 2017 | 2022 |
| 2018 // The bitcast here is safe because InnerAllocate doesn't actually allocate. | 2023 Node* elements = InnerAllocate(array, elements_offset); |
| 2019 Node* elements = InnerAllocate(BitcastTaggedToWord(array), elements_offset); | |
| 2020 StoreObjectField(array, JSObject::kElementsOffset, elements); | 2024 StoreObjectField(array, JSObject::kElementsOffset, elements); |
| 2021 | 2025 |
| 2022 return {array, elements}; | 2026 return {array, elements}; |
| 2023 } | 2027 } |
| 2024 | 2028 |
| 2025 Node* CodeStubAssembler::AllocateUninitializedJSArray(ElementsKind kind, | 2029 Node* CodeStubAssembler::AllocateUninitializedJSArray(ElementsKind kind, |
| 2026 Node* array_map, | 2030 Node* array_map, |
| 2027 Node* length, | 2031 Node* length, |
| 2028 Node* allocation_site, | 2032 Node* allocation_site, |
| 2029 Node* size_in_bytes) { | 2033 Node* size_in_bytes) { |
| 2030 Node* array = Allocate(size_in_bytes); | 2034 Node* array = Allocate(size_in_bytes); |
| 2031 | 2035 |
| 2032 Comment("write JSArray headers"); | 2036 Comment("write JSArray headers"); |
| 2033 StoreMapNoWriteBarrier(array, array_map); | 2037 StoreMapNoWriteBarrier(array, array_map); |
| 2034 | 2038 |
| 2039 CSA_ASSERT(this, TaggedIsSmi(length)); |
| 2035 StoreObjectFieldNoWriteBarrier(array, JSArray::kLengthOffset, length); | 2040 StoreObjectFieldNoWriteBarrier(array, JSArray::kLengthOffset, length); |
| 2036 | 2041 |
| 2037 StoreObjectFieldRoot(array, JSArray::kPropertiesOffset, | 2042 StoreObjectFieldRoot(array, JSArray::kPropertiesOffset, |
| 2038 Heap::kEmptyFixedArrayRootIndex); | 2043 Heap::kEmptyFixedArrayRootIndex); |
| 2039 | 2044 |
| 2040 if (allocation_site != nullptr) { | 2045 if (allocation_site != nullptr) { |
| 2041 InitializeAllocationMemento(array, JSArray::kSize, allocation_site); | 2046 InitializeAllocationMemento(array, JSArray::kSize, allocation_site); |
| 2042 } | 2047 } |
| 2043 return array; | 2048 return array; |
| 2044 } | 2049 } |
| (...skipping 1208 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3253 return var_result.value(); | 3258 return var_result.value(); |
| 3254 } | 3259 } |
| 3255 | 3260 |
| 3256 } // namespace | 3261 } // namespace |
| 3257 | 3262 |
| 3258 Node* CodeStubAssembler::SubString(Node* context, Node* string, Node* from, | 3263 Node* CodeStubAssembler::SubString(Node* context, Node* string, Node* from, |
| 3259 Node* to) { | 3264 Node* to) { |
| 3260 Label end(this); | 3265 Label end(this); |
| 3261 Label runtime(this); | 3266 Label runtime(this); |
| 3262 | 3267 |
| 3263 Variable var_instance_type(this, MachineRepresentation::kWord8); // Int32. | 3268 Variable var_instance_type(this, MachineRepresentation::kWord32); // Int32. |
| 3264 Variable var_result(this, MachineRepresentation::kTagged); // String. | 3269 Variable var_result(this, MachineRepresentation::kTagged); // String. |
| 3265 Variable var_from(this, MachineRepresentation::kTagged); // Smi. | 3270 Variable var_from(this, MachineRepresentation::kTagged); // Smi. |
| 3266 Variable var_string(this, MachineRepresentation::kTagged); // String. | 3271 Variable var_string(this, MachineRepresentation::kTagged); // String. |
| 3267 | 3272 |
| 3268 var_instance_type.Bind(Int32Constant(0)); | 3273 var_instance_type.Bind(Int32Constant(0)); |
| 3269 var_string.Bind(string); | 3274 var_string.Bind(string); |
| 3270 var_from.Bind(from); | 3275 var_from.Bind(from); |
| 3271 | 3276 |
| 3272 // Make sure first argument is a string. | 3277 // Make sure first argument is a string. |
| 3273 | 3278 |
| 3274 // Bailout if receiver is a Smi. | 3279 // Bailout if receiver is a Smi. |
| 3275 GotoIf(TaggedIsSmi(string), &runtime); | 3280 GotoIf(TaggedIsSmi(string), &runtime); |
| 3276 | 3281 |
| 3277 // Load the instance type of the {string}. | 3282 // Load the instance type of the {string}. |
| 3278 Node* const instance_type = LoadInstanceType(string); | 3283 Node* const instance_type = LoadInstanceType(string); |
| 3279 var_instance_type.Bind(instance_type); | 3284 var_instance_type.Bind(instance_type); |
| 3280 | 3285 |
| 3281 // Check if {string} is a String. | 3286 // Check if {string} is a String. |
| 3282 GotoUnless(IsStringInstanceType(instance_type), &runtime); | 3287 GotoUnless(IsStringInstanceType(instance_type), &runtime); |
| 3283 | 3288 |
| 3284 // Make sure that both from and to are non-negative smis. | 3289 // Make sure that both from and to are non-negative smis. |
| 3285 | 3290 |
| 3286 GotoUnless(WordIsPositiveSmi(from), &runtime); | 3291 GotoUnless(TaggedIsPositiveSmi(from), &runtime); |
| 3287 GotoUnless(WordIsPositiveSmi(to), &runtime); | 3292 GotoUnless(TaggedIsPositiveSmi(to), &runtime); |
| 3288 | 3293 |
| 3289 Node* const substr_length = SmiSub(to, from); | 3294 Node* const substr_length = SmiSub(to, from); |
| 3290 Node* const string_length = LoadStringLength(string); | 3295 Node* const string_length = LoadStringLength(string); |
| 3291 | 3296 |
| 3292 // Begin dispatching based on substring length. | 3297 // Begin dispatching based on substring length. |
| 3293 | 3298 |
| 3294 Label original_string_or_invalid_length(this); | 3299 Label original_string_or_invalid_length(this); |
| 3295 GotoIf(SmiAboveOrEqual(substr_length, string_length), | 3300 GotoIf(SmiAboveOrEqual(substr_length, string_length), |
| 3296 &original_string_or_invalid_length); | 3301 &original_string_or_invalid_length); |
| 3297 | 3302 |
| (...skipping 119 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3417 STATIC_ASSERT(kShortExternalStringTag != 0); | 3422 STATIC_ASSERT(kShortExternalStringTag != 0); |
| 3418 GotoIf(Word32NotEqual(Word32And(var_instance_type.value(), | 3423 GotoIf(Word32NotEqual(Word32And(var_instance_type.value(), |
| 3419 Int32Constant(kShortExternalStringMask)), | 3424 Int32Constant(kShortExternalStringMask)), |
| 3420 Int32Constant(0)), | 3425 Int32Constant(0)), |
| 3421 &runtime); | 3426 &runtime); |
| 3422 | 3427 |
| 3423 // Move the pointer so that offset-wise, it looks like a sequential string. | 3428 // Move the pointer so that offset-wise, it looks like a sequential string. |
| 3424 STATIC_ASSERT(SeqTwoByteString::kHeaderSize == | 3429 STATIC_ASSERT(SeqTwoByteString::kHeaderSize == |
| 3425 SeqOneByteString::kHeaderSize); | 3430 SeqOneByteString::kHeaderSize); |
| 3426 | 3431 |
| 3427 Node* resource_data = LoadObjectField(var_string.value(), | 3432 Node* resource_data = |
| 3428 ExternalString::kResourceDataOffset); | 3433 LoadObjectField(var_string.value(), ExternalString::kResourceDataOffset, |
| 3434 MachineType::Pointer()); |
| 3429 Node* const fake_sequential_string = IntPtrSub( | 3435 Node* const fake_sequential_string = IntPtrSub( |
| 3430 resource_data, | 3436 resource_data, |
| 3431 IntPtrConstant(SeqTwoByteString::kHeaderSize - kHeapObjectTag)); | 3437 IntPtrConstant(SeqTwoByteString::kHeaderSize - kHeapObjectTag)); |
| 3432 | 3438 |
| 3433 var_result.Bind(AllocAndCopyStringCharacters( | 3439 var_result.Bind(AllocAndCopyStringCharacters( |
| 3434 this, context, fake_sequential_string, var_instance_type.value(), | 3440 this, context, fake_sequential_string, var_instance_type.value(), |
| 3435 var_from.value(), substr_length)); | 3441 var_from.value(), substr_length)); |
| 3436 | 3442 |
| 3437 Counters* counters = isolate()->counters(); | 3443 Counters* counters = isolate()->counters(); |
| 3438 IncrementCounter(counters->sub_string_native(), 1); | 3444 IncrementCounter(counters->sub_string_native(), 1); |
| (...skipping 537 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3976 Label out(this); | 3982 Label out(this); |
| 3977 | 3983 |
| 3978 Variable var_result(this, MachineRepresentation::kTagged); | 3984 Variable var_result(this, MachineRepresentation::kTagged); |
| 3979 var_result.Bind(input); | 3985 var_result.Bind(input); |
| 3980 | 3986 |
| 3981 // Early exit for positive smis. | 3987 // Early exit for positive smis. |
| 3982 { | 3988 { |
| 3983 // TODO(jgruber): This branch and the recheck below can be removed once we | 3989 // TODO(jgruber): This branch and the recheck below can be removed once we |
| 3984 // have a ToNumber with multiple exits. | 3990 // have a ToNumber with multiple exits. |
| 3985 Label next(this, Label::kDeferred); | 3991 Label next(this, Label::kDeferred); |
| 3986 Branch(WordIsPositiveSmi(input), &out, &next); | 3992 Branch(TaggedIsPositiveSmi(input), &out, &next); |
| 3987 Bind(&next); | 3993 Bind(&next); |
| 3988 } | 3994 } |
| 3989 | 3995 |
| 3990 Node* const number = ToNumber(context, input); | 3996 Node* const number = ToNumber(context, input); |
| 3991 var_result.Bind(number); | 3997 var_result.Bind(number); |
| 3992 | 3998 |
| 3993 // Perhaps we have a positive smi now. | 3999 // Perhaps we have a positive smi now. |
| 3994 { | 4000 { |
| 3995 Label next(this, Label::kDeferred); | 4001 Label next(this, Label::kDeferred); |
| 3996 Branch(WordIsPositiveSmi(number), &out, &next); | 4002 Branch(TaggedIsPositiveSmi(number), &out, &next); |
| 3997 Bind(&next); | 4003 Bind(&next); |
| 3998 } | 4004 } |
| 3999 | 4005 |
| 4000 Label if_isnegativesmi(this), if_isheapnumber(this); | 4006 Label if_isnegativesmi(this), if_isheapnumber(this); |
| 4001 Branch(TaggedIsSmi(number), &if_isnegativesmi, &if_isheapnumber); | 4007 Branch(TaggedIsSmi(number), &if_isnegativesmi, &if_isheapnumber); |
| 4002 | 4008 |
| 4003 Bind(&if_isnegativesmi); | 4009 Bind(&if_isnegativesmi); |
| 4004 { | 4010 { |
| 4005 // floor({input}) mod 2^32 === {input} + 2^32. | 4011 // floor({input}) mod 2^32 === {input} + 2^32. |
| 4006 Node* const float_number = SmiToFloat64(number); | 4012 Node* const float_number = SmiToFloat64(number); |
| (...skipping 843 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4850 var_double_value.Bind(LoadHeapNumberValue(mutable_heap_number)); | 4856 var_double_value.Bind(LoadHeapNumberValue(mutable_heap_number)); |
| 4851 } | 4857 } |
| 4852 Goto(&rebox_double); | 4858 Goto(&rebox_double); |
| 4853 } | 4859 } |
| 4854 } | 4860 } |
| 4855 Bind(&if_backing_store); | 4861 Bind(&if_backing_store); |
| 4856 { | 4862 { |
| 4857 Comment("if_backing_store"); | 4863 Comment("if_backing_store"); |
| 4858 Node* properties = LoadProperties(object); | 4864 Node* properties = LoadProperties(object); |
| 4859 field_index = IntPtrSub(field_index, inobject_properties); | 4865 field_index = IntPtrSub(field_index, inobject_properties); |
| 4860 Node* value = LoadFixedArrayElement(properties, field_index); | 4866 Node* value = |
| 4867 LoadFixedArrayElement(properties, field_index, 0, INTPTR_PARAMETERS); |
| 4861 | 4868 |
| 4862 Label if_double(this), if_tagged(this); | 4869 Label if_double(this), if_tagged(this); |
| 4863 Branch(Word32NotEqual(representation, | 4870 Branch(Word32NotEqual(representation, |
| 4864 Int32Constant(Representation::kDouble)), | 4871 Int32Constant(Representation::kDouble)), |
| 4865 &if_tagged, &if_double); | 4872 &if_tagged, &if_double); |
| 4866 Bind(&if_tagged); | 4873 Bind(&if_tagged); |
| 4867 { | 4874 { |
| 4868 var_value->Bind(value); | 4875 var_value->Bind(value); |
| 4869 Goto(&done); | 4876 Goto(&done); |
| 4870 } | 4877 } |
| (...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4904 (NameDictionary::kEntryDetailsIndex - NameDictionary::kEntryKeyIndex) * | 4911 (NameDictionary::kEntryDetailsIndex - NameDictionary::kEntryKeyIndex) * |
| 4905 kPointerSize; | 4912 kPointerSize; |
| 4906 const int name_to_value_offset = | 4913 const int name_to_value_offset = |
| 4907 (NameDictionary::kEntryValueIndex - NameDictionary::kEntryKeyIndex) * | 4914 (NameDictionary::kEntryValueIndex - NameDictionary::kEntryKeyIndex) * |
| 4908 kPointerSize; | 4915 kPointerSize; |
| 4909 | 4916 |
| 4910 Node* details = LoadAndUntagToWord32FixedArrayElement(dictionary, name_index, | 4917 Node* details = LoadAndUntagToWord32FixedArrayElement(dictionary, name_index, |
| 4911 name_to_details_offset); | 4918 name_to_details_offset); |
| 4912 | 4919 |
| 4913 var_details->Bind(details); | 4920 var_details->Bind(details); |
| 4914 var_value->Bind( | 4921 var_value->Bind(LoadFixedArrayElement( |
| 4915 LoadFixedArrayElement(dictionary, name_index, name_to_value_offset)); | 4922 dictionary, name_index, name_to_value_offset, INTPTR_PARAMETERS)); |
| 4916 | 4923 |
| 4917 Comment("] LoadPropertyFromNameDictionary"); | 4924 Comment("] LoadPropertyFromNameDictionary"); |
| 4918 } | 4925 } |
| 4919 | 4926 |
| 4920 void CodeStubAssembler::LoadPropertyFromGlobalDictionary(Node* dictionary, | 4927 void CodeStubAssembler::LoadPropertyFromGlobalDictionary(Node* dictionary, |
| 4921 Node* name_index, | 4928 Node* name_index, |
| 4922 Variable* var_details, | 4929 Variable* var_details, |
| 4923 Variable* var_value, | 4930 Variable* var_value, |
| 4924 Label* if_deleted) { | 4931 Label* if_deleted) { |
| 4925 Comment("[ LoadPropertyFromGlobalDictionary"); | 4932 Comment("[ LoadPropertyFromGlobalDictionary"); |
| 4926 CSA_ASSERT(this, IsDictionary(dictionary)); | 4933 CSA_ASSERT(this, IsDictionary(dictionary)); |
| 4927 | 4934 |
| 4928 const int name_to_value_offset = | 4935 const int name_to_value_offset = |
| 4929 (GlobalDictionary::kEntryValueIndex - GlobalDictionary::kEntryKeyIndex) * | 4936 (GlobalDictionary::kEntryValueIndex - GlobalDictionary::kEntryKeyIndex) * |
| 4930 kPointerSize; | 4937 kPointerSize; |
| 4931 | 4938 |
| 4932 Node* property_cell = | 4939 Node* property_cell = LoadFixedArrayElement( |
| 4933 LoadFixedArrayElement(dictionary, name_index, name_to_value_offset); | 4940 dictionary, name_index, name_to_value_offset, INTPTR_PARAMETERS); |
| 4934 | 4941 |
| 4935 Node* value = LoadObjectField(property_cell, PropertyCell::kValueOffset); | 4942 Node* value = LoadObjectField(property_cell, PropertyCell::kValueOffset); |
| 4936 GotoIf(WordEqual(value, TheHoleConstant()), if_deleted); | 4943 GotoIf(WordEqual(value, TheHoleConstant()), if_deleted); |
| 4937 | 4944 |
| 4938 var_value->Bind(value); | 4945 var_value->Bind(value); |
| 4939 | 4946 |
| 4940 Node* details = LoadAndUntagToWord32ObjectField(property_cell, | 4947 Node* details = LoadAndUntagToWord32ObjectField(property_cell, |
| 4941 PropertyCell::kDetailsOffset); | 4948 PropertyCell::kDetailsOffset); |
| 4942 var_details->Bind(details); | 4949 var_details->Bind(details); |
| 4943 | 4950 |
| (...skipping 228 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5172 | 5179 |
| 5173 Variable var_index(this, MachineType::PointerRepresentation()); | 5180 Variable var_index(this, MachineType::PointerRepresentation()); |
| 5174 | 5181 |
| 5175 Label if_keyisindex(this), if_iskeyunique(this); | 5182 Label if_keyisindex(this), if_iskeyunique(this); |
| 5176 TryToName(key, &if_keyisindex, &var_index, &if_iskeyunique, if_bailout); | 5183 TryToName(key, &if_keyisindex, &var_index, &if_iskeyunique, if_bailout); |
| 5177 | 5184 |
| 5178 Bind(&if_iskeyunique); | 5185 Bind(&if_iskeyunique); |
| 5179 { | 5186 { |
| 5180 Variable var_holder(this, MachineRepresentation::kTagged); | 5187 Variable var_holder(this, MachineRepresentation::kTagged); |
| 5181 Variable var_holder_map(this, MachineRepresentation::kTagged); | 5188 Variable var_holder_map(this, MachineRepresentation::kTagged); |
| 5182 Variable var_holder_instance_type(this, MachineRepresentation::kWord8); | 5189 Variable var_holder_instance_type(this, MachineRepresentation::kWord32); |
| 5183 | 5190 |
| 5184 Variable* merged_variables[] = {&var_holder, &var_holder_map, | 5191 Variable* merged_variables[] = {&var_holder, &var_holder_map, |
| 5185 &var_holder_instance_type}; | 5192 &var_holder_instance_type}; |
| 5186 Label loop(this, arraysize(merged_variables), merged_variables); | 5193 Label loop(this, arraysize(merged_variables), merged_variables); |
| 5187 var_holder.Bind(receiver); | 5194 var_holder.Bind(receiver); |
| 5188 var_holder_map.Bind(map); | 5195 var_holder_map.Bind(map); |
| 5189 var_holder_instance_type.Bind(instance_type); | 5196 var_holder_instance_type.Bind(instance_type); |
| 5190 Goto(&loop); | 5197 Goto(&loop); |
| 5191 Bind(&loop); | 5198 Bind(&loop); |
| 5192 { | 5199 { |
| (...skipping 23 matching lines...) Expand all Loading... |
| 5216 var_holder.Bind(proto); | 5223 var_holder.Bind(proto); |
| 5217 var_holder_map.Bind(map); | 5224 var_holder_map.Bind(map); |
| 5218 var_holder_instance_type.Bind(instance_type); | 5225 var_holder_instance_type.Bind(instance_type); |
| 5219 Goto(&loop); | 5226 Goto(&loop); |
| 5220 } | 5227 } |
| 5221 } | 5228 } |
| 5222 Bind(&if_keyisindex); | 5229 Bind(&if_keyisindex); |
| 5223 { | 5230 { |
| 5224 Variable var_holder(this, MachineRepresentation::kTagged); | 5231 Variable var_holder(this, MachineRepresentation::kTagged); |
| 5225 Variable var_holder_map(this, MachineRepresentation::kTagged); | 5232 Variable var_holder_map(this, MachineRepresentation::kTagged); |
| 5226 Variable var_holder_instance_type(this, MachineRepresentation::kWord8); | 5233 Variable var_holder_instance_type(this, MachineRepresentation::kWord32); |
| 5227 | 5234 |
| 5228 Variable* merged_variables[] = {&var_holder, &var_holder_map, | 5235 Variable* merged_variables[] = {&var_holder, &var_holder_map, |
| 5229 &var_holder_instance_type}; | 5236 &var_holder_instance_type}; |
| 5230 Label loop(this, arraysize(merged_variables), merged_variables); | 5237 Label loop(this, arraysize(merged_variables), merged_variables); |
| 5231 var_holder.Bind(receiver); | 5238 var_holder.Bind(receiver); |
| 5232 var_holder_map.Bind(map); | 5239 var_holder_map.Bind(map); |
| 5233 var_holder_instance_type.Bind(instance_type); | 5240 var_holder_instance_type.Bind(instance_type); |
| 5234 Goto(&loop); | 5241 Goto(&loop); |
| 5235 Bind(&loop); | 5242 Bind(&loop); |
| 5236 { | 5243 { |
| (...skipping 204 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5441 } | 5448 } |
| 5442 | 5449 |
| 5443 void CodeStubAssembler::UpdateFeedback(Node* feedback, | 5450 void CodeStubAssembler::UpdateFeedback(Node* feedback, |
| 5444 Node* type_feedback_vector, | 5451 Node* type_feedback_vector, |
| 5445 Node* slot_id) { | 5452 Node* slot_id) { |
| 5446 // This method is used for binary op and compare feedback. These | 5453 // This method is used for binary op and compare feedback. These |
| 5447 // vector nodes are initialized with a smi 0, so we can simply OR | 5454 // vector nodes are initialized with a smi 0, so we can simply OR |
| 5448 // our new feedback in place. | 5455 // our new feedback in place. |
| 5449 // TODO(interpreter): Consider passing the feedback as Smi already to avoid | 5456 // TODO(interpreter): Consider passing the feedback as Smi already to avoid |
| 5450 // the tagging completely. | 5457 // the tagging completely. |
| 5451 Node* previous_feedback = | 5458 Node* previous_feedback = LoadFixedArrayElement(type_feedback_vector, slot_id, |
| 5452 LoadFixedArrayElement(type_feedback_vector, slot_id); | 5459 0, INTPTR_PARAMETERS); |
| 5453 Node* combined_feedback = SmiOr(previous_feedback, SmiFromWord32(feedback)); | 5460 Node* combined_feedback = SmiOr(previous_feedback, SmiFromWord32(feedback)); |
| 5454 StoreFixedArrayElement(type_feedback_vector, slot_id, combined_feedback, | 5461 StoreFixedArrayElement(type_feedback_vector, slot_id, combined_feedback, |
| 5455 SKIP_WRITE_BARRIER); | 5462 SKIP_WRITE_BARRIER, 0, INTPTR_PARAMETERS); |
| 5456 } | 5463 } |
| 5457 | 5464 |
| 5458 Node* CodeStubAssembler::LoadReceiverMap(Node* receiver) { | 5465 Node* CodeStubAssembler::LoadReceiverMap(Node* receiver) { |
| 5459 Variable var_receiver_map(this, MachineRepresentation::kTagged); | 5466 Variable var_receiver_map(this, MachineRepresentation::kTagged); |
| 5460 Label load_smi_map(this, Label::kDeferred), load_receiver_map(this), | 5467 Label load_smi_map(this, Label::kDeferred), load_receiver_map(this), |
| 5461 if_result(this); | 5468 if_result(this); |
| 5462 | 5469 |
| 5463 Branch(TaggedIsSmi(receiver), &load_smi_map, &load_receiver_map); | 5470 Branch(TaggedIsSmi(receiver), &load_smi_map, &load_receiver_map); |
| 5464 Bind(&load_smi_map); | 5471 Bind(&load_smi_map); |
| 5465 { | 5472 { |
| (...skipping 732 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6198 Node* zero_constant = SmiConstant(Smi::kZero); | 6205 Node* zero_constant = SmiConstant(Smi::kZero); |
| 6199 Branch(WordEqual(enum_length, zero_constant), &loop, use_runtime); | 6206 Branch(WordEqual(enum_length, zero_constant), &loop, use_runtime); |
| 6200 } | 6207 } |
| 6201 } | 6208 } |
| 6202 | 6209 |
| 6203 Node* CodeStubAssembler::CreateAllocationSiteInFeedbackVector( | 6210 Node* CodeStubAssembler::CreateAllocationSiteInFeedbackVector( |
| 6204 Node* feedback_vector, Node* slot) { | 6211 Node* feedback_vector, Node* slot) { |
| 6205 Node* size = IntPtrConstant(AllocationSite::kSize); | 6212 Node* size = IntPtrConstant(AllocationSite::kSize); |
| 6206 Node* site = Allocate(size, CodeStubAssembler::kPretenured); | 6213 Node* site = Allocate(size, CodeStubAssembler::kPretenured); |
| 6207 | 6214 |
| 6208 StoreMap(site, LoadRoot(Heap::kAllocationSiteMapRootIndex)); | 6215 StoreMap(site, AllocationSiteMapConstant()); |
| 6209 Node* kind = SmiConstant(Smi::FromInt(GetInitialFastElementsKind())); | 6216 Node* kind = SmiConstant(GetInitialFastElementsKind()); |
| 6210 StoreObjectFieldNoWriteBarrier(site, AllocationSite::kTransitionInfoOffset, | 6217 StoreObjectFieldNoWriteBarrier(site, AllocationSite::kTransitionInfoOffset, |
| 6211 kind); | 6218 kind); |
| 6212 | 6219 |
| 6213 // Unlike literals, constructed arrays don't have nested sites | 6220 // Unlike literals, constructed arrays don't have nested sites |
| 6214 Node* zero = IntPtrConstant(0); | 6221 Node* zero = SmiConstant(0); |
| 6215 StoreObjectFieldNoWriteBarrier(site, AllocationSite::kNestedSiteOffset, zero); | 6222 StoreObjectFieldNoWriteBarrier(site, AllocationSite::kNestedSiteOffset, zero); |
| 6216 | 6223 |
| 6217 // Pretenuring calculation field. | 6224 // Pretenuring calculation field. |
| 6218 StoreObjectFieldNoWriteBarrier(site, AllocationSite::kPretenureDataOffset, | 6225 StoreObjectFieldNoWriteBarrier(site, AllocationSite::kPretenureDataOffset, |
| 6219 zero); | 6226 zero); |
| 6220 | 6227 |
| 6221 // Pretenuring memento creation count field. | 6228 // Pretenuring memento creation count field. |
| 6222 StoreObjectFieldNoWriteBarrier( | 6229 StoreObjectFieldNoWriteBarrier( |
| 6223 site, AllocationSite::kPretenureCreateCountOffset, zero); | 6230 site, AllocationSite::kPretenureCreateCountOffset, zero); |
| 6224 | 6231 |
| (...skipping 1874 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 8099 var_map_index.Bind(map_index); | 8106 var_map_index.Bind(map_index); |
| 8100 var_array_map.Bind(UndefinedConstant()); | 8107 var_array_map.Bind(UndefinedConstant()); |
| 8101 Goto(&allocate_iterator); | 8108 Goto(&allocate_iterator); |
| 8102 } | 8109 } |
| 8103 } | 8110 } |
| 8104 | 8111 |
| 8105 Bind(&allocate_iterator); | 8112 Bind(&allocate_iterator); |
| 8106 { | 8113 { |
| 8107 Node* map = | 8114 Node* map = |
| 8108 LoadFixedArrayElement(LoadNativeContext(context), var_map_index.value(), | 8115 LoadFixedArrayElement(LoadNativeContext(context), var_map_index.value(), |
| 8109 0, CodeStubAssembler::INTPTR_PARAMETERS); | 8116 0, INTPTR_PARAMETERS); |
| 8110 var_result.Bind(AllocateJSArrayIterator(array, var_array_map.value(), map)); | 8117 var_result.Bind(AllocateJSArrayIterator(array, var_array_map.value(), map)); |
| 8111 Goto(&return_result); | 8118 Goto(&return_result); |
| 8112 } | 8119 } |
| 8113 | 8120 |
| 8114 Bind(&return_result); | 8121 Bind(&return_result); |
| 8115 return var_result.value(); | 8122 return var_result.value(); |
| 8116 } | 8123 } |
| 8117 | 8124 |
| 8118 Node* CodeStubAssembler::AllocateJSArrayIterator(Node* array, Node* array_map, | 8125 Node* CodeStubAssembler::AllocateJSArrayIterator(Node* array, Node* array_map, |
| 8119 Node* map) { | 8126 Node* map) { |
| (...skipping 112 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 8232 | 8239 |
| 8233 Node* CodeStubAssembler::IsDebugActive() { | 8240 Node* CodeStubAssembler::IsDebugActive() { |
| 8234 Node* is_debug_active = Load( | 8241 Node* is_debug_active = Load( |
| 8235 MachineType::Uint8(), | 8242 MachineType::Uint8(), |
| 8236 ExternalConstant(ExternalReference::debug_is_active_address(isolate()))); | 8243 ExternalConstant(ExternalReference::debug_is_active_address(isolate()))); |
| 8237 return WordNotEqual(is_debug_active, Int32Constant(0)); | 8244 return WordNotEqual(is_debug_active, Int32Constant(0)); |
| 8238 } | 8245 } |
| 8239 | 8246 |
| 8240 } // namespace internal | 8247 } // namespace internal |
| 8241 } // namespace v8 | 8248 } // namespace v8 |
| OLD | NEW |