OLD | NEW |
1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 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/elements.h" | 5 #include "src/elements.h" |
6 | 6 |
7 #include "src/arguments.h" | 7 #include "src/arguments.h" |
8 #include "src/conversions.h" | 8 #include "src/conversions.h" |
9 #include "src/factory.h" | 9 #include "src/factory.h" |
10 #include "src/isolate-inl.h" | 10 #include "src/isolate-inl.h" |
(...skipping 1554 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1565 if (IsFastPackedElementsKind(KindTraits::Kind) || | 1565 if (IsFastPackedElementsKind(KindTraits::Kind) || |
1566 HasEntryImpl(*elements, i)) { | 1566 HasEntryImpl(*elements, i)) { |
1567 accumulator->AddKey(Subclass::GetImpl(*elements, i), convert); | 1567 accumulator->AddKey(Subclass::GetImpl(*elements, i), convert); |
1568 } | 1568 } |
1569 } | 1569 } |
1570 } | 1570 } |
1571 | 1571 |
1572 static void ValidateContents(Handle<JSObject> holder, int length) { | 1572 static void ValidateContents(Handle<JSObject> holder, int length) { |
1573 #if DEBUG | 1573 #if DEBUG |
1574 Isolate* isolate = holder->GetIsolate(); | 1574 Isolate* isolate = holder->GetIsolate(); |
| 1575 Heap* heap = isolate->heap(); |
1575 HandleScope scope(isolate); | 1576 HandleScope scope(isolate); |
1576 Handle<FixedArrayBase> elements(holder->elements(), isolate); | 1577 Handle<FixedArrayBase> elements(holder->elements(), isolate); |
1577 Map* map = elements->map(); | 1578 Map* map = elements->map(); |
1578 DCHECK((IsFastSmiOrObjectElementsKind(KindTraits::Kind) && | 1579 if (IsFastSmiOrObjectElementsKind(KindTraits::Kind)) { |
1579 (map == isolate->heap()->fixed_array_map() || | 1580 DCHECK_NE(map, heap->fixed_double_array_map()); |
1580 map == isolate->heap()->fixed_cow_array_map())) || | 1581 } else if (IsFastDoubleElementsKind(KindTraits::Kind)) { |
1581 (IsFastDoubleElementsKind(KindTraits::Kind) == | 1582 DCHECK_NE(map, heap->fixed_cow_array_map()); |
1582 ((map == isolate->heap()->fixed_array_map() && length == 0) || | 1583 if (map == heap->fixed_array_map()) DCHECK_EQ(0, length); |
1583 map == isolate->heap()->fixed_double_array_map()))); | 1584 } else { |
| 1585 UNREACHABLE(); |
| 1586 } |
1584 if (length == 0) return; // nothing to do! | 1587 if (length == 0) return; // nothing to do! |
| 1588 #if ENABLE_SLOW_DCHECKS |
1585 DisallowHeapAllocation no_gc; | 1589 DisallowHeapAllocation no_gc; |
1586 Handle<BackingStore> backing_store = Handle<BackingStore>::cast(elements); | 1590 Handle<BackingStore> backing_store = Handle<BackingStore>::cast(elements); |
1587 if (IsFastSmiElementsKind(KindTraits::Kind)) { | 1591 if (IsFastSmiElementsKind(KindTraits::Kind)) { |
1588 for (int i = 0; i < length; i++) { | 1592 for (int i = 0; i < length; i++) { |
1589 DCHECK(BackingStore::get(*backing_store, i, isolate)->IsSmi() || | 1593 DCHECK(BackingStore::get(*backing_store, i, isolate)->IsSmi() || |
1590 (IsFastHoleyElementsKind(KindTraits::Kind) && | 1594 (IsFastHoleyElementsKind(KindTraits::Kind) && |
1591 backing_store->is_the_hole(i))); | 1595 backing_store->is_the_hole(i))); |
1592 } | 1596 } |
| 1597 } else if (KindTraits::Kind == FAST_ELEMENTS || |
| 1598 KindTraits::Kind == FAST_DOUBLE_ELEMENTS) { |
| 1599 for (int i = 0; i < length; i++) { |
| 1600 DCHECK(!backing_store->is_the_hole(i)); |
| 1601 } |
| 1602 } else { |
| 1603 DCHECK(IsFastHoleyElementsKind(KindTraits::Kind)); |
1593 } | 1604 } |
1594 #endif | 1605 #endif |
| 1606 #endif |
1595 } | 1607 } |
1596 | 1608 |
1597 static Handle<Object> PopImpl(Handle<JSArray> receiver) { | 1609 static Handle<Object> PopImpl(Handle<JSArray> receiver) { |
1598 return Subclass::RemoveElement(receiver, AT_END); | 1610 return Subclass::RemoveElement(receiver, AT_END); |
1599 } | 1611 } |
1600 | 1612 |
1601 static Handle<Object> ShiftImpl(Handle<JSArray> receiver) { | 1613 static Handle<Object> ShiftImpl(Handle<JSArray> receiver) { |
1602 return Subclass::RemoveElement(receiver, AT_START); | 1614 return Subclass::RemoveElement(receiver, AT_START); |
1603 } | 1615 } |
1604 | 1616 |
(...skipping 193 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1798 | 1810 |
1799 if (IsHoleyElementsKind(kind) && result->IsTheHole()) { | 1811 if (IsHoleyElementsKind(kind) && result->IsTheHole()) { |
1800 return isolate->factory()->undefined_value(); | 1812 return isolate->factory()->undefined_value(); |
1801 } | 1813 } |
1802 return result; | 1814 return result; |
1803 } | 1815 } |
1804 | 1816 |
1805 static uint32_t AddArguments(Handle<JSArray> receiver, | 1817 static uint32_t AddArguments(Handle<JSArray> receiver, |
1806 Handle<FixedArrayBase> backing_store, | 1818 Handle<FixedArrayBase> backing_store, |
1807 Arguments* args, uint32_t add_size, | 1819 Arguments* args, uint32_t add_size, |
1808 Where remove_position) { | 1820 Where add_position) { |
1809 uint32_t length = Smi::cast(receiver->length())->value(); | 1821 uint32_t length = Smi::cast(receiver->length())->value(); |
1810 DCHECK(0 < add_size); | 1822 DCHECK(0 < add_size); |
1811 uint32_t elms_len = backing_store->length(); | 1823 uint32_t elms_len = backing_store->length(); |
1812 // Check we do not overflow the new_length. | 1824 // Check we do not overflow the new_length. |
1813 DCHECK(add_size <= static_cast<uint32_t>(Smi::kMaxValue - length)); | 1825 DCHECK(add_size <= static_cast<uint32_t>(Smi::kMaxValue - length)); |
1814 uint32_t new_length = length + add_size; | 1826 uint32_t new_length = length + add_size; |
1815 | 1827 |
1816 if (new_length > elms_len) { | 1828 if (new_length > elms_len) { |
1817 // New backing storage is needed. | 1829 // New backing storage is needed. |
1818 uint32_t capacity = JSObject::NewElementsCapacity(new_length); | 1830 uint32_t capacity = JSObject::NewElementsCapacity(new_length); |
1819 // If we add arguments to the start we have to shift the existing objects. | 1831 // If we add arguments to the start we have to shift the existing objects. |
1820 int copy_dst_index = remove_position == AT_START ? add_size : 0; | 1832 int copy_dst_index = add_position == AT_START ? add_size : 0; |
1821 // Copy over all objects to a new backing_store. | 1833 // Copy over all objects to a new backing_store. |
1822 backing_store = Subclass::ConvertElementsWithCapacity( | 1834 backing_store = Subclass::ConvertElementsWithCapacity( |
1823 receiver, backing_store, KindTraits::Kind, capacity, 0, | 1835 receiver, backing_store, KindTraits::Kind, capacity, 0, |
1824 copy_dst_index, ElementsAccessor::kCopyToEndAndInitializeToHole); | 1836 copy_dst_index, ElementsAccessor::kCopyToEndAndInitializeToHole); |
1825 receiver->set_elements(*backing_store); | 1837 receiver->set_elements(*backing_store); |
1826 } else if (remove_position == AT_START) { | 1838 } else if (add_position == AT_START) { |
1827 // If the backing store has enough capacity and we add elements to the | 1839 // If the backing store has enough capacity and we add elements to the |
1828 // start we have to shift the existing objects. | 1840 // start we have to shift the existing objects. |
1829 Isolate* isolate = receiver->GetIsolate(); | 1841 Isolate* isolate = receiver->GetIsolate(); |
1830 Subclass::MoveElements(isolate, receiver, backing_store, add_size, 0, | 1842 Subclass::MoveElements(isolate, receiver, backing_store, add_size, 0, |
1831 length, 0, 0); | 1843 length, 0, 0); |
1832 } | 1844 } |
1833 | 1845 |
1834 int insertion_index = remove_position == AT_START ? 0 : length; | 1846 int insertion_index = add_position == AT_START ? 0 : length; |
1835 // Copy the arguments to the start. | 1847 // Copy the arguments to the start. |
1836 Subclass::CopyArguments(args, backing_store, add_size, 1, insertion_index); | 1848 Subclass::CopyArguments(args, backing_store, add_size, 1, insertion_index); |
1837 // Set the length. | 1849 // Set the length. |
1838 receiver->set_length(Smi::FromInt(new_length)); | 1850 receiver->set_length(Smi::FromInt(new_length)); |
1839 return new_length; | 1851 return new_length; |
1840 } | 1852 } |
1841 | 1853 |
1842 static void CopyArguments(Arguments* args, Handle<FixedArrayBase> dst_store, | 1854 static void CopyArguments(Arguments* args, Handle<FixedArrayBase> dst_store, |
1843 uint32_t copy_size, uint32_t src_index, | 1855 uint32_t copy_size, uint32_t src_index, |
1844 uint32_t dst_index) { | 1856 uint32_t dst_index) { |
1845 // Add the provided values. | 1857 // Add the provided values. |
1846 DisallowHeapAllocation no_gc; | 1858 DisallowHeapAllocation no_gc; |
1847 FixedArrayBase* raw_backing_store = *dst_store; | 1859 FixedArrayBase* raw_backing_store = *dst_store; |
1848 WriteBarrierMode mode = raw_backing_store->GetWriteBarrierMode(no_gc); | 1860 WriteBarrierMode mode = raw_backing_store->GetWriteBarrierMode(no_gc); |
1849 for (uint32_t i = 0; i < copy_size; i++) { | 1861 for (uint32_t i = 0; i < copy_size; i++) { |
1850 Object* argument = (*args)[i + src_index]; | 1862 Object* argument = (*args)[src_index + i]; |
1851 Subclass::SetImpl(raw_backing_store, i + dst_index, argument, mode); | 1863 DCHECK(!argument->IsTheHole()); |
| 1864 Subclass::SetImpl(raw_backing_store, dst_index + i, argument, mode); |
1852 } | 1865 } |
1853 } | 1866 } |
1854 }; | 1867 }; |
1855 | 1868 |
1856 template <typename Subclass, typename KindTraits> | 1869 template <typename Subclass, typename KindTraits> |
1857 class FastSmiOrObjectElementsAccessor | 1870 class FastSmiOrObjectElementsAccessor |
1858 : public FastElementsAccessor<Subclass, KindTraits> { | 1871 : public FastElementsAccessor<Subclass, KindTraits> { |
1859 public: | 1872 public: |
1860 explicit FastSmiOrObjectElementsAccessor(const char* name) | 1873 explicit FastSmiOrObjectElementsAccessor(const char* name) |
1861 : FastElementsAccessor<Subclass, KindTraits>(name) {} | 1874 : FastElementsAccessor<Subclass, KindTraits>(name) {} |
(...skipping 1047 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2909 Handle<FixedArrayBase> elms; | 2922 Handle<FixedArrayBase> elms; |
2910 if (IsFastDoubleElementsKind(elements_kind)) { | 2923 if (IsFastDoubleElementsKind(elements_kind)) { |
2911 elms = Handle<FixedArrayBase>::cast( | 2924 elms = Handle<FixedArrayBase>::cast( |
2912 factory->NewFixedDoubleArray(number_of_elements)); | 2925 factory->NewFixedDoubleArray(number_of_elements)); |
2913 } else { | 2926 } else { |
2914 elms = Handle<FixedArrayBase>::cast( | 2927 elms = Handle<FixedArrayBase>::cast( |
2915 factory->NewFixedArrayWithHoles(number_of_elements)); | 2928 factory->NewFixedArrayWithHoles(number_of_elements)); |
2916 } | 2929 } |
2917 | 2930 |
2918 // Fill in the content | 2931 // Fill in the content |
2919 switch (array->GetElementsKind()) { | 2932 switch (elements_kind) { |
2920 case FAST_HOLEY_SMI_ELEMENTS: | 2933 case FAST_HOLEY_SMI_ELEMENTS: |
2921 case FAST_SMI_ELEMENTS: { | 2934 case FAST_SMI_ELEMENTS: { |
2922 Handle<FixedArray> smi_elms = Handle<FixedArray>::cast(elms); | 2935 Handle<FixedArray> smi_elms = Handle<FixedArray>::cast(elms); |
2923 for (int entry = 0; entry < number_of_elements; entry++) { | 2936 for (int entry = 0; entry < number_of_elements; entry++) { |
2924 smi_elms->set(entry, (*args)[entry], SKIP_WRITE_BARRIER); | 2937 smi_elms->set(entry, (*args)[entry], SKIP_WRITE_BARRIER); |
2925 } | 2938 } |
2926 break; | 2939 break; |
2927 } | 2940 } |
2928 case FAST_HOLEY_ELEMENTS: | 2941 case FAST_HOLEY_ELEMENTS: |
2929 case FAST_ELEMENTS: { | 2942 case FAST_ELEMENTS: { |
(...skipping 109 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3039 insertion_index += len; | 3052 insertion_index += len; |
3040 } | 3053 } |
3041 | 3054 |
3042 DCHECK_EQ(insertion_index, result_len); | 3055 DCHECK_EQ(insertion_index, result_len); |
3043 return result_array; | 3056 return result_array; |
3044 } | 3057 } |
3045 | 3058 |
3046 ElementsAccessor** ElementsAccessor::elements_accessors_ = NULL; | 3059 ElementsAccessor** ElementsAccessor::elements_accessors_ = NULL; |
3047 } // namespace internal | 3060 } // namespace internal |
3048 } // namespace v8 | 3061 } // namespace v8 |
OLD | NEW |