| 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 584 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 595 new_capacity); | 595 new_capacity); |
| 596 } | 596 } |
| 597 | 597 |
| 598 static void AddImpl(Handle<JSObject> object, uint32_t index, | 598 static void AddImpl(Handle<JSObject> object, uint32_t index, |
| 599 Handle<Object> value, PropertyAttributes attributes, | 599 Handle<Object> value, PropertyAttributes attributes, |
| 600 uint32_t new_capacity) { | 600 uint32_t new_capacity) { |
| 601 UNREACHABLE(); | 601 UNREACHABLE(); |
| 602 } | 602 } |
| 603 | 603 |
| 604 virtual uint32_t Push(Handle<JSArray> receiver, | 604 virtual uint32_t Push(Handle<JSArray> receiver, |
| 605 Handle<FixedArrayBase> backing_store, Object** objects, | 605 Handle<FixedArrayBase> backing_store, Arguments* args, |
| 606 uint32_t push_size, int direction) final { | 606 uint32_t push_size) final { |
| 607 return ElementsAccessorSubclass::PushImpl(receiver, backing_store, objects, | 607 return ElementsAccessorSubclass::PushImpl(receiver, backing_store, args, |
| 608 push_size, direction); | 608 push_size); |
| 609 } | 609 } |
| 610 | 610 |
| 611 static uint32_t PushImpl(Handle<JSArray> receiver, | 611 static uint32_t PushImpl(Handle<JSArray> receiver, |
| 612 Handle<FixedArrayBase> elms_obj, Object** objects, | 612 Handle<FixedArrayBase> elms_obj, Arguments* args, |
| 613 uint32_t push_size, int direction) { | 613 uint32_t push_sized) { |
| 614 UNREACHABLE(); | 614 UNREACHABLE(); |
| 615 return 0; | 615 return 0; |
| 616 } | 616 } |
| 617 | 617 |
| 618 virtual uint32_t Unshift(Handle<JSArray> receiver, | 618 virtual uint32_t Unshift(Handle<JSArray> receiver, |
| 619 Handle<FixedArrayBase> backing_store, | 619 Handle<FixedArrayBase> backing_store, |
| 620 Arguments* args, uint32_t unshift_size) final { | 620 Arguments* args, uint32_t unshift_size) final { |
| 621 return ElementsAccessorSubclass::UnshiftImpl(receiver, backing_store, args, | 621 return ElementsAccessorSubclass::UnshiftImpl(receiver, backing_store, args, |
| 622 unshift_size); | 622 unshift_size); |
| 623 } | 623 } |
| (...skipping 15 matching lines...) Expand all Loading... |
| 639 static Handle<JSArray> SliceImpl(Handle<JSObject> receiver, | 639 static Handle<JSArray> SliceImpl(Handle<JSObject> receiver, |
| 640 Handle<FixedArrayBase> backing_store, | 640 Handle<FixedArrayBase> backing_store, |
| 641 uint32_t start, uint32_t end) { | 641 uint32_t start, uint32_t end) { |
| 642 UNREACHABLE(); | 642 UNREACHABLE(); |
| 643 return Handle<JSArray>(); | 643 return Handle<JSArray>(); |
| 644 } | 644 } |
| 645 | 645 |
| 646 virtual Handle<JSArray> Splice(Handle<JSArray> receiver, | 646 virtual Handle<JSArray> Splice(Handle<JSArray> receiver, |
| 647 Handle<FixedArrayBase> backing_store, | 647 Handle<FixedArrayBase> backing_store, |
| 648 uint32_t start, uint32_t delete_count, | 648 uint32_t start, uint32_t delete_count, |
| 649 Arguments args, uint32_t add_count) final { | 649 Arguments* args, uint32_t add_count) final { |
| 650 return ElementsAccessorSubclass::SpliceImpl(receiver, backing_store, start, | 650 return ElementsAccessorSubclass::SpliceImpl(receiver, backing_store, start, |
| 651 delete_count, args, add_count); | 651 delete_count, args, add_count); |
| 652 } | 652 } |
| 653 | 653 |
| 654 static Handle<JSArray> SpliceImpl(Handle<JSArray> receiver, | 654 static Handle<JSArray> SpliceImpl(Handle<JSArray> receiver, |
| 655 Handle<FixedArrayBase> backing_store, | 655 Handle<FixedArrayBase> backing_store, |
| 656 uint32_t start, uint32_t delete_count, | 656 uint32_t start, uint32_t delete_count, |
| 657 Arguments args, uint32_t add_count) { | 657 Arguments* args, uint32_t add_count) { |
| 658 UNREACHABLE(); | 658 UNREACHABLE(); |
| 659 return Handle<JSArray>(); | 659 return Handle<JSArray>(); |
| 660 } | 660 } |
| 661 | 661 |
| 662 virtual Handle<Object> Pop(Handle<JSArray> receiver, | 662 virtual Handle<Object> Pop(Handle<JSArray> receiver, |
| 663 Handle<FixedArrayBase> backing_store) final { | 663 Handle<FixedArrayBase> backing_store) final { |
| 664 return ElementsAccessorSubclass::PopImpl(receiver, backing_store); | 664 return ElementsAccessorSubclass::PopImpl(receiver, backing_store); |
| 665 } | 665 } |
| 666 | 666 |
| 667 static Handle<Object> PopImpl(Handle<JSArray> receiver, | 667 static Handle<Object> PopImpl(Handle<JSArray> receiver, |
| (...skipping 601 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1269 backing_store); | 1269 backing_store); |
| 1270 | 1270 |
| 1271 if (IsHoleyElementsKind(KindTraits::Kind) && result->IsTheHole()) { | 1271 if (IsHoleyElementsKind(KindTraits::Kind) && result->IsTheHole()) { |
| 1272 result = receiver->GetIsolate()->factory()->undefined_value(); | 1272 result = receiver->GetIsolate()->factory()->undefined_value(); |
| 1273 } | 1273 } |
| 1274 return result; | 1274 return result; |
| 1275 } | 1275 } |
| 1276 | 1276 |
| 1277 static uint32_t PushImpl(Handle<JSArray> receiver, | 1277 static uint32_t PushImpl(Handle<JSArray> receiver, |
| 1278 Handle<FixedArrayBase> backing_store, | 1278 Handle<FixedArrayBase> backing_store, |
| 1279 Object** objects, uint32_t push_size, | 1279 Arguments* args, uint32_t push_size) { |
| 1280 int direction) { | |
| 1281 uint32_t len = Smi::cast(receiver->length())->value(); | 1280 uint32_t len = Smi::cast(receiver->length())->value(); |
| 1282 if (push_size == 0) { | 1281 if (push_size == 0) { |
| 1283 return len; | 1282 return len; |
| 1284 } | 1283 } |
| 1285 uint32_t elms_len = backing_store->length(); | 1284 uint32_t elms_len = backing_store->length(); |
| 1286 // Currently fixed arrays cannot grow too big, so | 1285 // Currently fixed arrays cannot grow too big, so |
| 1287 // we should never hit this case. | 1286 // we should never hit this case. |
| 1288 DCHECK(push_size <= static_cast<uint32_t>(Smi::kMaxValue - len)); | 1287 DCHECK(push_size <= static_cast<uint32_t>(Smi::kMaxValue - len)); |
| 1289 uint32_t new_length = len + push_size; | 1288 uint32_t new_length = len + push_size; |
| 1290 Handle<FixedArrayBase> new_elms; | |
| 1291 | 1289 |
| 1292 if (new_length > elms_len) { | 1290 if (new_length > elms_len) { |
| 1293 // New backing storage is needed. | 1291 // New backing storage is needed. |
| 1294 uint32_t capacity = new_length + (new_length >> 1) + 16; | 1292 uint32_t capacity = new_length + (new_length >> 1) + 16; |
| 1295 new_elms = FastElementsAccessorSubclass::ConvertElementsWithCapacity( | 1293 backing_store = FastElementsAccessorSubclass::ConvertElementsWithCapacity( |
| 1296 receiver, backing_store, KindTraits::Kind, capacity); | 1294 receiver, backing_store, KindTraits::Kind, capacity); |
| 1297 } else { | 1295 receiver->set_elements(*backing_store); |
| 1298 // push_size is > 0 and new_length <= elms_len, so backing_store cannot be | |
| 1299 // the empty_fixed_array. | |
| 1300 new_elms = backing_store; | |
| 1301 } | 1296 } |
| 1302 | 1297 |
| 1303 // Add the provided values. | 1298 // Add the provided values. |
| 1304 DisallowHeapAllocation no_gc; | 1299 DisallowHeapAllocation no_gc; |
| 1305 DCHECK(direction == ElementsAccessor::kDirectionForward || | 1300 FixedArrayBase* raw_backing_store = *backing_store; |
| 1306 direction == ElementsAccessor::kDirectionReverse); | 1301 WriteBarrierMode mode = raw_backing_store->GetWriteBarrierMode(no_gc); |
| 1307 STATIC_ASSERT(ElementsAccessor::kDirectionForward == 1); | |
| 1308 STATIC_ASSERT(ElementsAccessor::kDirectionReverse == -1); | |
| 1309 for (uint32_t index = 0; index < push_size; index++) { | 1302 for (uint32_t index = 0; index < push_size; index++) { |
| 1310 int offset = direction * index; | 1303 Object* object = (*args)[index + 1]; |
| 1311 Object* object = objects[offset]; | 1304 FastElementsAccessorSubclass::SetImpl(raw_backing_store, index + len, |
| 1312 FastElementsAccessorSubclass::SetImpl(*new_elms, index + len, object); | 1305 object, mode); |
| 1313 } | 1306 } |
| 1314 if (!new_elms.is_identical_to(backing_store)) { | 1307 DCHECK(*backing_store == receiver->elements()); |
| 1315 receiver->set_elements(*new_elms); | |
| 1316 } | |
| 1317 DCHECK(*new_elms == receiver->elements()); | |
| 1318 // Set the length. | 1308 // Set the length. |
| 1319 receiver->set_length(Smi::FromInt(new_length)); | 1309 receiver->set_length(Smi::FromInt(new_length)); |
| 1320 return new_length; | 1310 return new_length; |
| 1321 } | 1311 } |
| 1322 | 1312 |
| 1323 static uint32_t UnshiftImpl(Handle<JSArray> receiver, | 1313 static uint32_t UnshiftImpl(Handle<JSArray> receiver, |
| 1324 Handle<FixedArrayBase> backing_store, | 1314 Handle<FixedArrayBase> backing_store, |
| 1325 Arguments* args, uint32_t unshift_size) { | 1315 Arguments* args, uint32_t unshift_size) { |
| 1326 uint32_t len = Smi::cast(receiver->length())->value(); | 1316 uint32_t len = Smi::cast(receiver->length())->value(); |
| 1327 if (unshift_size == 0) { | 1317 if (unshift_size == 0) { |
| (...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1382 DisallowHeapAllocation no_gc; | 1372 DisallowHeapAllocation no_gc; |
| 1383 FastElementsAccessorSubclass::CopyElementsImpl( | 1373 FastElementsAccessorSubclass::CopyElementsImpl( |
| 1384 *backing_store, start, result_array->elements(), KindTraits::Kind, 0, | 1374 *backing_store, start, result_array->elements(), KindTraits::Kind, 0, |
| 1385 kPackedSizeNotKnown, result_len); | 1375 kPackedSizeNotKnown, result_len); |
| 1386 return result_array; | 1376 return result_array; |
| 1387 } | 1377 } |
| 1388 | 1378 |
| 1389 static Handle<JSArray> SpliceImpl(Handle<JSArray> receiver, | 1379 static Handle<JSArray> SpliceImpl(Handle<JSArray> receiver, |
| 1390 Handle<FixedArrayBase> backing_store, | 1380 Handle<FixedArrayBase> backing_store, |
| 1391 uint32_t start, uint32_t delete_count, | 1381 uint32_t start, uint32_t delete_count, |
| 1392 Arguments args, uint32_t add_count) { | 1382 Arguments* args, uint32_t add_count) { |
| 1393 Isolate* isolate = receiver->GetIsolate(); | 1383 Isolate* isolate = receiver->GetIsolate(); |
| 1394 Heap* heap = isolate->heap(); | 1384 Heap* heap = isolate->heap(); |
| 1395 uint32_t len = Smi::cast(receiver->length())->value(); | 1385 uint32_t len = Smi::cast(receiver->length())->value(); |
| 1396 uint32_t new_length = len - delete_count + add_count; | 1386 uint32_t new_length = len - delete_count + add_count; |
| 1397 | 1387 |
| 1398 if (new_length == 0) { | 1388 if (new_length == 0) { |
| 1399 receiver->set_elements(heap->empty_fixed_array()); | 1389 receiver->set_elements(heap->empty_fixed_array()); |
| 1400 receiver->set_length(Smi::FromInt(0)); | 1390 receiver->set_length(Smi::FromInt(0)); |
| 1401 return isolate->factory()->NewJSArrayWithElements( | 1391 return isolate->factory()->NewJSArrayWithElements( |
| 1402 backing_store, KindTraits::Kind, delete_count); | 1392 backing_store, KindTraits::Kind, delete_count); |
| (...skipping 15 matching lines...) Expand all Loading... |
| 1418 elms_changed = SpliceShrinkStep(backing_store, heap, start, delete_count, | 1408 elms_changed = SpliceShrinkStep(backing_store, heap, start, delete_count, |
| 1419 add_count, len, new_length); | 1409 add_count, len, new_length); |
| 1420 } else if (add_count > delete_count) { | 1410 } else if (add_count > delete_count) { |
| 1421 elms_changed = | 1411 elms_changed = |
| 1422 SpliceGrowStep(receiver, backing_store, isolate, heap, start, | 1412 SpliceGrowStep(receiver, backing_store, isolate, heap, start, |
| 1423 delete_count, add_count, len, new_length); | 1413 delete_count, add_count, len, new_length); |
| 1424 } | 1414 } |
| 1425 | 1415 |
| 1426 // Copy new Elements from args | 1416 // Copy new Elements from args |
| 1427 DisallowHeapAllocation no_gc; | 1417 DisallowHeapAllocation no_gc; |
| 1428 for (uint32_t index = start; index < start + add_count; index++) { | 1418 FixedArrayBase* raw_backing_store = *backing_store; |
| 1429 Object* arg = args[3 + index - start]; | 1419 WriteBarrierMode mode = raw_backing_store->GetWriteBarrierMode(no_gc); |
| 1430 FastElementsAccessorSubclass::SetImpl(*backing_store, index, arg); | 1420 for (uint32_t index = 0; index < add_count; index++) { |
| 1421 Object* object = (*args)[3 + index]; |
| 1422 FastElementsAccessorSubclass::SetImpl(raw_backing_store, index + start, |
| 1423 object, mode); |
| 1431 } | 1424 } |
| 1432 | 1425 |
| 1433 if (elms_changed) { | 1426 if (elms_changed) { |
| 1434 receiver->set_elements(*backing_store); | 1427 receiver->set_elements(*backing_store); |
| 1435 } | 1428 } |
| 1436 receiver->set_length(Smi::FromInt(new_length)); | 1429 receiver->set_length(Smi::FromInt(new_length)); |
| 1437 return deleted_elements; | 1430 return deleted_elements; |
| 1438 } | 1431 } |
| 1439 | 1432 |
| 1440 private: | 1433 private: |
| (...skipping 883 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2324 if (elements_accessors_ == NULL) return; | 2317 if (elements_accessors_ == NULL) return; |
| 2325 #define ACCESSOR_DELETE(Class, Kind, Store) delete elements_accessors_[Kind]; | 2318 #define ACCESSOR_DELETE(Class, Kind, Store) delete elements_accessors_[Kind]; |
| 2326 ELEMENTS_LIST(ACCESSOR_DELETE) | 2319 ELEMENTS_LIST(ACCESSOR_DELETE) |
| 2327 #undef ACCESSOR_DELETE | 2320 #undef ACCESSOR_DELETE |
| 2328 elements_accessors_ = NULL; | 2321 elements_accessors_ = NULL; |
| 2329 } | 2322 } |
| 2330 | 2323 |
| 2331 ElementsAccessor** ElementsAccessor::elements_accessors_ = NULL; | 2324 ElementsAccessor** ElementsAccessor::elements_accessors_ = NULL; |
| 2332 } // namespace internal | 2325 } // namespace internal |
| 2333 } // namespace v8 | 2326 } // namespace v8 |
| OLD | NEW |