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 659 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
670 return ElementsAccessorSubclass::ShiftImpl(receiver, backing_store); | 670 return ElementsAccessorSubclass::ShiftImpl(receiver, backing_store); |
671 } | 671 } |
672 | 672 |
673 static Handle<Object> ShiftImpl(Handle<JSArray> receiver, | 673 static Handle<Object> ShiftImpl(Handle<JSArray> receiver, |
674 Handle<FixedArrayBase> backing_store) { | 674 Handle<FixedArrayBase> backing_store) { |
675 UNREACHABLE(); | 675 UNREACHABLE(); |
676 return Handle<Object>(); | 676 return Handle<Object>(); |
677 } | 677 } |
678 | 678 |
679 void SetLength(Handle<JSArray> array, uint32_t length) final { | 679 void SetLength(Handle<JSArray> array, uint32_t length) final { |
680 ElementsAccessorSubclass::SetLengthImpl(array, length, | 680 ElementsAccessorSubclass::SetLengthImpl(array->GetIsolate(), array, length, |
681 handle(array->elements())); | 681 handle(array->elements())); |
682 } | 682 } |
683 | 683 |
684 static void SetLengthImpl(Handle<JSArray> array, uint32_t length, | 684 static void SetLengthImpl(Isolate* isolate, Handle<JSArray> array, |
685 uint32_t length, | |
685 Handle<FixedArrayBase> backing_store) { | 686 Handle<FixedArrayBase> backing_store) { |
686 DCHECK(!array->SetLengthWouldNormalize(length)); | 687 DCHECK(!array->SetLengthWouldNormalize(length)); |
687 DCHECK(IsFastElementsKind(array->GetElementsKind())); | 688 DCHECK(IsFastElementsKind(array->GetElementsKind())); |
688 uint32_t old_length = 0; | 689 uint32_t old_length = 0; |
689 CHECK(array->length()->ToArrayIndex(&old_length)); | 690 CHECK(array->length()->ToArrayIndex(&old_length)); |
690 | 691 |
691 if (old_length < length) { | 692 if (old_length < length) { |
692 ElementsKind kind = array->GetElementsKind(); | 693 ElementsKind kind = array->GetElementsKind(); |
693 if (!IsFastHoleyElementsKind(kind)) { | 694 if (!IsFastHoleyElementsKind(kind)) { |
694 kind = GetHoleyElementsKind(kind); | 695 kind = GetHoleyElementsKind(kind); |
695 JSObject::TransitionElementsKind(array, kind); | 696 JSObject::TransitionElementsKind(array, kind); |
696 } | 697 } |
697 } | 698 } |
698 | 699 |
699 // Check whether the backing store should be shrunk. | 700 // Check whether the backing store should be shrunk. |
700 uint32_t capacity = backing_store->length(); | 701 uint32_t capacity = backing_store->length(); |
702 old_length = Min(old_length, capacity); | |
701 if (length == 0) { | 703 if (length == 0) { |
702 array->initialize_elements(); | 704 array->initialize_elements(); |
703 } else if (length <= capacity) { | 705 } else if (length <= capacity) { |
704 if (array->HasFastSmiOrObjectElements()) { | 706 if (array->HasFastSmiOrObjectElements()) { |
705 backing_store = JSObject::EnsureWritableFastElements(array); | 707 backing_store = JSObject::EnsureWritableFastElements(array); |
706 } | 708 } |
707 if (2 * length <= capacity) { | 709 if (2 * length <= capacity) { |
708 // If more than half the elements won't be used, trim the array. | 710 // If more than half the elements won't be used, trim the array. |
709 array->GetHeap()->RightTrimFixedArray<Heap::CONCURRENT_TO_SWEEPER>( | 711 isolate->heap()->RightTrimFixedArray<Heap::CONCURRENT_TO_SWEEPER>( |
710 *backing_store, capacity - length); | 712 *backing_store, capacity - length); |
711 } else { | 713 } else { |
712 // Otherwise, fill the unused tail with holes. | 714 // Otherwise, fill the unused tail with holes. |
713 for (uint32_t i = length; i < old_length; i++) { | 715 for (uint32_t i = length; i < old_length; i++) { |
714 BackingStore::cast(*backing_store)->set_the_hole(i); | 716 BackingStore::cast(*backing_store)->set_the_hole(i); |
715 } | 717 } |
716 } | 718 } |
717 } else { | 719 } else { |
718 // Check whether the backing store should be expanded. | 720 // Check whether the backing store should be expanded. |
719 capacity = Max(length, JSObject::NewElementsCapacity(capacity)); | 721 capacity = Max(length, JSObject::NewElementsCapacity(capacity)); |
(...skipping 245 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
965 | 967 |
966 | 968 |
967 class DictionaryElementsAccessor | 969 class DictionaryElementsAccessor |
968 : public ElementsAccessorBase<DictionaryElementsAccessor, | 970 : public ElementsAccessorBase<DictionaryElementsAccessor, |
969 ElementsKindTraits<DICTIONARY_ELEMENTS> > { | 971 ElementsKindTraits<DICTIONARY_ELEMENTS> > { |
970 public: | 972 public: |
971 explicit DictionaryElementsAccessor(const char* name) | 973 explicit DictionaryElementsAccessor(const char* name) |
972 : ElementsAccessorBase<DictionaryElementsAccessor, | 974 : ElementsAccessorBase<DictionaryElementsAccessor, |
973 ElementsKindTraits<DICTIONARY_ELEMENTS> >(name) {} | 975 ElementsKindTraits<DICTIONARY_ELEMENTS> >(name) {} |
974 | 976 |
975 static void SetLengthImpl(Handle<JSArray> array, uint32_t length, | 977 static void SetLengthImpl(Isolate* isolate, Handle<JSArray> array, |
978 uint32_t length, | |
976 Handle<FixedArrayBase> backing_store) { | 979 Handle<FixedArrayBase> backing_store) { |
977 Handle<SeededNumberDictionary> dict = | 980 Handle<SeededNumberDictionary> dict = |
978 Handle<SeededNumberDictionary>::cast(backing_store); | 981 Handle<SeededNumberDictionary>::cast(backing_store); |
979 Isolate* isolate = array->GetIsolate(); | |
980 int capacity = dict->Capacity(); | 982 int capacity = dict->Capacity(); |
981 uint32_t old_length = 0; | 983 uint32_t old_length = 0; |
982 CHECK(array->length()->ToArrayLength(&old_length)); | 984 CHECK(array->length()->ToArrayLength(&old_length)); |
983 if (length < old_length) { | 985 if (length < old_length) { |
984 if (dict->requires_slow_elements()) { | 986 if (dict->requires_slow_elements()) { |
985 // Find last non-deletable element in range of elements to be | 987 // Find last non-deletable element in range of elements to be |
986 // deleted and adjust range accordingly. | 988 // deleted and adjust range accordingly. |
987 for (int entry = 0; entry < capacity; entry++) { | 989 for (int entry = 0; entry < capacity; entry++) { |
988 DisallowHeapAllocation no_gc; | 990 DisallowHeapAllocation no_gc; |
989 Object* index = dict->KeyAt(entry); | 991 Object* index = dict->KeyAt(entry); |
(...skipping 355 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1345 args, push_size, AT_END); | 1347 args, push_size, AT_END); |
1346 } | 1348 } |
1347 | 1349 |
1348 static uint32_t UnshiftImpl(Handle<JSArray> receiver, | 1350 static uint32_t UnshiftImpl(Handle<JSArray> receiver, |
1349 Handle<FixedArrayBase> backing_store, | 1351 Handle<FixedArrayBase> backing_store, |
1350 Arguments* args, uint32_t unshift_size) { | 1352 Arguments* args, uint32_t unshift_size) { |
1351 return FastElementsAccessorSubclass::AddArguments( | 1353 return FastElementsAccessorSubclass::AddArguments( |
1352 receiver, backing_store, args, unshift_size, AT_START); | 1354 receiver, backing_store, args, unshift_size, AT_START); |
1353 } | 1355 } |
1354 | 1356 |
1355 static void MoveElements(Heap* heap, Handle<FixedArrayBase> backing_store, | 1357 static Handle<FixedArrayBase> MoveElements( |
1356 int dst_index, int src_index, int len, | 1358 Isolate* isolate, Handle<JSArray> receiver, |
1357 int hole_start, int hole_end) { | 1359 Handle<FixedArrayBase> backing_store, int dst_index, int src_index, |
1360 int len, int hole_start, int hole_end) { | |
1358 UNREACHABLE(); | 1361 UNREACHABLE(); |
1362 return backing_store; | |
1359 } | 1363 } |
1360 | 1364 |
1361 static Handle<JSArray> SliceImpl(Handle<JSObject> receiver, | 1365 static Handle<JSArray> SliceImpl(Handle<JSObject> receiver, |
1362 Handle<FixedArrayBase> backing_store, | 1366 Handle<FixedArrayBase> backing_store, |
1363 uint32_t start, uint32_t end) { | 1367 uint32_t start, uint32_t end) { |
1364 DCHECK(start < end); | 1368 DCHECK(start < end); |
1365 Isolate* isolate = receiver->GetIsolate(); | 1369 Isolate* isolate = receiver->GetIsolate(); |
1366 int result_len = end - start; | 1370 int result_len = end - start; |
1367 Handle<JSArray> result_array = isolate->factory()->NewJSArray( | 1371 Handle<JSArray> result_array = isolate->factory()->NewJSArray( |
1368 KindTraits::Kind, result_len, result_len); | 1372 KindTraits::Kind, result_len, result_len); |
(...skipping 27 matching lines...) Expand all Loading... | |
1396 KindTraits::Kind, delete_count, delete_count); | 1400 KindTraits::Kind, delete_count, delete_count); |
1397 if (delete_count > 0) { | 1401 if (delete_count > 0) { |
1398 DisallowHeapAllocation no_gc; | 1402 DisallowHeapAllocation no_gc; |
1399 FastElementsAccessorSubclass::CopyElementsImpl( | 1403 FastElementsAccessorSubclass::CopyElementsImpl( |
1400 *backing_store, start, deleted_elements->elements(), KindTraits::Kind, | 1404 *backing_store, start, deleted_elements->elements(), KindTraits::Kind, |
1401 0, kPackedSizeNotKnown, delete_count); | 1405 0, kPackedSizeNotKnown, delete_count); |
1402 } | 1406 } |
1403 | 1407 |
1404 // Delete and move elements to make space for add_count new elements. | 1408 // Delete and move elements to make space for add_count new elements. |
1405 if (add_count < delete_count) { | 1409 if (add_count < delete_count) { |
1406 FastElementsAccessorSubclass::SpliceShrinkStep(backing_store, heap, start, | 1410 backing_store = FastElementsAccessorSubclass::SpliceShrinkStep( |
1407 delete_count, add_count, | 1411 isolate, receiver, backing_store, start, delete_count, add_count, |
1408 length, new_length); | 1412 length, new_length); |
1409 } else if (add_count > delete_count) { | 1413 } else if (add_count > delete_count) { |
1410 backing_store = FastElementsAccessorSubclass::SpliceGrowStep( | 1414 backing_store = FastElementsAccessorSubclass::SpliceGrowStep( |
1411 receiver, backing_store, isolate, heap, start, delete_count, | 1415 isolate, receiver, backing_store, start, delete_count, add_count, |
1412 add_count, length, new_length); | 1416 length, new_length); |
1413 } | 1417 } |
1414 | 1418 |
1415 // Copy over the arguments. | 1419 // Copy over the arguments. |
1416 FastElementsAccessorSubclass::CopyArguments(args, backing_store, add_count, | 1420 FastElementsAccessorSubclass::CopyArguments(args, backing_store, add_count, |
1417 3, start); | 1421 3, start); |
1418 | 1422 |
1419 receiver->set_length(Smi::FromInt(new_length)); | 1423 receiver->set_length(Smi::FromInt(new_length)); |
1420 FastElementsAccessorSubclass::TryTransitionResultArrayToPacked( | 1424 FastElementsAccessorSubclass::TryTransitionResultArrayToPacked( |
1421 deleted_elements); | 1425 deleted_elements); |
1422 return deleted_elements; | 1426 return deleted_elements; |
1423 } | 1427 } |
1424 | 1428 |
1425 private: | 1429 private: |
1426 static void SpliceShrinkStep(Handle<FixedArrayBase> backing_store, Heap* heap, | 1430 static Handle<FixedArrayBase> SpliceShrinkStep( |
1427 uint32_t start, uint32_t delete_count, | 1431 Isolate* isolate, Handle<JSArray> receiver, |
1428 uint32_t add_count, uint32_t len, | 1432 Handle<FixedArrayBase> backing_store, uint32_t start, |
1429 uint32_t new_length) { | 1433 uint32_t delete_count, uint32_t add_count, uint32_t len, |
1434 uint32_t new_length) { | |
1430 const int move_left_count = len - delete_count - start; | 1435 const int move_left_count = len - delete_count - start; |
1431 const int move_left_dst_index = start + add_count; | 1436 const int move_left_dst_index = start + add_count; |
1432 FastElementsAccessorSubclass::MoveElements( | 1437 return FastElementsAccessorSubclass::MoveElements( |
1433 heap, backing_store, move_left_dst_index, start + delete_count, | 1438 isolate, receiver, backing_store, move_left_dst_index, |
1434 move_left_count, new_length, len); | 1439 start + delete_count, move_left_count, new_length, len); |
1435 } | 1440 } |
1436 | 1441 |
1437 | 1442 |
1438 static Handle<FixedArrayBase> SpliceGrowStep( | 1443 static Handle<FixedArrayBase> SpliceGrowStep( |
1439 Handle<JSArray> receiver, Handle<FixedArrayBase> backing_store, | 1444 Isolate* isolate, Handle<JSArray> receiver, |
1440 Isolate* isolate, Heap* heap, uint32_t start, uint32_t delete_count, | 1445 Handle<FixedArrayBase> backing_store, uint32_t start, |
1441 uint32_t add_count, uint32_t length, uint32_t new_length) { | 1446 uint32_t delete_count, uint32_t add_count, uint32_t length, |
1447 uint32_t new_length) { | |
1442 // Check we do not overflow the new_length. | 1448 // Check we do not overflow the new_length. |
1443 DCHECK((add_count - delete_count) <= (Smi::kMaxValue - length)); | 1449 DCHECK((add_count - delete_count) <= (Smi::kMaxValue - length)); |
1444 // Check if backing_store is big enough. | 1450 // Check if backing_store is big enough. |
1445 if (new_length <= static_cast<uint32_t>(backing_store->length())) { | 1451 if (new_length <= static_cast<uint32_t>(backing_store->length())) { |
1446 FastElementsAccessorSubclass::MoveElements( | 1452 return FastElementsAccessorSubclass::MoveElements( |
1447 heap, backing_store, start + add_count, start + delete_count, | 1453 isolate, receiver, backing_store, start + add_count, |
1448 (length - delete_count - start), 0, 0); | 1454 start + delete_count, (length - delete_count - start), 0, 0); |
1449 return backing_store; | |
1450 } | 1455 } |
1451 // New backing storage is needed. | 1456 // New backing storage is needed. |
1452 int capacity = JSObject::NewElementsCapacity(new_length); | 1457 int capacity = JSObject::NewElementsCapacity(new_length); |
1453 // Partially copy all elements up to start. | 1458 // Partially copy all elements up to start. |
1454 Handle<FixedArrayBase> new_elms = | 1459 Handle<FixedArrayBase> new_elms = |
1455 FastElementsAccessorSubclass::ConvertElementsWithCapacity( | 1460 FastElementsAccessorSubclass::ConvertElementsWithCapacity( |
1456 receiver, backing_store, KindTraits::Kind, capacity, start); | 1461 receiver, backing_store, KindTraits::Kind, capacity, start); |
1457 // Copy the trailing elements after start + delete_count | 1462 // Copy the trailing elements after start + delete_count |
1458 FastElementsAccessorSubclass::CopyElementsImpl( | 1463 FastElementsAccessorSubclass::CopyElementsImpl( |
1459 *backing_store, start + delete_count, *new_elms, KindTraits::Kind, | 1464 *backing_store, start + delete_count, *new_elms, KindTraits::Kind, |
1460 start + add_count, kPackedSizeNotKnown, | 1465 start + add_count, kPackedSizeNotKnown, |
1461 ElementsAccessor::kCopyToEndAndInitializeToHole); | 1466 ElementsAccessor::kCopyToEndAndInitializeToHole); |
1462 receiver->set_elements(*new_elms); | 1467 receiver->set_elements(*new_elms); |
1463 return new_elms; | 1468 return new_elms; |
1464 } | 1469 } |
1465 | 1470 |
1466 static Handle<Object> RemoveElement(Handle<JSArray> receiver, | 1471 static Handle<Object> RemoveElement(Handle<JSArray> receiver, |
1467 Handle<FixedArrayBase> backing_store, | 1472 Handle<FixedArrayBase> backing_store, |
1468 Where remove_position) { | 1473 Where remove_position) { |
1474 Isolate* isolate = receiver->GetIsolate(); | |
1469 uint32_t length = | 1475 uint32_t length = |
1470 static_cast<uint32_t>(Smi::cast(receiver->length())->value()); | 1476 static_cast<uint32_t>(Smi::cast(receiver->length())->value()); |
1471 Isolate* isolate = receiver->GetIsolate(); | |
1472 DCHECK(length > 0); | 1477 DCHECK(length > 0); |
1473 int new_length = length - 1; | 1478 int new_length = length - 1; |
1474 int remove_index = remove_position == AT_START ? 0 : new_length; | 1479 int remove_index = remove_position == AT_START ? 0 : new_length; |
1475 Handle<Object> result = | 1480 Handle<Object> result = |
1476 FastElementsAccessorSubclass::GetImpl(backing_store, remove_index); | 1481 FastElementsAccessorSubclass::GetImpl(backing_store, remove_index); |
1477 if (remove_position == AT_START) { | 1482 if (remove_position == AT_START) { |
1478 Heap* heap = isolate->heap(); | 1483 backing_store = FastElementsAccessorSubclass::MoveElements( |
1479 FastElementsAccessorSubclass::MoveElements(heap, backing_store, 0, 1, | 1484 isolate, receiver, backing_store, 0, 1, new_length, 0, 0); |
1480 new_length, 0, 0); | |
1481 } | 1485 } |
1482 FastElementsAccessorSubclass::SetLengthImpl(receiver, new_length, | 1486 FastElementsAccessorSubclass::SetLengthImpl(isolate, receiver, new_length, |
1483 backing_store); | 1487 backing_store); |
1484 | 1488 |
1485 if (IsHoleyElementsKind(KindTraits::Kind) && result->IsTheHole()) { | 1489 if (IsHoleyElementsKind(KindTraits::Kind) && result->IsTheHole()) { |
1486 return receiver->GetIsolate()->factory()->undefined_value(); | 1490 return receiver->GetIsolate()->factory()->undefined_value(); |
1487 } | 1491 } |
1488 return result; | 1492 return result; |
1489 } | 1493 } |
1490 | 1494 |
1491 static uint32_t AddArguments(Handle<JSArray> receiver, | 1495 static uint32_t AddArguments(Handle<JSArray> receiver, |
1492 Handle<FixedArrayBase> backing_store, | 1496 Handle<FixedArrayBase> backing_store, |
(...skipping 13 matching lines...) Expand all Loading... | |
1506 int copy_dst_index = remove_position == AT_START ? add_size : 0; | 1510 int copy_dst_index = remove_position == AT_START ? add_size : 0; |
1507 // Copy over all objects to a new backing_store. | 1511 // Copy over all objects to a new backing_store. |
1508 backing_store = FastElementsAccessorSubclass::ConvertElementsWithCapacity( | 1512 backing_store = FastElementsAccessorSubclass::ConvertElementsWithCapacity( |
1509 receiver, backing_store, KindTraits::Kind, capacity, 0, | 1513 receiver, backing_store, KindTraits::Kind, capacity, 0, |
1510 copy_dst_index, ElementsAccessor::kCopyToEndAndInitializeToHole); | 1514 copy_dst_index, ElementsAccessor::kCopyToEndAndInitializeToHole); |
1511 receiver->set_elements(*backing_store); | 1515 receiver->set_elements(*backing_store); |
1512 } else if (remove_position == AT_START) { | 1516 } else if (remove_position == AT_START) { |
1513 // If the backing store has enough capacity and we add elements to the | 1517 // If the backing store has enough capacity and we add elements to the |
1514 // start we have to shift the existing objects. | 1518 // start we have to shift the existing objects. |
1515 Isolate* isolate = receiver->GetIsolate(); | 1519 Isolate* isolate = receiver->GetIsolate(); |
1516 FastElementsAccessorSubclass::MoveElements(isolate->heap(), backing_store, | 1520 backing_store = FastElementsAccessorSubclass::MoveElements( |
1517 add_size, 0, length, 0, 0); | 1521 isolate, receiver, backing_store, add_size, 0, length, 0, 0); |
1518 } | 1522 } |
1519 | 1523 |
1520 int insertion_index = remove_position == AT_START ? 0 : length; | 1524 int insertion_index = remove_position == AT_START ? 0 : length; |
1521 // Copy the arguments to the start. | 1525 // Copy the arguments to the start. |
1522 FastElementsAccessorSubclass::CopyArguments(args, backing_store, add_size, | 1526 FastElementsAccessorSubclass::CopyArguments(args, backing_store, add_size, |
1523 1, insertion_index); | 1527 1, insertion_index); |
1524 // Set the length. | 1528 // Set the length. |
1525 receiver->set_length(Smi::FromInt(new_length)); | 1529 receiver->set_length(Smi::FromInt(new_length)); |
1526 return new_length; | 1530 return new_length; |
1527 } | 1531 } |
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1560 Object* value, WriteBarrierMode mode) { | 1564 Object* value, WriteBarrierMode mode) { |
1561 FixedArray::cast(backing_store)->set(entry, value, mode); | 1565 FixedArray::cast(backing_store)->set(entry, value, mode); |
1562 } | 1566 } |
1563 | 1567 |
1564 static Object* GetRaw(FixedArray* backing_store, uint32_t entry) { | 1568 static Object* GetRaw(FixedArray* backing_store, uint32_t entry) { |
1565 uint32_t index = FastElementsAccessorSubclass::GetIndexForEntryImpl( | 1569 uint32_t index = FastElementsAccessorSubclass::GetIndexForEntryImpl( |
1566 backing_store, entry); | 1570 backing_store, entry); |
1567 return backing_store->get(index); | 1571 return backing_store->get(index); |
1568 } | 1572 } |
1569 | 1573 |
1570 static void MoveElements(Heap* heap, Handle<FixedArrayBase> backing_store, | 1574 static Handle<FixedArrayBase> MoveElements( |
1571 int dst_index, int src_index, int len, | 1575 Isolate* isolate, Handle<JSArray> receiver, |
1572 int hole_start, int hole_end) { | 1576 Handle<FixedArrayBase> backing_store, int dst_index, int src_index, |
1577 int len, int hole_start, int hole_end) { | |
1578 Heap* heap = isolate->heap(); | |
1573 Handle<FixedArray> dst_elms = Handle<FixedArray>::cast(backing_store); | 1579 Handle<FixedArray> dst_elms = Handle<FixedArray>::cast(backing_store); |
1574 if (len != 0) { | 1580 if (heap->CanMoveObjectStart(*dst_elms) && dst_index == 0) { |
1581 dst_elms = Handle<FixedArray>( | |
Igor Sheludko
2015/12/22 10:02:36
Since
1) the left trimming is not "safe" in a sens
| |
1582 FixedArray::cast(heap->LeftTrimFixedArray(*dst_elms, src_index)), | |
1583 isolate); | |
1584 receiver->set_elements(*dst_elms); | |
1585 hole_end -= src_index; | |
Igor Sheludko
2015/12/22 10:02:36
Shouldn't we update hole_start here as well?
Camillo Bruni
2015/12/22 14:21:01
I added a DCHECK, the hole_start has to lie within
| |
1586 } else if (len != 0) { | |
1575 DisallowHeapAllocation no_gc; | 1587 DisallowHeapAllocation no_gc; |
1576 heap->MoveElements(*dst_elms, dst_index, src_index, len); | 1588 heap->MoveElements(*dst_elms, dst_index, src_index, len); |
1577 } | 1589 } |
1578 if (hole_start != hole_end) { | 1590 if (hole_start != hole_end) { |
1579 dst_elms->FillWithHoles(hole_start, hole_end); | 1591 dst_elms->FillWithHoles(hole_start, hole_end); |
1580 } | 1592 } |
1593 return dst_elms; | |
1581 } | 1594 } |
1582 | 1595 |
1583 // NOTE: this method violates the handlified function signature convention: | 1596 // NOTE: this method violates the handlified function signature convention: |
1584 // raw pointer parameters in the function that allocates. | 1597 // raw pointer parameters in the function that allocates. |
1585 // See ElementsAccessor::CopyElements() for details. | 1598 // See ElementsAccessor::CopyElements() for details. |
1586 // This method could actually allocate if copying from double elements to | 1599 // This method could actually allocate if copying from double elements to |
1587 // object elements. | 1600 // object elements. |
1588 static void CopyElementsImpl(FixedArrayBase* from, uint32_t from_start, | 1601 static void CopyElementsImpl(FixedArrayBase* from, uint32_t from_start, |
1589 FixedArrayBase* to, ElementsKind from_kind, | 1602 FixedArrayBase* to, ElementsKind from_kind, |
1590 uint32_t to_start, int packed_size, | 1603 uint32_t to_start, int packed_size, |
(...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1683 static inline void SetImpl(FixedArrayBase* backing_store, uint32_t entry, | 1696 static inline void SetImpl(FixedArrayBase* backing_store, uint32_t entry, |
1684 Object* value) { | 1697 Object* value) { |
1685 FixedDoubleArray::cast(backing_store)->set(entry, value->Number()); | 1698 FixedDoubleArray::cast(backing_store)->set(entry, value->Number()); |
1686 } | 1699 } |
1687 | 1700 |
1688 static inline void SetImpl(FixedArrayBase* backing_store, uint32_t entry, | 1701 static inline void SetImpl(FixedArrayBase* backing_store, uint32_t entry, |
1689 Object* value, WriteBarrierMode mode) { | 1702 Object* value, WriteBarrierMode mode) { |
1690 FixedDoubleArray::cast(backing_store)->set(entry, value->Number()); | 1703 FixedDoubleArray::cast(backing_store)->set(entry, value->Number()); |
1691 } | 1704 } |
1692 | 1705 |
1693 static void MoveElements(Heap* heap, Handle<FixedArrayBase> backing_store, | 1706 static Handle<FixedArrayBase> MoveElements( |
1694 int dst_index, int src_index, int len, | 1707 Isolate* isolate, Handle<JSArray> receiver, |
1695 int hole_start, int hole_end) { | 1708 Handle<FixedArrayBase> backing_store, int dst_index, int src_index, |
1709 int len, int hole_start, int hole_end) { | |
1710 Heap* heap = isolate->heap(); | |
1696 Handle<FixedDoubleArray> dst_elms = | 1711 Handle<FixedDoubleArray> dst_elms = |
1697 Handle<FixedDoubleArray>::cast(backing_store); | 1712 Handle<FixedDoubleArray>::cast(backing_store); |
1698 if (len != 0) { | 1713 if (heap->CanMoveObjectStart(*dst_elms) && dst_index == 0) { |
1714 dst_elms = Handle<FixedDoubleArray>( | |
Igor Sheludko
2015/12/22 10:02:36
Ditto...
| |
1715 FixedDoubleArray::cast( | |
1716 heap->LeftTrimFixedArray(*dst_elms, src_index)), | |
1717 isolate); | |
1718 receiver->set_elements(*dst_elms); | |
1719 hole_end -= src_index; | |
Igor Sheludko
2015/12/22 10:02:36
Ditto...
| |
1720 } else if (len != 0) { | |
1699 MemMove(dst_elms->data_start() + dst_index, | 1721 MemMove(dst_elms->data_start() + dst_index, |
1700 dst_elms->data_start() + src_index, len * kDoubleSize); | 1722 dst_elms->data_start() + src_index, len * kDoubleSize); |
1701 } | 1723 } |
1702 if (hole_start != hole_end) { | 1724 if (hole_start != hole_end) { |
1703 dst_elms->FillWithHoles(hole_start, hole_end); | 1725 dst_elms->FillWithHoles(hole_start, hole_end); |
1704 } | 1726 } |
1727 return dst_elms; | |
1705 } | 1728 } |
1706 | 1729 |
1707 static void CopyElementsImpl(FixedArrayBase* from, uint32_t from_start, | 1730 static void CopyElementsImpl(FixedArrayBase* from, uint32_t from_start, |
1708 FixedArrayBase* to, ElementsKind from_kind, | 1731 FixedArrayBase* to, ElementsKind from_kind, |
1709 uint32_t to_start, int packed_size, | 1732 uint32_t to_start, int packed_size, |
1710 int copy_size) { | 1733 int copy_size) { |
1711 DisallowHeapAllocation no_allocation; | 1734 DisallowHeapAllocation no_allocation; |
1712 switch (from_kind) { | 1735 switch (from_kind) { |
1713 case FAST_SMI_ELEMENTS: | 1736 case FAST_SMI_ELEMENTS: |
1714 CopyPackedSmiToDoubleElements(from, from_start, to, to_start, | 1737 CopyPackedSmiToDoubleElements(from, from_start, to, to_start, |
(...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1794 uint32_t entry) { | 1817 uint32_t entry) { |
1795 uint32_t index = GetIndexForEntryImpl(*backing_store, entry); | 1818 uint32_t index = GetIndexForEntryImpl(*backing_store, entry); |
1796 return BackingStore::get(Handle<BackingStore>::cast(backing_store), index); | 1819 return BackingStore::get(Handle<BackingStore>::cast(backing_store), index); |
1797 } | 1820 } |
1798 | 1821 |
1799 static PropertyDetails GetDetailsImpl(FixedArrayBase* backing_store, | 1822 static PropertyDetails GetDetailsImpl(FixedArrayBase* backing_store, |
1800 uint32_t entry) { | 1823 uint32_t entry) { |
1801 return PropertyDetails(DONT_DELETE, DATA, 0, PropertyCellType::kNoCell); | 1824 return PropertyDetails(DONT_DELETE, DATA, 0, PropertyCellType::kNoCell); |
1802 } | 1825 } |
1803 | 1826 |
1804 static void SetLengthImpl(Handle<JSArray> array, uint32_t length, | 1827 static void SetLengthImpl(Isolate* isolate, Handle<JSArray> array, |
1828 uint32_t length, | |
1805 Handle<FixedArrayBase> backing_store) { | 1829 Handle<FixedArrayBase> backing_store) { |
1806 // External arrays do not support changing their length. | 1830 // External arrays do not support changing their length. |
1807 UNREACHABLE(); | 1831 UNREACHABLE(); |
1808 } | 1832 } |
1809 | 1833 |
1810 static void DeleteImpl(Handle<JSObject> obj, uint32_t entry) { | 1834 static void DeleteImpl(Handle<JSObject> obj, uint32_t entry) { |
1811 UNREACHABLE(); | 1835 UNREACHABLE(); |
1812 } | 1836 } |
1813 | 1837 |
1814 static uint32_t GetIndexForEntryImpl(FixedArrayBase* backing_store, | 1838 static uint32_t GetIndexForEntryImpl(FixedArrayBase* backing_store, |
(...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1908 Context* context = Context::cast(parameter_map->get(0)); | 1932 Context* context = Context::cast(parameter_map->get(0)); |
1909 int context_entry = alias->aliased_context_slot(); | 1933 int context_entry = alias->aliased_context_slot(); |
1910 DCHECK(!context->get(context_entry)->IsTheHole()); | 1934 DCHECK(!context->get(context_entry)->IsTheHole()); |
1911 context->set(context_entry, value); | 1935 context->set(context_entry, value); |
1912 } else { | 1936 } else { |
1913 ArgumentsAccessor::SetImpl(arguments, entry - length, value); | 1937 ArgumentsAccessor::SetImpl(arguments, entry - length, value); |
1914 } | 1938 } |
1915 } | 1939 } |
1916 } | 1940 } |
1917 | 1941 |
1918 static void SetLengthImpl(Handle<JSArray> array, uint32_t length, | 1942 static void SetLengthImpl(Isolate* isolate, Handle<JSArray> array, |
1943 uint32_t length, | |
1919 Handle<FixedArrayBase> parameter_map) { | 1944 Handle<FixedArrayBase> parameter_map) { |
1920 // Sloppy arguments objects are not arrays. | 1945 // Sloppy arguments objects are not arrays. |
1921 UNREACHABLE(); | 1946 UNREACHABLE(); |
1922 } | 1947 } |
1923 | 1948 |
1924 static uint32_t GetCapacityImpl(JSObject* holder, | 1949 static uint32_t GetCapacityImpl(JSObject* holder, |
1925 FixedArrayBase* backing_store) { | 1950 FixedArrayBase* backing_store) { |
1926 FixedArray* parameter_map = FixedArray::cast(backing_store); | 1951 FixedArray* parameter_map = FixedArray::cast(backing_store); |
1927 FixedArrayBase* arguments = FixedArrayBase::cast(parameter_map->get(1)); | 1952 FixedArrayBase* arguments = FixedArrayBase::cast(parameter_map->get(1)); |
1928 return parameter_map->length() - 2 + | 1953 return parameter_map->length() - 2 + |
(...skipping 456 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2385 } | 2410 } |
2386 } | 2411 } |
2387 | 2412 |
2388 DCHECK(j == result_len); | 2413 DCHECK(j == result_len); |
2389 return result_array; | 2414 return result_array; |
2390 } | 2415 } |
2391 | 2416 |
2392 ElementsAccessor** ElementsAccessor::elements_accessors_ = NULL; | 2417 ElementsAccessor** ElementsAccessor::elements_accessors_ = NULL; |
2393 } // namespace internal | 2418 } // namespace internal |
2394 } // namespace v8 | 2419 } // namespace v8 |
OLD | NEW |