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(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(map != heap->fixed_cow_array_map()); |
Toon Verwaest
2016/04/07 13:01:39
DCHECK_NE Would already be included in the suggest
| |
1582 ((map == isolate->heap()->fixed_array_map() && length == 0) || | 1583 if (map == heap->fixed_array_map()) DCHECK_EQ(0, length); |
Toon Verwaest
2016/04/07 13:01:39
DCHECK(map == fixed_double_array_map() ||
(
Camillo Bruni
2016/04/07 13:12:38
I prefer the separate checks, makes it easier for
| |
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! |
1585 DisallowHeapAllocation no_gc; | 1588 DisallowHeapAllocation no_gc; |
1586 Handle<BackingStore> backing_store = Handle<BackingStore>::cast(elements); | 1589 Handle<BackingStore> backing_store = Handle<BackingStore>::cast(elements); |
1587 if (IsFastSmiElementsKind(KindTraits::Kind)) { | 1590 if (IsFastSmiElementsKind(KindTraits::Kind)) { |
1588 for (int i = 0; i < length; i++) { | 1591 for (int i = 0; i < length; i++) { |
1589 DCHECK(BackingStore::get(*backing_store, i, isolate)->IsSmi() || | 1592 DCHECK(BackingStore::get(*backing_store, i, isolate)->IsSmi() || |
1590 (IsFastHoleyElementsKind(KindTraits::Kind) && | 1593 (IsFastHoleyElementsKind(KindTraits::Kind) && |
1591 backing_store->is_the_hole(i))); | 1594 backing_store->is_the_hole(i))); |
1592 } | 1595 } |
1596 } else if (KindTraits::Kind == FAST_ELEMENTS || | |
1597 KindTraits::Kind == FAST_DOUBLE_ELEMENTS) { | |
1598 for (int i = 0; i < length; i++) { | |
Toon Verwaest
2016/04/07 13:01:39
This probably should be SLOW_ASSERTS
Camillo Bruni
2016/04/07 13:12:38
yup
| |
1599 DCHECK(!backing_store->is_the_hole(i)); | |
1600 } | |
1601 } else { | |
1602 DCHECK(IsFastHoleyElementsKind(KindTraits::Kind)); | |
1593 } | 1603 } |
1594 #endif | 1604 #endif |
1595 } | 1605 } |
1596 | 1606 |
1597 static Handle<Object> PopImpl(Handle<JSArray> receiver) { | 1607 static Handle<Object> PopImpl(Handle<JSArray> receiver) { |
1598 return Subclass::RemoveElement(receiver, AT_END); | 1608 return Subclass::RemoveElement(receiver, AT_END); |
1599 } | 1609 } |
1600 | 1610 |
1601 static Handle<Object> ShiftImpl(Handle<JSArray> receiver) { | 1611 static Handle<Object> ShiftImpl(Handle<JSArray> receiver) { |
1602 return Subclass::RemoveElement(receiver, AT_START); | 1612 return Subclass::RemoveElement(receiver, AT_START); |
(...skipping 195 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1798 | 1808 |
1799 if (IsHoleyElementsKind(kind) && result->IsTheHole()) { | 1809 if (IsHoleyElementsKind(kind) && result->IsTheHole()) { |
1800 return isolate->factory()->undefined_value(); | 1810 return isolate->factory()->undefined_value(); |
1801 } | 1811 } |
1802 return result; | 1812 return result; |
1803 } | 1813 } |
1804 | 1814 |
1805 static uint32_t AddArguments(Handle<JSArray> receiver, | 1815 static uint32_t AddArguments(Handle<JSArray> receiver, |
1806 Handle<FixedArrayBase> backing_store, | 1816 Handle<FixedArrayBase> backing_store, |
1807 Arguments* args, uint32_t add_size, | 1817 Arguments* args, uint32_t add_size, |
1808 Where remove_position) { | 1818 Where add_position) { |
1809 uint32_t length = Smi::cast(receiver->length())->value(); | 1819 uint32_t length = Smi::cast(receiver->length())->value(); |
1810 DCHECK(0 < add_size); | 1820 DCHECK(0 < add_size); |
1811 uint32_t elms_len = backing_store->length(); | 1821 uint32_t elms_len = backing_store->length(); |
1812 // Check we do not overflow the new_length. | 1822 // Check we do not overflow the new_length. |
1813 DCHECK(add_size <= static_cast<uint32_t>(Smi::kMaxValue - length)); | 1823 DCHECK(add_size <= static_cast<uint32_t>(Smi::kMaxValue - length)); |
1814 uint32_t new_length = length + add_size; | 1824 uint32_t new_length = length + add_size; |
1815 | 1825 |
1816 if (new_length > elms_len) { | 1826 if (new_length > elms_len) { |
1817 // New backing storage is needed. | 1827 // New backing storage is needed. |
1818 uint32_t capacity = JSObject::NewElementsCapacity(new_length); | 1828 uint32_t capacity = JSObject::NewElementsCapacity(new_length); |
1819 // If we add arguments to the start we have to shift the existing objects. | 1829 // 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; | 1830 int copy_dst_index = add_position == AT_START ? add_size : 0; |
1821 // Copy over all objects to a new backing_store. | 1831 // Copy over all objects to a new backing_store. |
1822 backing_store = Subclass::ConvertElementsWithCapacity( | 1832 backing_store = Subclass::ConvertElementsWithCapacity( |
1823 receiver, backing_store, KindTraits::Kind, capacity, 0, | 1833 receiver, backing_store, KindTraits::Kind, capacity, 0, |
1824 copy_dst_index, ElementsAccessor::kCopyToEndAndInitializeToHole); | 1834 copy_dst_index, ElementsAccessor::kCopyToEndAndInitializeToHole); |
1825 receiver->set_elements(*backing_store); | 1835 receiver->set_elements(*backing_store); |
1826 } else if (remove_position == AT_START) { | 1836 } else if (add_position == AT_START) { |
1827 // If the backing store has enough capacity and we add elements to the | 1837 // If the backing store has enough capacity and we add elements to the |
1828 // start we have to shift the existing objects. | 1838 // start we have to shift the existing objects. |
1829 Isolate* isolate = receiver->GetIsolate(); | 1839 Isolate* isolate = receiver->GetIsolate(); |
1830 Subclass::MoveElements(isolate, receiver, backing_store, add_size, 0, | 1840 Subclass::MoveElements(isolate, receiver, backing_store, add_size, 0, |
1831 length, 0, 0); | 1841 length, 0, 0); |
1832 } | 1842 } |
1833 | 1843 |
1834 int insertion_index = remove_position == AT_START ? 0 : length; | 1844 int insertion_index = add_position == AT_START ? 0 : length; |
1835 // Copy the arguments to the start. | 1845 // Copy the arguments to the start. |
1836 Subclass::CopyArguments(args, backing_store, add_size, 1, insertion_index); | 1846 Subclass::CopyArguments(args, backing_store, add_size, 1, insertion_index); |
1837 // Set the length. | 1847 // Set the length. |
1838 receiver->set_length(Smi::FromInt(new_length)); | 1848 receiver->set_length(Smi::FromInt(new_length)); |
1839 return new_length; | 1849 return new_length; |
1840 } | 1850 } |
1841 | 1851 |
1842 static void CopyArguments(Arguments* args, Handle<FixedArrayBase> dst_store, | 1852 static void CopyArguments(Arguments* args, Handle<FixedArrayBase> dst_store, |
1843 uint32_t copy_size, uint32_t src_index, | 1853 uint32_t copy_size, uint32_t src_index, |
1844 uint32_t dst_index) { | 1854 uint32_t dst_index) { |
1845 // Add the provided values. | 1855 // Add the provided values. |
1846 DisallowHeapAllocation no_gc; | 1856 DisallowHeapAllocation no_gc; |
1847 FixedArrayBase* raw_backing_store = *dst_store; | 1857 FixedArrayBase* raw_backing_store = *dst_store; |
1848 WriteBarrierMode mode = raw_backing_store->GetWriteBarrierMode(no_gc); | 1858 WriteBarrierMode mode = raw_backing_store->GetWriteBarrierMode(no_gc); |
1849 for (uint32_t i = 0; i < copy_size; i++) { | 1859 for (uint32_t i = 0; i < copy_size; i++) { |
1850 Object* argument = (*args)[i + src_index]; | 1860 Object* argument = (*args)[src_index + i]; |
1851 Subclass::SetImpl(raw_backing_store, i + dst_index, argument, mode); | 1861 DCHECK(!argument->IsTheHole()); |
1862 Subclass::SetImpl(raw_backing_store, dst_index + i, argument, mode); | |
1852 } | 1863 } |
1853 } | 1864 } |
1854 }; | 1865 }; |
1855 | 1866 |
1856 template <typename Subclass, typename KindTraits> | 1867 template <typename Subclass, typename KindTraits> |
1857 class FastSmiOrObjectElementsAccessor | 1868 class FastSmiOrObjectElementsAccessor |
1858 : public FastElementsAccessor<Subclass, KindTraits> { | 1869 : public FastElementsAccessor<Subclass, KindTraits> { |
1859 public: | 1870 public: |
1860 explicit FastSmiOrObjectElementsAccessor(const char* name) | 1871 explicit FastSmiOrObjectElementsAccessor(const char* name) |
1861 : FastElementsAccessor<Subclass, KindTraits>(name) {} | 1872 : FastElementsAccessor<Subclass, KindTraits>(name) {} |
(...skipping 1047 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2909 Handle<FixedArrayBase> elms; | 2920 Handle<FixedArrayBase> elms; |
2910 if (IsFastDoubleElementsKind(elements_kind)) { | 2921 if (IsFastDoubleElementsKind(elements_kind)) { |
2911 elms = Handle<FixedArrayBase>::cast( | 2922 elms = Handle<FixedArrayBase>::cast( |
2912 factory->NewFixedDoubleArray(number_of_elements)); | 2923 factory->NewFixedDoubleArray(number_of_elements)); |
2913 } else { | 2924 } else { |
2914 elms = Handle<FixedArrayBase>::cast( | 2925 elms = Handle<FixedArrayBase>::cast( |
2915 factory->NewFixedArrayWithHoles(number_of_elements)); | 2926 factory->NewFixedArrayWithHoles(number_of_elements)); |
2916 } | 2927 } |
2917 | 2928 |
2918 // Fill in the content | 2929 // Fill in the content |
2919 switch (array->GetElementsKind()) { | 2930 switch (elements_kind) { |
2920 case FAST_HOLEY_SMI_ELEMENTS: | 2931 case FAST_HOLEY_SMI_ELEMENTS: |
2921 case FAST_SMI_ELEMENTS: { | 2932 case FAST_SMI_ELEMENTS: { |
2922 Handle<FixedArray> smi_elms = Handle<FixedArray>::cast(elms); | 2933 Handle<FixedArray> smi_elms = Handle<FixedArray>::cast(elms); |
2923 for (int entry = 0; entry < number_of_elements; entry++) { | 2934 for (int entry = 0; entry < number_of_elements; entry++) { |
2924 smi_elms->set(entry, (*args)[entry], SKIP_WRITE_BARRIER); | 2935 smi_elms->set(entry, (*args)[entry], SKIP_WRITE_BARRIER); |
2925 } | 2936 } |
2926 break; | 2937 break; |
2927 } | 2938 } |
2928 case FAST_HOLEY_ELEMENTS: | 2939 case FAST_HOLEY_ELEMENTS: |
2929 case FAST_ELEMENTS: { | 2940 case FAST_ELEMENTS: { |
(...skipping 109 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
3039 insertion_index += len; | 3050 insertion_index += len; |
3040 } | 3051 } |
3041 | 3052 |
3042 DCHECK_EQ(insertion_index, result_len); | 3053 DCHECK_EQ(insertion_index, result_len); |
3043 return result_array; | 3054 return result_array; |
3044 } | 3055 } |
3045 | 3056 |
3046 ElementsAccessor** ElementsAccessor::elements_accessors_ = NULL; | 3057 ElementsAccessor** ElementsAccessor::elements_accessors_ = NULL; |
3047 } // namespace internal | 3058 } // namespace internal |
3048 } // namespace v8 | 3059 } // namespace v8 |
OLD | NEW |