Chromium Code Reviews| 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 void MoveElements(Isolate* isolate, Handle<JSArray> receiver, | 
| 1356 int dst_index, int src_index, int len, | 1358 Handle<FixedArrayBase>& backing_store, int dst_index, | 
| 1357 int hole_start, int hole_end) { | 1359 int src_index, int len, int hole_start, | 
| 1360 int hole_end) { | |
| 1358 UNREACHABLE(); | 1361 UNREACHABLE(); | 
| 1359 } | 1362 } | 
| 1360 | 1363 | 
| 1361 static Handle<JSArray> SliceImpl(Handle<JSObject> receiver, | 1364 static Handle<JSArray> SliceImpl(Handle<JSObject> receiver, | 
| 1362 Handle<FixedArrayBase> backing_store, | 1365 Handle<FixedArrayBase> backing_store, | 
| 1363 uint32_t start, uint32_t end) { | 1366 uint32_t start, uint32_t end) { | 
| 1364 DCHECK(start < end); | 1367 DCHECK(start < end); | 
| 1365 Isolate* isolate = receiver->GetIsolate(); | 1368 Isolate* isolate = receiver->GetIsolate(); | 
| 1366 int result_len = end - start; | 1369 int result_len = end - start; | 
| 1367 Handle<JSArray> result_array = isolate->factory()->NewJSArray( | 1370 Handle<JSArray> result_array = isolate->factory()->NewJSArray( | 
| (...skipping 28 matching lines...) Expand all Loading... | |
| 1396 KindTraits::Kind, delete_count, delete_count); | 1399 KindTraits::Kind, delete_count, delete_count); | 
| 1397 if (delete_count > 0) { | 1400 if (delete_count > 0) { | 
| 1398 DisallowHeapAllocation no_gc; | 1401 DisallowHeapAllocation no_gc; | 
| 1399 FastElementsAccessorSubclass::CopyElementsImpl( | 1402 FastElementsAccessorSubclass::CopyElementsImpl( | 
| 1400 *backing_store, start, deleted_elements->elements(), KindTraits::Kind, | 1403 *backing_store, start, deleted_elements->elements(), KindTraits::Kind, | 
| 1401 0, kPackedSizeNotKnown, delete_count); | 1404 0, kPackedSizeNotKnown, delete_count); | 
| 1402 } | 1405 } | 
| 1403 | 1406 | 
| 1404 // Delete and move elements to make space for add_count new elements. | 1407 // Delete and move elements to make space for add_count new elements. | 
| 1405 if (add_count < delete_count) { | 1408 if (add_count < delete_count) { | 
| 1406 FastElementsAccessorSubclass::SpliceShrinkStep(backing_store, heap, start, | 1409 FastElementsAccessorSubclass::SpliceShrinkStep( | 
| 1407 delete_count, add_count, | 1410 isolate, receiver, backing_store, start, delete_count, add_count, | 
| 1408 length, new_length); | 1411 length, new_length); | 
| 1409 } else if (add_count > delete_count) { | 1412 } else if (add_count > delete_count) { | 
| 1410 backing_store = FastElementsAccessorSubclass::SpliceGrowStep( | 1413 FastElementsAccessorSubclass::SpliceGrowStep( | 
| 1411 receiver, backing_store, isolate, heap, start, delete_count, | 1414 isolate, receiver, backing_store, start, delete_count, add_count, | 
| 1412 add_count, length, new_length); | 1415 length, new_length); | 
| 1413 } | 1416 } | 
| 1414 | 1417 | 
| 1415 // Copy over the arguments. | 1418 // Copy over the arguments. | 
| 1416 FastElementsAccessorSubclass::CopyArguments(args, backing_store, add_count, | 1419 FastElementsAccessorSubclass::CopyArguments(args, backing_store, add_count, | 
| 1417 3, start); | 1420 3, start); | 
| 1418 | 1421 | 
| 1419 receiver->set_length(Smi::FromInt(new_length)); | 1422 receiver->set_length(Smi::FromInt(new_length)); | 
| 1420 FastElementsAccessorSubclass::TryTransitionResultArrayToPacked( | 1423 FastElementsAccessorSubclass::TryTransitionResultArrayToPacked( | 
| 1421 deleted_elements); | 1424 deleted_elements); | 
| 1422 return deleted_elements; | 1425 return deleted_elements; | 
| 1423 } | 1426 } | 
| 1424 | 1427 | 
| 1425 private: | 1428 private: | 
| 1426 static void SpliceShrinkStep(Handle<FixedArrayBase> backing_store, Heap* heap, | 1429 // SpliceShrinkStep might modify the backing_store. | 
| 1430 static void SpliceShrinkStep(Isolate* isolate, Handle<JSArray> receiver, | |
| 1431 Handle<FixedArrayBase>& backing_store, | |
| 1427 uint32_t start, uint32_t delete_count, | 1432 uint32_t start, uint32_t delete_count, | 
| 1428 uint32_t add_count, uint32_t len, | 1433 uint32_t add_count, uint32_t len, | 
| 1429 uint32_t new_length) { | 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 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 // SpliceGrowStep might modify the backing_store. | 
| 1438 static Handle<FixedArrayBase> SpliceGrowStep( | 1443 static void SpliceGrowStep(Isolate* isolate, Handle<JSArray> receiver, | 
| 1439 Handle<JSArray> receiver, Handle<FixedArrayBase> backing_store, | 1444 Handle<FixedArrayBase>& backing_store, | 
| 1440 Isolate* isolate, Heap* heap, uint32_t start, uint32_t delete_count, | 1445 uint32_t start, uint32_t delete_count, | 
| 1441 uint32_t add_count, uint32_t length, uint32_t new_length) { | 1446 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 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; | 1455 return; | 
| 1450 } | 1456 } | 
| 1451 // New backing storage is needed. | 1457 // New backing storage is needed. | 
| 1452 int capacity = JSObject::NewElementsCapacity(new_length); | 1458 int capacity = JSObject::NewElementsCapacity(new_length); | 
| 1453 // Partially copy all elements up to start. | 1459 // Partially copy all elements up to start. | 
| 1454 Handle<FixedArrayBase> new_elms = | 1460 Handle<FixedArrayBase> new_elms = | 
| 1455 FastElementsAccessorSubclass::ConvertElementsWithCapacity( | 1461 FastElementsAccessorSubclass::ConvertElementsWithCapacity( | 
| 1456 receiver, backing_store, KindTraits::Kind, capacity, start); | 1462 receiver, backing_store, KindTraits::Kind, capacity, start); | 
| 1457 // Copy the trailing elements after start + delete_count | 1463 // Copy the trailing elements after start + delete_count | 
| 1458 FastElementsAccessorSubclass::CopyElementsImpl( | 1464 FastElementsAccessorSubclass::CopyElementsImpl( | 
| 1459 *backing_store, start + delete_count, *new_elms, KindTraits::Kind, | 1465 *backing_store, start + delete_count, *new_elms, KindTraits::Kind, | 
| 1460 start + add_count, kPackedSizeNotKnown, | 1466 start + add_count, kPackedSizeNotKnown, | 
| 1461 ElementsAccessor::kCopyToEndAndInitializeToHole); | 1467 ElementsAccessor::kCopyToEndAndInitializeToHole); | 
| 1462 receiver->set_elements(*new_elms); | 1468 receiver->set_elements(*new_elms); | 
| 1463 return new_elms; | 1469 backing_store = new_elms; | 
| 1464 } | 1470 } | 
| 1465 | 1471 | 
| 1466 static Handle<Object> RemoveElement(Handle<JSArray> receiver, | 1472 static Handle<Object> RemoveElement(Handle<JSArray> receiver, | 
| 1467 Handle<FixedArrayBase> backing_store, | 1473 Handle<FixedArrayBase> backing_store, | 
| 1468 Where remove_position) { | 1474 Where remove_position) { | 
| 1475 Isolate* isolate = receiver->GetIsolate(); | |
| 1469 uint32_t length = | 1476 uint32_t length = | 
| 1470 static_cast<uint32_t>(Smi::cast(receiver->length())->value()); | 1477 static_cast<uint32_t>(Smi::cast(receiver->length())->value()); | 
| 1471 Isolate* isolate = receiver->GetIsolate(); | |
| 1472 DCHECK(length > 0); | 1478 DCHECK(length > 0); | 
| 1473 int new_length = length - 1; | 1479 int new_length = length - 1; | 
| 1474 int remove_index = remove_position == AT_START ? 0 : new_length; | 1480 int remove_index = remove_position == AT_START ? 0 : new_length; | 
| 1475 Handle<Object> result = | 1481 Handle<Object> result = | 
| 1476 FastElementsAccessorSubclass::GetImpl(backing_store, remove_index); | 1482 FastElementsAccessorSubclass::GetImpl(backing_store, remove_index); | 
| 1477 if (remove_position == AT_START) { | 1483 if (remove_position == AT_START) { | 
| 1478 Heap* heap = isolate->heap(); | 1484 FastElementsAccessorSubclass::MoveElements( | 
| 1479 FastElementsAccessorSubclass::MoveElements(heap, backing_store, 0, 1, | 1485 isolate, receiver, backing_store, 0, 1, new_length, 0, 0); | 
| 1480 new_length, 0, 0); | |
| 1481 } | 1486 } | 
| 1482 FastElementsAccessorSubclass::SetLengthImpl(receiver, new_length, | 1487 FastElementsAccessorSubclass::SetLengthImpl(isolate, receiver, new_length, | 
| 1483 backing_store); | 1488 backing_store); | 
| 1484 | 1489 | 
| 1485 if (IsHoleyElementsKind(KindTraits::Kind) && result->IsTheHole()) { | 1490 if (IsHoleyElementsKind(KindTraits::Kind) && result->IsTheHole()) { | 
| 1486 return receiver->GetIsolate()->factory()->undefined_value(); | 1491 return receiver->GetIsolate()->factory()->undefined_value(); | 
| 1487 } | 1492 } | 
| 1488 return result; | 1493 return result; | 
| 1489 } | 1494 } | 
| 1490 | 1495 | 
| 1491 static uint32_t AddArguments(Handle<JSArray> receiver, | 1496 static uint32_t AddArguments(Handle<JSArray> receiver, | 
| 1492 Handle<FixedArrayBase> backing_store, | 1497 Handle<FixedArrayBase> backing_store, | 
| (...skipping 13 matching lines...) Expand all Loading... | |
| 1506 int copy_dst_index = remove_position == AT_START ? add_size : 0; | 1511 int copy_dst_index = remove_position == AT_START ? add_size : 0; | 
| 1507 // Copy over all objects to a new backing_store. | 1512 // Copy over all objects to a new backing_store. | 
| 1508 backing_store = FastElementsAccessorSubclass::ConvertElementsWithCapacity( | 1513 backing_store = FastElementsAccessorSubclass::ConvertElementsWithCapacity( | 
| 1509 receiver, backing_store, KindTraits::Kind, capacity, 0, | 1514 receiver, backing_store, KindTraits::Kind, capacity, 0, | 
| 1510 copy_dst_index, ElementsAccessor::kCopyToEndAndInitializeToHole); | 1515 copy_dst_index, ElementsAccessor::kCopyToEndAndInitializeToHole); | 
| 1511 receiver->set_elements(*backing_store); | 1516 receiver->set_elements(*backing_store); | 
| 1512 } else if (remove_position == AT_START) { | 1517 } else if (remove_position == AT_START) { | 
| 1513 // If the backing store has enough capacity and we add elements to the | 1518 // If the backing store has enough capacity and we add elements to the | 
| 1514 // start we have to shift the existing objects. | 1519 // start we have to shift the existing objects. | 
| 1515 Isolate* isolate = receiver->GetIsolate(); | 1520 Isolate* isolate = receiver->GetIsolate(); | 
| 1516 FastElementsAccessorSubclass::MoveElements(isolate->heap(), backing_store, | 1521 FastElementsAccessorSubclass::MoveElements( | 
| 1517 add_size, 0, length, 0, 0); | 1522 isolate, receiver, backing_store, add_size, 0, length, 0, 0); | 
| 1518 } | 1523 } | 
| 1519 | 1524 | 
| 1520 int insertion_index = remove_position == AT_START ? 0 : length; | 1525 int insertion_index = remove_position == AT_START ? 0 : length; | 
| 1521 // Copy the arguments to the start. | 1526 // Copy the arguments to the start. | 
| 1522 FastElementsAccessorSubclass::CopyArguments(args, backing_store, add_size, | 1527 FastElementsAccessorSubclass::CopyArguments(args, backing_store, add_size, | 
| 1523 1, insertion_index); | 1528 1, insertion_index); | 
| 1524 // Set the length. | 1529 // Set the length. | 
| 1525 receiver->set_length(Smi::FromInt(new_length)); | 1530 receiver->set_length(Smi::FromInt(new_length)); | 
| 1526 return new_length; | 1531 return new_length; | 
| 1527 } | 1532 } | 
| (...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1560 Object* value, WriteBarrierMode mode) { | 1565 Object* value, WriteBarrierMode mode) { | 
| 1561 FixedArray::cast(backing_store)->set(entry, value, mode); | 1566 FixedArray::cast(backing_store)->set(entry, value, mode); | 
| 1562 } | 1567 } | 
| 1563 | 1568 | 
| 1564 static Object* GetRaw(FixedArray* backing_store, uint32_t entry) { | 1569 static Object* GetRaw(FixedArray* backing_store, uint32_t entry) { | 
| 1565 uint32_t index = FastElementsAccessorSubclass::GetIndexForEntryImpl( | 1570 uint32_t index = FastElementsAccessorSubclass::GetIndexForEntryImpl( | 
| 1566 backing_store, entry); | 1571 backing_store, entry); | 
| 1567 return backing_store->get(index); | 1572 return backing_store->get(index); | 
| 1568 } | 1573 } | 
| 1569 | 1574 | 
| 1570 static void MoveElements(Heap* heap, Handle<FixedArrayBase> backing_store, | 1575 static void MoveElements(Isolate* isolate, Handle<JSArray> receiver, | 
| 1571 int dst_index, int src_index, int len, | 1576 Handle<FixedArrayBase>& backing_store, int dst_index, | 
| 1572 int hole_start, int hole_end) { | 1577 int src_index, int len, int hole_start, | 
| 1578 int hole_end) { | |
| 1579 Heap* heap = isolate->heap(); | |
| 1573 Handle<FixedArray> dst_elms = Handle<FixedArray>::cast(backing_store); | 1580 Handle<FixedArray> dst_elms = Handle<FixedArray>::cast(backing_store); | 
| 1574 if (len != 0) { | 1581 if (heap->CanMoveObjectStart(*dst_elms) && dst_index == 0) { | 
| 1582 dst_elms = Handle<FixedArray>( | |
| 
 
Igor Sheludko
2015/12/22 17:15:01
Sorry for confusion. I actually meant to do this:
 
 | |
| 1583 FixedArray::cast(heap->LeftTrimFixedArray(*dst_elms, src_index)), | |
| 1584 isolate); | |
| 1585 backing_store = dst_elms; | |
| 
 
Igor Sheludko
2015/12/22 17:15:01
Not needed once the above comment is addressed.
 
 | |
| 1586 receiver->set_elements(*dst_elms); | |
| 1587 // Adjust the hole offset as the array has been shrunk. | |
| 1588 hole_end -= src_index; | |
| 1589 DCHECK_LE(hole_start, backing_store->length()); | |
| 1590 DCHECK_LE(hole_end, backing_store->length()); | |
| 1591 } else if (len != 0) { | |
| 1575 DisallowHeapAllocation no_gc; | 1592 DisallowHeapAllocation no_gc; | 
| 1576 heap->MoveElements(*dst_elms, dst_index, src_index, len); | 1593 heap->MoveElements(*dst_elms, dst_index, src_index, len); | 
| 1577 } | 1594 } | 
| 1578 if (hole_start != hole_end) { | 1595 if (hole_start != hole_end) { | 
| 1579 dst_elms->FillWithHoles(hole_start, hole_end); | 1596 dst_elms->FillWithHoles(hole_start, hole_end); | 
| 1580 } | 1597 } | 
| 1581 } | 1598 } | 
| 1582 | 1599 | 
| 1583 // NOTE: this method violates the handlified function signature convention: | 1600 // NOTE: this method violates the handlified function signature convention: | 
| 1584 // raw pointer parameters in the function that allocates. | 1601 // raw pointer parameters in the function that allocates. | 
| (...skipping 98 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1683 static inline void SetImpl(FixedArrayBase* backing_store, uint32_t entry, | 1700 static inline void SetImpl(FixedArrayBase* backing_store, uint32_t entry, | 
| 1684 Object* value) { | 1701 Object* value) { | 
| 1685 FixedDoubleArray::cast(backing_store)->set(entry, value->Number()); | 1702 FixedDoubleArray::cast(backing_store)->set(entry, value->Number()); | 
| 1686 } | 1703 } | 
| 1687 | 1704 | 
| 1688 static inline void SetImpl(FixedArrayBase* backing_store, uint32_t entry, | 1705 static inline void SetImpl(FixedArrayBase* backing_store, uint32_t entry, | 
| 1689 Object* value, WriteBarrierMode mode) { | 1706 Object* value, WriteBarrierMode mode) { | 
| 1690 FixedDoubleArray::cast(backing_store)->set(entry, value->Number()); | 1707 FixedDoubleArray::cast(backing_store)->set(entry, value->Number()); | 
| 1691 } | 1708 } | 
| 1692 | 1709 | 
| 1693 static void MoveElements(Heap* heap, Handle<FixedArrayBase> backing_store, | 1710 static void MoveElements(Isolate* isolate, Handle<JSArray> receiver, | 
| 1694 int dst_index, int src_index, int len, | 1711 Handle<FixedArrayBase>& backing_store, int dst_index, | 
| 1695 int hole_start, int hole_end) { | 1712 int src_index, int len, int hole_start, | 
| 1713 int hole_end) { | |
| 1714 Heap* heap = isolate->heap(); | |
| 1696 Handle<FixedDoubleArray> dst_elms = | 1715 Handle<FixedDoubleArray> dst_elms = | 
| 1697 Handle<FixedDoubleArray>::cast(backing_store); | 1716 Handle<FixedDoubleArray>::cast(backing_store); | 
| 1698 if (len != 0) { | 1717 if (heap->CanMoveObjectStart(*dst_elms) && dst_index == 0) { | 
| 1718 dst_elms = Handle<FixedDoubleArray>( | |
| 
 
Igor Sheludko
2015/12/22 17:15:01
Ditto.
 
 | |
| 1719 FixedDoubleArray::cast( | |
| 1720 heap->LeftTrimFixedArray(*dst_elms, src_index)), | |
| 1721 isolate); | |
| 1722 backing_store = dst_elms; | |
| 
 
Igor Sheludko
2015/12/22 17:15:01
Ditto.
 
 | |
| 1723 receiver->set_elements(*dst_elms); | |
| 1724 // Adjust the hole offset as the array has been shrunk. | |
| 1725 hole_end -= src_index; | |
| 1726 DCHECK_LE(hole_start, backing_store->length()); | |
| 1727 DCHECK_LE(hole_end, backing_store->length()); | |
| 1728 } else if (len != 0) { | |
| 1699 MemMove(dst_elms->data_start() + dst_index, | 1729 MemMove(dst_elms->data_start() + dst_index, | 
| 1700 dst_elms->data_start() + src_index, len * kDoubleSize); | 1730 dst_elms->data_start() + src_index, len * kDoubleSize); | 
| 1701 } | 1731 } | 
| 1702 if (hole_start != hole_end) { | 1732 if (hole_start != hole_end) { | 
| 1703 dst_elms->FillWithHoles(hole_start, hole_end); | 1733 dst_elms->FillWithHoles(hole_start, hole_end); | 
| 1704 } | 1734 } | 
| 1705 } | 1735 } | 
| 1706 | 1736 | 
| 1707 static void CopyElementsImpl(FixedArrayBase* from, uint32_t from_start, | 1737 static void CopyElementsImpl(FixedArrayBase* from, uint32_t from_start, | 
| 1708 FixedArrayBase* to, ElementsKind from_kind, | 1738 FixedArrayBase* to, ElementsKind from_kind, | 
| (...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1794 uint32_t entry) { | 1824 uint32_t entry) { | 
| 1795 uint32_t index = GetIndexForEntryImpl(*backing_store, entry); | 1825 uint32_t index = GetIndexForEntryImpl(*backing_store, entry); | 
| 1796 return BackingStore::get(Handle<BackingStore>::cast(backing_store), index); | 1826 return BackingStore::get(Handle<BackingStore>::cast(backing_store), index); | 
| 1797 } | 1827 } | 
| 1798 | 1828 | 
| 1799 static PropertyDetails GetDetailsImpl(FixedArrayBase* backing_store, | 1829 static PropertyDetails GetDetailsImpl(FixedArrayBase* backing_store, | 
| 1800 uint32_t entry) { | 1830 uint32_t entry) { | 
| 1801 return PropertyDetails(DONT_DELETE, DATA, 0, PropertyCellType::kNoCell); | 1831 return PropertyDetails(DONT_DELETE, DATA, 0, PropertyCellType::kNoCell); | 
| 1802 } | 1832 } | 
| 1803 | 1833 | 
| 1804 static void SetLengthImpl(Handle<JSArray> array, uint32_t length, | 1834 static void SetLengthImpl(Isolate* isolate, Handle<JSArray> array, | 
| 1835 uint32_t length, | |
| 1805 Handle<FixedArrayBase> backing_store) { | 1836 Handle<FixedArrayBase> backing_store) { | 
| 1806 // External arrays do not support changing their length. | 1837 // External arrays do not support changing their length. | 
| 1807 UNREACHABLE(); | 1838 UNREACHABLE(); | 
| 1808 } | 1839 } | 
| 1809 | 1840 | 
| 1810 static void DeleteImpl(Handle<JSObject> obj, uint32_t entry) { | 1841 static void DeleteImpl(Handle<JSObject> obj, uint32_t entry) { | 
| 1811 UNREACHABLE(); | 1842 UNREACHABLE(); | 
| 1812 } | 1843 } | 
| 1813 | 1844 | 
| 1814 static uint32_t GetIndexForEntryImpl(FixedArrayBase* backing_store, | 1845 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)); | 1939 Context* context = Context::cast(parameter_map->get(0)); | 
| 1909 int context_entry = alias->aliased_context_slot(); | 1940 int context_entry = alias->aliased_context_slot(); | 
| 1910 DCHECK(!context->get(context_entry)->IsTheHole()); | 1941 DCHECK(!context->get(context_entry)->IsTheHole()); | 
| 1911 context->set(context_entry, value); | 1942 context->set(context_entry, value); | 
| 1912 } else { | 1943 } else { | 
| 1913 ArgumentsAccessor::SetImpl(arguments, entry - length, value); | 1944 ArgumentsAccessor::SetImpl(arguments, entry - length, value); | 
| 1914 } | 1945 } | 
| 1915 } | 1946 } | 
| 1916 } | 1947 } | 
| 1917 | 1948 | 
| 1918 static void SetLengthImpl(Handle<JSArray> array, uint32_t length, | 1949 static void SetLengthImpl(Isolate* isolate, Handle<JSArray> array, | 
| 1950 uint32_t length, | |
| 1919 Handle<FixedArrayBase> parameter_map) { | 1951 Handle<FixedArrayBase> parameter_map) { | 
| 1920 // Sloppy arguments objects are not arrays. | 1952 // Sloppy arguments objects are not arrays. | 
| 1921 UNREACHABLE(); | 1953 UNREACHABLE(); | 
| 1922 } | 1954 } | 
| 1923 | 1955 | 
| 1924 static uint32_t GetCapacityImpl(JSObject* holder, | 1956 static uint32_t GetCapacityImpl(JSObject* holder, | 
| 1925 FixedArrayBase* backing_store) { | 1957 FixedArrayBase* backing_store) { | 
| 1926 FixedArray* parameter_map = FixedArray::cast(backing_store); | 1958 FixedArray* parameter_map = FixedArray::cast(backing_store); | 
| 1927 FixedArrayBase* arguments = FixedArrayBase::cast(parameter_map->get(1)); | 1959 FixedArrayBase* arguments = FixedArrayBase::cast(parameter_map->get(1)); | 
| 1928 return parameter_map->length() - 2 + | 1960 return parameter_map->length() - 2 + | 
| (...skipping 456 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2385 } | 2417 } | 
| 2386 } | 2418 } | 
| 2387 | 2419 | 
| 2388 DCHECK(j == result_len); | 2420 DCHECK(j == result_len); | 
| 2389 return result_array; | 2421 return result_array; | 
| 2390 } | 2422 } | 
| 2391 | 2423 | 
| 2392 ElementsAccessor** ElementsAccessor::elements_accessors_ = NULL; | 2424 ElementsAccessor** ElementsAccessor::elements_accessors_ = NULL; | 
| 2393 } // namespace internal | 2425 } // namespace internal | 
| 2394 } // namespace v8 | 2426 } // namespace v8 | 
| OLD | NEW |