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

Side by Side Diff: src/objects.cc

Issue 2664173002: Throw when a holey property is set in Array.sort (Closed)
Patch Set: Patch PrepareSlowElementsForSort directly Created 3 years, 10 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 | « no previous file | test/mjsunit/array-sort.js » ('j') | test/mjsunit/array-sort.js » ('J')
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2015 the V8 project authors. All rights reserved. 1 // Copyright 2015 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/objects.h" 5 #include "src/objects.h"
6 6
7 #include <cmath> 7 #include <cmath>
8 #include <iomanip> 8 #include <iomanip>
9 #include <memory> 9 #include <memory>
10 #include <sstream> 10 #include <sstream>
(...skipping 16781 matching lines...) Expand 10 before | Expand all | Expand 10 after
16792 // Must stay in dictionary mode, either because of requires_slow_elements, 16792 // Must stay in dictionary mode, either because of requires_slow_elements,
16793 // or because we are not going to sort (and therefore compact) all of the 16793 // or because we are not going to sort (and therefore compact) all of the
16794 // elements. 16794 // elements.
16795 Handle<SeededNumberDictionary> dict(object->element_dictionary(), isolate); 16795 Handle<SeededNumberDictionary> dict(object->element_dictionary(), isolate);
16796 Handle<SeededNumberDictionary> new_dict = 16796 Handle<SeededNumberDictionary> new_dict =
16797 SeededNumberDictionary::New(isolate, dict->NumberOfElements()); 16797 SeededNumberDictionary::New(isolate, dict->NumberOfElements());
16798 16798
16799 uint32_t pos = 0; 16799 uint32_t pos = 0;
16800 uint32_t undefs = 0; 16800 uint32_t undefs = 0;
16801 int capacity = dict->Capacity(); 16801 int capacity = dict->Capacity();
16802 bool is_extensible = JSObject::IsExtensible(object);
adamk 2017/02/07 00:23:46 Please add a DCHECK to JSObject::PrepareElementsFo
Choongwoo Han 2017/02/07 09:45:49 Done.
16802 Handle<Smi> bailout(Smi::FromInt(-1), isolate); 16803 Handle<Smi> bailout(Smi::FromInt(-1), isolate);
16803 // Entry to the new dictionary does not cause it to grow, as we have 16804 // Entry to the new dictionary does not cause it to grow, as we have
16804 // allocated one that is large enough for all entries. 16805 // allocated one that is large enough for all entries.
16805 DisallowHeapAllocation no_gc; 16806 DisallowHeapAllocation no_gc;
16806 for (int i = 0; i < capacity; i++) { 16807 for (int i = 0; i < capacity; i++) {
16807 Object* k = dict->KeyAt(i); 16808 Object* k = dict->KeyAt(i);
16808 if (!dict->IsKey(isolate, k)) continue; 16809 if (!dict->IsKey(isolate, k)) continue;
16809 16810
16810 DCHECK(k->IsNumber()); 16811 DCHECK(k->IsNumber());
16811 DCHECK(!k->IsSmi() || Smi::cast(k)->value() >= 0); 16812 DCHECK(!k->IsSmi() || Smi::cast(k)->value() >= 0);
16812 DCHECK(!k->IsHeapNumber() || HeapNumber::cast(k)->value() >= 0); 16813 DCHECK(!k->IsHeapNumber() || HeapNumber::cast(k)->value() >= 0);
16813 DCHECK(!k->IsHeapNumber() || HeapNumber::cast(k)->value() <= kMaxUInt32); 16814 DCHECK(!k->IsHeapNumber() || HeapNumber::cast(k)->value() <= kMaxUInt32);
16814 16815
16815 HandleScope scope(isolate); 16816 HandleScope scope(isolate);
16816 Handle<Object> value(dict->ValueAt(i), isolate); 16817 Handle<Object> value(dict->ValueAt(i), isolate);
adamk 2017/02/07 00:23:46 Rather than changing the logic below, couldn't you
Choongwoo Han 2017/02/07 09:45:49 Since it is a dictionary iteration, value cannot b
adamk 2017/02/08 01:14:07 Hmm. The duplication doesn't look great either, an
16817 PropertyDetails details = dict->DetailsAt(i); 16818 PropertyDetails details = dict->DetailsAt(i);
16818 if (details.kind() == kAccessor || details.IsReadOnly()) { 16819 if (details.kind() == kAccessor || details.IsReadOnly()) {
16819 // Bail out and do the sorting of undefineds and array holes in JS. 16820 // Bail out and do the sorting of undefineds and array holes in JS.
16820 // Also bail out if the element is not supposed to be moved. 16821 // Also bail out if the element is not supposed to be moved.
16821 return bailout; 16822 return bailout;
16822 } 16823 }
16823 16824
16824 uint32_t key = NumberToUint32(k); 16825 uint32_t key = NumberToUint32(k);
16825 if (key < limit) { 16826 uint32_t new_pos = key < limit ? pos : key;
16826 if (value->IsUndefined(isolate)) { 16827 if (key < limit && value->IsUndefined(isolate)) {
16827 undefs++; 16828 undefs++;
16828 } else if (pos > static_cast<uint32_t>(Smi::kMaxValue)) { 16829 } else if (new_pos > static_cast<uint32_t>(Smi::kMaxValue)) {
16829 // Adding an entry with the key beyond smi-range requires
16830 // allocation. Bailout.
16831 return bailout;
16832 } else {
16833 Handle<Object> result = SeededNumberDictionary::AddNumberEntry(
16834 new_dict, pos, value, details, object);
16835 DCHECK(result.is_identical_to(new_dict));
16836 USE(result);
16837 pos++;
16838 }
16839 } else if (key > static_cast<uint32_t>(Smi::kMaxValue)) {
16840 // Adding an entry with the key beyond smi-range requires 16830 // Adding an entry with the key beyond smi-range requires
16841 // allocation. Bailout. 16831 // allocation. Bailout.
16842 return bailout; 16832 return bailout;
16833 } else if (!is_extensible && !dict->Has(isolate, new_pos)) {
16834 return bailout;
16843 } else { 16835 } else {
16844 Handle<Object> result = SeededNumberDictionary::AddNumberEntry( 16836 Handle<Object> result = SeededNumberDictionary::AddNumberEntry(
16845 new_dict, key, value, details, object); 16837 new_dict, new_pos, value, details, object);
16846 DCHECK(result.is_identical_to(new_dict)); 16838 DCHECK(result.is_identical_to(new_dict));
16847 USE(result); 16839 USE(result);
16840 if (key < limit) {
16841 pos++;
16842 }
16848 } 16843 }
16849 } 16844 }
16850 16845
16851 uint32_t result = pos; 16846 uint32_t result = pos;
16852 PropertyDetails no_details = PropertyDetails::Empty(); 16847 PropertyDetails no_details = PropertyDetails::Empty();
16853 while (undefs > 0) { 16848 while (undefs > 0) {
16854 if (pos > static_cast<uint32_t>(Smi::kMaxValue)) { 16849 if (pos > static_cast<uint32_t>(Smi::kMaxValue)) {
16855 // Adding an entry with the key beyond smi-range requires 16850 // Adding an entry with the key beyond smi-range requires
16856 // allocation. Bailout. 16851 // allocation. Bailout.
16857 return bailout; 16852 return bailout;
(...skipping 3167 matching lines...) Expand 10 before | Expand all | Expand 10 after
20025 // depend on this. 20020 // depend on this.
20026 return DICTIONARY_ELEMENTS; 20021 return DICTIONARY_ELEMENTS;
20027 } 20022 }
20028 DCHECK_LE(kind, LAST_ELEMENTS_KIND); 20023 DCHECK_LE(kind, LAST_ELEMENTS_KIND);
20029 return kind; 20024 return kind;
20030 } 20025 }
20031 } 20026 }
20032 20027
20033 } // namespace internal 20028 } // namespace internal
20034 } // namespace v8 20029 } // namespace v8
OLDNEW
« no previous file with comments | « no previous file | test/mjsunit/array-sort.js » ('j') | test/mjsunit/array-sort.js » ('J')

Powered by Google App Engine
This is Rietveld 408576698