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