Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(3)

Side by Side Diff: src/elements.cc

Issue 1322803002: Adding ElementsAccessor::Unshift (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@2015-08-28_elements_accessor_pop
Patch Set: less indirections Created 5 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « src/elements.h ('k') | src/objects.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 544 matching lines...) Expand 10 before | Expand all | Expand 10 after
555 uint32_t entry) { 555 uint32_t entry) {
556 uint32_t index = GetIndexForEntryImpl(*backing_store, entry); 556 uint32_t index = GetIndexForEntryImpl(*backing_store, entry);
557 return BackingStore::get(Handle<BackingStore>::cast(backing_store), index); 557 return BackingStore::get(Handle<BackingStore>::cast(backing_store), index);
558 } 558 }
559 559
560 virtual void Set(FixedArrayBase* backing_store, uint32_t entry, 560 virtual void Set(FixedArrayBase* backing_store, uint32_t entry,
561 Object* value) final { 561 Object* value) final {
562 ElementsAccessorSubclass::SetImpl(backing_store, entry, value); 562 ElementsAccessorSubclass::SetImpl(backing_store, entry, value);
563 } 563 }
564 564
565 static void SetImpl(FixedArrayBase* backing_store, uint32_t entry, 565 static inline void SetImpl(FixedArrayBase* backing_store, uint32_t entry,
566 Object* value) { 566 Object* value) {
567 BackingStore::cast(backing_store)->SetValue(entry, value); 567 BackingStore::cast(backing_store)->SetValue(entry, value);
568 } 568 }
569 569
570 static inline void SetImpl(FixedArrayBase* backing_store, uint32_t entry,
571 Object* value, WriteBarrierMode mode) {
572 BackingStore::cast(backing_store)->SetValue(entry, value);
573 }
574
570 virtual void Reconfigure(Handle<JSObject> object, 575 virtual void Reconfigure(Handle<JSObject> object,
571 Handle<FixedArrayBase> store, uint32_t entry, 576 Handle<FixedArrayBase> store, uint32_t entry,
572 Handle<Object> value, 577 Handle<Object> value,
573 PropertyAttributes attributes) final { 578 PropertyAttributes attributes) final {
574 ElementsAccessorSubclass::ReconfigureImpl(object, store, entry, value, 579 ElementsAccessorSubclass::ReconfigureImpl(object, store, entry, value,
575 attributes); 580 attributes);
576 } 581 }
577 582
578 static void ReconfigureImpl(Handle<JSObject> object, 583 static void ReconfigureImpl(Handle<JSObject> object,
579 Handle<FixedArrayBase> store, uint32_t entry, 584 Handle<FixedArrayBase> store, uint32_t entry,
(...skipping 22 matching lines...) Expand all
602 push_size, direction); 607 push_size, direction);
603 } 608 }
604 609
605 static uint32_t PushImpl(Handle<JSArray> receiver, 610 static uint32_t PushImpl(Handle<JSArray> receiver,
606 Handle<FixedArrayBase> elms_obj, Object** objects, 611 Handle<FixedArrayBase> elms_obj, Object** objects,
607 uint32_t push_size, int direction) { 612 uint32_t push_size, int direction) {
608 UNREACHABLE(); 613 UNREACHABLE();
609 return 0; 614 return 0;
610 } 615 }
611 616
617 virtual uint32_t Unshift(Handle<JSArray> receiver,
618 Handle<FixedArrayBase> backing_store,
619 Arguments* args, uint32_t unshift_size) final {
620 return ElementsAccessorSubclass::UnshiftImpl(receiver, backing_store, args,
621 unshift_size);
622 }
623
624 static uint32_t UnshiftImpl(Handle<JSArray> receiver,
625 Handle<FixedArrayBase> elms_obj, Arguments* args,
626 uint32_t unshift_size) {
627 UNREACHABLE();
628 return 0;
629 }
630
612 virtual Handle<JSArray> Slice(Handle<JSObject> receiver, 631 virtual Handle<JSArray> Slice(Handle<JSObject> receiver,
613 Handle<FixedArrayBase> backing_store, 632 Handle<FixedArrayBase> backing_store,
614 uint32_t start, uint32_t end) final { 633 uint32_t start, uint32_t end) final {
615 return ElementsAccessorSubclass::SliceImpl(receiver, backing_store, start, 634 return ElementsAccessorSubclass::SliceImpl(receiver, backing_store, start,
616 end); 635 end);
617 } 636 }
618 637
619 static Handle<JSArray> SliceImpl(Handle<JSObject> receiver, 638 static Handle<JSArray> SliceImpl(Handle<JSObject> receiver,
620 Handle<FixedArrayBase> backing_store, 639 Handle<FixedArrayBase> backing_store,
621 uint32_t start, uint32_t end) { 640 uint32_t start, uint32_t end) {
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
655 handle(array->elements())); 674 handle(array->elements()));
656 } 675 }
657 676
658 static void SetLengthImpl(Handle<JSArray> array, uint32_t length, 677 static void SetLengthImpl(Handle<JSArray> array, uint32_t length,
659 Handle<FixedArrayBase> backing_store); 678 Handle<FixedArrayBase> backing_store);
660 679
661 static Handle<FixedArrayBase> ConvertElementsWithCapacity( 680 static Handle<FixedArrayBase> ConvertElementsWithCapacity(
662 Handle<JSObject> object, Handle<FixedArrayBase> old_elements, 681 Handle<JSObject> object, Handle<FixedArrayBase> old_elements,
663 ElementsKind from_kind, uint32_t capacity) { 682 ElementsKind from_kind, uint32_t capacity) {
664 return ConvertElementsWithCapacity( 683 return ConvertElementsWithCapacity(
665 object, old_elements, from_kind, capacity, 684 object, old_elements, from_kind, capacity, 0, 0,
666 ElementsAccessor::kCopyToEndAndInitializeToHole); 685 ElementsAccessor::kCopyToEndAndInitializeToHole);
667 } 686 }
668 687
669 static Handle<FixedArrayBase> ConvertElementsWithCapacity( 688 static Handle<FixedArrayBase> ConvertElementsWithCapacity(
670 Handle<JSObject> object, Handle<FixedArrayBase> old_elements, 689 Handle<JSObject> object, Handle<FixedArrayBase> old_elements,
671 ElementsKind from_kind, uint32_t capacity, int copy_size) { 690 ElementsKind from_kind, uint32_t capacity, int copy_size) {
691 return ConvertElementsWithCapacity(object, old_elements, from_kind,
692 capacity, 0, 0, copy_size);
693 }
694
695 static Handle<FixedArrayBase> ConvertElementsWithCapacity(
696 Handle<JSObject> object, Handle<FixedArrayBase> old_elements,
697 ElementsKind from_kind, uint32_t capacity, uint32_t src_index,
698 uint32_t dst_index, int copy_size) {
Camillo Bruni 2015/09/01 08:45:12 Added this ConvertElementsWithCapacity to avoid co
672 Isolate* isolate = object->GetIsolate(); 699 Isolate* isolate = object->GetIsolate();
673 Handle<FixedArrayBase> new_elements; 700 Handle<FixedArrayBase> new_elements;
674 if (IsFastDoubleElementsKind(kind())) { 701 if (IsFastDoubleElementsKind(kind())) {
675 new_elements = isolate->factory()->NewFixedDoubleArray(capacity); 702 new_elements = isolate->factory()->NewFixedDoubleArray(capacity);
676 } else { 703 } else {
677 new_elements = isolate->factory()->NewUninitializedFixedArray(capacity); 704 new_elements = isolate->factory()->NewUninitializedFixedArray(capacity);
678 } 705 }
679 706
680 int packed_size = kPackedSizeNotKnown; 707 int packed_size = kPackedSizeNotKnown;
681 if (IsFastPackedElementsKind(from_kind) && object->IsJSArray()) { 708 if (IsFastPackedElementsKind(from_kind) && object->IsJSArray()) {
682 packed_size = Smi::cast(JSArray::cast(*object)->length())->value(); 709 packed_size = Smi::cast(JSArray::cast(*object)->length())->value();
683 } 710 }
684 711
685 ElementsAccessorSubclass::CopyElementsImpl( 712 ElementsAccessorSubclass::CopyElementsImpl(
686 *old_elements, 0, *new_elements, from_kind, 0, packed_size, copy_size); 713 *old_elements, src_index, *new_elements, from_kind, dst_index,
714 packed_size, copy_size);
687 715
688 return new_elements; 716 return new_elements;
689 } 717 }
690 718
691 static void GrowCapacityAndConvertImpl(Handle<JSObject> object, 719 static void GrowCapacityAndConvertImpl(Handle<JSObject> object,
692 uint32_t capacity) { 720 uint32_t capacity) {
693 ElementsKind from_kind = object->GetElementsKind(); 721 ElementsKind from_kind = object->GetElementsKind();
694 if (IsFastSmiOrObjectElementsKind(from_kind)) { 722 if (IsFastSmiOrObjectElementsKind(from_kind)) {
695 // Array optimizations rely on the prototype lookups of Array objects 723 // Array optimizations rely on the prototype lookups of Array objects
696 // always returning undefined. If there is a store to the initial 724 // always returning undefined. If there is a store to the initial
(...skipping 297 matching lines...) Expand 10 before | Expand all | Expand 10 after
994 static Object* GetRaw(FixedArrayBase* store, uint32_t entry) { 1022 static Object* GetRaw(FixedArrayBase* store, uint32_t entry) {
995 SeededNumberDictionary* backing_store = SeededNumberDictionary::cast(store); 1023 SeededNumberDictionary* backing_store = SeededNumberDictionary::cast(store);
996 return backing_store->ValueAt(entry); 1024 return backing_store->ValueAt(entry);
997 } 1025 }
998 1026
999 static Handle<Object> GetImpl(Handle<FixedArrayBase> store, uint32_t entry) { 1027 static Handle<Object> GetImpl(Handle<FixedArrayBase> store, uint32_t entry) {
1000 Isolate* isolate = store->GetIsolate(); 1028 Isolate* isolate = store->GetIsolate();
1001 return handle(GetRaw(*store, entry), isolate); 1029 return handle(GetRaw(*store, entry), isolate);
1002 } 1030 }
1003 1031
1004 static void SetImpl(FixedArrayBase* store, uint32_t entry, Object* value) { 1032 static inline void SetImpl(FixedArrayBase* store, uint32_t entry,
1033 Object* value) {
1005 SeededNumberDictionary* dictionary = SeededNumberDictionary::cast(store); 1034 SeededNumberDictionary* dictionary = SeededNumberDictionary::cast(store);
1006 dictionary->ValueAtPut(entry, value); 1035 dictionary->ValueAtPut(entry, value);
1007 } 1036 }
1008 1037
1009 static void ReconfigureImpl(Handle<JSObject> object, 1038 static void ReconfigureImpl(Handle<JSObject> object,
1010 Handle<FixedArrayBase> store, uint32_t entry, 1039 Handle<FixedArrayBase> store, uint32_t entry,
1011 Handle<Object> value, 1040 Handle<Object> value,
1012 PropertyAttributes attributes) { 1041 PropertyAttributes attributes) {
1013 SeededNumberDictionary* dictionary = SeededNumberDictionary::cast(*store); 1042 SeededNumberDictionary* dictionary = SeededNumberDictionary::cast(*store);
1014 if (attributes != NONE) object->RequireSlowElements(dictionary); 1043 if (attributes != NONE) object->RequireSlowElements(dictionary);
(...skipping 268 matching lines...) Expand 10 before | Expand all | Expand 10 after
1283 } 1312 }
1284 if (!new_elms.is_identical_to(backing_store)) { 1313 if (!new_elms.is_identical_to(backing_store)) {
1285 receiver->set_elements(*new_elms); 1314 receiver->set_elements(*new_elms);
1286 } 1315 }
1287 DCHECK(*new_elms == receiver->elements()); 1316 DCHECK(*new_elms == receiver->elements());
1288 // Set the length. 1317 // Set the length.
1289 receiver->set_length(Smi::FromInt(new_length)); 1318 receiver->set_length(Smi::FromInt(new_length));
1290 return new_length; 1319 return new_length;
1291 } 1320 }
1292 1321
1322 static uint32_t UnshiftImpl(Handle<JSArray> receiver,
1323 Handle<FixedArrayBase> backing_store,
1324 Arguments* args, uint32_t unshift_size) {
1325 uint32_t len = Smi::cast(receiver->length())->value();
1326 if (unshift_size == 0) {
1327 return len;
1328 }
1329 uint32_t elms_len = backing_store->length();
1330 // Currently fixed arrays cannot grow too big, so
1331 // we should never hit this case.
1332 DCHECK(unshift_size <= static_cast<uint32_t>(Smi::kMaxValue - len));
1333 uint32_t new_length = len + unshift_size;
1334
1335 if (new_length > elms_len) {
1336 // New backing storage is needed.
1337 uint32_t capacity = new_length + (new_length >> 1) + 16;
1338 backing_store = FastElementsAccessorSubclass::ConvertElementsWithCapacity(
1339 receiver, backing_store, KindTraits::Kind, capacity, 0, unshift_size,
1340 ElementsAccessor::kCopyToEndAndInitializeToHole);
1341 DisallowHeapAllocation no_gc;
1342 receiver->set_elements(*backing_store);
1343 } else {
1344 // unshift_size is > 0 and new_length <= elms_len, so backing_store cannot
1345 // be the empty_fixed_array.
1346 DisallowHeapAllocation no_gc;
1347 Isolate* isolate = receiver->GetIsolate();
1348 FastElementsAccessorSubclass::MoveElements(isolate->heap(), backing_store,
1349 unshift_size, 0, len, 0, 0);
1350 }
1351
1352 // Add the provided values.
1353 DisallowHeapAllocation no_gc;
1354 FixedArrayBase* raw_backing_store = *backing_store;
1355 WriteBarrierMode mode = raw_backing_store->GetWriteBarrierMode(no_gc);
Camillo Bruni 2015/09/01 08:45:12 Introduced the second SetImpl so we can pass along
1356 for (uint32_t index = 0; index < unshift_size; index++) {
1357 FastElementsAccessorSubclass::SetImpl(raw_backing_store, index,
1358 (*args)[index + 1], mode);
1359 }
1360 // Set the length.
1361 receiver->set_length(Smi::FromInt(new_length));
1362 return new_length;
1363 }
1364
1293 static void MoveElements(Heap* heap, Handle<FixedArrayBase> backing_store, 1365 static void MoveElements(Heap* heap, Handle<FixedArrayBase> backing_store,
1294 int dst_index, int src_index, int len, 1366 int dst_index, int src_index, int len,
1295 int hole_start, int hole_end) { 1367 int hole_start, int hole_end) {
1296 UNREACHABLE(); 1368 UNREACHABLE();
1297 } 1369 }
1298 1370
1299 static Handle<JSArray> SliceImpl(Handle<JSObject> receiver, 1371 static Handle<JSArray> SliceImpl(Handle<JSObject> receiver,
1300 Handle<FixedArrayBase> backing_store, 1372 Handle<FixedArrayBase> backing_store,
1301 uint32_t start, uint32_t end) { 1373 uint32_t start, uint32_t end) {
1302 Isolate* isolate = receiver->GetIsolate(); 1374 Isolate* isolate = receiver->GetIsolate();
(...skipping 125 matching lines...) Expand 10 before | Expand all | Expand 10 after
1428 1500
1429 template<typename FastElementsAccessorSubclass, 1501 template<typename FastElementsAccessorSubclass,
1430 typename KindTraits> 1502 typename KindTraits>
1431 class FastSmiOrObjectElementsAccessor 1503 class FastSmiOrObjectElementsAccessor
1432 : public FastElementsAccessor<FastElementsAccessorSubclass, KindTraits> { 1504 : public FastElementsAccessor<FastElementsAccessorSubclass, KindTraits> {
1433 public: 1505 public:
1434 explicit FastSmiOrObjectElementsAccessor(const char* name) 1506 explicit FastSmiOrObjectElementsAccessor(const char* name)
1435 : FastElementsAccessor<FastElementsAccessorSubclass, 1507 : FastElementsAccessor<FastElementsAccessorSubclass,
1436 KindTraits>(name) {} 1508 KindTraits>(name) {}
1437 1509
1510 static inline void SetImpl(FixedArrayBase* backing_store, uint32_t entry,
1511 Object* value) {
1512 FixedArray::cast(backing_store)->set(entry, value);
Camillo Bruni 2015/09/01 08:45:13 If I don't use the more uniform SetValue method (w
1513 }
1514
1515 static inline void SetImpl(FixedArrayBase* backing_store, uint32_t entry,
1516 Object* value, WriteBarrierMode mode) {
1517 FixedArray::cast(backing_store)->set(entry, value, mode);
1518 }
1519
1438 static Object* GetRaw(FixedArray* backing_store, uint32_t entry) { 1520 static Object* GetRaw(FixedArray* backing_store, uint32_t entry) {
1439 uint32_t index = FastElementsAccessorSubclass::GetIndexForEntryImpl( 1521 uint32_t index = FastElementsAccessorSubclass::GetIndexForEntryImpl(
1440 backing_store, entry); 1522 backing_store, entry);
1441 return backing_store->get(index); 1523 return backing_store->get(index);
1442 } 1524 }
1443 1525
1444 static void MoveElements(Heap* heap, Handle<FixedArrayBase> backing_store, 1526 static void MoveElements(Heap* heap, Handle<FixedArrayBase> backing_store,
1445 int dst_index, int src_index, int len, 1527 int dst_index, int src_index, int len,
1446 int hole_start, int hole_end) { 1528 int hole_start, int hole_end) {
1447 Handle<FixedArray> dst_elms = Handle<FixedArray>::cast(backing_store); 1529 Handle<FixedArray> dst_elms = Handle<FixedArray>::cast(backing_store);
(...skipping 99 matching lines...) Expand 10 before | Expand all | Expand 10 after
1547 1629
1548 template<typename FastElementsAccessorSubclass, 1630 template<typename FastElementsAccessorSubclass,
1549 typename KindTraits> 1631 typename KindTraits>
1550 class FastDoubleElementsAccessor 1632 class FastDoubleElementsAccessor
1551 : public FastElementsAccessor<FastElementsAccessorSubclass, KindTraits> { 1633 : public FastElementsAccessor<FastElementsAccessorSubclass, KindTraits> {
1552 public: 1634 public:
1553 explicit FastDoubleElementsAccessor(const char* name) 1635 explicit FastDoubleElementsAccessor(const char* name)
1554 : FastElementsAccessor<FastElementsAccessorSubclass, 1636 : FastElementsAccessor<FastElementsAccessorSubclass,
1555 KindTraits>(name) {} 1637 KindTraits>(name) {}
1556 1638
1639 static inline void SetImpl(FixedArrayBase* backing_store, uint32_t entry,
1640 Object* value) {
Camillo Bruni 2015/09/01 08:45:12 If I leave out this version (for FixedDoubleArray)
1641 FixedDoubleArray::cast(backing_store)->set(entry, value->Number());
1642 }
1643
1644 static inline void SetImpl(FixedArrayBase* backing_store, uint32_t entry,
1645 Object* value, WriteBarrierMode mode) {
1646 FixedDoubleArray::cast(backing_store)->set(entry, value->Number());
1647 }
1648
1557 static void MoveElements(Heap* heap, Handle<FixedArrayBase> backing_store, 1649 static void MoveElements(Heap* heap, Handle<FixedArrayBase> backing_store,
1558 int dst_index, int src_index, int len, 1650 int dst_index, int src_index, int len,
1559 int hole_start, int hole_end) { 1651 int hole_start, int hole_end) {
1560 Handle<FixedDoubleArray> dst_elms = 1652 Handle<FixedDoubleArray> dst_elms =
1561 Handle<FixedDoubleArray>::cast(backing_store); 1653 Handle<FixedDoubleArray>::cast(backing_store);
1562 if (len != 0) { 1654 if (len != 0) {
1563 MemMove(dst_elms->data_start() + dst_index, 1655 MemMove(dst_elms->data_start() + dst_index,
1564 dst_elms->data_start() + src_index, len * kDoubleSize); 1656 dst_elms->data_start() + src_index, len * kDoubleSize);
1565 } 1657 }
1566 if (hole_start != hole_end) { 1658 if (hole_start != hole_end) {
(...skipping 170 matching lines...) Expand 10 before | Expand all | Expand 10 after
1737 } 1829 }
1738 return result; 1830 return result;
1739 } 1831 }
1740 } 1832 }
1741 1833
1742 static void GrowCapacityAndConvertImpl(Handle<JSObject> object, 1834 static void GrowCapacityAndConvertImpl(Handle<JSObject> object,
1743 uint32_t capacity) { 1835 uint32_t capacity) {
1744 UNREACHABLE(); 1836 UNREACHABLE();
1745 } 1837 }
1746 1838
1747 static void SetImpl(FixedArrayBase* store, uint32_t entry, Object* value) { 1839 static inline void SetImpl(FixedArrayBase* store, uint32_t entry,
1840 Object* value) {
1748 FixedArray* parameter_map = FixedArray::cast(store); 1841 FixedArray* parameter_map = FixedArray::cast(store);
1749 uint32_t length = parameter_map->length() - 2; 1842 uint32_t length = parameter_map->length() - 2;
1750 if (entry < length) { 1843 if (entry < length) {
1751 Object* probe = parameter_map->get(entry + 2); 1844 Object* probe = parameter_map->get(entry + 2);
1752 Context* context = Context::cast(parameter_map->get(0)); 1845 Context* context = Context::cast(parameter_map->get(0));
1753 int context_entry = Smi::cast(probe)->value(); 1846 int context_entry = Smi::cast(probe)->value();
1754 DCHECK(!context->get(context_entry)->IsTheHole()); 1847 DCHECK(!context->get(context_entry)->IsTheHole());
1755 context->set(context_entry, value); 1848 context->set(context_entry, value);
1756 } else { 1849 } else {
1757 FixedArray* arguments = FixedArray::cast(parameter_map->get(1)); 1850 FixedArray* arguments = FixedArray::cast(parameter_map->get(1));
(...skipping 459 matching lines...) Expand 10 before | Expand all | Expand 10 after
2217 2310
2218 2311
2219 void ElementsAccessor::TearDown() { 2312 void ElementsAccessor::TearDown() {
2220 if (elements_accessors_ == NULL) return; 2313 if (elements_accessors_ == NULL) return;
2221 #define ACCESSOR_DELETE(Class, Kind, Store) delete elements_accessors_[Kind]; 2314 #define ACCESSOR_DELETE(Class, Kind, Store) delete elements_accessors_[Kind];
2222 ELEMENTS_LIST(ACCESSOR_DELETE) 2315 ELEMENTS_LIST(ACCESSOR_DELETE)
2223 #undef ACCESSOR_DELETE 2316 #undef ACCESSOR_DELETE
2224 elements_accessors_ = NULL; 2317 elements_accessors_ = NULL;
2225 } 2318 }
2226 2319
2227
2228 ElementsAccessor** ElementsAccessor::elements_accessors_ = NULL; 2320 ElementsAccessor** ElementsAccessor::elements_accessors_ = NULL;
2229 } // namespace internal 2321 } // namespace internal
2230 } // namespace v8 2322 } // namespace v8
OLDNEW
« no previous file with comments | « src/elements.h ('k') | src/objects.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698