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 1585 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1596 args, push_size, AT_END); | 1596 args, push_size, AT_END); |
1597 } | 1597 } |
1598 | 1598 |
1599 static uint32_t UnshiftImpl(Handle<JSArray> receiver, | 1599 static uint32_t UnshiftImpl(Handle<JSArray> receiver, |
1600 Arguments* args, uint32_t unshift_size) { | 1600 Arguments* args, uint32_t unshift_size) { |
1601 Handle<FixedArrayBase> backing_store(receiver->elements()); | 1601 Handle<FixedArrayBase> backing_store(receiver->elements()); |
1602 return FastElementsAccessorSubclass::AddArguments( | 1602 return FastElementsAccessorSubclass::AddArguments( |
1603 receiver, backing_store, args, unshift_size, AT_START); | 1603 receiver, backing_store, args, unshift_size, AT_START); |
1604 } | 1604 } |
1605 | 1605 |
1606 static void MoveElements(Isolate* isolate, Handle<JSArray> receiver, | |
1607 Handle<FixedArrayBase> backing_store, int dst_index, | |
1608 int src_index, int len, int hole_start, | |
1609 int hole_end) { | |
1610 UNREACHABLE(); | |
1611 } | |
1612 | |
1613 static Handle<JSArray> SliceImpl(Handle<JSObject> receiver, | 1606 static Handle<JSArray> SliceImpl(Handle<JSObject> receiver, |
1614 uint32_t start, uint32_t end) { | 1607 uint32_t start, uint32_t end) { |
1615 Isolate* isolate = receiver->GetIsolate(); | 1608 Isolate* isolate = receiver->GetIsolate(); |
1616 Handle<FixedArrayBase> backing_store(receiver->elements(), isolate); | 1609 Handle<FixedArrayBase> backing_store(receiver->elements(), isolate); |
1617 int result_len = end < start ? 0u : end - start; | 1610 int result_len = end < start ? 0u : end - start; |
1618 Handle<JSArray> result_array = isolate->factory()->NewJSArray( | 1611 Handle<JSArray> result_array = isolate->factory()->NewJSArray( |
1619 KindTraits::Kind, result_len, result_len); | 1612 KindTraits::Kind, result_len, result_len); |
1620 DisallowHeapAllocation no_gc; | 1613 DisallowHeapAllocation no_gc; |
1621 FastElementsAccessorSubclass::CopyElementsImpl( | 1614 FastElementsAccessorSubclass::CopyElementsImpl( |
1622 *backing_store, start, result_array->elements(), KindTraits::Kind, 0, | 1615 *backing_store, start, result_array->elements(), KindTraits::Kind, 0, |
(...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1693 FastElementsAccessorSubclass::GetImpl(object->elements(), index); | 1686 FastElementsAccessorSubclass::GetImpl(object->elements(), index); |
1694 if (get_entries) { | 1687 if (get_entries) { |
1695 value = MakeEntryPair(isolate, index, value); | 1688 value = MakeEntryPair(isolate, index, value); |
1696 } | 1689 } |
1697 values_or_entries->set(count++, *value); | 1690 values_or_entries->set(count++, *value); |
1698 } | 1691 } |
1699 *nof_items = count; | 1692 *nof_items = count; |
1700 return Just(true); | 1693 return Just(true); |
1701 } | 1694 } |
1702 | 1695 |
| 1696 static void MoveElements(Isolate* isolate, Handle<JSArray> receiver, |
| 1697 Handle<FixedArrayBase> backing_store, int dst_index, |
| 1698 int src_index, int len, int hole_start, |
| 1699 int hole_end) { |
| 1700 Heap* heap = isolate->heap(); |
| 1701 Handle<BackingStore> dst_elms = Handle<BackingStore>::cast(backing_store); |
| 1702 if (heap->CanMoveObjectStart(*dst_elms) && dst_index == 0) { |
| 1703 // Update all the copies of this backing_store handle. |
| 1704 *dst_elms.location() = |
| 1705 BackingStore::cast(heap->LeftTrimFixedArray(*dst_elms, src_index)); |
| 1706 receiver->set_elements(*dst_elms); |
| 1707 // Adjust the hole offset as the array has been shrunk. |
| 1708 hole_end -= src_index; |
| 1709 DCHECK_LE(hole_start, backing_store->length()); |
| 1710 DCHECK_LE(hole_end, backing_store->length()); |
| 1711 } else if (len != 0) { |
| 1712 if (IsFastDoubleElementsKind(KindTraits::Kind)) { |
| 1713 MemMove(dst_elms->data_start() + dst_index, |
| 1714 dst_elms->data_start() + src_index, len * kDoubleSize); |
| 1715 } else { |
| 1716 DisallowHeapAllocation no_gc; |
| 1717 heap->MoveElements(FixedArray::cast(*dst_elms), dst_index, src_index, |
| 1718 len); |
| 1719 } |
| 1720 } |
| 1721 if (hole_start != hole_end) { |
| 1722 dst_elms->FillWithHoles(hole_start, hole_end); |
| 1723 } |
| 1724 } |
| 1725 |
1703 private: | 1726 private: |
1704 // SpliceShrinkStep might modify the backing_store. | 1727 // SpliceShrinkStep might modify the backing_store. |
1705 static void SpliceShrinkStep(Isolate* isolate, Handle<JSArray> receiver, | 1728 static void SpliceShrinkStep(Isolate* isolate, Handle<JSArray> receiver, |
1706 Handle<FixedArrayBase> backing_store, | 1729 Handle<FixedArrayBase> backing_store, |
1707 uint32_t start, uint32_t delete_count, | 1730 uint32_t start, uint32_t delete_count, |
1708 uint32_t add_count, uint32_t len, | 1731 uint32_t add_count, uint32_t len, |
1709 uint32_t new_length) { | 1732 uint32_t new_length) { |
1710 const int move_left_count = len - delete_count - start; | 1733 const int move_left_count = len - delete_count - start; |
1711 const int move_left_dst_index = start + add_count; | 1734 const int move_left_dst_index = start + add_count; |
1712 FastElementsAccessorSubclass::MoveElements( | 1735 FastElementsAccessorSubclass::MoveElements( |
(...skipping 138 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1851 Object* value, WriteBarrierMode mode) { | 1874 Object* value, WriteBarrierMode mode) { |
1852 FixedArray::cast(backing_store)->set(entry, value, mode); | 1875 FixedArray::cast(backing_store)->set(entry, value, mode); |
1853 } | 1876 } |
1854 | 1877 |
1855 static Object* GetRaw(FixedArray* backing_store, uint32_t entry) { | 1878 static Object* GetRaw(FixedArray* backing_store, uint32_t entry) { |
1856 uint32_t index = FastElementsAccessorSubclass::GetIndexForEntryImpl( | 1879 uint32_t index = FastElementsAccessorSubclass::GetIndexForEntryImpl( |
1857 backing_store, entry); | 1880 backing_store, entry); |
1858 return backing_store->get(index); | 1881 return backing_store->get(index); |
1859 } | 1882 } |
1860 | 1883 |
1861 static void MoveElements(Isolate* isolate, Handle<JSArray> receiver, | |
1862 Handle<FixedArrayBase> backing_store, int dst_index, | |
1863 int src_index, int len, int hole_start, | |
1864 int hole_end) { | |
1865 Heap* heap = isolate->heap(); | |
1866 Handle<FixedArray> dst_elms = Handle<FixedArray>::cast(backing_store); | |
1867 if (heap->CanMoveObjectStart(*dst_elms) && dst_index == 0) { | |
1868 // Update all the copies of this backing_store handle. | |
1869 *dst_elms.location() = | |
1870 FixedArray::cast(heap->LeftTrimFixedArray(*dst_elms, src_index)); | |
1871 receiver->set_elements(*dst_elms); | |
1872 // Adjust the hole offset as the array has been shrunk. | |
1873 hole_end -= src_index; | |
1874 DCHECK_LE(hole_start, backing_store->length()); | |
1875 DCHECK_LE(hole_end, backing_store->length()); | |
1876 } else if (len != 0) { | |
1877 DisallowHeapAllocation no_gc; | |
1878 heap->MoveElements(*dst_elms, dst_index, src_index, len); | |
1879 } | |
1880 if (hole_start != hole_end) { | |
1881 dst_elms->FillWithHoles(hole_start, hole_end); | |
1882 } | |
1883 } | |
1884 | 1884 |
1885 // NOTE: this method violates the handlified function signature convention: | 1885 // NOTE: this method violates the handlified function signature convention: |
1886 // raw pointer parameters in the function that allocates. | 1886 // raw pointer parameters in the function that allocates. |
1887 // See ElementsAccessor::CopyElements() for details. | 1887 // See ElementsAccessor::CopyElements() for details. |
1888 // This method could actually allocate if copying from double elements to | 1888 // This method could actually allocate if copying from double elements to |
1889 // object elements. | 1889 // object elements. |
1890 static void CopyElementsImpl(FixedArrayBase* from, uint32_t from_start, | 1890 static void CopyElementsImpl(FixedArrayBase* from, uint32_t from_start, |
1891 FixedArrayBase* to, ElementsKind from_kind, | 1891 FixedArrayBase* to, ElementsKind from_kind, |
1892 uint32_t to_start, int packed_size, | 1892 uint32_t to_start, int packed_size, |
1893 int copy_size) { | 1893 int copy_size) { |
(...skipping 111 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2005 static inline void SetImpl(FixedArrayBase* backing_store, uint32_t entry, | 2005 static inline void SetImpl(FixedArrayBase* backing_store, uint32_t entry, |
2006 Object* value) { | 2006 Object* value) { |
2007 FixedDoubleArray::cast(backing_store)->set(entry, value->Number()); | 2007 FixedDoubleArray::cast(backing_store)->set(entry, value->Number()); |
2008 } | 2008 } |
2009 | 2009 |
2010 static inline void SetImpl(FixedArrayBase* backing_store, uint32_t entry, | 2010 static inline void SetImpl(FixedArrayBase* backing_store, uint32_t entry, |
2011 Object* value, WriteBarrierMode mode) { | 2011 Object* value, WriteBarrierMode mode) { |
2012 FixedDoubleArray::cast(backing_store)->set(entry, value->Number()); | 2012 FixedDoubleArray::cast(backing_store)->set(entry, value->Number()); |
2013 } | 2013 } |
2014 | 2014 |
2015 static void MoveElements(Isolate* isolate, Handle<JSArray> receiver, | |
2016 Handle<FixedArrayBase> backing_store, int dst_index, | |
2017 int src_index, int len, int hole_start, | |
2018 int hole_end) { | |
2019 Heap* heap = isolate->heap(); | |
2020 Handle<FixedDoubleArray> dst_elms = | |
2021 Handle<FixedDoubleArray>::cast(backing_store); | |
2022 if (heap->CanMoveObjectStart(*dst_elms) && dst_index == 0) { | |
2023 // Update all the copies of this backing_store handle. | |
2024 *dst_elms.location() = FixedDoubleArray::cast( | |
2025 heap->LeftTrimFixedArray(*dst_elms, src_index)); | |
2026 receiver->set_elements(*dst_elms); | |
2027 // Adjust the hole offset as the array has been shrunk. | |
2028 hole_end -= src_index; | |
2029 DCHECK_LE(hole_start, backing_store->length()); | |
2030 DCHECK_LE(hole_end, backing_store->length()); | |
2031 } else if (len != 0) { | |
2032 MemMove(dst_elms->data_start() + dst_index, | |
2033 dst_elms->data_start() + src_index, len * kDoubleSize); | |
2034 } | |
2035 if (hole_start != hole_end) { | |
2036 dst_elms->FillWithHoles(hole_start, hole_end); | |
2037 } | |
2038 } | |
2039 | |
2040 static void CopyElementsImpl(FixedArrayBase* from, uint32_t from_start, | 2015 static void CopyElementsImpl(FixedArrayBase* from, uint32_t from_start, |
2041 FixedArrayBase* to, ElementsKind from_kind, | 2016 FixedArrayBase* to, ElementsKind from_kind, |
2042 uint32_t to_start, int packed_size, | 2017 uint32_t to_start, int packed_size, |
2043 int copy_size) { | 2018 int copy_size) { |
2044 DisallowHeapAllocation no_allocation; | 2019 DisallowHeapAllocation no_allocation; |
2045 switch (from_kind) { | 2020 switch (from_kind) { |
2046 case FAST_SMI_ELEMENTS: | 2021 case FAST_SMI_ELEMENTS: |
2047 CopyPackedSmiToDoubleElements(from, from_start, to, to_start, | 2022 CopyPackedSmiToDoubleElements(from, from_start, to, to_start, |
2048 packed_size, copy_size); | 2023 packed_size, copy_size); |
2049 break; | 2024 break; |
(...skipping 979 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3029 insertion_index += len; | 3004 insertion_index += len; |
3030 } | 3005 } |
3031 | 3006 |
3032 DCHECK_EQ(insertion_index, result_len); | 3007 DCHECK_EQ(insertion_index, result_len); |
3033 return result_array; | 3008 return result_array; |
3034 } | 3009 } |
3035 | 3010 |
3036 ElementsAccessor** ElementsAccessor::elements_accessors_ = NULL; | 3011 ElementsAccessor** ElementsAccessor::elements_accessors_ = NULL; |
3037 } // namespace internal | 3012 } // namespace internal |
3038 } // namespace v8 | 3013 } // namespace v8 |
OLD | NEW |