Chromium Code Reviews| OLD | NEW |
|---|---|
| 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 Loading... | |
| 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 Loading... | |
| 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 |
| OLD | NEW |