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

Side by Side Diff: src/elements.cc

Issue 1194943002: Inline SetLengthWithoutNormalize into its callers (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Only find last non-configurable element in dicts if it can be present Created 5 years, 6 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 | src/objects.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/v8.h" 5 #include "src/v8.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/elements.h" 9 #include "src/elements.h"
10 #include "src/messages.h" 10 #include "src/messages.h"
(...skipping 844 matching lines...) Expand 10 before | Expand all | Expand 10 after
855 public: 855 public:
856 explicit FastElementsAccessor(const char* name) 856 explicit FastElementsAccessor(const char* name)
857 : ElementsAccessorBase<FastElementsAccessorSubclass, 857 : ElementsAccessorBase<FastElementsAccessorSubclass,
858 KindTraits>(name) {} 858 KindTraits>(name) {}
859 protected: 859 protected:
860 friend class ElementsAccessorBase<FastElementsAccessorSubclass, KindTraits>; 860 friend class ElementsAccessorBase<FastElementsAccessorSubclass, KindTraits>;
861 friend class SloppyArgumentsElementsAccessor; 861 friend class SloppyArgumentsElementsAccessor;
862 862
863 typedef typename KindTraits::BackingStore BackingStore; 863 typedef typename KindTraits::BackingStore BackingStore;
864 864
865 // Adjusts the length of the fast backing store.
866 static uint32_t SetLengthWithoutNormalize(
867 Handle<FixedArrayBase> backing_store, Handle<JSArray> array,
868 uint32_t length) {
869 Isolate* isolate = array->GetIsolate();
870 uint32_t old_capacity = backing_store->length();
871 Handle<Object> old_length(array->length(), isolate);
872 bool same_or_smaller_size = old_length->IsSmi() &&
873 static_cast<uint32_t>(Handle<Smi>::cast(old_length)->value()) >= length;
874 ElementsKind kind = array->GetElementsKind();
875
876 if (!same_or_smaller_size && IsFastElementsKind(kind) &&
877 !IsFastHoleyElementsKind(kind)) {
878 kind = GetHoleyElementsKind(kind);
879 JSObject::TransitionElementsKind(array, kind);
880 }
881
882 // Check whether the backing store should be shrunk.
883 if (length <= old_capacity) {
884 if (array->HasFastSmiOrObjectElements()) {
885 backing_store = JSObject::EnsureWritableFastElements(array);
886 }
887 if (2 * length <= old_capacity) {
888 // If more than half the elements won't be used, trim the array.
889 if (length == 0) {
890 array->initialize_elements();
891 } else {
892 isolate->heap()->RightTrimFixedArray<Heap::CONCURRENT_TO_SWEEPER>(
893 *backing_store, old_capacity - length);
894 }
895 } else {
896 // Otherwise, fill the unused tail with holes.
897 int old_length = FastD2IChecked(array->length()->Number());
898 for (int i = length; i < old_length; i++) {
899 Handle<BackingStore>::cast(backing_store)->set_the_hole(i);
900 }
901 }
902 return length;
903 }
904
905 // Check whether the backing store should be expanded.
906 uint32_t min = JSObject::NewElementsCapacity(old_capacity);
907 uint32_t new_capacity = length > min ? length : min;
908 FastElementsAccessorSubclass::SetFastElementsCapacityAndLength(
909 array, new_capacity, length);
910 JSObject::ValidateElements(array);
911 return length;
912 }
913
914 static void DeleteCommon(Handle<JSObject> obj, uint32_t key, 865 static void DeleteCommon(Handle<JSObject> obj, uint32_t key,
915 LanguageMode language_mode) { 866 LanguageMode language_mode) {
916 DCHECK(obj->HasFastSmiOrObjectElements() || 867 DCHECK(obj->HasFastSmiOrObjectElements() ||
917 obj->HasFastDoubleElements() || 868 obj->HasFastDoubleElements() ||
918 obj->HasFastArgumentsElements()); 869 obj->HasFastArgumentsElements());
919 Isolate* isolate = obj->GetIsolate(); 870 Isolate* isolate = obj->GetIsolate();
920 Heap* heap = obj->GetHeap(); 871 Heap* heap = obj->GetHeap();
921 Handle<FixedArrayBase> elements(obj->elements()); 872 Handle<FixedArrayBase> elements(obj->elements());
922 if (*elements == heap->empty_fixed_array()) return; 873 if (*elements == heap->empty_fixed_array()) return;
923 874
(...skipping 390 matching lines...) Expand 10 before | Expand all | Expand 10 after
1314 class DictionaryElementsAccessor 1265 class DictionaryElementsAccessor
1315 : public ElementsAccessorBase<DictionaryElementsAccessor, 1266 : public ElementsAccessorBase<DictionaryElementsAccessor,
1316 ElementsKindTraits<DICTIONARY_ELEMENTS> > { 1267 ElementsKindTraits<DICTIONARY_ELEMENTS> > {
1317 public: 1268 public:
1318 explicit DictionaryElementsAccessor(const char* name) 1269 explicit DictionaryElementsAccessor(const char* name)
1319 : ElementsAccessorBase<DictionaryElementsAccessor, 1270 : ElementsAccessorBase<DictionaryElementsAccessor,
1320 ElementsKindTraits<DICTIONARY_ELEMENTS> >(name) {} 1271 ElementsKindTraits<DICTIONARY_ELEMENTS> >(name) {}
1321 1272
1322 static void SetLengthImpl(Handle<JSArray> array, uint32_t length, 1273 static void SetLengthImpl(Handle<JSArray> array, uint32_t length,
1323 Handle<FixedArrayBase> backing_store) { 1274 Handle<FixedArrayBase> backing_store) {
1324 uint32_t new_length =
1325 SetLengthWithoutNormalize(backing_store, array, length);
1326 // SetLengthWithoutNormalize does not allow length to drop below the last
1327 // non-deletable element.
1328 DCHECK_GE(new_length, length);
1329 if (new_length <= Smi::kMaxValue) {
1330 array->set_length(Smi::FromInt(new_length));
1331 } else {
1332 Isolate* isolate = array->GetIsolate();
1333 Handle<Object> length_obj =
1334 isolate->factory()->NewNumberFromUint(new_length);
1335 array->set_length(*length_obj);
1336 }
1337 }
1338
1339 // Adjusts the length of the dictionary backing store and returns the new
1340 // length according to ES5 section 15.4.5.2 behavior.
1341 static uint32_t SetLengthWithoutNormalize(Handle<FixedArrayBase> store,
1342 Handle<JSArray> array,
1343 uint32_t length) {
1344 Handle<SeededNumberDictionary> dict = 1275 Handle<SeededNumberDictionary> dict =
1345 Handle<SeededNumberDictionary>::cast(store); 1276 Handle<SeededNumberDictionary>::cast(backing_store);
1346 Isolate* isolate = array->GetIsolate(); 1277 Isolate* isolate = array->GetIsolate();
1347 int capacity = dict->Capacity(); 1278 int capacity = dict->Capacity();
1348 uint32_t old_length = 0; 1279 uint32_t old_length = 0;
1349 CHECK(array->length()->ToArrayLength(&old_length)); 1280 CHECK(array->length()->ToArrayLength(&old_length));
1350 if (length < old_length) { 1281 if (dict->requires_slow_elements() && length < old_length) {
1351 // Find last non-deletable element in range of elements to be 1282 // Find last non-deletable element in range of elements to be
1352 // deleted and adjust range accordingly. 1283 // deleted and adjust range accordingly.
1353 for (int i = 0; i < capacity; i++) { 1284 for (int i = 0; i < capacity; i++) {
1354 DisallowHeapAllocation no_gc; 1285 DisallowHeapAllocation no_gc;
1355 Object* key = dict->KeyAt(i); 1286 Object* key = dict->KeyAt(i);
1356 if (key->IsNumber()) { 1287 if (key->IsNumber()) {
1357 uint32_t number = static_cast<uint32_t>(key->Number()); 1288 uint32_t number = static_cast<uint32_t>(key->Number());
1358 if (length <= number && number < old_length) { 1289 if (length <= number && number < old_length) {
1359 PropertyDetails details = dict->DetailsAt(i); 1290 PropertyDetails details = dict->DetailsAt(i);
1360 if (!details.IsConfigurable()) length = number + 1; 1291 if (!details.IsConfigurable()) length = number + 1;
(...skipping 17 matching lines...) Expand all
1378 if (length <= number && number < old_length) { 1309 if (length <= number && number < old_length) {
1379 dict->SetEntry(i, the_hole_value, the_hole_value); 1310 dict->SetEntry(i, the_hole_value, the_hole_value);
1380 removed_entries++; 1311 removed_entries++;
1381 } 1312 }
1382 } 1313 }
1383 } 1314 }
1384 1315
1385 // Update the number of elements. 1316 // Update the number of elements.
1386 dict->ElementsRemoved(removed_entries); 1317 dict->ElementsRemoved(removed_entries);
1387 } 1318 }
1388 return length; 1319
1320 if (length <= Smi::kMaxValue) {
1321 array->set_length(Smi::FromInt(length));
1322 } else {
1323 Isolate* isolate = array->GetIsolate();
brucedawson 2015/06/22 17:12:35 This declaration of 'isolate' shadows a seemingly
1324 Handle<Object> length_obj = isolate->factory()->NewNumberFromUint(length);
1325 array->set_length(*length_obj);
1326 }
1389 } 1327 }
1390 1328
1391 static void DeleteCommon(Handle<JSObject> obj, uint32_t key, 1329 static void DeleteCommon(Handle<JSObject> obj, uint32_t key,
1392 LanguageMode language_mode) { 1330 LanguageMode language_mode) {
1393 Isolate* isolate = obj->GetIsolate(); 1331 Isolate* isolate = obj->GetIsolate();
1394 Handle<FixedArray> backing_store(FixedArray::cast(obj->elements()), 1332 Handle<FixedArray> backing_store(FixedArray::cast(obj->elements()),
1395 isolate); 1333 isolate);
1396 bool is_arguments = 1334 bool is_arguments =
1397 (obj->GetElementsKind() == SLOPPY_ARGUMENTS_ELEMENTS); 1335 (obj->GetElementsKind() == SLOPPY_ARGUMENTS_ELEMENTS);
1398 if (is_arguments) { 1336 if (is_arguments) {
(...skipping 301 matching lines...) Expand 10 before | Expand all | Expand 10 after
1700 ELEMENTS_LIST(ACCESSOR_DELETE) 1638 ELEMENTS_LIST(ACCESSOR_DELETE)
1701 #undef ACCESSOR_DELETE 1639 #undef ACCESSOR_DELETE
1702 elements_accessors_ = NULL; 1640 elements_accessors_ = NULL;
1703 } 1641 }
1704 1642
1705 1643
1706 template <typename ElementsAccessorSubclass, typename ElementsKindTraits> 1644 template <typename ElementsAccessorSubclass, typename ElementsKindTraits>
1707 void ElementsAccessorBase<ElementsAccessorSubclass, ElementsKindTraits>:: 1645 void ElementsAccessorBase<ElementsAccessorSubclass, ElementsKindTraits>::
1708 SetLengthImpl(Handle<JSArray> array, uint32_t length, 1646 SetLengthImpl(Handle<JSArray> array, uint32_t length,
1709 Handle<FixedArrayBase> backing_store) { 1647 Handle<FixedArrayBase> backing_store) {
1710 // Normalize if the length does not fit in a smi. Fast mode arrays only 1648 DCHECK(!JSArray::SetLengthWouldNormalize(array->GetHeap(), length));
1711 // support smi length. 1649 DCHECK(IsFastElementsKind(array->GetElementsKind()));
1712 if (JSArray::SetLengthWouldNormalize(array->GetHeap(), length)) { 1650 uint32_t old_length = 0;
1713 Handle<SeededNumberDictionary> dictionary = 1651 CHECK(array->length()->ToArrayIndex(&old_length));
1714 JSObject::NormalizeElements(array); 1652
1715 DCHECK(!dictionary.is_null()); 1653 if (old_length < length) {
1716 DictionaryElementsAccessor::SetLengthImpl(array, length, dictionary); 1654 ElementsKind kind = array->GetElementsKind();
1655 if (!IsFastHoleyElementsKind(kind)) {
1656 kind = GetHoleyElementsKind(kind);
1657 JSObject::TransitionElementsKind(array, kind);
1658 }
1659 }
1660
1661 // Check whether the backing store should be shrunk.
1662 uint32_t capacity = backing_store->length();
1663 if (length == 0) {
1664 array->initialize_elements();
1665 } else if (length <= capacity) {
1666 if (array->HasFastSmiOrObjectElements()) {
1667 backing_store = JSObject::EnsureWritableFastElements(array);
1668 }
1669 if (2 * length <= capacity) {
1670 // If more than half the elements won't be used, trim the array.
1671 array->GetHeap()->RightTrimFixedArray<Heap::CONCURRENT_TO_SWEEPER>(
1672 *backing_store, capacity - length);
1673 } else {
1674 // Otherwise, fill the unused tail with holes.
1675 for (uint32_t i = length; i < old_length; i++) {
1676 BackingStore::cast(*backing_store)->set_the_hole(i);
1677 }
1678 }
1717 } else { 1679 } else {
1718 #ifdef DEBUG 1680 // Check whether the backing store should be expanded.
1719 uint32_t max = Smi::kMaxValue; 1681 capacity = Max(length, JSObject::NewElementsCapacity(capacity));
1720 DCHECK_LE(length, max); 1682 ElementsAccessorSubclass::SetFastElementsCapacityAndLength(array, capacity,
1721 #endif 1683 length);
1722 uint32_t new_length = ElementsAccessorSubclass::SetLengthWithoutNormalize(
1723 backing_store, array, length);
1724 DCHECK_EQ(length, new_length);
1725 array->set_length(Smi::FromInt(new_length));
1726 } 1684 }
1685
1686 array->set_length(Smi::FromInt(length));
1687 JSObject::ValidateElements(array);
1727 } 1688 }
1728 1689
1729 1690
1730 MaybeHandle<Object> ArrayConstructInitializeElements(Handle<JSArray> array, 1691 MaybeHandle<Object> ArrayConstructInitializeElements(Handle<JSArray> array,
1731 Arguments* args) { 1692 Arguments* args) {
1732 if (args->length() == 0) { 1693 if (args->length() == 0) {
1733 // Optimize the case where there are no parameters passed. 1694 // Optimize the case where there are no parameters passed.
1734 JSArray::Initialize(array, JSArray::kPreallocatedArrayElements); 1695 JSArray::Initialize(array, JSArray::kPreallocatedArrayElements);
1735 return array; 1696 return array;
1736 1697
(...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after
1812 break; 1773 break;
1813 } 1774 }
1814 1775
1815 array->set_elements(*elms); 1776 array->set_elements(*elms);
1816 array->set_length(Smi::FromInt(number_of_elements)); 1777 array->set_length(Smi::FromInt(number_of_elements));
1817 return array; 1778 return array;
1818 } 1779 }
1819 1780
1820 } // namespace internal 1781 } // namespace internal
1821 } // namespace v8 1782 } // namespace v8
OLDNEW
« no previous file with comments | « no previous file | src/objects.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698