OLD | NEW |
1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 the V8 project authors. All rights reserved. |
2 // Redistribution and use in source and binary forms, with or without | 2 // Redistribution and use in source and binary forms, with or without |
3 // modification, are permitted provided that the following conditions are | 3 // modification, are permitted provided that the following conditions are |
4 // met: | 4 // met: |
5 // | 5 // |
6 // * Redistributions of source code must retain the above copyright | 6 // * Redistributions of source code must retain the above copyright |
7 // notice, this list of conditions and the following disclaimer. | 7 // notice, this list of conditions and the following disclaimer. |
8 // * Redistributions in binary form must reproduce the above | 8 // * Redistributions in binary form must reproduce the above |
9 // copyright notice, this list of conditions and the following | 9 // copyright notice, this list of conditions and the following |
10 // disclaimer in the documentation and/or other materials provided | 10 // disclaimer in the documentation and/or other materials provided |
(...skipping 128 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
139 static const ElementsKind Kind = KindParam; \ | 139 static const ElementsKind Kind = KindParam; \ |
140 typedef Store BackingStore; \ | 140 typedef Store BackingStore; \ |
141 }; | 141 }; |
142 ELEMENTS_LIST(ELEMENTS_TRAITS) | 142 ELEMENTS_LIST(ELEMENTS_TRAITS) |
143 #undef ELEMENTS_TRAITS | 143 #undef ELEMENTS_TRAITS |
144 | 144 |
145 | 145 |
146 ElementsAccessor** ElementsAccessor::elements_accessors_; | 146 ElementsAccessor** ElementsAccessor::elements_accessors_; |
147 | 147 |
148 | 148 |
149 static bool HasKey(Handle<FixedArray> array, Handle<Object> key_handle) { | 149 static bool HasKey(FixedArray* array, Object* key) { |
150 DisallowHeapAllocation no_gc; | |
151 Object* key = *key_handle; | |
152 int len0 = array->length(); | 150 int len0 = array->length(); |
153 for (int i = 0; i < len0; i++) { | 151 for (int i = 0; i < len0; i++) { |
154 Object* element = array->get(i); | 152 Object* element = array->get(i); |
155 if (element->IsSmi() && element == key) return true; | 153 if (element->IsSmi() && element == key) return true; |
156 if (element->IsString() && | 154 if (element->IsString() && |
157 key->IsString() && String::cast(element)->Equals(String::cast(key))) { | 155 key->IsString() && String::cast(element)->Equals(String::cast(key))) { |
158 return true; | 156 return true; |
159 } | 157 } |
160 } | 158 } |
161 return false; | 159 return false; |
(...skipping 454 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
616 virtual void Validate(Handle<JSObject> holder) V8_FINAL V8_OVERRIDE { | 614 virtual void Validate(Handle<JSObject> holder) V8_FINAL V8_OVERRIDE { |
617 DisallowHeapAllocation no_gc; | 615 DisallowHeapAllocation no_gc; |
618 ElementsAccessorSubclass::ValidateImpl(*holder); | 616 ElementsAccessorSubclass::ValidateImpl(*holder); |
619 } | 617 } |
620 | 618 |
621 static bool HasElementImpl(Handle<Object> receiver, | 619 static bool HasElementImpl(Handle<Object> receiver, |
622 Handle<JSObject> holder, | 620 Handle<JSObject> holder, |
623 uint32_t key, | 621 uint32_t key, |
624 Handle<FixedArrayBase> backing_store) { | 622 Handle<FixedArrayBase> backing_store) { |
625 return ElementsAccessorSubclass::GetAttributesImpl( | 623 return ElementsAccessorSubclass::GetAttributesImpl( |
626 receiver, holder, key, backing_store) != ABSENT; | 624 *receiver, *holder, key, *backing_store) != ABSENT; |
627 } | 625 } |
628 | 626 |
629 virtual bool HasElement( | 627 virtual bool HasElement( |
630 Handle<Object> receiver, | 628 Handle<Object> receiver, |
631 Handle<JSObject> holder, | 629 Handle<JSObject> holder, |
632 uint32_t key, | 630 uint32_t key, |
633 Handle<FixedArrayBase> backing_store) V8_FINAL V8_OVERRIDE { | 631 Handle<FixedArrayBase> backing_store) V8_FINAL V8_OVERRIDE { |
634 return ElementsAccessorSubclass::HasElementImpl( | 632 return ElementsAccessorSubclass::HasElementImpl( |
635 receiver, holder, key, backing_store); | 633 receiver, holder, key, backing_store); |
636 } | 634 } |
(...skipping 15 matching lines...) Expand all Loading... |
652 } | 650 } |
653 | 651 |
654 return ElementsAccessorSubclass::GetImpl( | 652 return ElementsAccessorSubclass::GetImpl( |
655 receiver, holder, key, backing_store); | 653 receiver, holder, key, backing_store); |
656 } | 654 } |
657 | 655 |
658 static Handle<Object> GetImpl(Handle<Object> receiver, | 656 static Handle<Object> GetImpl(Handle<Object> receiver, |
659 Handle<JSObject> obj, | 657 Handle<JSObject> obj, |
660 uint32_t key, | 658 uint32_t key, |
661 Handle<FixedArrayBase> backing_store) { | 659 Handle<FixedArrayBase> backing_store) { |
662 if (key < ElementsAccessorSubclass::GetCapacityImpl(backing_store)) { | 660 if (key < ElementsAccessorSubclass::GetCapacityImpl(*backing_store)) { |
663 return BackingStore::get(Handle<BackingStore>::cast(backing_store), key); | 661 return BackingStore::get(Handle<BackingStore>::cast(backing_store), key); |
664 } else { | 662 } else { |
665 return backing_store->GetIsolate()->factory()->the_hole_value(); | 663 return backing_store->GetIsolate()->factory()->the_hole_value(); |
666 } | 664 } |
667 } | 665 } |
668 | 666 |
669 MUST_USE_RESULT virtual PropertyAttributes GetAttributes( | 667 MUST_USE_RESULT virtual PropertyAttributes GetAttributes( |
670 Handle<Object> receiver, | 668 Handle<Object> receiver, |
671 Handle<JSObject> holder, | 669 Handle<JSObject> holder, |
672 uint32_t key, | 670 uint32_t key, |
673 Handle<FixedArrayBase> backing_store) V8_FINAL V8_OVERRIDE { | 671 Handle<FixedArrayBase> backing_store) V8_FINAL V8_OVERRIDE { |
674 return ElementsAccessorSubclass::GetAttributesImpl( | 672 return ElementsAccessorSubclass::GetAttributesImpl( |
| 673 *receiver, *holder, key, *backing_store); |
| 674 } |
| 675 |
| 676 // TODO(ishell): To be removed once elements.cc is handlified. |
| 677 MUST_USE_RESULT virtual PropertyAttributes GetAttributes( |
| 678 Object* receiver, |
| 679 JSObject* holder, |
| 680 uint32_t key, |
| 681 FixedArrayBase* backing_store) V8_FINAL V8_OVERRIDE { |
| 682 return ElementsAccessorSubclass::GetAttributesImpl( |
675 receiver, holder, key, backing_store); | 683 receiver, holder, key, backing_store); |
676 } | 684 } |
677 | 685 |
678 MUST_USE_RESULT static PropertyAttributes GetAttributesImpl( | 686 MUST_USE_RESULT static PropertyAttributes GetAttributesImpl( |
679 Handle<Object> receiver, | 687 Object* receiver, |
680 Handle<JSObject> obj, | 688 JSObject* obj, |
681 uint32_t key, | 689 uint32_t key, |
682 Handle<FixedArrayBase> backing_store) { | 690 FixedArrayBase* backing_store) { |
683 if (key >= ElementsAccessorSubclass::GetCapacityImpl(backing_store)) { | 691 if (key >= ElementsAccessorSubclass::GetCapacityImpl(backing_store)) { |
684 return ABSENT; | 692 return ABSENT; |
685 } | 693 } |
686 return | 694 return BackingStore::cast(backing_store)->is_the_hole(key) ? ABSENT : NONE; |
687 Handle<BackingStore>::cast(backing_store)->is_the_hole(key) | |
688 ? ABSENT : NONE; | |
689 } | 695 } |
690 | 696 |
691 MUST_USE_RESULT virtual PropertyType GetType( | 697 MUST_USE_RESULT virtual PropertyType GetType( |
692 Handle<Object> receiver, | 698 Handle<Object> receiver, |
693 Handle<JSObject> holder, | 699 Handle<JSObject> holder, |
694 uint32_t key, | 700 uint32_t key, |
695 Handle<FixedArrayBase> backing_store) V8_FINAL V8_OVERRIDE { | 701 Handle<FixedArrayBase> backing_store) V8_FINAL V8_OVERRIDE { |
696 return ElementsAccessorSubclass::GetTypeImpl( | 702 return ElementsAccessorSubclass::GetTypeImpl( |
| 703 *receiver, *holder, key, *backing_store); |
| 704 } |
| 705 |
| 706 // TODO(ishell): To be removed once elements.cc is handlified. |
| 707 MUST_USE_RESULT virtual PropertyType GetType( |
| 708 Object* receiver, |
| 709 JSObject* holder, |
| 710 uint32_t key, |
| 711 FixedArrayBase* backing_store) V8_FINAL V8_OVERRIDE { |
| 712 return ElementsAccessorSubclass::GetTypeImpl( |
697 receiver, holder, key, backing_store); | 713 receiver, holder, key, backing_store); |
698 } | 714 } |
699 | 715 |
700 MUST_USE_RESULT static PropertyType GetTypeImpl( | 716 MUST_USE_RESULT static PropertyType GetTypeImpl( |
701 Handle<Object> receiver, | 717 Object* receiver, |
702 Handle<JSObject> obj, | 718 JSObject* obj, |
703 uint32_t key, | 719 uint32_t key, |
704 Handle<FixedArrayBase> backing_store) { | 720 FixedArrayBase* backing_store) { |
705 if (key >= ElementsAccessorSubclass::GetCapacityImpl(backing_store)) { | 721 if (key >= ElementsAccessorSubclass::GetCapacityImpl(backing_store)) { |
706 return NONEXISTENT; | 722 return NONEXISTENT; |
707 } | 723 } |
708 return | 724 return BackingStore::cast(backing_store)->is_the_hole(key) |
709 Handle<BackingStore>::cast(backing_store)->is_the_hole(key) | 725 ? NONEXISTENT : FIELD; |
710 ? NONEXISTENT : FIELD; | |
711 } | 726 } |
712 | 727 |
713 MUST_USE_RESULT virtual MaybeHandle<AccessorPair> GetAccessorPair( | 728 MUST_USE_RESULT virtual MaybeHandle<AccessorPair> GetAccessorPair( |
714 Handle<Object> receiver, | 729 Handle<Object> receiver, |
715 Handle<JSObject> holder, | 730 Handle<JSObject> holder, |
716 uint32_t key, | 731 uint32_t key, |
717 Handle<FixedArrayBase> backing_store) V8_FINAL V8_OVERRIDE { | 732 Handle<FixedArrayBase> backing_store) V8_FINAL V8_OVERRIDE { |
718 return ElementsAccessorSubclass::GetAccessorPairImpl( | 733 return ElementsAccessorSubclass::GetAccessorPairImpl( |
719 receiver, holder, key, backing_store); | 734 receiver, holder, key, backing_store); |
720 } | 735 } |
(...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
813 #ifdef ENABLE_SLOW_ASSERTS | 828 #ifdef ENABLE_SLOW_ASSERTS |
814 if (FLAG_enable_slow_asserts) { | 829 if (FLAG_enable_slow_asserts) { |
815 for (int i = 0; i < len0; i++) { | 830 for (int i = 0; i < len0; i++) { |
816 ASSERT(!to->get(i)->IsTheHole()); | 831 ASSERT(!to->get(i)->IsTheHole()); |
817 } | 832 } |
818 } | 833 } |
819 #endif | 834 #endif |
820 | 835 |
821 // Optimize if 'other' is empty. | 836 // Optimize if 'other' is empty. |
822 // We cannot optimize if 'this' is empty, as other may have holes. | 837 // We cannot optimize if 'this' is empty, as other may have holes. |
823 uint32_t len1 = ElementsAccessorSubclass::GetCapacityImpl(from); | 838 uint32_t len1 = ElementsAccessorSubclass::GetCapacityImpl(*from); |
824 if (len1 == 0) return to; | 839 if (len1 == 0) return to; |
825 | 840 |
826 // Compute how many elements are not in other. | 841 // Compute how many elements are not in other. |
827 uint32_t extra = 0; | 842 uint32_t extra = 0; |
828 for (uint32_t y = 0; y < len1; y++) { | 843 for (uint32_t y = 0; y < len1; y++) { |
829 uint32_t key = ElementsAccessorSubclass::GetKeyForIndexImpl(from, y); | 844 uint32_t key = ElementsAccessorSubclass::GetKeyForIndexImpl(*from, y); |
830 if (ElementsAccessorSubclass::HasElementImpl( | 845 if (ElementsAccessorSubclass::HasElementImpl( |
831 receiver, holder, key, from)) { | 846 receiver, holder, key, from)) { |
832 Handle<Object> value = | 847 Handle<Object> value = |
833 ElementsAccessorSubclass::GetImpl(receiver, holder, key, from); | 848 ElementsAccessorSubclass::GetImpl(receiver, holder, key, from); |
834 | 849 |
835 ASSERT(!value->IsTheHole()); | 850 ASSERT(!value->IsTheHole()); |
836 if (!HasKey(to, value)) { | 851 if (!HasKey(*to, *value)) { |
837 extra++; | 852 extra++; |
838 } | 853 } |
839 } | 854 } |
840 } | 855 } |
841 | 856 |
842 if (extra == 0) return to; | 857 if (extra == 0) return to; |
843 | 858 |
844 // Allocate the result | 859 // Allocate the result |
845 Isolate* isolate = from->GetIsolate(); | 860 Isolate* isolate = from->GetIsolate(); |
846 Handle<FixedArray> result = isolate->factory()->NewFixedArray(len0 + extra); | 861 Handle<FixedArray> result = isolate->factory()->NewFixedArray(len0 + extra); |
847 | 862 |
848 // Fill in the content | 863 // Fill in the content |
849 { | 864 { |
850 DisallowHeapAllocation no_gc; | 865 DisallowHeapAllocation no_gc; |
851 WriteBarrierMode mode = result->GetWriteBarrierMode(no_gc); | 866 WriteBarrierMode mode = result->GetWriteBarrierMode(no_gc); |
852 for (int i = 0; i < len0; i++) { | 867 for (int i = 0; i < len0; i++) { |
853 Object* e = to->get(i); | 868 Object* e = to->get(i); |
854 ASSERT(e->IsString() || e->IsNumber()); | 869 ASSERT(e->IsString() || e->IsNumber()); |
855 result->set(i, e, mode); | 870 result->set(i, e, mode); |
856 } | 871 } |
857 } | 872 } |
858 // Fill in the extra values. | 873 // Fill in the extra values. |
859 uint32_t index = 0; | 874 uint32_t index = 0; |
860 for (uint32_t y = 0; y < len1; y++) { | 875 for (uint32_t y = 0; y < len1; y++) { |
861 uint32_t key = | 876 uint32_t key = |
862 ElementsAccessorSubclass::GetKeyForIndexImpl(from, y); | 877 ElementsAccessorSubclass::GetKeyForIndexImpl(*from, y); |
863 if (ElementsAccessorSubclass::HasElementImpl( | 878 if (ElementsAccessorSubclass::HasElementImpl( |
864 receiver, holder, key, from)) { | 879 receiver, holder, key, from)) { |
865 Handle<Object> value = | 880 Handle<Object> value = |
866 ElementsAccessorSubclass::GetImpl(receiver, holder, key, from); | 881 ElementsAccessorSubclass::GetImpl(receiver, holder, key, from); |
867 if (!value->IsTheHole() && !HasKey(to, value)) { | 882 if (!value->IsTheHole() && !HasKey(*to, *value)) { |
868 result->set(len0 + index, *value); | 883 result->set(len0 + index, *value); |
869 index++; | 884 index++; |
870 } | 885 } |
871 } | 886 } |
872 } | 887 } |
873 ASSERT(extra == index); | 888 ASSERT(extra == index); |
874 return result; | 889 return result; |
875 } | 890 } |
876 | 891 |
877 protected: | 892 protected: |
878 static uint32_t GetCapacityImpl(Handle<FixedArrayBase> backing_store) { | 893 static uint32_t GetCapacityImpl(FixedArrayBase* backing_store) { |
879 return backing_store->length(); | 894 return backing_store->length(); |
880 } | 895 } |
881 | 896 |
882 virtual uint32_t GetCapacity(Handle<FixedArrayBase> backing_store) | 897 virtual uint32_t GetCapacity(FixedArrayBase* backing_store) |
883 V8_FINAL V8_OVERRIDE { | 898 V8_FINAL V8_OVERRIDE { |
884 return ElementsAccessorSubclass::GetCapacityImpl(backing_store); | 899 return ElementsAccessorSubclass::GetCapacityImpl(backing_store); |
885 } | 900 } |
886 | 901 |
887 static uint32_t GetKeyForIndexImpl(Handle<FixedArrayBase> backing_store, | 902 static uint32_t GetKeyForIndexImpl(FixedArrayBase* backing_store, |
888 uint32_t index) { | 903 uint32_t index) { |
889 return index; | 904 return index; |
890 } | 905 } |
891 | 906 |
892 virtual uint32_t GetKeyForIndex(Handle<FixedArrayBase> backing_store, | 907 virtual uint32_t GetKeyForIndex(Handle<FixedArrayBase> backing_store, |
893 uint32_t index) V8_FINAL V8_OVERRIDE { | 908 uint32_t index) V8_FINAL V8_OVERRIDE { |
894 return ElementsAccessorSubclass::GetKeyForIndexImpl(backing_store, index); | 909 return ElementsAccessorSubclass::GetKeyForIndexImpl(*backing_store, index); |
895 } | 910 } |
896 | 911 |
897 private: | 912 private: |
898 DISALLOW_COPY_AND_ASSIGN(ElementsAccessorBase); | 913 DISALLOW_COPY_AND_ASSIGN(ElementsAccessorBase); |
899 }; | 914 }; |
900 | 915 |
901 | 916 |
902 // Super class for all fast element arrays. | 917 // Super class for all fast element arrays. |
903 template<typename FastElementsAccessorSubclass, | 918 template<typename FastElementsAccessorSubclass, |
904 typename KindTraits, | 919 typename KindTraits, |
(...skipping 167 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1072 ASSERT((!IsFastSmiElementsKind(KindTraits::Kind) || | 1087 ASSERT((!IsFastSmiElementsKind(KindTraits::Kind) || |
1073 static_cast<Object*>(backing_store->get(i))->IsSmi()) || | 1088 static_cast<Object*>(backing_store->get(i))->IsSmi()) || |
1074 (IsFastHoleyElementsKind(KindTraits::Kind) == | 1089 (IsFastHoleyElementsKind(KindTraits::Kind) == |
1075 backing_store->is_the_hole(i))); | 1090 backing_store->is_the_hole(i))); |
1076 } | 1091 } |
1077 #endif | 1092 #endif |
1078 } | 1093 } |
1079 }; | 1094 }; |
1080 | 1095 |
1081 | 1096 |
1082 static inline ElementsKind ElementsKindForArray(Handle<FixedArrayBase> array) { | 1097 static inline ElementsKind ElementsKindForArray(FixedArrayBase* array) { |
1083 switch (array->map()->instance_type()) { | 1098 switch (array->map()->instance_type()) { |
1084 case FIXED_ARRAY_TYPE: | 1099 case FIXED_ARRAY_TYPE: |
1085 if (array->IsDictionary()) { | 1100 if (array->IsDictionary()) { |
1086 return DICTIONARY_ELEMENTS; | 1101 return DICTIONARY_ELEMENTS; |
1087 } else { | 1102 } else { |
1088 return FAST_HOLEY_ELEMENTS; | 1103 return FAST_HOLEY_ELEMENTS; |
1089 } | 1104 } |
1090 case FIXED_DOUBLE_ARRAY_TYPE: | 1105 case FIXED_DOUBLE_ARRAY_TYPE: |
1091 return FAST_HOLEY_DOUBLE_ELEMENTS; | 1106 return FAST_HOLEY_DOUBLE_ELEMENTS; |
1092 | 1107 |
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1143 CopyDictionaryToObjectElements( | 1158 CopyDictionaryToObjectElements( |
1144 from, from_start, to, to_kind, to_start, copy_size); | 1159 from, from_start, to, to_kind, to_start, copy_size); |
1145 break; | 1160 break; |
1146 case SLOPPY_ARGUMENTS_ELEMENTS: { | 1161 case SLOPPY_ARGUMENTS_ELEMENTS: { |
1147 // TODO(verwaest): This is a temporary hack to support extending | 1162 // TODO(verwaest): This is a temporary hack to support extending |
1148 // SLOPPY_ARGUMENTS_ELEMENTS in SetFastElementsCapacityAndLength. | 1163 // SLOPPY_ARGUMENTS_ELEMENTS in SetFastElementsCapacityAndLength. |
1149 // This case should be UNREACHABLE(). | 1164 // This case should be UNREACHABLE(). |
1150 Handle<FixedArray> parameter_map = Handle<FixedArray>::cast(from); | 1165 Handle<FixedArray> parameter_map = Handle<FixedArray>::cast(from); |
1151 Handle<FixedArrayBase> arguments( | 1166 Handle<FixedArrayBase> arguments( |
1152 FixedArrayBase::cast(parameter_map->get(1))); | 1167 FixedArrayBase::cast(parameter_map->get(1))); |
1153 ElementsKind from_kind = ElementsKindForArray(arguments); | 1168 ElementsKind from_kind = ElementsKindForArray(*arguments); |
1154 CopyElementsImpl(arguments, from_start, to, from_kind, | 1169 CopyElementsImpl(arguments, from_start, to, from_kind, |
1155 to_start, packed_size, copy_size); | 1170 to_start, packed_size, copy_size); |
1156 break; | 1171 break; |
1157 } | 1172 } |
1158 #define TYPED_ARRAY_CASE(Type, type, TYPE, ctype, size) \ | 1173 #define TYPED_ARRAY_CASE(Type, type, TYPE, ctype, size) \ |
1159 case EXTERNAL_##TYPE##_ELEMENTS: \ | 1174 case EXTERNAL_##TYPE##_ELEMENTS: \ |
1160 case TYPE##_ELEMENTS: \ | 1175 case TYPE##_ELEMENTS: \ |
1161 UNREACHABLE(); | 1176 UNREACHABLE(); |
1162 TYPED_ARRAYS(TYPED_ARRAY_CASE) | 1177 TYPED_ARRAYS(TYPED_ARRAY_CASE) |
1163 #undef TYPED_ARRAY_CASE | 1178 #undef TYPED_ARRAY_CASE |
(...skipping 166 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1330 typedef typename ElementsKindTraits<Kind>::BackingStore BackingStore; | 1345 typedef typename ElementsKindTraits<Kind>::BackingStore BackingStore; |
1331 typedef TypedElementsAccessor<Kind> AccessorClass; | 1346 typedef TypedElementsAccessor<Kind> AccessorClass; |
1332 | 1347 |
1333 friend class ElementsAccessorBase<AccessorClass, | 1348 friend class ElementsAccessorBase<AccessorClass, |
1334 ElementsKindTraits<Kind> >; | 1349 ElementsKindTraits<Kind> >; |
1335 | 1350 |
1336 static Handle<Object> GetImpl(Handle<Object> receiver, | 1351 static Handle<Object> GetImpl(Handle<Object> receiver, |
1337 Handle<JSObject> obj, | 1352 Handle<JSObject> obj, |
1338 uint32_t key, | 1353 uint32_t key, |
1339 Handle<FixedArrayBase> backing_store) { | 1354 Handle<FixedArrayBase> backing_store) { |
1340 if (key < AccessorClass::GetCapacityImpl(backing_store)) { | 1355 if (key < AccessorClass::GetCapacityImpl(*backing_store)) { |
1341 return BackingStore::get(Handle<BackingStore>::cast(backing_store), key); | 1356 return BackingStore::get(Handle<BackingStore>::cast(backing_store), key); |
1342 } else { | 1357 } else { |
1343 return backing_store->GetIsolate()->factory()->undefined_value(); | 1358 return backing_store->GetIsolate()->factory()->undefined_value(); |
1344 } | 1359 } |
1345 } | 1360 } |
1346 | 1361 |
1347 MUST_USE_RESULT static PropertyAttributes GetAttributesImpl( | 1362 MUST_USE_RESULT static PropertyAttributes GetAttributesImpl( |
1348 Handle<Object> receiver, | 1363 Object* receiver, |
1349 Handle<JSObject> obj, | 1364 JSObject* obj, |
1350 uint32_t key, | 1365 uint32_t key, |
1351 Handle<FixedArrayBase> backing_store) { | 1366 FixedArrayBase* backing_store) { |
1352 return | 1367 return |
1353 key < AccessorClass::GetCapacityImpl(backing_store) | 1368 key < AccessorClass::GetCapacityImpl(backing_store) |
1354 ? NONE : ABSENT; | 1369 ? NONE : ABSENT; |
1355 } | 1370 } |
1356 | 1371 |
1357 MUST_USE_RESULT static PropertyType GetTypeImpl( | 1372 MUST_USE_RESULT static PropertyType GetTypeImpl( |
1358 Handle<Object> receiver, | 1373 Object* receiver, |
1359 Handle<JSObject> obj, | 1374 JSObject* obj, |
1360 uint32_t key, | 1375 uint32_t key, |
1361 Handle<FixedArrayBase> backing_store) { | 1376 FixedArrayBase* backing_store) { |
1362 return | 1377 return |
1363 key < AccessorClass::GetCapacityImpl(backing_store) | 1378 key < AccessorClass::GetCapacityImpl(backing_store) |
1364 ? FIELD : NONEXISTENT; | 1379 ? FIELD : NONEXISTENT; |
1365 } | 1380 } |
1366 | 1381 |
1367 MUST_USE_RESULT static Handle<Object> SetLengthImpl( | 1382 MUST_USE_RESULT static Handle<Object> SetLengthImpl( |
1368 Handle<JSObject> obj, | 1383 Handle<JSObject> obj, |
1369 Handle<Object> length, | 1384 Handle<Object> length, |
1370 Handle<FixedArrayBase> backing_store) { | 1385 Handle<FixedArrayBase> backing_store) { |
1371 // External arrays do not support changing their length. | 1386 // External arrays do not support changing their length. |
1372 UNREACHABLE(); | 1387 UNREACHABLE(); |
1373 return obj; | 1388 return obj; |
1374 } | 1389 } |
1375 | 1390 |
1376 MUST_USE_RESULT virtual Handle<Object> Delete( | 1391 MUST_USE_RESULT virtual Handle<Object> Delete( |
1377 Handle<JSObject> obj, | 1392 Handle<JSObject> obj, |
1378 uint32_t key, | 1393 uint32_t key, |
1379 JSReceiver::DeleteMode mode) V8_FINAL V8_OVERRIDE { | 1394 JSReceiver::DeleteMode mode) V8_FINAL V8_OVERRIDE { |
1380 // External arrays always ignore deletes. | 1395 // External arrays always ignore deletes. |
1381 return obj->GetIsolate()->factory()->true_value(); | 1396 return obj->GetIsolate()->factory()->true_value(); |
1382 } | 1397 } |
1383 | 1398 |
1384 static bool HasElementImpl(Handle<Object> receiver, | 1399 static bool HasElementImpl(Handle<Object> receiver, |
1385 Handle<JSObject> holder, | 1400 Handle<JSObject> holder, |
1386 uint32_t key, | 1401 uint32_t key, |
1387 Handle<FixedArrayBase> backing_store) { | 1402 Handle<FixedArrayBase> backing_store) { |
1388 uint32_t capacity = | 1403 uint32_t capacity = |
1389 AccessorClass::GetCapacityImpl(backing_store); | 1404 AccessorClass::GetCapacityImpl(*backing_store); |
1390 return key < capacity; | 1405 return key < capacity; |
1391 } | 1406 } |
1392 }; | 1407 }; |
1393 | 1408 |
1394 | 1409 |
1395 | 1410 |
1396 #define EXTERNAL_ELEMENTS_ACCESSOR(Type, type, TYPE, ctype, size) \ | 1411 #define EXTERNAL_ELEMENTS_ACCESSOR(Type, type, TYPE, ctype, size) \ |
1397 typedef TypedElementsAccessor<EXTERNAL_##TYPE##_ELEMENTS> \ | 1412 typedef TypedElementsAccessor<EXTERNAL_##TYPE##_ELEMENTS> \ |
1398 External##Type##ElementsAccessor; | 1413 External##Type##ElementsAccessor; |
1399 | 1414 |
(...skipping 181 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1581 return JSObject::GetElementWithCallback( | 1596 return JSObject::GetElementWithCallback( |
1582 obj, receiver, element, key, obj); | 1597 obj, receiver, element, key, obj); |
1583 } else { | 1598 } else { |
1584 return element; | 1599 return element; |
1585 } | 1600 } |
1586 } | 1601 } |
1587 return isolate->factory()->the_hole_value(); | 1602 return isolate->factory()->the_hole_value(); |
1588 } | 1603 } |
1589 | 1604 |
1590 MUST_USE_RESULT static PropertyAttributes GetAttributesImpl( | 1605 MUST_USE_RESULT static PropertyAttributes GetAttributesImpl( |
1591 Handle<Object> receiver, | 1606 Object* receiver, |
1592 Handle<JSObject> obj, | 1607 JSObject* obj, |
1593 uint32_t key, | 1608 uint32_t key, |
1594 Handle<FixedArrayBase> backing_store) { | 1609 FixedArrayBase* backing_store) { |
1595 Handle<SeededNumberDictionary> dictionary = | 1610 SeededNumberDictionary* dictionary = |
1596 Handle<SeededNumberDictionary>::cast(backing_store); | 1611 SeededNumberDictionary::cast(backing_store); |
1597 int entry = dictionary->FindEntry(key); | 1612 int entry = dictionary->FindEntry(key); |
1598 if (entry != SeededNumberDictionary::kNotFound) { | 1613 if (entry != SeededNumberDictionary::kNotFound) { |
1599 return dictionary->DetailsAt(entry).attributes(); | 1614 return dictionary->DetailsAt(entry).attributes(); |
1600 } | 1615 } |
1601 return ABSENT; | 1616 return ABSENT; |
1602 } | 1617 } |
1603 | 1618 |
1604 MUST_USE_RESULT static PropertyType GetTypeImpl( | 1619 MUST_USE_RESULT static PropertyType GetTypeImpl( |
1605 Handle<Object> receiver, | 1620 Object* receiver, |
1606 Handle<JSObject> obj, | 1621 JSObject* obj, |
1607 uint32_t key, | 1622 uint32_t key, |
1608 Handle<FixedArrayBase> store) { | 1623 FixedArrayBase* store) { |
1609 Handle<SeededNumberDictionary> backing_store = | 1624 SeededNumberDictionary* backing_store = SeededNumberDictionary::cast(store); |
1610 Handle<SeededNumberDictionary>::cast(store); | |
1611 int entry = backing_store->FindEntry(key); | 1625 int entry = backing_store->FindEntry(key); |
1612 if (entry != SeededNumberDictionary::kNotFound) { | 1626 if (entry != SeededNumberDictionary::kNotFound) { |
1613 return backing_store->DetailsAt(entry).type(); | 1627 return backing_store->DetailsAt(entry).type(); |
1614 } | 1628 } |
1615 return NONEXISTENT; | 1629 return NONEXISTENT; |
1616 } | 1630 } |
1617 | 1631 |
1618 MUST_USE_RESULT static MaybeHandle<AccessorPair> GetAccessorPairImpl( | 1632 MUST_USE_RESULT static MaybeHandle<AccessorPair> GetAccessorPairImpl( |
1619 Handle<Object> receiver, | 1633 Handle<Object> receiver, |
1620 Handle<JSObject> obj, | 1634 Handle<JSObject> obj, |
(...skipping 12 matching lines...) Expand all Loading... |
1633 | 1647 |
1634 static bool HasElementImpl(Handle<Object> receiver, | 1648 static bool HasElementImpl(Handle<Object> receiver, |
1635 Handle<JSObject> holder, | 1649 Handle<JSObject> holder, |
1636 uint32_t key, | 1650 uint32_t key, |
1637 Handle<FixedArrayBase> store) { | 1651 Handle<FixedArrayBase> store) { |
1638 Handle<SeededNumberDictionary> backing_store = | 1652 Handle<SeededNumberDictionary> backing_store = |
1639 Handle<SeededNumberDictionary>::cast(store); | 1653 Handle<SeededNumberDictionary>::cast(store); |
1640 return backing_store->FindEntry(key) != SeededNumberDictionary::kNotFound; | 1654 return backing_store->FindEntry(key) != SeededNumberDictionary::kNotFound; |
1641 } | 1655 } |
1642 | 1656 |
1643 static uint32_t GetKeyForIndexImpl(Handle<FixedArrayBase> store, | 1657 // TODO(ishell): Handlify when all callers are handlified. |
| 1658 static uint32_t GetKeyForIndexImpl(FixedArrayBase* store, |
1644 uint32_t index) { | 1659 uint32_t index) { |
1645 DisallowHeapAllocation no_gc; | 1660 SeededNumberDictionary* dict = SeededNumberDictionary::cast(store); |
1646 Handle<SeededNumberDictionary> dict = | |
1647 Handle<SeededNumberDictionary>::cast(store); | |
1648 Object* key = dict->KeyAt(index); | 1661 Object* key = dict->KeyAt(index); |
1649 return Smi::cast(key)->value(); | 1662 return Smi::cast(key)->value(); |
1650 } | 1663 } |
1651 }; | 1664 }; |
1652 | 1665 |
1653 | 1666 |
1654 class SloppyArgumentsElementsAccessor : public ElementsAccessorBase< | 1667 class SloppyArgumentsElementsAccessor : public ElementsAccessorBase< |
1655 SloppyArgumentsElementsAccessor, | 1668 SloppyArgumentsElementsAccessor, |
1656 ElementsKindTraits<SLOPPY_ARGUMENTS_ELEMENTS> > { | 1669 ElementsKindTraits<SLOPPY_ARGUMENTS_ELEMENTS> > { |
1657 public: | 1670 public: |
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1692 int context_index = entry->aliased_context_slot(); | 1705 int context_index = entry->aliased_context_slot(); |
1693 ASSERT(!context->get(context_index)->IsTheHole()); | 1706 ASSERT(!context->get(context_index)->IsTheHole()); |
1694 return handle(context->get(context_index), isolate); | 1707 return handle(context->get(context_index), isolate); |
1695 } else { | 1708 } else { |
1696 return result; | 1709 return result; |
1697 } | 1710 } |
1698 } | 1711 } |
1699 } | 1712 } |
1700 | 1713 |
1701 MUST_USE_RESULT static PropertyAttributes GetAttributesImpl( | 1714 MUST_USE_RESULT static PropertyAttributes GetAttributesImpl( |
1702 Handle<Object> receiver, | 1715 Object* receiver, |
1703 Handle<JSObject> obj, | 1716 JSObject* obj, |
1704 uint32_t key, | 1717 uint32_t key, |
1705 Handle<FixedArrayBase> backing_store) { | 1718 FixedArrayBase* backing_store) { |
1706 Handle<FixedArray> parameter_map = Handle<FixedArray>::cast(backing_store); | 1719 FixedArray* parameter_map = FixedArray::cast(backing_store); |
1707 Handle<Object> probe = GetParameterMapArg(obj, parameter_map, key); | 1720 Object* probe = GetParameterMapArg(obj, parameter_map, key); |
1708 if (!probe->IsTheHole()) { | 1721 if (!probe->IsTheHole()) { |
1709 return NONE; | 1722 return NONE; |
1710 } else { | 1723 } else { |
1711 // If not aliased, check the arguments. | 1724 // If not aliased, check the arguments. |
1712 Handle<FixedArray> arguments(FixedArray::cast(parameter_map->get(1))); | 1725 FixedArray* arguments = FixedArray::cast(parameter_map->get(1)); |
1713 return ElementsAccessor::ForArray(arguments)->GetAttributes( | 1726 return ElementsAccessor::ForArray(arguments)->GetAttributes( |
1714 receiver, obj, key, arguments); | 1727 receiver, obj, key, arguments); |
1715 } | 1728 } |
1716 } | 1729 } |
1717 | 1730 |
1718 MUST_USE_RESULT static PropertyType GetTypeImpl( | 1731 MUST_USE_RESULT static PropertyType GetTypeImpl( |
1719 Handle<Object> receiver, | 1732 Object* receiver, |
1720 Handle<JSObject> obj, | 1733 JSObject* obj, |
1721 uint32_t key, | 1734 uint32_t key, |
1722 Handle<FixedArrayBase> parameters) { | 1735 FixedArrayBase* parameters) { |
1723 Handle<FixedArray> parameter_map = Handle<FixedArray>::cast(parameters); | 1736 FixedArray* parameter_map = FixedArray::cast(parameters); |
1724 Handle<Object> probe = GetParameterMapArg(obj, parameter_map, key); | 1737 Object* probe = GetParameterMapArg(obj, parameter_map, key); |
1725 if (!probe->IsTheHole()) { | 1738 if (!probe->IsTheHole()) { |
1726 return FIELD; | 1739 return FIELD; |
1727 } else { | 1740 } else { |
1728 // If not aliased, check the arguments. | 1741 // If not aliased, check the arguments. |
1729 Handle<FixedArray> arguments(FixedArray::cast(parameter_map->get(1))); | 1742 FixedArray* arguments = FixedArray::cast(parameter_map->get(1)); |
1730 return ElementsAccessor::ForArray(arguments)->GetType( | 1743 return ElementsAccessor::ForArray(arguments)->GetType( |
1731 receiver, obj, key, arguments); | 1744 receiver, obj, key, arguments); |
1732 } | 1745 } |
1733 } | 1746 } |
1734 | 1747 |
1735 MUST_USE_RESULT static MaybeHandle<AccessorPair> GetAccessorPairImpl( | 1748 MUST_USE_RESULT static MaybeHandle<AccessorPair> GetAccessorPairImpl( |
1736 Handle<Object> receiver, | 1749 Handle<Object> receiver, |
1737 Handle<JSObject> obj, | 1750 Handle<JSObject> obj, |
1738 uint32_t key, | 1751 uint32_t key, |
1739 Handle<FixedArrayBase> parameters) { | 1752 Handle<FixedArrayBase> parameters) { |
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1788 static void CopyElementsImpl(Handle<FixedArrayBase> from, | 1801 static void CopyElementsImpl(Handle<FixedArrayBase> from, |
1789 uint32_t from_start, | 1802 uint32_t from_start, |
1790 Handle<FixedArrayBase> to, | 1803 Handle<FixedArrayBase> to, |
1791 ElementsKind from_kind, | 1804 ElementsKind from_kind, |
1792 uint32_t to_start, | 1805 uint32_t to_start, |
1793 int packed_size, | 1806 int packed_size, |
1794 int copy_size) { | 1807 int copy_size) { |
1795 UNREACHABLE(); | 1808 UNREACHABLE(); |
1796 } | 1809 } |
1797 | 1810 |
1798 static uint32_t GetCapacityImpl(Handle<FixedArrayBase> backing_store) { | 1811 static uint32_t GetCapacityImpl(FixedArrayBase* backing_store) { |
1799 Handle<FixedArray> parameter_map = Handle<FixedArray>::cast(backing_store); | 1812 FixedArray* parameter_map = FixedArray::cast(backing_store); |
1800 Handle<FixedArrayBase> arguments( | 1813 FixedArrayBase* arguments = FixedArrayBase::cast(parameter_map->get(1)); |
1801 FixedArrayBase::cast(parameter_map->get(1))); | |
1802 return Max(static_cast<uint32_t>(parameter_map->length() - 2), | 1814 return Max(static_cast<uint32_t>(parameter_map->length() - 2), |
1803 ForArray(arguments)->GetCapacity(arguments)); | 1815 ForArray(arguments)->GetCapacity(arguments)); |
1804 } | 1816 } |
1805 | 1817 |
1806 static uint32_t GetKeyForIndexImpl(Handle<FixedArrayBase> dict, | 1818 // TODO(ishell): Handlify when all callers are handlified. |
| 1819 static uint32_t GetKeyForIndexImpl(FixedArrayBase* dict, |
1807 uint32_t index) { | 1820 uint32_t index) { |
1808 return index; | 1821 return index; |
1809 } | 1822 } |
1810 | 1823 |
1811 static bool HasElementImpl(Handle<Object> receiver, | 1824 static bool HasElementImpl(Handle<Object> receiver, |
1812 Handle<JSObject> holder, | 1825 Handle<JSObject> holder, |
1813 uint32_t key, | 1826 uint32_t key, |
1814 Handle<FixedArrayBase> parameters) { | 1827 Handle<FixedArrayBase> parameters) { |
1815 Handle<FixedArray> parameter_map = Handle<FixedArray>::cast(parameters); | 1828 Handle<FixedArray> parameter_map = Handle<FixedArray>::cast(parameters); |
1816 Handle<Object> probe = GetParameterMapArg(holder, parameter_map, key); | 1829 Handle<Object> probe = GetParameterMapArg(holder, parameter_map, key); |
1817 if (!probe->IsTheHole()) { | 1830 if (!probe->IsTheHole()) { |
1818 return true; | 1831 return true; |
1819 } else { | 1832 } else { |
1820 Handle<FixedArrayBase> arguments(FixedArrayBase::cast( | 1833 Handle<FixedArrayBase> arguments(FixedArrayBase::cast( |
1821 Handle<FixedArray>::cast(parameter_map)->get(1))); | 1834 Handle<FixedArray>::cast(parameter_map)->get(1))); |
1822 ElementsAccessor* accessor = ElementsAccessor::ForArray(arguments); | 1835 ElementsAccessor* accessor = ElementsAccessor::ForArray(arguments); |
1823 return !accessor->Get(receiver, holder, key, arguments)->IsTheHole(); | 1836 return !accessor->Get(receiver, holder, key, arguments)->IsTheHole(); |
1824 } | 1837 } |
1825 } | 1838 } |
1826 | 1839 |
1827 private: | 1840 private: |
| 1841 // TODO(ishell): remove when all usages are handlified. |
| 1842 static Object* GetParameterMapArg(JSObject* holder, |
| 1843 FixedArray* parameter_map, |
| 1844 uint32_t key) { |
| 1845 uint32_t length = holder->IsJSArray() |
| 1846 ? Smi::cast(JSArray::cast(holder)->length())->value() |
| 1847 : parameter_map->length(); |
| 1848 return key < (length - 2) |
| 1849 ? parameter_map->get(key + 2) |
| 1850 : parameter_map->GetHeap()->the_hole_value(); |
| 1851 } |
| 1852 |
1828 static Handle<Object> GetParameterMapArg(Handle<JSObject> holder, | 1853 static Handle<Object> GetParameterMapArg(Handle<JSObject> holder, |
1829 Handle<FixedArray> parameter_map, | 1854 Handle<FixedArray> parameter_map, |
1830 uint32_t key) { | 1855 uint32_t key) { |
1831 Isolate* isolate = holder->GetIsolate(); | 1856 Isolate* isolate = holder->GetIsolate(); |
1832 uint32_t length = holder->IsJSArray() | 1857 uint32_t length = holder->IsJSArray() |
1833 ? Smi::cast(Handle<JSArray>::cast(holder)->length())->value() | 1858 ? Smi::cast(Handle<JSArray>::cast(holder)->length())->value() |
1834 : parameter_map->length(); | 1859 : parameter_map->length(); |
1835 return key < (length - 2) | 1860 return key < (length - 2) |
1836 ? handle(parameter_map->get(key + 2), isolate) | 1861 ? handle(parameter_map->get(key + 2), isolate) |
1837 : Handle<Object>::cast(isolate->factory()->the_hole_value()); | 1862 : Handle<Object>::cast(isolate->factory()->the_hole_value()); |
1838 } | 1863 } |
1839 }; | 1864 }; |
1840 | 1865 |
1841 | 1866 |
1842 ElementsAccessor* ElementsAccessor::ForArray(Handle<FixedArrayBase> array) { | 1867 ElementsAccessor* ElementsAccessor::ForArray(FixedArrayBase* array) { |
1843 return elements_accessors_[ElementsKindForArray(array)]; | 1868 return elements_accessors_[ElementsKindForArray(array)]; |
1844 } | 1869 } |
1845 | 1870 |
1846 | 1871 |
1847 void ElementsAccessor::InitializeOncePerProcess() { | 1872 void ElementsAccessor::InitializeOncePerProcess() { |
1848 static ElementsAccessor* accessor_array[] = { | 1873 static ElementsAccessor* accessor_array[] = { |
1849 #define ACCESSOR_ARRAY(Class, Kind, Store) new Class(#Kind), | 1874 #define ACCESSOR_ARRAY(Class, Kind, Store) new Class(#Kind), |
1850 ELEMENTS_LIST(ACCESSOR_ARRAY) | 1875 ELEMENTS_LIST(ACCESSOR_ARRAY) |
1851 #undef ACCESSOR_ARRAY | 1876 #undef ACCESSOR_ARRAY |
1852 }; | 1877 }; |
(...skipping 166 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2019 UNREACHABLE(); | 2044 UNREACHABLE(); |
2020 break; | 2045 break; |
2021 } | 2046 } |
2022 | 2047 |
2023 array->set_elements(*elms); | 2048 array->set_elements(*elms); |
2024 array->set_length(Smi::FromInt(number_of_elements)); | 2049 array->set_length(Smi::FromInt(number_of_elements)); |
2025 return array; | 2050 return array; |
2026 } | 2051 } |
2027 | 2052 |
2028 } } // namespace v8::internal | 2053 } } // namespace v8::internal |
OLD | NEW |