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

Side by Side Diff: src/elements.cc

Issue 1191313003: More cleanup related to setting array.length (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: 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 | « src/elements.h ('k') | 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 618 matching lines...) Expand 10 before | Expand all | Expand 10 after
629 return ElementsAccessorSubclass::GetAccessorPairImpl(holder, key, 629 return ElementsAccessorSubclass::GetAccessorPairImpl(holder, key,
630 backing_store); 630 backing_store);
631 } 631 }
632 632
633 static MaybeHandle<AccessorPair> GetAccessorPairImpl( 633 static MaybeHandle<AccessorPair> GetAccessorPairImpl(
634 Handle<JSObject> obj, uint32_t key, 634 Handle<JSObject> obj, uint32_t key,
635 Handle<FixedArrayBase> backing_store) { 635 Handle<FixedArrayBase> backing_store) {
636 return MaybeHandle<AccessorPair>(); 636 return MaybeHandle<AccessorPair>();
637 } 637 }
638 638
639 MUST_USE_RESULT virtual MaybeHandle<Object> SetLength( 639 virtual void SetLength(Handle<JSArray> array, uint32_t length) final {
640 Handle<JSArray> array, Handle<Object> length) final { 640 ElementsAccessorSubclass::SetLengthImpl(array, length,
641 return ElementsAccessorSubclass::SetLengthImpl( 641 handle(array->elements()));
642 array, length, handle(array->elements()));
643 } 642 }
644 643
645 MUST_USE_RESULT static MaybeHandle<Object> SetLengthImpl( 644 static void SetLengthImpl(Handle<JSArray> array, uint32_t length,
646 Handle<JSObject> obj, 645 Handle<FixedArrayBase> backing_store);
647 Handle<Object> length,
648 Handle<FixedArrayBase> backing_store);
649 646
650 virtual void SetCapacityAndLength(Handle<JSArray> array, int capacity, 647 virtual void SetCapacityAndLength(Handle<JSArray> array, int capacity,
651 int length) final { 648 int length) final {
652 ElementsAccessorSubclass:: 649 ElementsAccessorSubclass::
653 SetFastElementsCapacityAndLength(array, capacity, length); 650 SetFastElementsCapacityAndLength(array, capacity, length);
654 } 651 }
655 652
656 static void SetFastElementsCapacityAndLength( 653 static void SetFastElementsCapacityAndLength(
657 Handle<JSObject> obj, 654 Handle<JSObject> obj,
658 int capacity, 655 int capacity,
(...skipping 200 matching lines...) Expand 10 before | Expand all | Expand 10 after
859 explicit FastElementsAccessor(const char* name) 856 explicit FastElementsAccessor(const char* name)
860 : ElementsAccessorBase<FastElementsAccessorSubclass, 857 : ElementsAccessorBase<FastElementsAccessorSubclass,
861 KindTraits>(name) {} 858 KindTraits>(name) {}
862 protected: 859 protected:
863 friend class ElementsAccessorBase<FastElementsAccessorSubclass, KindTraits>; 860 friend class ElementsAccessorBase<FastElementsAccessorSubclass, KindTraits>;
864 friend class SloppyArgumentsElementsAccessor; 861 friend class SloppyArgumentsElementsAccessor;
865 862
866 typedef typename KindTraits::BackingStore BackingStore; 863 typedef typename KindTraits::BackingStore BackingStore;
867 864
868 // Adjusts the length of the fast backing store. 865 // Adjusts the length of the fast backing store.
869 static Handle<Object> SetLengthWithoutNormalize( 866 static uint32_t SetLengthWithoutNormalize(
870 Handle<FixedArrayBase> backing_store, 867 Handle<FixedArrayBase> backing_store, Handle<JSArray> array,
871 Handle<JSArray> array,
872 Handle<Object> length_object,
873 uint32_t length) { 868 uint32_t length) {
874 Isolate* isolate = array->GetIsolate(); 869 Isolate* isolate = array->GetIsolate();
875 uint32_t old_capacity = backing_store->length(); 870 uint32_t old_capacity = backing_store->length();
876 Handle<Object> old_length(array->length(), isolate); 871 Handle<Object> old_length(array->length(), isolate);
877 bool same_or_smaller_size = old_length->IsSmi() && 872 bool same_or_smaller_size = old_length->IsSmi() &&
878 static_cast<uint32_t>(Handle<Smi>::cast(old_length)->value()) >= length; 873 static_cast<uint32_t>(Handle<Smi>::cast(old_length)->value()) >= length;
879 ElementsKind kind = array->GetElementsKind(); 874 ElementsKind kind = array->GetElementsKind();
880 875
881 if (!same_or_smaller_size && IsFastElementsKind(kind) && 876 if (!same_or_smaller_size && IsFastElementsKind(kind) &&
882 !IsFastHoleyElementsKind(kind)) { 877 !IsFastHoleyElementsKind(kind)) {
(...skipping 14 matching lines...) Expand all
897 isolate->heap()->RightTrimFixedArray<Heap::CONCURRENT_TO_SWEEPER>( 892 isolate->heap()->RightTrimFixedArray<Heap::CONCURRENT_TO_SWEEPER>(
898 *backing_store, old_capacity - length); 893 *backing_store, old_capacity - length);
899 } 894 }
900 } else { 895 } else {
901 // Otherwise, fill the unused tail with holes. 896 // Otherwise, fill the unused tail with holes.
902 int old_length = FastD2IChecked(array->length()->Number()); 897 int old_length = FastD2IChecked(array->length()->Number());
903 for (int i = length; i < old_length; i++) { 898 for (int i = length; i < old_length; i++) {
904 Handle<BackingStore>::cast(backing_store)->set_the_hole(i); 899 Handle<BackingStore>::cast(backing_store)->set_the_hole(i);
905 } 900 }
906 } 901 }
907 return length_object; 902 return length;
908 } 903 }
909 904
910 // Check whether the backing store should be expanded. 905 // Check whether the backing store should be expanded.
911 uint32_t min = JSObject::NewElementsCapacity(old_capacity); 906 uint32_t min = JSObject::NewElementsCapacity(old_capacity);
912 uint32_t new_capacity = length > min ? length : min; 907 uint32_t new_capacity = length > min ? length : min;
913 FastElementsAccessorSubclass::SetFastElementsCapacityAndLength( 908 FastElementsAccessorSubclass::SetFastElementsCapacityAndLength(
914 array, new_capacity, length); 909 array, new_capacity, length);
915 JSObject::ValidateElements(array); 910 JSObject::ValidateElements(array);
916 return length_object; 911 return length;
917 } 912 }
918 913
919 static void DeleteCommon(Handle<JSObject> obj, uint32_t key, 914 static void DeleteCommon(Handle<JSObject> obj, uint32_t key,
920 LanguageMode language_mode) { 915 LanguageMode language_mode) {
921 DCHECK(obj->HasFastSmiOrObjectElements() || 916 DCHECK(obj->HasFastSmiOrObjectElements() ||
922 obj->HasFastDoubleElements() || 917 obj->HasFastDoubleElements() ||
923 obj->HasFastArgumentsElements()); 918 obj->HasFastArgumentsElements());
924 Isolate* isolate = obj->GetIsolate(); 919 Isolate* isolate = obj->GetIsolate();
925 Heap* heap = obj->GetHeap(); 920 Heap* heap = obj->GetHeap();
926 Handle<FixedArrayBase> elements(obj->elements()); 921 Handle<FixedArrayBase> elements(obj->elements());
(...skipping 337 matching lines...) Expand 10 before | Expand all | Expand 10 after
1264 } else { 1259 } else {
1265 return backing_store->GetIsolate()->factory()->undefined_value(); 1260 return backing_store->GetIsolate()->factory()->undefined_value();
1266 } 1261 }
1267 } 1262 }
1268 1263
1269 static PropertyDetails GetDetailsImpl(FixedArrayBase* backing_store, 1264 static PropertyDetails GetDetailsImpl(FixedArrayBase* backing_store,
1270 uint32_t index) { 1265 uint32_t index) {
1271 return PropertyDetails(DONT_DELETE, DATA, 0, PropertyCellType::kNoCell); 1266 return PropertyDetails(DONT_DELETE, DATA, 0, PropertyCellType::kNoCell);
1272 } 1267 }
1273 1268
1274 MUST_USE_RESULT static MaybeHandle<Object> SetLengthImpl( 1269 static void SetLengthImpl(Handle<JSArray> array, uint32_t length,
1275 Handle<JSObject> obj, 1270 Handle<FixedArrayBase> backing_store) {
1276 Handle<Object> length,
1277 Handle<FixedArrayBase> backing_store) {
1278 // External arrays do not support changing their length. 1271 // External arrays do not support changing their length.
1279 UNREACHABLE(); 1272 UNREACHABLE();
1280 return obj;
1281 } 1273 }
1282 1274
1283 virtual void Delete(Handle<JSObject> obj, uint32_t key, 1275 virtual void Delete(Handle<JSObject> obj, uint32_t key,
1284 LanguageMode language_mode) final { 1276 LanguageMode language_mode) final {
1285 // External arrays always ignore deletes. 1277 // External arrays always ignore deletes.
1286 } 1278 }
1287 1279
1288 static uint32_t GetIndexForKeyImpl(JSObject* holder, 1280 static uint32_t GetIndexForKeyImpl(JSObject* holder,
1289 FixedArrayBase* backing_store, 1281 FixedArrayBase* backing_store,
1290 uint32_t key) { 1282 uint32_t key) {
(...skipping 29 matching lines...) Expand all
1320 1312
1321 1313
1322 class DictionaryElementsAccessor 1314 class DictionaryElementsAccessor
1323 : public ElementsAccessorBase<DictionaryElementsAccessor, 1315 : public ElementsAccessorBase<DictionaryElementsAccessor,
1324 ElementsKindTraits<DICTIONARY_ELEMENTS> > { 1316 ElementsKindTraits<DICTIONARY_ELEMENTS> > {
1325 public: 1317 public:
1326 explicit DictionaryElementsAccessor(const char* name) 1318 explicit DictionaryElementsAccessor(const char* name)
1327 : ElementsAccessorBase<DictionaryElementsAccessor, 1319 : ElementsAccessorBase<DictionaryElementsAccessor,
1328 ElementsKindTraits<DICTIONARY_ELEMENTS> >(name) {} 1320 ElementsKindTraits<DICTIONARY_ELEMENTS> >(name) {}
1329 1321
1322 static void SetLengthImpl(Handle<JSArray> array, uint32_t length,
1323 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
1330 // Adjusts the length of the dictionary backing store and returns the new 1339 // Adjusts the length of the dictionary backing store and returns the new
1331 // length according to ES5 section 15.4.5.2 behavior. 1340 // length according to ES5 section 15.4.5.2 behavior.
1332 static Handle<Object> SetLengthWithoutNormalize( 1341 static uint32_t SetLengthWithoutNormalize(Handle<FixedArrayBase> store,
1333 Handle<FixedArrayBase> store, 1342 Handle<JSArray> array,
1334 Handle<JSArray> array, 1343 uint32_t length) {
1335 Handle<Object> length_object,
1336 uint32_t length) {
1337 Handle<SeededNumberDictionary> dict = 1344 Handle<SeededNumberDictionary> dict =
1338 Handle<SeededNumberDictionary>::cast(store); 1345 Handle<SeededNumberDictionary>::cast(store);
1339 Isolate* isolate = array->GetIsolate(); 1346 Isolate* isolate = array->GetIsolate();
1340 int capacity = dict->Capacity(); 1347 int capacity = dict->Capacity();
1341 uint32_t new_length = length; 1348 uint32_t old_length = 0;
1342 uint32_t old_length = static_cast<uint32_t>(array->length()->Number()); 1349 CHECK(array->length()->ToArrayLength(&old_length));
1343 if (new_length < old_length) { 1350 if (length < old_length) {
1344 // Find last non-deletable element in range of elements to be 1351 // Find last non-deletable element in range of elements to be
1345 // deleted and adjust range accordingly. 1352 // deleted and adjust range accordingly.
1346 for (int i = 0; i < capacity; i++) { 1353 for (int i = 0; i < capacity; i++) {
1347 DisallowHeapAllocation no_gc; 1354 DisallowHeapAllocation no_gc;
1348 Object* key = dict->KeyAt(i); 1355 Object* key = dict->KeyAt(i);
1349 if (key->IsNumber()) { 1356 if (key->IsNumber()) {
1350 uint32_t number = static_cast<uint32_t>(key->Number()); 1357 uint32_t number = static_cast<uint32_t>(key->Number());
1351 if (new_length <= number && number < old_length) { 1358 if (length <= number && number < old_length) {
1352 PropertyDetails details = dict->DetailsAt(i); 1359 PropertyDetails details = dict->DetailsAt(i);
1353 if (!details.IsConfigurable()) new_length = number + 1; 1360 if (!details.IsConfigurable()) length = number + 1;
1354 } 1361 }
1355 } 1362 }
1356 } 1363 }
1357 if (new_length != length) {
1358 length_object = isolate->factory()->NewNumberFromUint(new_length);
1359 }
1360 } 1364 }
1361 1365
1362 if (new_length == 0) { 1366 if (length == 0) {
1363 // Flush the backing store. 1367 // Flush the backing store.
1364 JSObject::ResetElements(array); 1368 JSObject::ResetElements(array);
1365 } else { 1369 } else {
1366 DisallowHeapAllocation no_gc; 1370 DisallowHeapAllocation no_gc;
1367 // Remove elements that should be deleted. 1371 // Remove elements that should be deleted.
1368 int removed_entries = 0; 1372 int removed_entries = 0;
1369 Handle<Object> the_hole_value = isolate->factory()->the_hole_value(); 1373 Handle<Object> the_hole_value = isolate->factory()->the_hole_value();
1370 for (int i = 0; i < capacity; i++) { 1374 for (int i = 0; i < capacity; i++) {
1371 Object* key = dict->KeyAt(i); 1375 Object* key = dict->KeyAt(i);
1372 if (key->IsNumber()) { 1376 if (key->IsNumber()) {
1373 uint32_t number = static_cast<uint32_t>(key->Number()); 1377 uint32_t number = static_cast<uint32_t>(key->Number());
1374 if (new_length <= number && number < old_length) { 1378 if (length <= number && number < old_length) {
1375 dict->SetEntry(i, the_hole_value, the_hole_value); 1379 dict->SetEntry(i, the_hole_value, the_hole_value);
1376 removed_entries++; 1380 removed_entries++;
1377 } 1381 }
1378 } 1382 }
1379 } 1383 }
1380 1384
1381 // Update the number of elements. 1385 // Update the number of elements.
1382 dict->ElementsRemoved(removed_entries); 1386 dict->ElementsRemoved(removed_entries);
1383 } 1387 }
1384 return length_object; 1388 return length;
1385 } 1389 }
1386 1390
1387 static void DeleteCommon(Handle<JSObject> obj, uint32_t key, 1391 static void DeleteCommon(Handle<JSObject> obj, uint32_t key,
1388 LanguageMode language_mode) { 1392 LanguageMode language_mode) {
1389 Isolate* isolate = obj->GetIsolate(); 1393 Isolate* isolate = obj->GetIsolate();
1390 Handle<FixedArray> backing_store(FixedArray::cast(obj->elements()), 1394 Handle<FixedArray> backing_store(FixedArray::cast(obj->elements()),
1391 isolate); 1395 isolate);
1392 bool is_arguments = 1396 bool is_arguments =
1393 (obj->GetElementsKind() == SLOPPY_ARGUMENTS_ELEMENTS); 1397 (obj->GetElementsKind() == SLOPPY_ARGUMENTS_ELEMENTS);
1394 if (is_arguments) { 1398 if (is_arguments) {
(...skipping 164 matching lines...) Expand 10 before | Expand all | Expand 10 after
1559 if (!probe->IsTheHole()) { 1563 if (!probe->IsTheHole()) {
1560 return MaybeHandle<AccessorPair>(); 1564 return MaybeHandle<AccessorPair>();
1561 } else { 1565 } else {
1562 // If not aliased, check the arguments. 1566 // If not aliased, check the arguments.
1563 Handle<FixedArray> arguments(FixedArray::cast(parameter_map->get(1))); 1567 Handle<FixedArray> arguments(FixedArray::cast(parameter_map->get(1)));
1564 return ElementsAccessor::ForArray(arguments) 1568 return ElementsAccessor::ForArray(arguments)
1565 ->GetAccessorPair(obj, key, arguments); 1569 ->GetAccessorPair(obj, key, arguments);
1566 } 1570 }
1567 } 1571 }
1568 1572
1569 MUST_USE_RESULT static MaybeHandle<Object> SetLengthImpl( 1573 static void SetLengthImpl(Handle<JSArray> array, uint32_t length,
1570 Handle<JSObject> obj, 1574 Handle<FixedArrayBase> parameter_map) {
1571 Handle<Object> length, 1575 // Sloppy arguments objects are not arrays.
1572 Handle<FixedArrayBase> parameter_map) { 1576 UNREACHABLE();
1573 // TODO(mstarzinger): This was never implemented but will be used once we
1574 // correctly implement [[DefineOwnProperty]] on arrays.
1575 UNIMPLEMENTED();
1576 return obj;
1577 } 1577 }
1578 1578
1579 virtual void Delete(Handle<JSObject> obj, uint32_t key, 1579 virtual void Delete(Handle<JSObject> obj, uint32_t key,
1580 LanguageMode language_mode) final { 1580 LanguageMode language_mode) final {
1581 Isolate* isolate = obj->GetIsolate(); 1581 Isolate* isolate = obj->GetIsolate();
1582 Handle<FixedArray> parameter_map(FixedArray::cast(obj->elements())); 1582 Handle<FixedArray> parameter_map(FixedArray::cast(obj->elements()));
1583 Handle<Object> probe(GetParameterMapArg(*parameter_map, key), isolate); 1583 Handle<Object> probe(GetParameterMapArg(*parameter_map, key), isolate);
1584 if (!probe->IsTheHole()) { 1584 if (!probe->IsTheHole()) {
1585 // TODO(kmillikin): We could check if this was the last aliased 1585 // TODO(kmillikin): We could check if this was the last aliased
1586 // parameter, and revert to normal elements in that case. That 1586 // parameter, and revert to normal elements in that case. That
(...skipping 110 matching lines...) Expand 10 before | Expand all | Expand 10 after
1697 void ElementsAccessor::TearDown() { 1697 void ElementsAccessor::TearDown() {
1698 if (elements_accessors_ == NULL) return; 1698 if (elements_accessors_ == NULL) return;
1699 #define ACCESSOR_DELETE(Class, Kind, Store) delete elements_accessors_[Kind]; 1699 #define ACCESSOR_DELETE(Class, Kind, Store) delete elements_accessors_[Kind];
1700 ELEMENTS_LIST(ACCESSOR_DELETE) 1700 ELEMENTS_LIST(ACCESSOR_DELETE)
1701 #undef ACCESSOR_DELETE 1701 #undef ACCESSOR_DELETE
1702 elements_accessors_ = NULL; 1702 elements_accessors_ = NULL;
1703 } 1703 }
1704 1704
1705 1705
1706 template <typename ElementsAccessorSubclass, typename ElementsKindTraits> 1706 template <typename ElementsAccessorSubclass, typename ElementsKindTraits>
1707 MUST_USE_RESULT MaybeHandle<Object> ElementsAccessorBase< 1707 void ElementsAccessorBase<ElementsAccessorSubclass, ElementsKindTraits>::
1708 ElementsAccessorSubclass, 1708 SetLengthImpl(Handle<JSArray> array, uint32_t length,
1709 ElementsKindTraits>::SetLengthImpl(Handle<JSObject> obj, 1709 Handle<FixedArrayBase> backing_store) {
1710 Handle<Object> length_obj, 1710 // Normalize if the length does not fit in a smi. Fast mode arrays only
1711 Handle<FixedArrayBase> backing_store) { 1711 // support smi length.
1712 Handle<JSArray> array = Handle<JSArray>::cast(obj); 1712 if (JSArray::SetLengthWouldNormalize(array->GetHeap(), length)) {
1713 1713 Handle<SeededNumberDictionary> dictionary =
1714 uint32_t length = 0; 1714 JSObject::NormalizeElements(array);
1715 CHECK(length_obj->ToArrayLength(&length)); 1715 DCHECK(!dictionary.is_null());
1716 // Fast case: length fits in a smi. 1716 DictionaryElementsAccessor::SetLengthImpl(array, length, dictionary);
1717 if (length <= Smi::kMaxValue) { 1717 } else {
1718 Handle<Smi> smi(Smi::FromInt(length), obj->GetIsolate()); 1718 #ifdef DEBUG
1719 Handle<Object> new_length = 1719 uint32_t max = Smi::kMaxValue;
1720 ElementsAccessorSubclass::SetLengthWithoutNormalize(backing_store, 1720 DCHECK_LE(length, max);
1721 array, smi, length); 1721 #endif
1722 DCHECK(!new_length.is_null()); 1722 uint32_t new_length = ElementsAccessorSubclass::SetLengthWithoutNormalize(
1723 1723 backing_store, array, length);
1724 // Even though the proposed length was a smi, new_length could 1724 DCHECK_EQ(length, new_length);
1725 // still be a heap number because SetLengthWithoutNormalize doesn't 1725 array->set_length(Smi::FromInt(new_length));
1726 // allow the array length property to drop below the index of
1727 // non-deletable elements.
1728 DCHECK(new_length->IsSmi() || new_length->IsHeapNumber() ||
1729 new_length->IsUndefined());
1730 if (new_length->IsSmi()) {
1731 array->set_length(*Handle<Smi>::cast(new_length));
1732 return array;
1733 } else if (new_length->IsHeapNumber()) {
1734 array->set_length(*new_length);
1735 return array;
1736 }
1737 } 1726 }
1738
1739 // Slow case: The new length does not fit into a Smi or conversion
1740 // to slow elements is needed for other reasons.
1741 Handle<SeededNumberDictionary> dictionary =
1742 JSObject::NormalizeElements(array);
1743 DCHECK(!dictionary.is_null());
1744
1745 Handle<Object> new_length =
1746 DictionaryElementsAccessor::SetLengthWithoutNormalize(dictionary, array,
1747 length_obj, length);
1748 DCHECK(!new_length.is_null());
1749
1750 DCHECK(new_length->IsNumber());
1751 array->set_length(*new_length);
1752 return array;
1753 } 1727 }
1754 1728
1755 1729
1756 MaybeHandle<Object> ArrayConstructInitializeElements(Handle<JSArray> array, 1730 MaybeHandle<Object> ArrayConstructInitializeElements(Handle<JSArray> array,
1757 Arguments* args) { 1731 Arguments* args) {
1758 if (args->length() == 0) { 1732 if (args->length() == 0) {
1759 // Optimize the case where there are no parameters passed. 1733 // Optimize the case where there are no parameters passed.
1760 JSArray::Initialize(array, JSArray::kPreallocatedArrayElements); 1734 JSArray::Initialize(array, JSArray::kPreallocatedArrayElements);
1761 return array; 1735 return array;
1762 1736
1763 } else if (args->length() == 1 && args->at<Object>(0)->IsNumber()) { 1737 } else if (args->length() == 1 && args->at<Object>(0)->IsNumber()) {
1764 uint32_t length; 1738 uint32_t length;
1765 if (!args->at<Object>(0)->ToArrayLength(&length)) { 1739 if (!args->at<Object>(0)->ToArrayLength(&length)) {
1766 return ThrowArrayLengthRangeError(array->GetIsolate()); 1740 return ThrowArrayLengthRangeError(array->GetIsolate());
1767 } 1741 }
1768 1742
1769 // Optimize the case where there is one argument and the argument is a small 1743 // Optimize the case where there is one argument and the argument is a small
1770 // smi. 1744 // smi.
1771 if (length > 0 && length < JSObject::kInitialMaxFastElementArray) { 1745 if (length > 0 && length < JSObject::kInitialMaxFastElementArray) {
1772 ElementsKind elements_kind = array->GetElementsKind(); 1746 ElementsKind elements_kind = array->GetElementsKind();
1773 JSArray::Initialize(array, length, length); 1747 JSArray::Initialize(array, length, length);
1774 1748
1775 if (!IsFastHoleyElementsKind(elements_kind)) { 1749 if (!IsFastHoleyElementsKind(elements_kind)) {
1776 elements_kind = GetHoleyElementsKind(elements_kind); 1750 elements_kind = GetHoleyElementsKind(elements_kind);
1777 JSObject::TransitionElementsKind(array, elements_kind); 1751 JSObject::TransitionElementsKind(array, elements_kind);
1778 } 1752 }
1779 return array;
1780 } else if (length == 0) { 1753 } else if (length == 0) {
1781 JSArray::Initialize(array, JSArray::kPreallocatedArrayElements); 1754 JSArray::Initialize(array, JSArray::kPreallocatedArrayElements);
1782 return array; 1755 } else {
1756 // Take the argument as the length.
1757 JSArray::Initialize(array, 0);
1758 JSArray::SetLength(array, length);
1783 } 1759 }
1784 1760 return array;
1785 // Take the argument as the length.
1786 JSArray::Initialize(array, 0);
1787 return JSArray::SetElementsLength(array, args->at<Object>(0));
1788 } 1761 }
1789 1762
1790 Factory* factory = array->GetIsolate()->factory(); 1763 Factory* factory = array->GetIsolate()->factory();
1791 1764
1792 // Set length and elements on the array. 1765 // Set length and elements on the array.
1793 int number_of_elements = args->length(); 1766 int number_of_elements = args->length();
1794 JSObject::EnsureCanContainElements( 1767 JSObject::EnsureCanContainElements(
1795 array, args, 0, number_of_elements, ALLOW_CONVERTED_DOUBLE_ELEMENTS); 1768 array, args, 0, number_of_elements, ALLOW_CONVERTED_DOUBLE_ELEMENTS);
1796 1769
1797 // Allocate an appropriately typed elements array. 1770 // Allocate an appropriately typed elements array.
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after
1839 break; 1812 break;
1840 } 1813 }
1841 1814
1842 array->set_elements(*elms); 1815 array->set_elements(*elms);
1843 array->set_length(Smi::FromInt(number_of_elements)); 1816 array->set_length(Smi::FromInt(number_of_elements));
1844 return array; 1817 return array;
1845 } 1818 }
1846 1819
1847 } // namespace internal 1820 } // namespace internal
1848 } // namespace v8 1821 } // namespace v8
OLDNEW
« no previous file with comments | « src/elements.h ('k') | src/objects.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698