| OLD | NEW |
| 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/messages.h" | 10 #include "src/messages.h" |
| (...skipping 673 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 684 return ElementsAccessorSubclass::ShiftImpl(receiver, backing_store); | 684 return ElementsAccessorSubclass::ShiftImpl(receiver, backing_store); |
| 685 } | 685 } |
| 686 | 686 |
| 687 static Handle<Object> ShiftImpl(Handle<JSArray> receiver, | 687 static Handle<Object> ShiftImpl(Handle<JSArray> receiver, |
| 688 Handle<FixedArrayBase> backing_store) { | 688 Handle<FixedArrayBase> backing_store) { |
| 689 UNREACHABLE(); | 689 UNREACHABLE(); |
| 690 return Handle<Object>(); | 690 return Handle<Object>(); |
| 691 } | 691 } |
| 692 | 692 |
| 693 virtual void SetLength(Handle<JSArray> array, uint32_t length) final { | 693 virtual void SetLength(Handle<JSArray> array, uint32_t length) final { |
| 694 ElementsAccessorSubclass::SetLengthImpl(array, length, | 694 ElementsAccessorSubclass::SetLengthImpl(array->GetIsolate(), array, length, |
| 695 handle(array->elements())); | 695 handle(array->elements())); |
| 696 } | 696 } |
| 697 | 697 |
| 698 static void SetLengthImpl(Handle<JSArray> array, uint32_t length, | 698 static void SetLengthImpl(Isolate* isolate, Handle<JSArray> array, |
| 699 uint32_t length, |
| 699 Handle<FixedArrayBase> backing_store) { | 700 Handle<FixedArrayBase> backing_store) { |
| 700 DCHECK(!array->SetLengthWouldNormalize(length)); | 701 DCHECK(!array->SetLengthWouldNormalize(length)); |
| 701 DCHECK(IsFastElementsKind(array->GetElementsKind())); | 702 DCHECK(IsFastElementsKind(array->GetElementsKind())); |
| 702 uint32_t old_length = 0; | 703 uint32_t old_length = 0; |
| 703 CHECK(array->length()->ToArrayIndex(&old_length)); | 704 CHECK(array->length()->ToArrayIndex(&old_length)); |
| 704 | 705 |
| 705 if (old_length < length) { | 706 if (old_length < length) { |
| 706 ElementsKind kind = array->GetElementsKind(); | 707 ElementsKind kind = array->GetElementsKind(); |
| 707 if (!IsFastHoleyElementsKind(kind)) { | 708 if (!IsFastHoleyElementsKind(kind)) { |
| 708 kind = GetHoleyElementsKind(kind); | 709 kind = GetHoleyElementsKind(kind); |
| 709 JSObject::TransitionElementsKind(array, kind); | 710 JSObject::TransitionElementsKind(array, kind); |
| 710 } | 711 } |
| 711 } | 712 } |
| 712 | 713 |
| 713 // Check whether the backing store should be shrunk. | 714 // Check whether the backing store should be shrunk. |
| 714 uint32_t capacity = backing_store->length(); | 715 uint32_t capacity = backing_store->length(); |
| 716 old_length = Min(old_length, capacity); |
| 715 if (length == 0) { | 717 if (length == 0) { |
| 716 array->initialize_elements(); | 718 array->initialize_elements(); |
| 717 } else if (length <= capacity) { | 719 } else if (length <= capacity) { |
| 718 if (array->HasFastSmiOrObjectElements()) { | 720 if (array->HasFastSmiOrObjectElements()) { |
| 719 backing_store = JSObject::EnsureWritableFastElements(array); | 721 backing_store = JSObject::EnsureWritableFastElements(array); |
| 720 } | 722 } |
| 721 if (2 * length <= capacity) { | 723 if (2 * length <= capacity) { |
| 722 // If more than half the elements won't be used, trim the array. | 724 // If more than half the elements won't be used, trim the array. |
| 723 array->GetHeap()->RightTrimFixedArray<Heap::CONCURRENT_TO_SWEEPER>( | 725 isolate->heap()->RightTrimFixedArray<Heap::CONCURRENT_TO_SWEEPER>( |
| 724 *backing_store, capacity - length); | 726 *backing_store, capacity - length); |
| 725 } else { | 727 } else { |
| 726 // Otherwise, fill the unused tail with holes. | 728 // Otherwise, fill the unused tail with holes. |
| 727 for (uint32_t i = length; i < old_length; i++) { | 729 for (uint32_t i = length; i < old_length; i++) { |
| 728 BackingStore::cast(*backing_store)->set_the_hole(i); | 730 BackingStore::cast(*backing_store)->set_the_hole(i); |
| 729 } | 731 } |
| 730 } | 732 } |
| 731 } else { | 733 } else { |
| 732 // Check whether the backing store should be expanded. | 734 // Check whether the backing store should be expanded. |
| 733 capacity = Max(length, JSObject::NewElementsCapacity(capacity)); | 735 capacity = Max(length, JSObject::NewElementsCapacity(capacity)); |
| (...skipping 213 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 947 | 949 |
| 948 | 950 |
| 949 class DictionaryElementsAccessor | 951 class DictionaryElementsAccessor |
| 950 : public ElementsAccessorBase<DictionaryElementsAccessor, | 952 : public ElementsAccessorBase<DictionaryElementsAccessor, |
| 951 ElementsKindTraits<DICTIONARY_ELEMENTS> > { | 953 ElementsKindTraits<DICTIONARY_ELEMENTS> > { |
| 952 public: | 954 public: |
| 953 explicit DictionaryElementsAccessor(const char* name) | 955 explicit DictionaryElementsAccessor(const char* name) |
| 954 : ElementsAccessorBase<DictionaryElementsAccessor, | 956 : ElementsAccessorBase<DictionaryElementsAccessor, |
| 955 ElementsKindTraits<DICTIONARY_ELEMENTS> >(name) {} | 957 ElementsKindTraits<DICTIONARY_ELEMENTS> >(name) {} |
| 956 | 958 |
| 957 static void SetLengthImpl(Handle<JSArray> array, uint32_t length, | 959 static void SetLengthImpl(Isolate* isolate, Handle<JSArray> array, |
| 960 uint32_t length, |
| 958 Handle<FixedArrayBase> backing_store) { | 961 Handle<FixedArrayBase> backing_store) { |
| 959 Handle<SeededNumberDictionary> dict = | 962 Handle<SeededNumberDictionary> dict = |
| 960 Handle<SeededNumberDictionary>::cast(backing_store); | 963 Handle<SeededNumberDictionary>::cast(backing_store); |
| 961 Isolate* isolate = array->GetIsolate(); | |
| 962 int capacity = dict->Capacity(); | 964 int capacity = dict->Capacity(); |
| 963 uint32_t old_length = 0; | 965 uint32_t old_length = 0; |
| 964 CHECK(array->length()->ToArrayLength(&old_length)); | 966 CHECK(array->length()->ToArrayLength(&old_length)); |
| 965 if (length < old_length) { | 967 if (length < old_length) { |
| 966 if (dict->requires_slow_elements()) { | 968 if (dict->requires_slow_elements()) { |
| 967 // Find last non-deletable element in range of elements to be | 969 // Find last non-deletable element in range of elements to be |
| 968 // deleted and adjust range accordingly. | 970 // deleted and adjust range accordingly. |
| 969 for (int entry = 0; entry < capacity; entry++) { | 971 for (int entry = 0; entry < capacity; entry++) { |
| 970 DisallowHeapAllocation no_gc; | 972 DisallowHeapAllocation no_gc; |
| 971 Object* index = dict->KeyAt(entry); | 973 Object* index = dict->KeyAt(entry); |
| (...skipping 319 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1291 args, push_size, AT_END); | 1293 args, push_size, AT_END); |
| 1292 } | 1294 } |
| 1293 | 1295 |
| 1294 static uint32_t UnshiftImpl(Handle<JSArray> receiver, | 1296 static uint32_t UnshiftImpl(Handle<JSArray> receiver, |
| 1295 Handle<FixedArrayBase> backing_store, | 1297 Handle<FixedArrayBase> backing_store, |
| 1296 Arguments* args, uint32_t unshift_size) { | 1298 Arguments* args, uint32_t unshift_size) { |
| 1297 return FastElementsAccessorSubclass::AddArguments( | 1299 return FastElementsAccessorSubclass::AddArguments( |
| 1298 receiver, backing_store, args, unshift_size, AT_START); | 1300 receiver, backing_store, args, unshift_size, AT_START); |
| 1299 } | 1301 } |
| 1300 | 1302 |
| 1301 static void MoveElements(Heap* heap, Handle<FixedArrayBase> backing_store, | 1303 static void MoveElements(Isolate* isolate, Handle<JSArray> receiver, |
| 1302 int dst_index, int src_index, int len, | 1304 Handle<FixedArrayBase> backing_store, int dst_index, |
| 1303 int hole_start, int hole_end) { | 1305 int src_index, int len, int hole_start, |
| 1306 int hole_end) { |
| 1304 UNREACHABLE(); | 1307 UNREACHABLE(); |
| 1305 } | 1308 } |
| 1306 | 1309 |
| 1307 static Handle<JSArray> SliceImpl(Handle<JSObject> receiver, | 1310 static Handle<JSArray> SliceImpl(Handle<JSObject> receiver, |
| 1308 Handle<FixedArrayBase> backing_store, | 1311 Handle<FixedArrayBase> backing_store, |
| 1309 uint32_t start, uint32_t end) { | 1312 uint32_t start, uint32_t end) { |
| 1310 DCHECK(start < end); | 1313 DCHECK(start < end); |
| 1311 Isolate* isolate = receiver->GetIsolate(); | 1314 Isolate* isolate = receiver->GetIsolate(); |
| 1312 int result_len = end - start; | 1315 int result_len = end - start; |
| 1313 Handle<JSArray> result_array = isolate->factory()->NewJSArray( | 1316 Handle<JSArray> result_array = isolate->factory()->NewJSArray( |
| (...skipping 28 matching lines...) Expand all Loading... |
| 1342 KindTraits::Kind, delete_count, delete_count); | 1345 KindTraits::Kind, delete_count, delete_count); |
| 1343 if (delete_count > 0) { | 1346 if (delete_count > 0) { |
| 1344 DisallowHeapAllocation no_gc; | 1347 DisallowHeapAllocation no_gc; |
| 1345 FastElementsAccessorSubclass::CopyElementsImpl( | 1348 FastElementsAccessorSubclass::CopyElementsImpl( |
| 1346 *backing_store, start, deleted_elements->elements(), KindTraits::Kind, | 1349 *backing_store, start, deleted_elements->elements(), KindTraits::Kind, |
| 1347 0, kPackedSizeNotKnown, delete_count); | 1350 0, kPackedSizeNotKnown, delete_count); |
| 1348 } | 1351 } |
| 1349 | 1352 |
| 1350 // Delete and move elements to make space for add_count new elements. | 1353 // Delete and move elements to make space for add_count new elements. |
| 1351 if (add_count < delete_count) { | 1354 if (add_count < delete_count) { |
| 1352 FastElementsAccessorSubclass::SpliceShrinkStep(backing_store, heap, start, | 1355 FastElementsAccessorSubclass::SpliceShrinkStep( |
| 1353 delete_count, add_count, | 1356 isolate, receiver, backing_store, start, delete_count, add_count, |
| 1354 length, new_length); | 1357 length, new_length); |
| 1355 } else if (add_count > delete_count) { | 1358 } else if (add_count > delete_count) { |
| 1356 backing_store = FastElementsAccessorSubclass::SpliceGrowStep( | 1359 backing_store = FastElementsAccessorSubclass::SpliceGrowStep( |
| 1357 receiver, backing_store, isolate, heap, start, delete_count, | 1360 isolate, receiver, backing_store, start, delete_count, add_count, |
| 1358 add_count, length, new_length); | 1361 length, new_length); |
| 1359 } | 1362 } |
| 1360 | 1363 |
| 1361 // Copy over the arguments. | 1364 // Copy over the arguments. |
| 1362 FastElementsAccessorSubclass::CopyArguments(args, backing_store, add_count, | 1365 FastElementsAccessorSubclass::CopyArguments(args, backing_store, add_count, |
| 1363 3, start); | 1366 3, start); |
| 1364 | 1367 |
| 1365 receiver->set_length(Smi::FromInt(new_length)); | 1368 receiver->set_length(Smi::FromInt(new_length)); |
| 1366 FastElementsAccessorSubclass::TryTransitionResultArrayToPacked( | 1369 FastElementsAccessorSubclass::TryTransitionResultArrayToPacked( |
| 1367 deleted_elements); | 1370 deleted_elements); |
| 1368 return deleted_elements; | 1371 return deleted_elements; |
| 1369 } | 1372 } |
| 1370 | 1373 |
| 1371 private: | 1374 private: |
| 1372 static void SpliceShrinkStep(Handle<FixedArrayBase> backing_store, Heap* heap, | 1375 // SpliceShrinkStep might modify the backing_store. |
| 1376 static void SpliceShrinkStep(Isolate* isolate, Handle<JSArray> receiver, |
| 1377 Handle<FixedArrayBase> backing_store, |
| 1373 uint32_t start, uint32_t delete_count, | 1378 uint32_t start, uint32_t delete_count, |
| 1374 uint32_t add_count, uint32_t len, | 1379 uint32_t add_count, uint32_t len, |
| 1375 uint32_t new_length) { | 1380 uint32_t new_length) { |
| 1376 const int move_left_count = len - delete_count - start; | 1381 const int move_left_count = len - delete_count - start; |
| 1377 const int move_left_dst_index = start + add_count; | 1382 const int move_left_dst_index = start + add_count; |
| 1378 FastElementsAccessorSubclass::MoveElements( | 1383 FastElementsAccessorSubclass::MoveElements( |
| 1379 heap, backing_store, move_left_dst_index, start + delete_count, | 1384 isolate, receiver, backing_store, move_left_dst_index, |
| 1380 move_left_count, new_length, len); | 1385 start + delete_count, move_left_count, new_length, len); |
| 1381 } | 1386 } |
| 1382 | 1387 |
| 1383 | 1388 // SpliceGrowStep might modify the backing_store. |
| 1384 static Handle<FixedArrayBase> SpliceGrowStep( | 1389 static Handle<FixedArrayBase> SpliceGrowStep( |
| 1385 Handle<JSArray> receiver, Handle<FixedArrayBase> backing_store, | 1390 Isolate* isolate, Handle<JSArray> receiver, |
| 1386 Isolate* isolate, Heap* heap, uint32_t start, uint32_t delete_count, | 1391 Handle<FixedArrayBase> backing_store, uint32_t start, |
| 1387 uint32_t add_count, uint32_t length, uint32_t new_length) { | 1392 uint32_t delete_count, uint32_t add_count, uint32_t length, |
| 1393 uint32_t new_length) { |
| 1388 // Check we do not overflow the new_length. | 1394 // Check we do not overflow the new_length. |
| 1389 DCHECK((add_count - delete_count) <= (Smi::kMaxValue - length)); | 1395 DCHECK((add_count - delete_count) <= (Smi::kMaxValue - length)); |
| 1390 // Check if backing_store is big enough. | 1396 // Check if backing_store is big enough. |
| 1391 if (new_length <= static_cast<uint32_t>(backing_store->length())) { | 1397 if (new_length <= static_cast<uint32_t>(backing_store->length())) { |
| 1392 FastElementsAccessorSubclass::MoveElements( | 1398 FastElementsAccessorSubclass::MoveElements( |
| 1393 heap, backing_store, start + add_count, start + delete_count, | 1399 isolate, receiver, backing_store, start + add_count, |
| 1394 (length - delete_count - start), 0, 0); | 1400 start + delete_count, (length - delete_count - start), 0, 0); |
| 1401 // MoveElements updates the backing_store in-place. |
| 1395 return backing_store; | 1402 return backing_store; |
| 1396 } | 1403 } |
| 1397 // New backing storage is needed. | 1404 // New backing storage is needed. |
| 1398 int capacity = JSObject::NewElementsCapacity(new_length); | 1405 int capacity = JSObject::NewElementsCapacity(new_length); |
| 1399 // Partially copy all elements up to start. | 1406 // Partially copy all elements up to start. |
| 1400 Handle<FixedArrayBase> new_elms = | 1407 Handle<FixedArrayBase> new_elms = |
| 1401 FastElementsAccessorSubclass::ConvertElementsWithCapacity( | 1408 FastElementsAccessorSubclass::ConvertElementsWithCapacity( |
| 1402 receiver, backing_store, KindTraits::Kind, capacity, start); | 1409 receiver, backing_store, KindTraits::Kind, capacity, start); |
| 1403 // Copy the trailing elements after start + delete_count | 1410 // Copy the trailing elements after start + delete_count |
| 1404 FastElementsAccessorSubclass::CopyElementsImpl( | 1411 FastElementsAccessorSubclass::CopyElementsImpl( |
| 1405 *backing_store, start + delete_count, *new_elms, KindTraits::Kind, | 1412 *backing_store, start + delete_count, *new_elms, KindTraits::Kind, |
| 1406 start + add_count, kPackedSizeNotKnown, | 1413 start + add_count, kPackedSizeNotKnown, |
| 1407 ElementsAccessor::kCopyToEndAndInitializeToHole); | 1414 ElementsAccessor::kCopyToEndAndInitializeToHole); |
| 1408 receiver->set_elements(*new_elms); | 1415 receiver->set_elements(*new_elms); |
| 1409 return new_elms; | 1416 return new_elms; |
| 1410 } | 1417 } |
| 1411 | 1418 |
| 1412 static Handle<Object> RemoveElement(Handle<JSArray> receiver, | 1419 static Handle<Object> RemoveElement(Handle<JSArray> receiver, |
| 1413 Handle<FixedArrayBase> backing_store, | 1420 Handle<FixedArrayBase> backing_store, |
| 1414 Where remove_position) { | 1421 Where remove_position) { |
| 1422 Isolate* isolate = receiver->GetIsolate(); |
| 1415 uint32_t length = | 1423 uint32_t length = |
| 1416 static_cast<uint32_t>(Smi::cast(receiver->length())->value()); | 1424 static_cast<uint32_t>(Smi::cast(receiver->length())->value()); |
| 1417 Isolate* isolate = receiver->GetIsolate(); | |
| 1418 DCHECK(length > 0); | 1425 DCHECK(length > 0); |
| 1419 int new_length = length - 1; | 1426 int new_length = length - 1; |
| 1420 int remove_index = remove_position == AT_START ? 0 : new_length; | 1427 int remove_index = remove_position == AT_START ? 0 : new_length; |
| 1421 Handle<Object> result = | 1428 Handle<Object> result = |
| 1422 FastElementsAccessorSubclass::GetImpl(backing_store, remove_index); | 1429 FastElementsAccessorSubclass::GetImpl(backing_store, remove_index); |
| 1423 if (remove_position == AT_START) { | 1430 if (remove_position == AT_START) { |
| 1424 Heap* heap = isolate->heap(); | 1431 FastElementsAccessorSubclass::MoveElements( |
| 1425 FastElementsAccessorSubclass::MoveElements(heap, backing_store, 0, 1, | 1432 isolate, receiver, backing_store, 0, 1, new_length, 0, 0); |
| 1426 new_length, 0, 0); | |
| 1427 } | 1433 } |
| 1428 FastElementsAccessorSubclass::SetLengthImpl(receiver, new_length, | 1434 FastElementsAccessorSubclass::SetLengthImpl(isolate, receiver, new_length, |
| 1429 backing_store); | 1435 backing_store); |
| 1430 | 1436 |
| 1431 if (IsHoleyElementsKind(KindTraits::Kind) && result->IsTheHole()) { | 1437 if (IsHoleyElementsKind(KindTraits::Kind) && result->IsTheHole()) { |
| 1432 return receiver->GetIsolate()->factory()->undefined_value(); | 1438 return receiver->GetIsolate()->factory()->undefined_value(); |
| 1433 } | 1439 } |
| 1434 return result; | 1440 return result; |
| 1435 } | 1441 } |
| 1436 | 1442 |
| 1437 static uint32_t AddArguments(Handle<JSArray> receiver, | 1443 static uint32_t AddArguments(Handle<JSArray> receiver, |
| 1438 Handle<FixedArrayBase> backing_store, | 1444 Handle<FixedArrayBase> backing_store, |
| (...skipping 13 matching lines...) Expand all Loading... |
| 1452 int copy_dst_index = remove_position == AT_START ? add_size : 0; | 1458 int copy_dst_index = remove_position == AT_START ? add_size : 0; |
| 1453 // Copy over all objects to a new backing_store. | 1459 // Copy over all objects to a new backing_store. |
| 1454 backing_store = FastElementsAccessorSubclass::ConvertElementsWithCapacity( | 1460 backing_store = FastElementsAccessorSubclass::ConvertElementsWithCapacity( |
| 1455 receiver, backing_store, KindTraits::Kind, capacity, 0, | 1461 receiver, backing_store, KindTraits::Kind, capacity, 0, |
| 1456 copy_dst_index, ElementsAccessor::kCopyToEndAndInitializeToHole); | 1462 copy_dst_index, ElementsAccessor::kCopyToEndAndInitializeToHole); |
| 1457 receiver->set_elements(*backing_store); | 1463 receiver->set_elements(*backing_store); |
| 1458 } else if (remove_position == AT_START) { | 1464 } else if (remove_position == AT_START) { |
| 1459 // If the backing store has enough capacity and we add elements to the | 1465 // If the backing store has enough capacity and we add elements to the |
| 1460 // start we have to shift the existing objects. | 1466 // start we have to shift the existing objects. |
| 1461 Isolate* isolate = receiver->GetIsolate(); | 1467 Isolate* isolate = receiver->GetIsolate(); |
| 1462 FastElementsAccessorSubclass::MoveElements(isolate->heap(), backing_store, | 1468 FastElementsAccessorSubclass::MoveElements( |
| 1463 add_size, 0, length, 0, 0); | 1469 isolate, receiver, backing_store, add_size, 0, length, 0, 0); |
| 1464 } | 1470 } |
| 1465 | 1471 |
| 1466 int insertion_index = remove_position == AT_START ? 0 : length; | 1472 int insertion_index = remove_position == AT_START ? 0 : length; |
| 1467 // Copy the arguments to the start. | 1473 // Copy the arguments to the start. |
| 1468 FastElementsAccessorSubclass::CopyArguments(args, backing_store, add_size, | 1474 FastElementsAccessorSubclass::CopyArguments(args, backing_store, add_size, |
| 1469 1, insertion_index); | 1475 1, insertion_index); |
| 1470 // Set the length. | 1476 // Set the length. |
| 1471 receiver->set_length(Smi::FromInt(new_length)); | 1477 receiver->set_length(Smi::FromInt(new_length)); |
| 1472 return new_length; | 1478 return new_length; |
| 1473 } | 1479 } |
| (...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1506 Object* value, WriteBarrierMode mode) { | 1512 Object* value, WriteBarrierMode mode) { |
| 1507 FixedArray::cast(backing_store)->set(entry, value, mode); | 1513 FixedArray::cast(backing_store)->set(entry, value, mode); |
| 1508 } | 1514 } |
| 1509 | 1515 |
| 1510 static Object* GetRaw(FixedArray* backing_store, uint32_t entry) { | 1516 static Object* GetRaw(FixedArray* backing_store, uint32_t entry) { |
| 1511 uint32_t index = FastElementsAccessorSubclass::GetIndexForEntryImpl( | 1517 uint32_t index = FastElementsAccessorSubclass::GetIndexForEntryImpl( |
| 1512 backing_store, entry); | 1518 backing_store, entry); |
| 1513 return backing_store->get(index); | 1519 return backing_store->get(index); |
| 1514 } | 1520 } |
| 1515 | 1521 |
| 1516 static void MoveElements(Heap* heap, Handle<FixedArrayBase> backing_store, | 1522 static void MoveElements(Isolate* isolate, Handle<JSArray> receiver, |
| 1517 int dst_index, int src_index, int len, | 1523 Handle<FixedArrayBase> backing_store, int dst_index, |
| 1518 int hole_start, int hole_end) { | 1524 int src_index, int len, int hole_start, |
| 1525 int hole_end) { |
| 1526 Heap* heap = isolate->heap(); |
| 1519 Handle<FixedArray> dst_elms = Handle<FixedArray>::cast(backing_store); | 1527 Handle<FixedArray> dst_elms = Handle<FixedArray>::cast(backing_store); |
| 1520 if (len != 0) { | 1528 if (heap->CanMoveObjectStart(*dst_elms) && dst_index == 0) { |
| 1529 // Update all the copies of this backing_store handle. |
| 1530 *dst_elms.location() = |
| 1531 FixedArray::cast(heap->LeftTrimFixedArray(*dst_elms, src_index)); |
| 1532 receiver->set_elements(*dst_elms); |
| 1533 // Adjust the hole offset as the array has been shrunk. |
| 1534 hole_end -= src_index; |
| 1535 DCHECK_LE(hole_start, backing_store->length()); |
| 1536 DCHECK_LE(hole_end, backing_store->length()); |
| 1537 } else if (len != 0) { |
| 1521 DisallowHeapAllocation no_gc; | 1538 DisallowHeapAllocation no_gc; |
| 1522 heap->MoveElements(*dst_elms, dst_index, src_index, len); | 1539 heap->MoveElements(*dst_elms, dst_index, src_index, len); |
| 1523 } | 1540 } |
| 1524 if (hole_start != hole_end) { | 1541 if (hole_start != hole_end) { |
| 1525 dst_elms->FillWithHoles(hole_start, hole_end); | 1542 dst_elms->FillWithHoles(hole_start, hole_end); |
| 1526 } | 1543 } |
| 1527 } | 1544 } |
| 1528 | 1545 |
| 1529 // NOTE: this method violates the handlified function signature convention: | 1546 // NOTE: this method violates the handlified function signature convention: |
| 1530 // raw pointer parameters in the function that allocates. | 1547 // raw pointer parameters in the function that allocates. |
| (...skipping 98 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1629 static inline void SetImpl(FixedArrayBase* backing_store, uint32_t entry, | 1646 static inline void SetImpl(FixedArrayBase* backing_store, uint32_t entry, |
| 1630 Object* value) { | 1647 Object* value) { |
| 1631 FixedDoubleArray::cast(backing_store)->set(entry, value->Number()); | 1648 FixedDoubleArray::cast(backing_store)->set(entry, value->Number()); |
| 1632 } | 1649 } |
| 1633 | 1650 |
| 1634 static inline void SetImpl(FixedArrayBase* backing_store, uint32_t entry, | 1651 static inline void SetImpl(FixedArrayBase* backing_store, uint32_t entry, |
| 1635 Object* value, WriteBarrierMode mode) { | 1652 Object* value, WriteBarrierMode mode) { |
| 1636 FixedDoubleArray::cast(backing_store)->set(entry, value->Number()); | 1653 FixedDoubleArray::cast(backing_store)->set(entry, value->Number()); |
| 1637 } | 1654 } |
| 1638 | 1655 |
| 1639 static void MoveElements(Heap* heap, Handle<FixedArrayBase> backing_store, | 1656 static void MoveElements(Isolate* isolate, Handle<JSArray> receiver, |
| 1640 int dst_index, int src_index, int len, | 1657 Handle<FixedArrayBase> backing_store, int dst_index, |
| 1641 int hole_start, int hole_end) { | 1658 int src_index, int len, int hole_start, |
| 1659 int hole_end) { |
| 1660 Heap* heap = isolate->heap(); |
| 1642 Handle<FixedDoubleArray> dst_elms = | 1661 Handle<FixedDoubleArray> dst_elms = |
| 1643 Handle<FixedDoubleArray>::cast(backing_store); | 1662 Handle<FixedDoubleArray>::cast(backing_store); |
| 1644 if (len != 0) { | 1663 if (heap->CanMoveObjectStart(*dst_elms) && dst_index == 0) { |
| 1664 // Update all the copies of this backing_store handle. |
| 1665 *dst_elms.location() = FixedDoubleArray::cast( |
| 1666 heap->LeftTrimFixedArray(*dst_elms, src_index)); |
| 1667 receiver->set_elements(*dst_elms); |
| 1668 // Adjust the hole offset as the array has been shrunk. |
| 1669 hole_end -= src_index; |
| 1670 DCHECK_LE(hole_start, backing_store->length()); |
| 1671 DCHECK_LE(hole_end, backing_store->length()); |
| 1672 } else if (len != 0) { |
| 1645 MemMove(dst_elms->data_start() + dst_index, | 1673 MemMove(dst_elms->data_start() + dst_index, |
| 1646 dst_elms->data_start() + src_index, len * kDoubleSize); | 1674 dst_elms->data_start() + src_index, len * kDoubleSize); |
| 1647 } | 1675 } |
| 1648 if (hole_start != hole_end) { | 1676 if (hole_start != hole_end) { |
| 1649 dst_elms->FillWithHoles(hole_start, hole_end); | 1677 dst_elms->FillWithHoles(hole_start, hole_end); |
| 1650 } | 1678 } |
| 1651 } | 1679 } |
| 1652 | 1680 |
| 1653 static void CopyElementsImpl(FixedArrayBase* from, uint32_t from_start, | 1681 static void CopyElementsImpl(FixedArrayBase* from, uint32_t from_start, |
| 1654 FixedArrayBase* to, ElementsKind from_kind, | 1682 FixedArrayBase* to, ElementsKind from_kind, |
| (...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1740 uint32_t entry) { | 1768 uint32_t entry) { |
| 1741 uint32_t index = GetIndexForEntryImpl(*backing_store, entry); | 1769 uint32_t index = GetIndexForEntryImpl(*backing_store, entry); |
| 1742 return BackingStore::get(Handle<BackingStore>::cast(backing_store), index); | 1770 return BackingStore::get(Handle<BackingStore>::cast(backing_store), index); |
| 1743 } | 1771 } |
| 1744 | 1772 |
| 1745 static PropertyDetails GetDetailsImpl(FixedArrayBase* backing_store, | 1773 static PropertyDetails GetDetailsImpl(FixedArrayBase* backing_store, |
| 1746 uint32_t entry) { | 1774 uint32_t entry) { |
| 1747 return PropertyDetails(DONT_DELETE, DATA, 0, PropertyCellType::kNoCell); | 1775 return PropertyDetails(DONT_DELETE, DATA, 0, PropertyCellType::kNoCell); |
| 1748 } | 1776 } |
| 1749 | 1777 |
| 1750 static void SetLengthImpl(Handle<JSArray> array, uint32_t length, | 1778 static void SetLengthImpl(Isolate* isolate, Handle<JSArray> array, |
| 1779 uint32_t length, |
| 1751 Handle<FixedArrayBase> backing_store) { | 1780 Handle<FixedArrayBase> backing_store) { |
| 1752 // External arrays do not support changing their length. | 1781 // External arrays do not support changing their length. |
| 1753 UNREACHABLE(); | 1782 UNREACHABLE(); |
| 1754 } | 1783 } |
| 1755 | 1784 |
| 1756 static void DeleteImpl(Handle<JSObject> obj, uint32_t entry) { | 1785 static void DeleteImpl(Handle<JSObject> obj, uint32_t entry) { |
| 1757 UNREACHABLE(); | 1786 UNREACHABLE(); |
| 1758 } | 1787 } |
| 1759 | 1788 |
| 1760 static uint32_t GetIndexForEntryImpl(FixedArrayBase* backing_store, | 1789 static uint32_t GetIndexForEntryImpl(FixedArrayBase* backing_store, |
| (...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1854 Context* context = Context::cast(parameter_map->get(0)); | 1883 Context* context = Context::cast(parameter_map->get(0)); |
| 1855 int context_entry = alias->aliased_context_slot(); | 1884 int context_entry = alias->aliased_context_slot(); |
| 1856 DCHECK(!context->get(context_entry)->IsTheHole()); | 1885 DCHECK(!context->get(context_entry)->IsTheHole()); |
| 1857 context->set(context_entry, value); | 1886 context->set(context_entry, value); |
| 1858 } else { | 1887 } else { |
| 1859 ArgumentsAccessor::SetImpl(arguments, entry - length, value); | 1888 ArgumentsAccessor::SetImpl(arguments, entry - length, value); |
| 1860 } | 1889 } |
| 1861 } | 1890 } |
| 1862 } | 1891 } |
| 1863 | 1892 |
| 1864 static void SetLengthImpl(Handle<JSArray> array, uint32_t length, | 1893 static void SetLengthImpl(Isolate* isolate, Handle<JSArray> array, |
| 1894 uint32_t length, |
| 1865 Handle<FixedArrayBase> parameter_map) { | 1895 Handle<FixedArrayBase> parameter_map) { |
| 1866 // Sloppy arguments objects are not arrays. | 1896 // Sloppy arguments objects are not arrays. |
| 1867 UNREACHABLE(); | 1897 UNREACHABLE(); |
| 1868 } | 1898 } |
| 1869 | 1899 |
| 1870 static uint32_t GetCapacityImpl(JSObject* holder, | 1900 static uint32_t GetCapacityImpl(JSObject* holder, |
| 1871 FixedArrayBase* backing_store) { | 1901 FixedArrayBase* backing_store) { |
| 1872 FixedArray* parameter_map = FixedArray::cast(backing_store); | 1902 FixedArray* parameter_map = FixedArray::cast(backing_store); |
| 1873 FixedArrayBase* arguments = FixedArrayBase::cast(parameter_map->get(1)); | 1903 FixedArrayBase* arguments = FixedArrayBase::cast(parameter_map->get(1)); |
| 1874 return parameter_map->length() - 2 + | 1904 return parameter_map->length() - 2 + |
| (...skipping 456 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2331 } | 2361 } |
| 2332 } | 2362 } |
| 2333 | 2363 |
| 2334 DCHECK(j == result_len); | 2364 DCHECK(j == result_len); |
| 2335 return result_array; | 2365 return result_array; |
| 2336 } | 2366 } |
| 2337 | 2367 |
| 2338 ElementsAccessor** ElementsAccessor::elements_accessors_ = NULL; | 2368 ElementsAccessor** ElementsAccessor::elements_accessors_ = NULL; |
| 2339 } // namespace internal | 2369 } // namespace internal |
| 2340 } // namespace v8 | 2370 } // namespace v8 |
| OLD | NEW |