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

Side by Side Diff: src/elements.cc

Issue 1159433003: Use GetProperty for getting elements. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Addressed comments Created 5 years, 6 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/ic/ic.cc » ('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/v8.h" 5 #include "src/v8.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/elements.h" 9 #include "src/elements.h"
10 #include "src/messages.h" 10 #include "src/messages.h"
(...skipping 567 matching lines...) Expand 10 before | Expand all | Expand 10 after
578 ElementsAccessorSubclass::ValidateContents(holder, length); 578 ElementsAccessorSubclass::ValidateContents(holder, length);
579 } 579 }
580 580
581 void Validate(Handle<JSObject> holder) final { 581 void Validate(Handle<JSObject> holder) final {
582 DisallowHeapAllocation no_gc; 582 DisallowHeapAllocation no_gc;
583 ElementsAccessorSubclass::ValidateImpl(holder); 583 ElementsAccessorSubclass::ValidateImpl(holder);
584 } 584 }
585 585
586 static bool HasElementImpl(Handle<JSObject> holder, uint32_t key, 586 static bool HasElementImpl(Handle<JSObject> holder, uint32_t key,
587 Handle<FixedArrayBase> backing_store) { 587 Handle<FixedArrayBase> backing_store) {
588 return ElementsAccessorSubclass::GetAttributesImpl(holder, key, 588 return ElementsAccessorSubclass::GetAttributesImpl(
589 backing_store) != ABSENT; 589 *holder, key, *backing_store) != ABSENT;
590 } 590 }
591 591
592 virtual bool HasElement(Handle<JSObject> holder, uint32_t key, 592 virtual bool HasElement(Handle<JSObject> holder, uint32_t key,
593 Handle<FixedArrayBase> backing_store) final { 593 Handle<FixedArrayBase> backing_store) final {
594 return ElementsAccessorSubclass::HasElementImpl(holder, key, backing_store); 594 return ElementsAccessorSubclass::HasElementImpl(holder, key, backing_store);
595 } 595 }
596 596
597 MUST_USE_RESULT virtual MaybeHandle<Object> Get( 597 virtual Handle<Object> Get(Handle<JSObject> holder, uint32_t key,
598 Handle<Object> receiver, Handle<JSObject> holder, uint32_t key, 598 Handle<FixedArrayBase> backing_store) final {
599 Handle<FixedArrayBase> backing_store) final {
600 if (!IsExternalArrayElementsKind(ElementsTraits::Kind) && 599 if (!IsExternalArrayElementsKind(ElementsTraits::Kind) &&
601 FLAG_trace_js_array_abuse) { 600 FLAG_trace_js_array_abuse) {
602 CheckArrayAbuse(holder, "elements read", key); 601 CheckArrayAbuse(holder, "elements read", key);
603 } 602 }
604 603
605 if (IsExternalArrayElementsKind(ElementsTraits::Kind) && 604 if (IsExternalArrayElementsKind(ElementsTraits::Kind) &&
606 FLAG_trace_external_array_abuse) { 605 FLAG_trace_external_array_abuse) {
607 CheckArrayAbuse(holder, "external elements read", key); 606 CheckArrayAbuse(holder, "external elements read", key);
608 } 607 }
609 608
610 return ElementsAccessorSubclass::GetImpl( 609 return ElementsAccessorSubclass::GetImpl(holder, key, backing_store);
611 receiver, holder, key, backing_store);
612 } 610 }
613 611
614 MUST_USE_RESULT static MaybeHandle<Object> GetImpl( 612 static Handle<Object> GetImpl(Handle<JSObject> obj, uint32_t key,
615 Handle<Object> receiver, 613 Handle<FixedArrayBase> backing_store) {
616 Handle<JSObject> obj,
617 uint32_t key,
618 Handle<FixedArrayBase> backing_store) {
619 if (key < ElementsAccessorSubclass::GetCapacityImpl(*obj, *backing_store)) { 614 if (key < ElementsAccessorSubclass::GetCapacityImpl(*obj, *backing_store)) {
620 return BackingStore::get(Handle<BackingStore>::cast(backing_store), key); 615 return BackingStore::get(Handle<BackingStore>::cast(backing_store), key);
621 } else { 616 } else {
622 return backing_store->GetIsolate()->factory()->the_hole_value(); 617 return backing_store->GetIsolate()->factory()->the_hole_value();
623 } 618 }
624 } 619 }
625 620
626 MUST_USE_RESULT virtual PropertyAttributes GetAttributes( 621 virtual PropertyAttributes GetAttributes(
627 Handle<JSObject> holder, uint32_t key, 622 JSObject* holder, uint32_t key, FixedArrayBase* backing_store) final {
628 Handle<FixedArrayBase> backing_store) final {
629 return ElementsAccessorSubclass::GetAttributesImpl(holder, key, 623 return ElementsAccessorSubclass::GetAttributesImpl(holder, key,
630 backing_store); 624 backing_store);
631 } 625 }
632 626
633 MUST_USE_RESULT static PropertyAttributes GetAttributesImpl( 627 static PropertyAttributes GetAttributesImpl(JSObject* obj, uint32_t key,
634 Handle<JSObject> obj, 628 FixedArrayBase* backing_store) {
635 uint32_t key, 629 if (key >= ElementsAccessorSubclass::GetCapacityImpl(obj, backing_store)) {
636 Handle<FixedArrayBase> backing_store) {
637 if (key >=
638 ElementsAccessorSubclass::GetCapacityImpl(*obj, *backing_store)) {
639 return ABSENT; 630 return ABSENT;
640 } 631 }
641 return 632 return BackingStore::cast(backing_store)->is_the_hole(key) ? ABSENT : NONE;
642 Handle<BackingStore>::cast(backing_store)->is_the_hole(key)
643 ? ABSENT : NONE;
644 } 633 }
645 634
646 MUST_USE_RESULT virtual MaybeHandle<AccessorPair> GetAccessorPair( 635 virtual MaybeHandle<AccessorPair> GetAccessorPair(
647 Handle<JSObject> holder, uint32_t key, 636 Handle<JSObject> holder, uint32_t key,
648 Handle<FixedArrayBase> backing_store) final { 637 Handle<FixedArrayBase> backing_store) final {
649 return ElementsAccessorSubclass::GetAccessorPairImpl(holder, key, 638 return ElementsAccessorSubclass::GetAccessorPairImpl(holder, key,
650 backing_store); 639 backing_store);
651 } 640 }
652 641
653 MUST_USE_RESULT static MaybeHandle<AccessorPair> GetAccessorPairImpl( 642 static MaybeHandle<AccessorPair> GetAccessorPairImpl(
654 Handle<JSObject> obj, 643 Handle<JSObject> obj, uint32_t key,
655 uint32_t key,
656 Handle<FixedArrayBase> backing_store) { 644 Handle<FixedArrayBase> backing_store) {
657 return MaybeHandle<AccessorPair>(); 645 return MaybeHandle<AccessorPair>();
658 } 646 }
659 647
660 MUST_USE_RESULT virtual MaybeHandle<Object> SetLength( 648 MUST_USE_RESULT virtual MaybeHandle<Object> SetLength(
661 Handle<JSArray> array, Handle<Object> length) final { 649 Handle<JSArray> array, Handle<Object> length) final {
662 return ElementsAccessorSubclass::SetLengthImpl( 650 return ElementsAccessorSubclass::SetLengthImpl(
663 array, length, handle(array->elements())); 651 array, length, handle(array->elements()));
664 } 652 }
665 653
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after
727 // intentionally to avoid ArrayConcat() builtin performance degradation. 715 // intentionally to avoid ArrayConcat() builtin performance degradation.
728 // 716 //
729 // Details: The idea is that allocations actually happen only in case of 717 // Details: The idea is that allocations actually happen only in case of
730 // copying from object with fast double elements to object with object 718 // copying from object with fast double elements to object with object
731 // elements. In all the other cases there are no allocations performed and 719 // elements. In all the other cases there are no allocations performed and
732 // handle creation causes noticeable performance degradation of the builtin. 720 // handle creation causes noticeable performance degradation of the builtin.
733 ElementsAccessorSubclass::CopyElementsImpl( 721 ElementsAccessorSubclass::CopyElementsImpl(
734 from, from_start, *to, from_kind, to_start, packed_size, copy_size); 722 from, from_start, *to, from_kind, to_start, packed_size, copy_size);
735 } 723 }
736 724
737 virtual MaybeHandle<FixedArray> AddElementsToFixedArray( 725 virtual Handle<FixedArray> AddElementsToFixedArray(
738 Handle<JSObject> receiver, Handle<FixedArray> to, 726 Handle<JSObject> receiver, Handle<FixedArray> to,
739 FixedArray::KeyFilter filter) final { 727 FixedArray::KeyFilter filter) final {
740 Handle<FixedArrayBase> from(receiver->elements()); 728 Handle<FixedArrayBase> from(receiver->elements());
741 729
742 int len0 = to->length(); 730 int len0 = to->length();
743 #ifdef ENABLE_SLOW_DCHECKS 731 #ifdef ENABLE_SLOW_DCHECKS
744 if (FLAG_enable_slow_asserts) { 732 if (FLAG_enable_slow_asserts) {
745 for (int i = 0; i < len0; i++) { 733 for (int i = 0; i < len0; i++) {
746 DCHECK(!to->get(i)->IsTheHole()); 734 DCHECK(!to->get(i)->IsTheHole());
747 } 735 }
748 } 736 }
749 #endif 737 #endif
750 738
751 // Optimize if 'other' is empty. 739 // Optimize if 'other' is empty.
752 // We cannot optimize if 'this' is empty, as other may have holes. 740 // We cannot optimize if 'this' is empty, as other may have holes.
753 uint32_t len1 = ElementsAccessorSubclass::GetCapacityImpl(*receiver, *from); 741 uint32_t len1 = ElementsAccessorSubclass::GetCapacityImpl(*receiver, *from);
754 if (len1 == 0) return to; 742 if (len1 == 0) return to;
755 743
756 Isolate* isolate = from->GetIsolate(); 744 Isolate* isolate = from->GetIsolate();
757 745
758 // Compute how many elements are not in other. 746 // Compute how many elements are not in other.
759 uint32_t extra = 0; 747 uint32_t extra = 0;
760 for (uint32_t y = 0; y < len1; y++) { 748 for (uint32_t y = 0; y < len1; y++) {
761 uint32_t key = ElementsAccessorSubclass::GetKeyForIndexImpl(*from, y); 749 if (ElementsAccessorSubclass::HasIndexImpl(*from, y)) {
762 if (ElementsAccessorSubclass::HasElementImpl(receiver, key, from)) { 750 uint32_t key = ElementsAccessorSubclass::GetKeyForIndexImpl(*from, y);
763 Handle<Object> value; 751 Handle<Object> value =
764 ASSIGN_RETURN_ON_EXCEPTION( 752 ElementsAccessorSubclass::GetImpl(receiver, key, from);
765 isolate, value,
766 ElementsAccessorSubclass::GetImpl(receiver, receiver, key, from),
767 FixedArray);
768 753
769 DCHECK(!value->IsTheHole()); 754 DCHECK(!value->IsTheHole());
755 DCHECK(!value->IsAccessorPair());
756 DCHECK(!value->IsExecutableAccessorInfo());
770 if (filter == FixedArray::NON_SYMBOL_KEYS && value->IsSymbol()) { 757 if (filter == FixedArray::NON_SYMBOL_KEYS && value->IsSymbol()) {
771 continue; 758 continue;
772 } 759 }
773 if (!HasKey(to, value)) { 760 if (!HasKey(to, value)) {
774 extra++; 761 extra++;
775 } 762 }
776 } 763 }
777 } 764 }
778 765
779 if (extra == 0) return to; 766 if (extra == 0) return to;
780 767
781 // Allocate the result 768 // Allocate the result
782 Handle<FixedArray> result = isolate->factory()->NewFixedArray(len0 + extra); 769 Handle<FixedArray> result = isolate->factory()->NewFixedArray(len0 + extra);
783 770
784 // Fill in the content 771 // Fill in the content
785 { 772 {
786 DisallowHeapAllocation no_gc; 773 DisallowHeapAllocation no_gc;
787 WriteBarrierMode mode = result->GetWriteBarrierMode(no_gc); 774 WriteBarrierMode mode = result->GetWriteBarrierMode(no_gc);
788 for (int i = 0; i < len0; i++) { 775 for (int i = 0; i < len0; i++) {
789 Object* e = to->get(i); 776 Object* e = to->get(i);
790 DCHECK(e->IsString() || e->IsNumber()); 777 DCHECK(e->IsString() || e->IsNumber());
791 result->set(i, e, mode); 778 result->set(i, e, mode);
792 } 779 }
793 } 780 }
794 // Fill in the extra values. 781 // Fill in the extra values.
795 uint32_t index = 0; 782 uint32_t index = 0;
796 for (uint32_t y = 0; y < len1; y++) { 783 for (uint32_t y = 0; y < len1; y++) {
797 uint32_t key = ElementsAccessorSubclass::GetKeyForIndexImpl(*from, y); 784 if (ElementsAccessorSubclass::HasIndexImpl(*from, y)) {
798 if (ElementsAccessorSubclass::HasElementImpl(receiver, key, from)) { 785 uint32_t key = ElementsAccessorSubclass::GetKeyForIndexImpl(*from, y);
799 Handle<Object> value; 786 Handle<Object> value =
800 ASSIGN_RETURN_ON_EXCEPTION( 787 ElementsAccessorSubclass::GetImpl(receiver, key, from);
801 isolate, value, 788 DCHECK(!value->IsAccessorPair());
802 ElementsAccessorSubclass::GetImpl(receiver, receiver, key, from), 789 DCHECK(!value->IsExecutableAccessorInfo());
803 FixedArray);
804 if (filter == FixedArray::NON_SYMBOL_KEYS && value->IsSymbol()) { 790 if (filter == FixedArray::NON_SYMBOL_KEYS && value->IsSymbol()) {
805 continue; 791 continue;
806 } 792 }
807 if (!value->IsTheHole() && !HasKey(to, value)) { 793 if (!value->IsTheHole() && !HasKey(to, value)) {
808 result->set(len0 + index, *value); 794 result->set(len0 + index, *value);
809 index++; 795 index++;
810 } 796 }
811 } 797 }
812 } 798 }
813 DCHECK(extra == index); 799 DCHECK(extra == index);
814 return result; 800 return result;
815 } 801 }
816 802
817 protected: 803 protected:
818 static uint32_t GetCapacityImpl(JSObject* holder, 804 static uint32_t GetCapacityImpl(JSObject* holder,
819 FixedArrayBase* backing_store) { 805 FixedArrayBase* backing_store) {
820 return backing_store->length(); 806 return backing_store->length();
821 } 807 }
822 808
823 uint32_t GetCapacity(JSObject* holder, FixedArrayBase* backing_store) final { 809 uint32_t GetCapacity(JSObject* holder, FixedArrayBase* backing_store) final {
824 return ElementsAccessorSubclass::GetCapacityImpl(holder, backing_store); 810 return ElementsAccessorSubclass::GetCapacityImpl(holder, backing_store);
825 } 811 }
826 812
813 static bool HasIndexImpl(FixedArrayBase* backing_store, uint32_t index) {
814 return true;
815 }
816
817 virtual bool HasIndex(FixedArrayBase* backing_store, uint32_t index) final {
818 return ElementsAccessorSubclass::HasIndexImpl(backing_store, index);
819 }
820
827 static uint32_t GetKeyForIndexImpl(FixedArrayBase* backing_store, 821 static uint32_t GetKeyForIndexImpl(FixedArrayBase* backing_store,
828 uint32_t index) { 822 uint32_t index) {
829 return index; 823 return index;
830 } 824 }
831 825
832 virtual uint32_t GetKeyForIndex(FixedArrayBase* backing_store, 826 virtual uint32_t GetKeyForIndex(FixedArrayBase* backing_store,
833 uint32_t index) final { 827 uint32_t index) final {
834 return ElementsAccessorSubclass::GetKeyForIndexImpl(backing_store, index); 828 return ElementsAccessorSubclass::GetKeyForIndexImpl(backing_store, index);
835 } 829 }
836 830
(...skipping 164 matching lines...) Expand 10 before | Expand all | Expand 10 after
1001 static bool HasElementImpl( 995 static bool HasElementImpl(
1002 Handle<JSObject> holder, 996 Handle<JSObject> holder,
1003 uint32_t key, 997 uint32_t key,
1004 Handle<FixedArrayBase> backing_store) { 998 Handle<FixedArrayBase> backing_store) {
1005 if (key >= static_cast<uint32_t>(backing_store->length())) { 999 if (key >= static_cast<uint32_t>(backing_store->length())) {
1006 return false; 1000 return false;
1007 } 1001 }
1008 return !Handle<BackingStore>::cast(backing_store)->is_the_hole(key); 1002 return !Handle<BackingStore>::cast(backing_store)->is_the_hole(key);
1009 } 1003 }
1010 1004
1005 static bool HasIndexImpl(FixedArrayBase* backing_store, uint32_t index) {
1006 return !BackingStore::cast(backing_store)->is_the_hole(index);
1007 }
1008
1011 static void ValidateContents(Handle<JSObject> holder, int length) { 1009 static void ValidateContents(Handle<JSObject> holder, int length) {
1012 #if DEBUG 1010 #if DEBUG
1013 Isolate* isolate = holder->GetIsolate(); 1011 Isolate* isolate = holder->GetIsolate();
1014 HandleScope scope(isolate); 1012 HandleScope scope(isolate);
1015 Handle<FixedArrayBase> elements(holder->elements(), isolate); 1013 Handle<FixedArrayBase> elements(holder->elements(), isolate);
1016 Map* map = elements->map(); 1014 Map* map = elements->map();
1017 DCHECK((IsFastSmiOrObjectElementsKind(KindTraits::Kind) && 1015 DCHECK((IsFastSmiOrObjectElementsKind(KindTraits::Kind) &&
1018 (map == isolate->heap()->fixed_array_map() || 1016 (map == isolate->heap()->fixed_array_map() ||
1019 map == isolate->heap()->fixed_cow_array_map())) || 1017 map == isolate->heap()->fixed_cow_array_map())) ||
1020 (IsFastDoubleElementsKind(KindTraits::Kind) == 1018 (IsFastDoubleElementsKind(KindTraits::Kind) ==
(...skipping 256 matching lines...) Expand 10 before | Expand all | Expand 10 after
1277 : ElementsAccessorBase<AccessorClass, 1275 : ElementsAccessorBase<AccessorClass,
1278 ElementsKindTraits<Kind> >(name) {} 1276 ElementsKindTraits<Kind> >(name) {}
1279 1277
1280 protected: 1278 protected:
1281 typedef typename ElementsKindTraits<Kind>::BackingStore BackingStore; 1279 typedef typename ElementsKindTraits<Kind>::BackingStore BackingStore;
1282 typedef TypedElementsAccessor<Kind> AccessorClass; 1280 typedef TypedElementsAccessor<Kind> AccessorClass;
1283 1281
1284 friend class ElementsAccessorBase<AccessorClass, 1282 friend class ElementsAccessorBase<AccessorClass,
1285 ElementsKindTraits<Kind> >; 1283 ElementsKindTraits<Kind> >;
1286 1284
1287 MUST_USE_RESULT static MaybeHandle<Object> GetImpl( 1285 static Handle<Object> GetImpl(Handle<JSObject> obj, uint32_t key,
1288 Handle<Object> receiver, 1286 Handle<FixedArrayBase> backing_store) {
1289 Handle<JSObject> obj,
1290 uint32_t key,
1291 Handle<FixedArrayBase> backing_store) {
1292 if (key < AccessorClass::GetCapacityImpl(*obj, *backing_store)) { 1287 if (key < AccessorClass::GetCapacityImpl(*obj, *backing_store)) {
1293 return BackingStore::get(Handle<BackingStore>::cast(backing_store), key); 1288 return BackingStore::get(Handle<BackingStore>::cast(backing_store), key);
1294 } else { 1289 } else {
1295 return backing_store->GetIsolate()->factory()->undefined_value(); 1290 return backing_store->GetIsolate()->factory()->undefined_value();
1296 } 1291 }
1297 } 1292 }
1298 1293
1299 MUST_USE_RESULT static PropertyAttributes GetAttributesImpl( 1294 static PropertyAttributes GetAttributesImpl(JSObject* obj, uint32_t key,
1300 Handle<JSObject> obj, 1295 FixedArrayBase* backing_store) {
1301 uint32_t key, 1296 return key < AccessorClass::GetCapacityImpl(obj, backing_store) ? NONE
1302 Handle<FixedArrayBase> backing_store) { 1297 : ABSENT;
1303 return key < AccessorClass::GetCapacityImpl(*obj, *backing_store) ? NONE
1304 : ABSENT;
1305 } 1298 }
1306 1299
1307 MUST_USE_RESULT static MaybeHandle<Object> SetLengthImpl( 1300 MUST_USE_RESULT static MaybeHandle<Object> SetLengthImpl(
1308 Handle<JSObject> obj, 1301 Handle<JSObject> obj,
1309 Handle<Object> length, 1302 Handle<Object> length,
1310 Handle<FixedArrayBase> backing_store) { 1303 Handle<FixedArrayBase> backing_store) {
1311 // External arrays do not support changing their length. 1304 // External arrays do not support changing their length.
1312 UNREACHABLE(); 1305 UNREACHABLE();
1313 return obj; 1306 return obj;
1314 } 1307 }
(...skipping 159 matching lines...) Expand 10 before | Expand all | Expand 10 after
1474 1467
1475 protected: 1468 protected:
1476 friend class ElementsAccessorBase<DictionaryElementsAccessor, 1469 friend class ElementsAccessorBase<DictionaryElementsAccessor,
1477 ElementsKindTraits<DICTIONARY_ELEMENTS> >; 1470 ElementsKindTraits<DICTIONARY_ELEMENTS> >;
1478 1471
1479 MUST_USE_RESULT virtual MaybeHandle<Object> Delete( 1472 MUST_USE_RESULT virtual MaybeHandle<Object> Delete(
1480 Handle<JSObject> obj, uint32_t key, LanguageMode language_mode) final { 1473 Handle<JSObject> obj, uint32_t key, LanguageMode language_mode) final {
1481 return DeleteCommon(obj, key, language_mode); 1474 return DeleteCommon(obj, key, language_mode);
1482 } 1475 }
1483 1476
1484 MUST_USE_RESULT static MaybeHandle<Object> GetImpl( 1477 static Handle<Object> GetImpl(Handle<JSObject> obj, uint32_t key,
1485 Handle<Object> receiver, 1478 Handle<FixedArrayBase> store) {
1486 Handle<JSObject> obj,
1487 uint32_t key,
1488 Handle<FixedArrayBase> store) {
1489 Handle<SeededNumberDictionary> backing_store = 1479 Handle<SeededNumberDictionary> backing_store =
1490 Handle<SeededNumberDictionary>::cast(store); 1480 Handle<SeededNumberDictionary>::cast(store);
1491 Isolate* isolate = backing_store->GetIsolate(); 1481 Isolate* isolate = backing_store->GetIsolate();
1492 int entry = backing_store->FindEntry(key); 1482 int entry = backing_store->FindEntry(key);
1493 if (entry != SeededNumberDictionary::kNotFound) { 1483 if (entry != SeededNumberDictionary::kNotFound) {
1494 Handle<Object> element(backing_store->ValueAt(entry), isolate); 1484 return handle(backing_store->ValueAt(entry), isolate);
1495 PropertyDetails details = backing_store->DetailsAt(entry);
1496 if (details.type() == ACCESSOR_CONSTANT) {
1497 return JSObject::GetElementWithCallback(
1498 obj, receiver, element, key, obj);
1499 } else {
1500 return element;
1501 }
1502 } 1485 }
1503 return isolate->factory()->the_hole_value(); 1486 return isolate->factory()->the_hole_value();
1504 } 1487 }
1505 1488
1506 MUST_USE_RESULT static PropertyAttributes GetAttributesImpl( 1489 static PropertyAttributes GetAttributesImpl(JSObject* obj, uint32_t key,
1507 Handle<JSObject> obj, 1490 FixedArrayBase* backing_store) {
1508 uint32_t key, 1491 SeededNumberDictionary* dictionary =
1509 Handle<FixedArrayBase> backing_store) { 1492 SeededNumberDictionary::cast(backing_store);
1510 Handle<SeededNumberDictionary> dictionary =
1511 Handle<SeededNumberDictionary>::cast(backing_store);
1512 int entry = dictionary->FindEntry(key); 1493 int entry = dictionary->FindEntry(key);
1513 if (entry != SeededNumberDictionary::kNotFound) { 1494 if (entry != SeededNumberDictionary::kNotFound) {
1514 return dictionary->DetailsAt(entry).attributes(); 1495 return dictionary->DetailsAt(entry).attributes();
1515 } 1496 }
1516 return ABSENT; 1497 return ABSENT;
1517 } 1498 }
1518 1499
1519 MUST_USE_RESULT static MaybeHandle<AccessorPair> GetAccessorPairImpl( 1500 static MaybeHandle<AccessorPair> GetAccessorPairImpl(
1520 Handle<JSObject> obj, 1501 Handle<JSObject> obj, uint32_t key, Handle<FixedArrayBase> store) {
1521 uint32_t key,
1522 Handle<FixedArrayBase> store) {
1523 Handle<SeededNumberDictionary> backing_store = 1502 Handle<SeededNumberDictionary> backing_store =
1524 Handle<SeededNumberDictionary>::cast(store); 1503 Handle<SeededNumberDictionary>::cast(store);
1525 int entry = backing_store->FindEntry(key); 1504 int entry = backing_store->FindEntry(key);
1526 if (entry != SeededNumberDictionary::kNotFound && 1505 if (entry != SeededNumberDictionary::kNotFound &&
1527 backing_store->DetailsAt(entry).type() == ACCESSOR_CONSTANT && 1506 backing_store->DetailsAt(entry).type() == ACCESSOR_CONSTANT &&
1528 backing_store->ValueAt(entry)->IsAccessorPair()) { 1507 backing_store->ValueAt(entry)->IsAccessorPair()) {
1529 return handle(AccessorPair::cast(backing_store->ValueAt(entry))); 1508 return handle(AccessorPair::cast(backing_store->ValueAt(entry)));
1530 } 1509 }
1531 return MaybeHandle<AccessorPair>(); 1510 return MaybeHandle<AccessorPair>();
1532 } 1511 }
1533 1512
1534 static bool HasElementImpl(Handle<JSObject> holder, uint32_t key, 1513 static bool HasElementImpl(Handle<JSObject> holder, uint32_t key,
1535 Handle<FixedArrayBase> store) { 1514 Handle<FixedArrayBase> store) {
1536 Handle<SeededNumberDictionary> backing_store = 1515 Handle<SeededNumberDictionary> backing_store =
1537 Handle<SeededNumberDictionary>::cast(store); 1516 Handle<SeededNumberDictionary>::cast(store);
1538 return backing_store->FindEntry(key) != SeededNumberDictionary::kNotFound; 1517 return backing_store->FindEntry(key) != SeededNumberDictionary::kNotFound;
1539 } 1518 }
1540 1519
1520 static bool HasIndexImpl(FixedArrayBase* store, uint32_t index) {
1521 DisallowHeapAllocation no_gc;
1522 SeededNumberDictionary* dict = SeededNumberDictionary::cast(store);
1523 Object* key = dict->KeyAt(index);
1524 return !key->IsTheHole();
1525 }
1526
1541 static uint32_t GetKeyForIndexImpl(FixedArrayBase* store, uint32_t index) { 1527 static uint32_t GetKeyForIndexImpl(FixedArrayBase* store, uint32_t index) {
1542 DisallowHeapAllocation no_gc; 1528 DisallowHeapAllocation no_gc;
1543 SeededNumberDictionary* dict = SeededNumberDictionary::cast(store); 1529 SeededNumberDictionary* dict = SeededNumberDictionary::cast(store);
1544 Object* key = dict->KeyAt(index); 1530 Object* key = dict->KeyAt(index);
1545 return Smi::cast(key)->value(); 1531 return Smi::cast(key)->value();
1546 } 1532 }
1547 1533
1548 static uint32_t GetIndexForKeyImpl(FixedArrayBase* store, uint32_t key) { 1534 static uint32_t GetIndexForKeyImpl(FixedArrayBase* store, uint32_t key) {
1549 DisallowHeapAllocation no_gc; 1535 DisallowHeapAllocation no_gc;
1550 SeededNumberDictionary* dict = SeededNumberDictionary::cast(store); 1536 SeededNumberDictionary* dict = SeededNumberDictionary::cast(store);
(...skipping 17 matching lines...) Expand all
1568 public: 1554 public:
1569 explicit SloppyArgumentsElementsAccessor(const char* name) 1555 explicit SloppyArgumentsElementsAccessor(const char* name)
1570 : ElementsAccessorBase< 1556 : ElementsAccessorBase<
1571 SloppyArgumentsElementsAccessor, 1557 SloppyArgumentsElementsAccessor,
1572 ElementsKindTraits<SLOPPY_ARGUMENTS_ELEMENTS> >(name) {} 1558 ElementsKindTraits<SLOPPY_ARGUMENTS_ELEMENTS> >(name) {}
1573 protected: 1559 protected:
1574 friend class ElementsAccessorBase< 1560 friend class ElementsAccessorBase<
1575 SloppyArgumentsElementsAccessor, 1561 SloppyArgumentsElementsAccessor,
1576 ElementsKindTraits<SLOPPY_ARGUMENTS_ELEMENTS> >; 1562 ElementsKindTraits<SLOPPY_ARGUMENTS_ELEMENTS> >;
1577 1563
1578 MUST_USE_RESULT static MaybeHandle<Object> GetImpl( 1564 static Handle<Object> GetImpl(Handle<JSObject> obj, uint32_t key,
1579 Handle<Object> receiver, 1565 Handle<FixedArrayBase> parameters) {
1580 Handle<JSObject> obj,
1581 uint32_t key,
1582 Handle<FixedArrayBase> parameters) {
1583 Isolate* isolate = obj->GetIsolate(); 1566 Isolate* isolate = obj->GetIsolate();
1584 Handle<FixedArray> parameter_map = Handle<FixedArray>::cast(parameters); 1567 Handle<FixedArray> parameter_map = Handle<FixedArray>::cast(parameters);
1585 Handle<Object> probe = GetParameterMapArg(obj, parameter_map, key); 1568 Handle<Object> probe(GetParameterMapArg(*parameter_map, key), isolate);
1586 if (!probe->IsTheHole()) { 1569 if (!probe->IsTheHole()) {
1587 DisallowHeapAllocation no_gc; 1570 DisallowHeapAllocation no_gc;
1588 Context* context = Context::cast(parameter_map->get(0)); 1571 Context* context = Context::cast(parameter_map->get(0));
1589 int context_index = Handle<Smi>::cast(probe)->value(); 1572 int context_index = Handle<Smi>::cast(probe)->value();
1590 DCHECK(!context->get(context_index)->IsTheHole()); 1573 DCHECK(!context->get(context_index)->IsTheHole());
1591 return handle(context->get(context_index), isolate); 1574 return handle(context->get(context_index), isolate);
1592 } else { 1575 } else {
1593 // Object is not mapped, defer to the arguments. 1576 // Object is not mapped, defer to the arguments.
1594 Handle<FixedArray> arguments(FixedArray::cast(parameter_map->get(1)), 1577 Handle<FixedArray> arguments(FixedArray::cast(parameter_map->get(1)),
1595 isolate); 1578 isolate);
1596 Handle<Object> result; 1579 Handle<Object> result =
1597 ASSIGN_RETURN_ON_EXCEPTION( 1580 ElementsAccessor::ForArray(arguments)->Get(obj, key, arguments);
1598 isolate, result,
1599 ElementsAccessor::ForArray(arguments)->Get(
1600 receiver, obj, key, arguments),
1601 Object);
1602 // Elements of the arguments object in slow mode might be slow aliases. 1581 // Elements of the arguments object in slow mode might be slow aliases.
1603 if (result->IsAliasedArgumentsEntry()) { 1582 if (result->IsAliasedArgumentsEntry()) {
1604 DisallowHeapAllocation no_gc; 1583 DisallowHeapAllocation no_gc;
1605 AliasedArgumentsEntry* entry = AliasedArgumentsEntry::cast(*result); 1584 AliasedArgumentsEntry* entry = AliasedArgumentsEntry::cast(*result);
1606 Context* context = Context::cast(parameter_map->get(0)); 1585 Context* context = Context::cast(parameter_map->get(0));
1607 int context_index = entry->aliased_context_slot(); 1586 int context_index = entry->aliased_context_slot();
1608 DCHECK(!context->get(context_index)->IsTheHole()); 1587 DCHECK(!context->get(context_index)->IsTheHole());
1609 return handle(context->get(context_index), isolate); 1588 return handle(context->get(context_index), isolate);
1610 } else { 1589 } else {
1611 return result; 1590 return result;
1612 } 1591 }
1613 } 1592 }
1614 } 1593 }
1615 1594
1616 MUST_USE_RESULT static PropertyAttributes GetAttributesImpl( 1595 static PropertyAttributes GetAttributesImpl(JSObject* obj, uint32_t key,
1617 Handle<JSObject> obj, 1596 FixedArrayBase* backing_store) {
1618 uint32_t key, 1597 FixedArray* parameter_map = FixedArray::cast(backing_store);
1619 Handle<FixedArrayBase> backing_store) { 1598 Object* probe = GetParameterMapArg(parameter_map, key);
1620 Handle<FixedArray> parameter_map = Handle<FixedArray>::cast(backing_store);
1621 Handle<Object> probe = GetParameterMapArg(obj, parameter_map, key);
1622 if (!probe->IsTheHole()) { 1599 if (!probe->IsTheHole()) {
1623 return NONE; 1600 return NONE;
1624 } else { 1601 } else {
1625 // If not aliased, check the arguments. 1602 // If not aliased, check the arguments.
1626 Handle<FixedArray> arguments(FixedArray::cast(parameter_map->get(1))); 1603 FixedArray* arguments = FixedArray::cast(parameter_map->get(1));
1627 return ElementsAccessor::ForArray(arguments) 1604 return ElementsAccessor::ForArray(arguments)
1628 ->GetAttributes(obj, key, arguments); 1605 ->GetAttributes(obj, key, arguments);
1629 } 1606 }
1630 } 1607 }
1631 1608
1632 MUST_USE_RESULT static MaybeHandle<AccessorPair> GetAccessorPairImpl( 1609 static MaybeHandle<AccessorPair> GetAccessorPairImpl(
1633 Handle<JSObject> obj, 1610 Handle<JSObject> obj, uint32_t key, Handle<FixedArrayBase> parameters) {
1634 uint32_t key,
1635 Handle<FixedArrayBase> parameters) {
1636 Handle<FixedArray> parameter_map = Handle<FixedArray>::cast(parameters); 1611 Handle<FixedArray> parameter_map = Handle<FixedArray>::cast(parameters);
1637 Handle<Object> probe = GetParameterMapArg(obj, parameter_map, key); 1612 Handle<Object> probe(GetParameterMapArg(*parameter_map, key),
1613 obj->GetIsolate());
1638 if (!probe->IsTheHole()) { 1614 if (!probe->IsTheHole()) {
1639 return MaybeHandle<AccessorPair>(); 1615 return MaybeHandle<AccessorPair>();
1640 } else { 1616 } else {
1641 // If not aliased, check the arguments. 1617 // If not aliased, check the arguments.
1642 Handle<FixedArray> arguments(FixedArray::cast(parameter_map->get(1))); 1618 Handle<FixedArray> arguments(FixedArray::cast(parameter_map->get(1)));
1643 return ElementsAccessor::ForArray(arguments) 1619 return ElementsAccessor::ForArray(arguments)
1644 ->GetAccessorPair(obj, key, arguments); 1620 ->GetAccessorPair(obj, key, arguments);
1645 } 1621 }
1646 } 1622 }
1647 1623
1648 MUST_USE_RESULT static MaybeHandle<Object> SetLengthImpl( 1624 MUST_USE_RESULT static MaybeHandle<Object> SetLengthImpl(
1649 Handle<JSObject> obj, 1625 Handle<JSObject> obj,
1650 Handle<Object> length, 1626 Handle<Object> length,
1651 Handle<FixedArrayBase> parameter_map) { 1627 Handle<FixedArrayBase> parameter_map) {
1652 // TODO(mstarzinger): This was never implemented but will be used once we 1628 // TODO(mstarzinger): This was never implemented but will be used once we
1653 // correctly implement [[DefineOwnProperty]] on arrays. 1629 // correctly implement [[DefineOwnProperty]] on arrays.
1654 UNIMPLEMENTED(); 1630 UNIMPLEMENTED();
1655 return obj; 1631 return obj;
1656 } 1632 }
1657 1633
1658 MUST_USE_RESULT virtual MaybeHandle<Object> Delete( 1634 MUST_USE_RESULT virtual MaybeHandle<Object> Delete(
1659 Handle<JSObject> obj, uint32_t key, LanguageMode language_mode) final { 1635 Handle<JSObject> obj, uint32_t key, LanguageMode language_mode) final {
1660 Isolate* isolate = obj->GetIsolate(); 1636 Isolate* isolate = obj->GetIsolate();
1661 Handle<FixedArray> parameter_map(FixedArray::cast(obj->elements())); 1637 Handle<FixedArray> parameter_map(FixedArray::cast(obj->elements()));
1662 Handle<Object> probe = GetParameterMapArg(obj, parameter_map, key); 1638 Handle<Object> probe(GetParameterMapArg(*parameter_map, key), isolate);
1663 if (!probe->IsTheHole()) { 1639 if (!probe->IsTheHole()) {
1664 // TODO(kmillikin): We could check if this was the last aliased 1640 // TODO(kmillikin): We could check if this was the last aliased
1665 // parameter, and revert to normal elements in that case. That 1641 // parameter, and revert to normal elements in that case. That
1666 // would enable GC of the context. 1642 // would enable GC of the context.
1667 parameter_map->set_the_hole(key + 2); 1643 parameter_map->set_the_hole(key + 2);
1668 } else { 1644 } else {
1669 Handle<FixedArray> arguments(FixedArray::cast(parameter_map->get(1))); 1645 Handle<FixedArray> arguments(FixedArray::cast(parameter_map->get(1)));
1670 if (arguments->IsDictionary()) { 1646 if (arguments->IsDictionary()) {
1671 return DictionaryElementsAccessor::DeleteCommon(obj, key, 1647 return DictionaryElementsAccessor::DeleteCommon(obj, key,
1672 language_mode); 1648 language_mode);
(...skipping 12 matching lines...) Expand all
1685 FixedArrayBase* to, ElementsKind from_kind, 1661 FixedArrayBase* to, ElementsKind from_kind,
1686 uint32_t to_start, int packed_size, 1662 uint32_t to_start, int packed_size,
1687 int copy_size) { 1663 int copy_size) {
1688 UNREACHABLE(); 1664 UNREACHABLE();
1689 } 1665 }
1690 1666
1691 static uint32_t GetCapacityImpl(JSObject* holder, 1667 static uint32_t GetCapacityImpl(JSObject* holder,
1692 FixedArrayBase* backing_store) { 1668 FixedArrayBase* backing_store) {
1693 FixedArray* parameter_map = FixedArray::cast(backing_store); 1669 FixedArray* parameter_map = FixedArray::cast(backing_store);
1694 FixedArrayBase* arguments = FixedArrayBase::cast(parameter_map->get(1)); 1670 FixedArrayBase* arguments = FixedArrayBase::cast(parameter_map->get(1));
1695 return Max(static_cast<uint32_t>(parameter_map->length() - 2), 1671 return parameter_map->length() - 2 +
1696 ForArray(arguments)->GetCapacity(holder, arguments)); 1672 ForArray(arguments)->GetCapacity(holder, arguments);
1697 } 1673 }
1698 1674
1699 static uint32_t GetKeyForIndexImpl(FixedArrayBase* dict, uint32_t index) { 1675 static bool HasIndexImpl(FixedArrayBase* parameters, uint32_t index) {
1700 return index; 1676 FixedArray* parameter_map = FixedArray::cast(parameters);
1677 uint32_t length = parameter_map->length() - 2;
1678 if (index < length) {
1679 return !GetParameterMapArg(parameter_map, index)->IsTheHole();
1680 }
1681
1682 FixedArrayBase* arguments = FixedArrayBase::cast(parameter_map->get(1));
1683 return ForArray(arguments)->HasIndex(arguments, index - length);
1701 } 1684 }
1702 1685
1703 static uint32_t GetIndexForKeyImpl(FixedArrayBase* dict, uint32_t key) { 1686 static uint32_t GetKeyForIndexImpl(FixedArrayBase* parameters,
1704 return key; 1687 uint32_t index) {
1688 FixedArray* parameter_map = FixedArray::cast(parameters);
1689 uint32_t length = parameter_map->length() - 2;
1690 if (index < length) return index;
1691
1692 FixedArray* arguments = FixedArray::cast(parameter_map->get(1));
1693 return ForArray(arguments)->GetKeyForIndex(arguments, index - length);
1705 } 1694 }
1706 1695
1707 static PropertyDetails GetDetailsImpl(FixedArrayBase* backing_store, 1696 static uint32_t GetIndexForKeyImpl(FixedArrayBase* parameters, uint32_t key) {
1708 uint32_t index) { 1697 FixedArray* parameter_map = FixedArray::cast(parameters);
1709 return PropertyDetails(NONE, DATA, 0, PropertyCellType::kNoCell); 1698 Object* probe = GetParameterMapArg(parameter_map, key);
1699 if (!probe->IsTheHole()) return key;
1700
1701 uint32_t length = parameter_map->length() - 2;
1702 FixedArray* arguments = FixedArray::cast(parameter_map->get(1));
1703 return length +
1704 ElementsAccessor::ForArray(arguments)
1705 ->GetIndexForKey(arguments, key);
1710 } 1706 }
1711 1707
1708 static PropertyDetails GetDetailsImpl(FixedArrayBase* parameters,
1709 uint32_t index) {
1710 FixedArray* parameter_map = FixedArray::cast(parameters);
1711 uint32_t length = parameter_map->length() - 2;
1712 if (index < length) {
1713 return PropertyDetails(NONE, DATA, 0, PropertyCellType::kNoCell);
1714 }
1715 index -= length;
1716 FixedArray* arguments = FixedArray::cast(parameter_map->get(1));
1717 return ElementsAccessor::ForArray(arguments)->GetDetails(arguments, index);
1718 }
1712 1719
1713 private: 1720 private:
1714 static Handle<Object> GetParameterMapArg(Handle<JSObject> holder, 1721 static Object* GetParameterMapArg(FixedArray* parameter_map, uint32_t key) {
1715 Handle<FixedArray> parameter_map, 1722 uint32_t length = parameter_map->length() - 2;
1716 uint32_t key) { 1723 return key < length
1717 Isolate* isolate = holder->GetIsolate(); 1724 ? parameter_map->get(key + 2)
1718 uint32_t length = holder->IsJSArray() 1725 : Object::cast(parameter_map->GetHeap()->the_hole_value());
1719 ? Smi::cast(Handle<JSArray>::cast(holder)->length())->value()
1720 : parameter_map->length();
1721 return key < (length - 2)
1722 ? handle(parameter_map->get(key + 2), isolate)
1723 : Handle<Object>::cast(isolate->factory()->the_hole_value());
1724 } 1726 }
1725 }; 1727 };
1726 1728
1727 1729
1728 ElementsAccessor* ElementsAccessor::ForArray(FixedArrayBase* array) { 1730 ElementsAccessor* ElementsAccessor::ForArray(FixedArrayBase* array) {
1729 return elements_accessors_[ElementsKindForArray(array)]; 1731 return elements_accessors_[ElementsKindForArray(array)];
1730 } 1732 }
1731 1733
1732 1734
1733 ElementsAccessor* ElementsAccessor::ForArray(Handle<FixedArrayBase> array) { 1735 ElementsAccessor* ElementsAccessor::ForArray(Handle<FixedArrayBase> array) {
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after
1794 } 1796 }
1795 } else { 1797 } else {
1796 return ThrowArrayLengthRangeError(isolate); 1798 return ThrowArrayLengthRangeError(isolate);
1797 } 1799 }
1798 } 1800 }
1799 1801
1800 // Slow case: The new length does not fit into a Smi or conversion 1802 // Slow case: The new length does not fit into a Smi or conversion
1801 // to slow elements is needed for other reasons. 1803 // to slow elements is needed for other reasons.
1802 if (length->IsNumber()) { 1804 if (length->IsNumber()) {
1803 uint32_t value; 1805 uint32_t value;
1804 if (length->ToArrayIndex(&value)) { 1806 if (length->ToArrayLength(&value)) {
1805 Handle<SeededNumberDictionary> dictionary = 1807 Handle<SeededNumberDictionary> dictionary =
1806 JSObject::NormalizeElements(array); 1808 JSObject::NormalizeElements(array);
1807 DCHECK(!dictionary.is_null()); 1809 DCHECK(!dictionary.is_null());
1808 1810
1809 Handle<Object> new_length = DictionaryElementsAccessor:: 1811 Handle<Object> new_length = DictionaryElementsAccessor::
1810 SetLengthWithoutNormalize(dictionary, array, length, value); 1812 SetLengthWithoutNormalize(dictionary, array, length, value);
1811 DCHECK(!new_length.is_null()); 1813 DCHECK(!new_length.is_null());
1812 1814
1813 DCHECK(new_length->IsNumber()); 1815 DCHECK(new_length->IsNumber());
1814 array->set_length(*new_length); 1816 array->set_length(*new_length);
(...skipping 99 matching lines...) Expand 10 before | Expand all | Expand 10 after
1914 break; 1916 break;
1915 } 1917 }
1916 1918
1917 array->set_elements(*elms); 1919 array->set_elements(*elms);
1918 array->set_length(Smi::FromInt(number_of_elements)); 1920 array->set_length(Smi::FromInt(number_of_elements));
1919 return array; 1921 return array;
1920 } 1922 }
1921 1923
1922 } // namespace internal 1924 } // namespace internal
1923 } // namespace v8 1925 } // namespace v8
OLDNEW
« no previous file with comments | « src/elements.h ('k') | src/ic/ic.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698