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 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
44 | 44 |
45 namespace v8 { | 45 namespace v8 { |
46 namespace internal { | 46 namespace internal { |
47 | 47 |
48 | 48 |
49 namespace { | 49 namespace { |
50 | 50 |
51 | 51 |
52 static const int kPackedSizeNotKnown = -1; | 52 static const int kPackedSizeNotKnown = -1; |
53 | 53 |
| 54 enum Where { AT_START, AT_END }; |
| 55 |
54 | 56 |
55 // First argument in list is the accessor class, the second argument is the | 57 // First argument in list is the accessor class, the second argument is the |
56 // accessor ElementsKind, and the third is the backing store class. Use the | 58 // accessor ElementsKind, and the third is the backing store class. Use the |
57 // fast element handler for smi-only arrays. The implementation is currently | 59 // fast element handler for smi-only arrays. The implementation is currently |
58 // identical. Note that the order must match that of the ElementsKind enum for | 60 // identical. Note that the order must match that of the ElementsKind enum for |
59 // the |accessor_array[]| below to work. | 61 // the |accessor_array[]| below to work. |
60 #define ELEMENTS_LIST(V) \ | 62 #define ELEMENTS_LIST(V) \ |
61 V(FastPackedSmiElementsAccessor, FAST_SMI_ELEMENTS, FixedArray) \ | 63 V(FastPackedSmiElementsAccessor, FAST_SMI_ELEMENTS, FixedArray) \ |
62 V(FastHoleySmiElementsAccessor, FAST_HOLEY_SMI_ELEMENTS, FixedArray) \ | 64 V(FastHoleySmiElementsAccessor, FAST_HOLEY_SMI_ELEMENTS, FixedArray) \ |
63 V(FastPackedObjectElementsAccessor, FAST_ELEMENTS, FixedArray) \ | 65 V(FastPackedObjectElementsAccessor, FAST_ELEMENTS, FixedArray) \ |
(...skipping 1267 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1331 DCHECK(BackingStore::get(backing_store, i)->IsSmi() || | 1333 DCHECK(BackingStore::get(backing_store, i)->IsSmi() || |
1332 (IsFastHoleyElementsKind(KindTraits::Kind) && | 1334 (IsFastHoleyElementsKind(KindTraits::Kind) && |
1333 backing_store->is_the_hole(i))); | 1335 backing_store->is_the_hole(i))); |
1334 } | 1336 } |
1335 } | 1337 } |
1336 #endif | 1338 #endif |
1337 } | 1339 } |
1338 | 1340 |
1339 static Handle<Object> PopImpl(Handle<JSArray> receiver, | 1341 static Handle<Object> PopImpl(Handle<JSArray> receiver, |
1340 Handle<FixedArrayBase> backing_store) { | 1342 Handle<FixedArrayBase> backing_store) { |
1341 uint32_t len = | 1343 return FastElementsAccessorSubclass::RemoveElement(receiver, backing_store, |
1342 static_cast<uint32_t>(Smi::cast(receiver->length())->value()); | 1344 AT_END); |
1343 DCHECK(len > 0); | |
1344 uint32_t new_length = len - 1; | |
1345 Handle<Object> result = | |
1346 FastElementsAccessorSubclass::GetImpl(backing_store, new_length); | |
1347 FastElementsAccessorSubclass::SetLengthImpl(receiver, new_length, | |
1348 backing_store); | |
1349 | |
1350 if (IsHoleyElementsKind(KindTraits::Kind) && result->IsTheHole()) { | |
1351 return receiver->GetIsolate()->factory()->undefined_value(); | |
1352 } | |
1353 return result; | |
1354 } | 1345 } |
1355 | 1346 |
1356 static Handle<Object> ShiftImpl(Handle<JSArray> receiver, | 1347 static Handle<Object> ShiftImpl(Handle<JSArray> receiver, |
1357 Handle<FixedArrayBase> backing_store) { | 1348 Handle<FixedArrayBase> backing_store) { |
1358 uint32_t len = | 1349 return FastElementsAccessorSubclass::RemoveElement(receiver, backing_store, |
1359 static_cast<uint32_t>(Smi::cast(receiver->length())->value()); | 1350 AT_START); |
1360 Isolate* isolate = receiver->GetIsolate(); | |
1361 DCHECK(len > 0); | |
1362 int new_length = len - 1; | |
1363 Handle<Object> result = | |
1364 FastElementsAccessorSubclass::GetImpl(backing_store, 0); | |
1365 Heap* heap = isolate->heap(); | |
1366 if (heap->CanMoveObjectStart(*backing_store)) { | |
1367 receiver->set_elements(heap->LeftTrimFixedArray(*backing_store, 1)); | |
1368 } else { | |
1369 FastElementsAccessorSubclass::MoveElements(heap, backing_store, 0, 1, | |
1370 new_length, 0, 0); | |
1371 } | |
1372 FastElementsAccessorSubclass::SetLengthImpl(receiver, new_length, | |
1373 backing_store); | |
1374 | |
1375 if (IsHoleyElementsKind(KindTraits::Kind) && result->IsTheHole()) { | |
1376 result = receiver->GetIsolate()->factory()->undefined_value(); | |
1377 } | |
1378 return result; | |
1379 } | 1351 } |
1380 | 1352 |
1381 static uint32_t PushImpl(Handle<JSArray> receiver, | 1353 static uint32_t PushImpl(Handle<JSArray> receiver, |
1382 Handle<FixedArrayBase> backing_store, | 1354 Handle<FixedArrayBase> backing_store, |
1383 Arguments* args, uint32_t push_size) { | 1355 Arguments* args, uint32_t push_size) { |
1384 uint32_t len = Smi::cast(receiver->length())->value(); | 1356 return FastElementsAccessorSubclass::AddArguments(receiver, backing_store, |
1385 DCHECK(push_size > 0); | 1357 args, push_size, AT_END); |
1386 uint32_t elms_len = backing_store->length(); | |
1387 // Currently fixed arrays cannot grow too big, so | |
1388 // we should never hit this case. | |
1389 DCHECK(push_size <= static_cast<uint32_t>(Smi::kMaxValue - len)); | |
1390 uint32_t new_length = len + push_size; | |
1391 | |
1392 if (new_length > elms_len) { | |
1393 // New backing storage is needed. | |
1394 uint32_t capacity = new_length + (new_length >> 1) + 16; | |
1395 backing_store = FastElementsAccessorSubclass::ConvertElementsWithCapacity( | |
1396 receiver, backing_store, KindTraits::Kind, capacity); | |
1397 receiver->set_elements(*backing_store); | |
1398 } | |
1399 | |
1400 // Add the provided values. | |
1401 DisallowHeapAllocation no_gc; | |
1402 FixedArrayBase* raw_backing_store = *backing_store; | |
1403 WriteBarrierMode mode = raw_backing_store->GetWriteBarrierMode(no_gc); | |
1404 for (uint32_t index = 0; index < push_size; index++) { | |
1405 Object* object = (*args)[index + 1]; | |
1406 FastElementsAccessorSubclass::SetImpl(raw_backing_store, index + len, | |
1407 object, mode); | |
1408 } | |
1409 DCHECK(*backing_store == receiver->elements()); | |
1410 // Set the length. | |
1411 receiver->set_length(Smi::FromInt(new_length)); | |
1412 return new_length; | |
1413 } | 1358 } |
1414 | 1359 |
1415 static uint32_t UnshiftImpl(Handle<JSArray> receiver, | 1360 static uint32_t UnshiftImpl(Handle<JSArray> receiver, |
1416 Handle<FixedArrayBase> backing_store, | 1361 Handle<FixedArrayBase> backing_store, |
1417 Arguments* args, uint32_t unshift_size) { | 1362 Arguments* args, uint32_t unshift_size) { |
1418 uint32_t len = Smi::cast(receiver->length())->value(); | 1363 return FastElementsAccessorSubclass::AddArguments( |
1419 DCHECK(unshift_size > 0); | 1364 receiver, backing_store, args, unshift_size, AT_START); |
1420 uint32_t elms_len = backing_store->length(); | |
1421 // Currently fixed arrays cannot grow too big, so | |
1422 // we should never hit this case. | |
1423 DCHECK(unshift_size <= static_cast<uint32_t>(Smi::kMaxValue - len)); | |
1424 uint32_t new_length = len + unshift_size; | |
1425 | |
1426 if (new_length > elms_len) { | |
1427 // New backing storage is needed. | |
1428 uint32_t capacity = new_length + (new_length >> 1) + 16; | |
1429 backing_store = FastElementsAccessorSubclass::ConvertElementsWithCapacity( | |
1430 receiver, backing_store, KindTraits::Kind, capacity, 0, unshift_size, | |
1431 ElementsAccessor::kCopyToEndAndInitializeToHole); | |
1432 DisallowHeapAllocation no_gc; | |
1433 receiver->set_elements(*backing_store); | |
1434 } else { | |
1435 // unshift_size is > 0 and new_length <= elms_len, so backing_store cannot | |
1436 // be the empty_fixed_array. | |
1437 DisallowHeapAllocation no_gc; | |
1438 Isolate* isolate = receiver->GetIsolate(); | |
1439 FastElementsAccessorSubclass::MoveElements(isolate->heap(), backing_store, | |
1440 unshift_size, 0, len, 0, 0); | |
1441 } | |
1442 | |
1443 // Add the provided values. | |
1444 DisallowHeapAllocation no_gc; | |
1445 FixedArrayBase* raw_backing_store = *backing_store; | |
1446 WriteBarrierMode mode = raw_backing_store->GetWriteBarrierMode(no_gc); | |
1447 for (uint32_t index = 0; index < unshift_size; index++) { | |
1448 FastElementsAccessorSubclass::SetImpl(raw_backing_store, index, | |
1449 (*args)[index + 1], mode); | |
1450 } | |
1451 // Set the length. | |
1452 receiver->set_length(Smi::FromInt(new_length)); | |
1453 return new_length; | |
1454 } | 1365 } |
1455 | 1366 |
1456 static void MoveElements(Heap* heap, Handle<FixedArrayBase> backing_store, | 1367 static void MoveElements(Heap* heap, Handle<FixedArrayBase> backing_store, |
1457 int dst_index, int src_index, int len, | 1368 int dst_index, int src_index, int len, |
1458 int hole_start, int hole_end) { | 1369 int hole_start, int hole_end) { |
1459 UNREACHABLE(); | 1370 UNREACHABLE(); |
1460 } | 1371 } |
1461 | 1372 |
1462 static Handle<JSArray> SliceImpl(Handle<JSObject> receiver, | 1373 static Handle<JSArray> SliceImpl(Handle<JSObject> receiver, |
1463 Handle<FixedArrayBase> backing_store, | 1374 Handle<FixedArrayBase> backing_store, |
(...skipping 11 matching lines...) Expand all Loading... |
1475 result_array); | 1386 result_array); |
1476 return result_array; | 1387 return result_array; |
1477 } | 1388 } |
1478 | 1389 |
1479 static Handle<JSArray> SpliceImpl(Handle<JSArray> receiver, | 1390 static Handle<JSArray> SpliceImpl(Handle<JSArray> receiver, |
1480 Handle<FixedArrayBase> backing_store, | 1391 Handle<FixedArrayBase> backing_store, |
1481 uint32_t start, uint32_t delete_count, | 1392 uint32_t start, uint32_t delete_count, |
1482 Arguments* args, uint32_t add_count) { | 1393 Arguments* args, uint32_t add_count) { |
1483 Isolate* isolate = receiver->GetIsolate(); | 1394 Isolate* isolate = receiver->GetIsolate(); |
1484 Heap* heap = isolate->heap(); | 1395 Heap* heap = isolate->heap(); |
1485 uint32_t len = Smi::cast(receiver->length())->value(); | 1396 uint32_t length = Smi::cast(receiver->length())->value(); |
1486 uint32_t new_length = len - delete_count + add_count; | 1397 uint32_t new_length = length - delete_count + add_count; |
1487 | 1398 |
1488 if (new_length == 0) { | 1399 if (new_length == 0) { |
1489 receiver->set_elements(heap->empty_fixed_array()); | 1400 receiver->set_elements(heap->empty_fixed_array()); |
1490 receiver->set_length(Smi::FromInt(0)); | 1401 receiver->set_length(Smi::FromInt(0)); |
1491 return isolate->factory()->NewJSArrayWithElements( | 1402 return isolate->factory()->NewJSArrayWithElements( |
1492 backing_store, KindTraits::Kind, delete_count); | 1403 backing_store, KindTraits::Kind, delete_count); |
1493 } | 1404 } |
1494 | 1405 |
1495 // construct the result array which holds the deleted elements | 1406 // Construct the result array which holds the deleted elements. |
1496 Handle<JSArray> deleted_elements = isolate->factory()->NewJSArray( | 1407 Handle<JSArray> deleted_elements = isolate->factory()->NewJSArray( |
1497 KindTraits::Kind, delete_count, delete_count); | 1408 KindTraits::Kind, delete_count, delete_count); |
1498 if (delete_count > 0) { | 1409 if (delete_count > 0) { |
1499 DisallowHeapAllocation no_gc; | 1410 DisallowHeapAllocation no_gc; |
1500 FastElementsAccessorSubclass::CopyElementsImpl( | 1411 FastElementsAccessorSubclass::CopyElementsImpl( |
1501 *backing_store, start, deleted_elements->elements(), KindTraits::Kind, | 1412 *backing_store, start, deleted_elements->elements(), KindTraits::Kind, |
1502 0, kPackedSizeNotKnown, delete_count); | 1413 0, kPackedSizeNotKnown, delete_count); |
1503 } | 1414 } |
1504 | 1415 |
1505 // delete and move elements to make space for add_count new elements | 1416 // Delete and move elements to make space for add_count new elements. |
1506 bool elms_changed = false; | |
1507 if (add_count < delete_count) { | 1417 if (add_count < delete_count) { |
1508 elms_changed = SpliceShrinkStep(backing_store, heap, start, delete_count, | 1418 FastElementsAccessorSubclass::SpliceShrinkStep(backing_store, heap, start, |
1509 add_count, len, new_length); | 1419 delete_count, add_count, |
| 1420 length, new_length); |
1510 } else if (add_count > delete_count) { | 1421 } else if (add_count > delete_count) { |
1511 elms_changed = | 1422 backing_store = FastElementsAccessorSubclass::SpliceGrowStep( |
1512 SpliceGrowStep(receiver, backing_store, isolate, heap, start, | 1423 receiver, backing_store, isolate, heap, start, delete_count, |
1513 delete_count, add_count, len, new_length); | 1424 add_count, length, new_length); |
1514 } | 1425 } |
1515 | 1426 |
1516 // Copy new Elements from args | 1427 // Copy over the arguments. |
1517 DisallowHeapAllocation no_gc; | 1428 FastElementsAccessorSubclass::CopyArguments(args, backing_store, add_count, |
1518 FixedArrayBase* raw_backing_store = *backing_store; | 1429 3, start); |
1519 WriteBarrierMode mode = raw_backing_store->GetWriteBarrierMode(no_gc); | |
1520 for (uint32_t index = 0; index < add_count; index++) { | |
1521 Object* object = (*args)[3 + index]; | |
1522 FastElementsAccessorSubclass::SetImpl(raw_backing_store, index + start, | |
1523 object, mode); | |
1524 } | |
1525 | 1430 |
1526 if (elms_changed) { | |
1527 receiver->set_elements(*backing_store); | |
1528 } | |
1529 receiver->set_length(Smi::FromInt(new_length)); | 1431 receiver->set_length(Smi::FromInt(new_length)); |
1530 FastElementsAccessorSubclass::TryTransitionResultArrayToPacked( | 1432 FastElementsAccessorSubclass::TryTransitionResultArrayToPacked( |
1531 deleted_elements); | 1433 deleted_elements); |
1532 return deleted_elements; | 1434 return deleted_elements; |
1533 } | 1435 } |
1534 | 1436 |
1535 private: | 1437 private: |
1536 static bool SpliceShrinkStep(Handle<FixedArrayBase>& backing_store, | 1438 static void SpliceShrinkStep(Handle<FixedArrayBase> backing_store, Heap* heap, |
1537 Heap* heap, uint32_t start, | 1439 uint32_t start, uint32_t delete_count, |
1538 uint32_t delete_count, uint32_t add_count, | 1440 uint32_t add_count, uint32_t len, |
1539 uint32_t len, uint32_t new_length) { | 1441 uint32_t new_length) { |
1540 const int move_left_count = len - delete_count - start; | 1442 const int move_left_count = len - delete_count - start; |
1541 const int move_left_dst_index = start + add_count; | 1443 const int move_left_dst_index = start + add_count; |
1542 const bool left_trim_array = heap->CanMoveObjectStart(*backing_store) && | 1444 FastElementsAccessorSubclass::MoveElements( |
1543 (move_left_dst_index < move_left_count); | 1445 heap, backing_store, move_left_dst_index, start + delete_count, |
1544 if (left_trim_array) { | 1446 move_left_count, new_length, len); |
1545 const int delta = delete_count - add_count; | |
1546 // shift from before the insertion point to the right | |
1547 FastElementsAccessorSubclass::MoveElements(heap, backing_store, delta, 0, | |
1548 start, 0, 0); | |
1549 backing_store = handle(heap->LeftTrimFixedArray(*backing_store, delta)); | |
1550 return true; | |
1551 } else { | |
1552 // No left-trim needed or possible (in this case we left-move and store | |
1553 // the hole) | |
1554 FastElementsAccessorSubclass::MoveElements( | |
1555 heap, backing_store, move_left_dst_index, start + delete_count, | |
1556 move_left_count, new_length, len); | |
1557 } | |
1558 return false; | |
1559 } | 1447 } |
1560 | 1448 |
1561 | 1449 |
1562 static bool SpliceGrowStep(Handle<JSArray> receiver, | 1450 static Handle<FixedArrayBase> SpliceGrowStep( |
1563 Handle<FixedArrayBase>& backing_store, | 1451 Handle<JSArray> receiver, Handle<FixedArrayBase> backing_store, |
1564 Isolate* isolate, Heap* heap, uint32_t start, | 1452 Isolate* isolate, Heap* heap, uint32_t start, uint32_t delete_count, |
1565 uint32_t delete_count, uint32_t add_count, | 1453 uint32_t add_count, uint32_t length, uint32_t new_length) { |
1566 uint32_t len, uint32_t new_length) { | 1454 // Check we do not overflow the new_length. |
1567 // Currently fixed arrays cannot grow too big, so | 1455 DCHECK((add_count - delete_count) <= (Smi::kMaxValue - length)); |
1568 // we should never hit this case. | 1456 // Check if backing_store is big enough. |
1569 DCHECK((add_count - delete_count) <= (Smi::kMaxValue - len)); | 1457 if (new_length <= static_cast<uint32_t>(backing_store->length())) { |
1570 // Check if backing_store needs to grow. | |
1571 if (new_length > static_cast<uint32_t>(backing_store->length())) { | |
1572 // New backing storage is needed. | |
1573 int capacity = new_length + (new_length >> 1) + 16; | |
1574 // partially copy all elements up to start | |
1575 Handle<FixedArrayBase> new_elms = | |
1576 FastElementsAccessorSubclass::ConvertElementsWithCapacity( | |
1577 receiver, backing_store, KindTraits::Kind, capacity, start); | |
1578 // Copy the trailing elements after start + delete_count | |
1579 FastElementsAccessorSubclass::CopyElementsImpl( | |
1580 *backing_store, start + delete_count, *new_elms, KindTraits::Kind, | |
1581 start + add_count, kPackedSizeNotKnown, | |
1582 ElementsAccessor::kCopyToEndAndInitializeToHole); | |
1583 | |
1584 backing_store = new_elms; | |
1585 return true; | |
1586 } else { | |
1587 DisallowHeapAllocation no_gc; | |
1588 FastElementsAccessorSubclass::MoveElements( | 1458 FastElementsAccessorSubclass::MoveElements( |
1589 heap, backing_store, start + add_count, start + delete_count, | 1459 heap, backing_store, start + add_count, start + delete_count, |
1590 (len - delete_count - start), 0, 0); | 1460 (length - delete_count - start), 0, 0); |
| 1461 return backing_store; |
1591 } | 1462 } |
1592 return false; | 1463 // New backing storage is needed. |
| 1464 int capacity = JSObject::NewElementsCapacity(new_length); |
| 1465 // Partially copy all elements up to start. |
| 1466 Handle<FixedArrayBase> new_elms = |
| 1467 FastElementsAccessorSubclass::ConvertElementsWithCapacity( |
| 1468 receiver, backing_store, KindTraits::Kind, capacity, start); |
| 1469 // Copy the trailing elements after start + delete_count |
| 1470 FastElementsAccessorSubclass::CopyElementsImpl( |
| 1471 *backing_store, start + delete_count, *new_elms, KindTraits::Kind, |
| 1472 start + add_count, kPackedSizeNotKnown, |
| 1473 ElementsAccessor::kCopyToEndAndInitializeToHole); |
| 1474 receiver->set_elements(*new_elms); |
| 1475 return new_elms; |
| 1476 } |
| 1477 |
| 1478 static Handle<Object> RemoveElement(Handle<JSArray> receiver, |
| 1479 Handle<FixedArrayBase> backing_store, |
| 1480 Where remove_position) { |
| 1481 uint32_t length = |
| 1482 static_cast<uint32_t>(Smi::cast(receiver->length())->value()); |
| 1483 Isolate* isolate = receiver->GetIsolate(); |
| 1484 DCHECK(length > 0); |
| 1485 int new_length = length - 1; |
| 1486 int remove_index = remove_position == AT_START ? 0 : new_length; |
| 1487 Handle<Object> result = |
| 1488 FastElementsAccessorSubclass::GetImpl(backing_store, remove_index); |
| 1489 if (remove_position == AT_START) { |
| 1490 Heap* heap = isolate->heap(); |
| 1491 FastElementsAccessorSubclass::MoveElements(heap, backing_store, 0, 1, |
| 1492 new_length, 0, 0); |
| 1493 } |
| 1494 FastElementsAccessorSubclass::SetLengthImpl(receiver, new_length, |
| 1495 backing_store); |
| 1496 |
| 1497 if (IsHoleyElementsKind(KindTraits::Kind) && result->IsTheHole()) { |
| 1498 return receiver->GetIsolate()->factory()->undefined_value(); |
| 1499 } |
| 1500 return result; |
| 1501 } |
| 1502 |
| 1503 static uint32_t AddArguments(Handle<JSArray> receiver, |
| 1504 Handle<FixedArrayBase> backing_store, |
| 1505 Arguments* args, uint32_t add_size, |
| 1506 Where remove_position) { |
| 1507 uint32_t length = Smi::cast(receiver->length())->value(); |
| 1508 DCHECK(add_size > 0); |
| 1509 uint32_t elms_len = backing_store->length(); |
| 1510 // Check we do not overflow the new_length. |
| 1511 DCHECK(add_size <= static_cast<uint32_t>(Smi::kMaxValue - length)); |
| 1512 uint32_t new_length = length + add_size; |
| 1513 |
| 1514 if (new_length > elms_len) { |
| 1515 // New backing storage is needed. |
| 1516 uint32_t capacity = JSObject::NewElementsCapacity(new_length); |
| 1517 // If we add arguments to the start we have to shift the existing objects. |
| 1518 int copy_dst_index = remove_position == AT_START ? add_size : 0; |
| 1519 // Copy over all objects to a new backing_store. |
| 1520 backing_store = FastElementsAccessorSubclass::ConvertElementsWithCapacity( |
| 1521 receiver, backing_store, KindTraits::Kind, capacity, 0, |
| 1522 copy_dst_index, ElementsAccessor::kCopyToEndAndInitializeToHole); |
| 1523 receiver->set_elements(*backing_store); |
| 1524 } else if (remove_position == AT_START) { |
| 1525 // If the backing store has enough capacity and we add elements to the |
| 1526 // start we have to shift the existing objects. |
| 1527 Isolate* isolate = receiver->GetIsolate(); |
| 1528 FastElementsAccessorSubclass::MoveElements(isolate->heap(), backing_store, |
| 1529 add_size, 0, length, 0, 0); |
| 1530 } |
| 1531 |
| 1532 int insertion_index = remove_position == AT_START ? 0 : length; |
| 1533 // Copy the arguments to the start. |
| 1534 FastElementsAccessorSubclass::CopyArguments(args, backing_store, add_size, |
| 1535 1, insertion_index); |
| 1536 // Set the length. |
| 1537 receiver->set_length(Smi::FromInt(new_length)); |
| 1538 return new_length; |
| 1539 } |
| 1540 |
| 1541 static void CopyArguments(Arguments* args, Handle<FixedArrayBase> dst_store, |
| 1542 uint32_t copy_size, uint32_t src_index, |
| 1543 uint32_t dst_index) { |
| 1544 // Add the provided values. |
| 1545 DisallowHeapAllocation no_gc; |
| 1546 FixedArrayBase* raw_backing_store = *dst_store; |
| 1547 WriteBarrierMode mode = raw_backing_store->GetWriteBarrierMode(no_gc); |
| 1548 for (uint32_t i = 0; i < copy_size; i++) { |
| 1549 Object* argument = (*args)[i + src_index]; |
| 1550 FastElementsAccessorSubclass::SetImpl(raw_backing_store, i + dst_index, |
| 1551 argument, mode); |
| 1552 } |
1593 } | 1553 } |
1594 }; | 1554 }; |
1595 | 1555 |
1596 | 1556 |
1597 template<typename FastElementsAccessorSubclass, | 1557 template<typename FastElementsAccessorSubclass, |
1598 typename KindTraits> | 1558 typename KindTraits> |
1599 class FastSmiOrObjectElementsAccessor | 1559 class FastSmiOrObjectElementsAccessor |
1600 : public FastElementsAccessor<FastElementsAccessorSubclass, KindTraits> { | 1560 : public FastElementsAccessor<FastElementsAccessorSubclass, KindTraits> { |
1601 public: | 1561 public: |
1602 explicit FastSmiOrObjectElementsAccessor(const char* name) | 1562 explicit FastSmiOrObjectElementsAccessor(const char* name) |
(...skipping 834 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2437 } | 2397 } |
2438 } | 2398 } |
2439 | 2399 |
2440 DCHECK(j == result_len); | 2400 DCHECK(j == result_len); |
2441 return result_array; | 2401 return result_array; |
2442 } | 2402 } |
2443 | 2403 |
2444 ElementsAccessor** ElementsAccessor::elements_accessors_ = NULL; | 2404 ElementsAccessor** ElementsAccessor::elements_accessors_ = NULL; |
2445 } // namespace internal | 2405 } // namespace internal |
2446 } // namespace v8 | 2406 } // namespace v8 |
OLD | NEW |