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

Side by Side Diff: src/elements.cc

Issue 1870433003: Improve elements validation and object printing (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: further checks Created 4 years, 8 months 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/builtins.cc ('k') | src/objects-inl.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 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
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
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
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
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
OLDNEW
« no previous file with comments | « src/builtins.cc ('k') | src/objects-inl.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698