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

Side by Side Diff: src/elements.cc

Issue 1225493002: Move slow classes above fast to directly call ReconfigureImpl, remove friends, make things public (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Just make everything public within elements.cc Created 5 years, 5 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 | « no previous file | no next file » | 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 530 matching lines...) Expand 10 before | Expand all | Expand 10 after
541 // ... 541 // ...
542 // } 542 // }
543 // 543 //
544 // This is an example of the Curiously Recurring Template Pattern (see 544 // This is an example of the Curiously Recurring Template Pattern (see
545 // http://en.wikipedia.org/wiki/Curiously_recurring_template_pattern). We use 545 // http://en.wikipedia.org/wiki/Curiously_recurring_template_pattern). We use
546 // CRTP to guarantee aggressive compile time optimizations (i.e. inlining and 546 // CRTP to guarantee aggressive compile time optimizations (i.e. inlining and
547 // specialization of SomeElementsAccessor methods). 547 // specialization of SomeElementsAccessor methods).
548 template <typename ElementsAccessorSubclass, 548 template <typename ElementsAccessorSubclass,
549 typename ElementsTraitsParam> 549 typename ElementsTraitsParam>
550 class ElementsAccessorBase : public ElementsAccessor { 550 class ElementsAccessorBase : public ElementsAccessor {
551 protected: 551 public:
552 template <typename SloppyArgumentsElementsAccessorSubclass,
553 typename ArgumentsAccessor, typename KindTraits>
554 friend class SloppyArgumentsElementsAccessor;
555 explicit ElementsAccessorBase(const char* name) 552 explicit ElementsAccessorBase(const char* name)
556 : ElementsAccessor(name) { } 553 : ElementsAccessor(name) { }
557 554
558 typedef ElementsTraitsParam ElementsTraits; 555 typedef ElementsTraitsParam ElementsTraits;
559 typedef typename ElementsTraitsParam::BackingStore BackingStore; 556 typedef typename ElementsTraitsParam::BackingStore BackingStore;
560 557
561 static ElementsKind kind() { return ElementsTraits::Kind; } 558 static ElementsKind kind() { return ElementsTraits::Kind; }
562 559
563 static void ValidateContents(Handle<JSObject> holder, int length) { 560 static void ValidateContents(Handle<JSObject> holder, int length) {
564 } 561 }
(...skipping 292 matching lines...) Expand 10 before | Expand all | Expand 10 after
857 if (!value->IsTheHole() && !HasKey(to, value)) { 854 if (!value->IsTheHole() && !HasKey(to, value)) {
858 result->set(len0 + index, *value); 855 result->set(len0 + index, *value);
859 index++; 856 index++;
860 } 857 }
861 } 858 }
862 } 859 }
863 DCHECK(extra == index); 860 DCHECK(extra == index);
864 return result; 861 return result;
865 } 862 }
866 863
867 protected:
868 static uint32_t GetCapacityImpl(JSObject* holder, 864 static uint32_t GetCapacityImpl(JSObject* holder,
869 FixedArrayBase* backing_store) { 865 FixedArrayBase* backing_store) {
870 return backing_store->length(); 866 return backing_store->length();
871 } 867 }
872 868
873 uint32_t GetCapacity(JSObject* holder, FixedArrayBase* backing_store) final { 869 uint32_t GetCapacity(JSObject* holder, FixedArrayBase* backing_store) final {
874 return ElementsAccessorSubclass::GetCapacityImpl(holder, backing_store); 870 return ElementsAccessorSubclass::GetCapacityImpl(holder, backing_store);
875 } 871 }
876 872
877 static bool HasIndexImpl(FixedArrayBase* backing_store, uint32_t index) { 873 static bool HasIndexImpl(FixedArrayBase* backing_store, uint32_t index) {
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after
917 virtual PropertyDetails GetDetails(FixedArrayBase* backing_store, 913 virtual PropertyDetails GetDetails(FixedArrayBase* backing_store,
918 uint32_t index) final { 914 uint32_t index) final {
919 return ElementsAccessorSubclass::GetDetailsImpl(backing_store, index); 915 return ElementsAccessorSubclass::GetDetailsImpl(backing_store, index);
920 } 916 }
921 917
922 private: 918 private:
923 DISALLOW_COPY_AND_ASSIGN(ElementsAccessorBase); 919 DISALLOW_COPY_AND_ASSIGN(ElementsAccessorBase);
924 }; 920 };
925 921
926 922
927 class FastSloppyArgumentsElementsAccessor; 923 class DictionaryElementsAccessor
928 class FastHoleyObjectElementsAccessor; 924 : public ElementsAccessorBase<DictionaryElementsAccessor,
929 template <typename SloppyArgumentsElementsAccessorSubclass, 925 ElementsKindTraits<DICTIONARY_ELEMENTS> > {
930 typename ArgumentsAccessor, typename KindTraits> 926 public:
931 class SloppyArgumentsElementsAccessor; 927 explicit DictionaryElementsAccessor(const char* name)
928 : ElementsAccessorBase<DictionaryElementsAccessor,
929 ElementsKindTraits<DICTIONARY_ELEMENTS> >(name) {}
930
931 static void SetLengthImpl(Handle<JSArray> array, uint32_t length,
932 Handle<FixedArrayBase> backing_store) {
933 Handle<SeededNumberDictionary> dict =
934 Handle<SeededNumberDictionary>::cast(backing_store);
935 Isolate* isolate = array->GetIsolate();
936 int capacity = dict->Capacity();
937 uint32_t old_length = 0;
938 CHECK(array->length()->ToArrayLength(&old_length));
939 if (length < old_length) {
940 if (dict->requires_slow_elements()) {
941 // Find last non-deletable element in range of elements to be
942 // deleted and adjust range accordingly.
943 for (int i = 0; i < capacity; i++) {
944 DisallowHeapAllocation no_gc;
945 Object* key = dict->KeyAt(i);
946 if (key->IsNumber()) {
947 uint32_t number = static_cast<uint32_t>(key->Number());
948 if (length <= number && number < old_length) {
949 PropertyDetails details = dict->DetailsAt(i);
950 if (!details.IsConfigurable()) length = number + 1;
951 }
952 }
953 }
954 }
955
956 if (length == 0) {
957 // Flush the backing store.
958 JSObject::ResetElements(array);
959 } else {
960 DisallowHeapAllocation no_gc;
961 // Remove elements that should be deleted.
962 int removed_entries = 0;
963 Handle<Object> the_hole_value = isolate->factory()->the_hole_value();
964 for (int i = 0; i < capacity; i++) {
965 Object* key = dict->KeyAt(i);
966 if (key->IsNumber()) {
967 uint32_t number = static_cast<uint32_t>(key->Number());
968 if (length <= number && number < old_length) {
969 dict->SetEntry(i, the_hole_value, the_hole_value);
970 removed_entries++;
971 }
972 }
973 }
974
975 // Update the number of elements.
976 dict->ElementsRemoved(removed_entries);
977 }
978 }
979
980 Handle<Object> length_obj = isolate->factory()->NewNumberFromUint(length);
981 array->set_length(*length_obj);
982 }
983
984 static void CopyElementsImpl(FixedArrayBase* from, uint32_t from_start,
985 FixedArrayBase* to, ElementsKind from_kind,
986 uint32_t to_start, int packed_size,
987 int copy_size) {
988 UNREACHABLE();
989 }
990
991
992 static void DeleteCommon(Handle<JSObject> obj, uint32_t key,
993 LanguageMode language_mode) {
994 Isolate* isolate = obj->GetIsolate();
995 Handle<FixedArray> backing_store(FixedArray::cast(obj->elements()),
996 isolate);
997 bool is_arguments = obj->HasSloppyArgumentsElements();
998 if (is_arguments) {
999 backing_store = handle(FixedArray::cast(backing_store->get(1)), isolate);
1000 }
1001 Handle<SeededNumberDictionary> dictionary =
1002 Handle<SeededNumberDictionary>::cast(backing_store);
1003 int entry = dictionary->FindEntry(key);
1004 if (entry != SeededNumberDictionary::kNotFound) {
1005 Handle<Object> result =
1006 SeededNumberDictionary::DeleteProperty(dictionary, entry);
1007 USE(result);
1008 DCHECK(result->IsTrue());
1009 Handle<FixedArray> new_elements =
1010 SeededNumberDictionary::Shrink(dictionary, key);
1011
1012 if (is_arguments) {
1013 FixedArray::cast(obj->elements())->set(1, *new_elements);
1014 } else {
1015 obj->set_elements(*new_elements);
1016 }
1017 }
1018 }
1019
1020 virtual void Delete(Handle<JSObject> obj, uint32_t key,
1021 LanguageMode language_mode) final {
1022 DeleteCommon(obj, key, language_mode);
1023 }
1024
1025 static Handle<Object> GetImpl(Handle<JSObject> obj, uint32_t key,
1026 Handle<FixedArrayBase> store) {
1027 Handle<SeededNumberDictionary> backing_store =
1028 Handle<SeededNumberDictionary>::cast(store);
1029 Isolate* isolate = backing_store->GetIsolate();
1030 int entry = backing_store->FindEntry(key);
1031 if (entry != SeededNumberDictionary::kNotFound) {
1032 return handle(backing_store->ValueAt(entry), isolate);
1033 }
1034 return isolate->factory()->the_hole_value();
1035 }
1036
1037 static void SetImpl(FixedArrayBase* store, uint32_t key, Object* value) {
1038 SeededNumberDictionary* dictionary = SeededNumberDictionary::cast(store);
1039 int entry = dictionary->FindEntry(key);
1040 DCHECK_NE(SeededNumberDictionary::kNotFound, entry);
1041 dictionary->ValueAtPut(entry, value);
1042 }
1043
1044 static void ReconfigureImpl(Handle<JSObject> object,
1045 Handle<FixedArrayBase> store, uint32_t index,
1046 Handle<Object> value,
1047 PropertyAttributes attributes) {
1048 SeededNumberDictionary* dictionary = SeededNumberDictionary::cast(*store);
1049 if (attributes != NONE) dictionary->set_requires_slow_elements();
1050 dictionary->ValueAtPut(index, *value);
1051 PropertyDetails details = dictionary->DetailsAt(index);
1052 details = PropertyDetails(attributes, DATA, details.dictionary_index(),
1053 PropertyCellType::kNoCell);
1054 dictionary->DetailsAtPut(index, details);
1055 }
1056
1057 static void AddImpl(Handle<JSObject> object, uint32_t index,
1058 Handle<Object> value, PropertyAttributes attributes,
1059 uint32_t new_capacity) {
1060 PropertyDetails details(attributes, DATA, 0, PropertyCellType::kNoCell);
1061 Handle<SeededNumberDictionary> dictionary =
1062 object->HasFastElements()
1063 ? JSObject::NormalizeElements(object)
1064 : handle(SeededNumberDictionary::cast(object->elements()));
1065 Handle<SeededNumberDictionary> new_dictionary =
1066 SeededNumberDictionary::AddNumberEntry(dictionary, index, value,
1067 details);
1068 if (attributes != NONE) new_dictionary->set_requires_slow_elements();
1069 if (dictionary.is_identical_to(new_dictionary)) return;
1070 object->set_elements(*new_dictionary);
1071 }
1072
1073 static MaybeHandle<AccessorPair> GetAccessorPairImpl(
1074 Handle<JSObject> obj, uint32_t key, Handle<FixedArrayBase> store) {
1075 Handle<SeededNumberDictionary> backing_store =
1076 Handle<SeededNumberDictionary>::cast(store);
1077 int entry = backing_store->FindEntry(key);
1078 if (entry != SeededNumberDictionary::kNotFound &&
1079 backing_store->DetailsAt(entry).type() == ACCESSOR_CONSTANT &&
1080 backing_store->ValueAt(entry)->IsAccessorPair()) {
1081 return handle(AccessorPair::cast(backing_store->ValueAt(entry)));
1082 }
1083 return MaybeHandle<AccessorPair>();
1084 }
1085
1086 static bool HasIndexImpl(FixedArrayBase* store, uint32_t index) {
1087 DisallowHeapAllocation no_gc;
1088 SeededNumberDictionary* dict = SeededNumberDictionary::cast(store);
1089 Object* key = dict->KeyAt(index);
1090 return !key->IsTheHole();
1091 }
1092
1093 static uint32_t GetKeyForIndexImpl(FixedArrayBase* store, uint32_t index) {
1094 DisallowHeapAllocation no_gc;
1095 SeededNumberDictionary* dict = SeededNumberDictionary::cast(store);
1096 uint32_t result = 0;
1097 CHECK(dict->KeyAt(index)->ToArrayIndex(&result));
1098 return result;
1099 }
1100
1101 static uint32_t GetIndexForKeyImpl(JSObject* holder, FixedArrayBase* store,
1102 uint32_t key) {
1103 DisallowHeapAllocation no_gc;
1104 SeededNumberDictionary* dict = SeededNumberDictionary::cast(store);
1105 int entry = dict->FindEntry(key);
1106 return entry == SeededNumberDictionary::kNotFound
1107 ? kMaxUInt32
1108 : static_cast<uint32_t>(entry);
1109 }
1110
1111 static PropertyDetails GetDetailsImpl(FixedArrayBase* backing_store,
1112 uint32_t index) {
1113 return SeededNumberDictionary::cast(backing_store)->DetailsAt(index);
1114 }
1115 };
1116
932 1117
933 // Super class for all fast element arrays. 1118 // Super class for all fast element arrays.
934 template<typename FastElementsAccessorSubclass, 1119 template<typename FastElementsAccessorSubclass,
935 typename KindTraits> 1120 typename KindTraits>
936 class FastElementsAccessor 1121 class FastElementsAccessor
937 : public ElementsAccessorBase<FastElementsAccessorSubclass, KindTraits> { 1122 : public ElementsAccessorBase<FastElementsAccessorSubclass, KindTraits> {
938 public: 1123 public:
939 explicit FastElementsAccessor(const char* name) 1124 explicit FastElementsAccessor(const char* name)
940 : ElementsAccessorBase<FastElementsAccessorSubclass, 1125 : ElementsAccessorBase<FastElementsAccessorSubclass,
941 KindTraits>(name) {} 1126 KindTraits>(name) {}
942 1127
943 protected:
944 friend class ElementsAccessorBase<FastElementsAccessorSubclass, KindTraits>;
945 friend class SloppyArgumentsElementsAccessor<
946 FastSloppyArgumentsElementsAccessor, FastHoleyObjectElementsAccessor,
947 ElementsKindTraits<FAST_SLOPPY_ARGUMENTS_ELEMENTS> >;
948
949 typedef typename KindTraits::BackingStore BackingStore; 1128 typedef typename KindTraits::BackingStore BackingStore;
950 1129
951 static void DeleteCommon(Handle<JSObject> obj, uint32_t key, 1130 static void DeleteCommon(Handle<JSObject> obj, uint32_t key,
952 LanguageMode language_mode) { 1131 LanguageMode language_mode) {
953 DCHECK(obj->HasFastSmiOrObjectElements() || 1132 DCHECK(obj->HasFastSmiOrObjectElements() ||
954 obj->HasFastDoubleElements() || 1133 obj->HasFastDoubleElements() ||
955 obj->HasFastArgumentsElements()); 1134 obj->HasFastArgumentsElements());
956 Isolate* isolate = obj->GetIsolate(); 1135 Isolate* isolate = obj->GetIsolate();
957 Heap* heap = obj->GetHeap(); 1136 Heap* heap = obj->GetHeap();
958 Handle<FixedArrayBase> elements(obj->elements()); 1137 Handle<FixedArrayBase> elements(obj->elements());
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after
1004 } 1183 }
1005 } 1184 }
1006 1185
1007 static void ReconfigureImpl(Handle<JSObject> object, 1186 static void ReconfigureImpl(Handle<JSObject> object,
1008 Handle<FixedArrayBase> store, uint32_t index, 1187 Handle<FixedArrayBase> store, uint32_t index,
1009 Handle<Object> value, 1188 Handle<Object> value,
1010 PropertyAttributes attributes) { 1189 PropertyAttributes attributes) {
1011 Handle<SeededNumberDictionary> dictionary = 1190 Handle<SeededNumberDictionary> dictionary =
1012 JSObject::NormalizeElements(object); 1191 JSObject::NormalizeElements(object);
1013 index = dictionary->FindEntry(index); 1192 index = dictionary->FindEntry(index);
1014 object->GetElementsAccessor()->Reconfigure(object, dictionary, index, value, 1193 DictionaryElementsAccessor::ReconfigureImpl(object, dictionary, index,
1015 attributes); 1194 value, attributes);
1016 } 1195 }
1017 1196
1018 static void AddImpl(Handle<JSObject> object, uint32_t index, 1197 static void AddImpl(Handle<JSObject> object, uint32_t index,
1019 Handle<Object> value, PropertyAttributes attributes, 1198 Handle<Object> value, PropertyAttributes attributes,
1020 uint32_t new_capacity) { 1199 uint32_t new_capacity) {
1021 DCHECK_EQ(NONE, attributes); 1200 DCHECK_EQ(NONE, attributes);
1022 ElementsKind from_kind = object->GetElementsKind(); 1201 ElementsKind from_kind = object->GetElementsKind();
1023 ElementsKind to_kind = FastElementsAccessorSubclass::kind(); 1202 ElementsKind to_kind = FastElementsAccessorSubclass::kind();
1024 if (IsDictionaryElementsKind(from_kind) || 1203 if (IsDictionaryElementsKind(from_kind) ||
1025 IsFastDoubleElementsKind(from_kind) != 1204 IsFastDoubleElementsKind(from_kind) !=
(...skipping 153 matching lines...) Expand 10 before | Expand all | Expand 10 after
1179 1358
1180 template<typename FastElementsAccessorSubclass, 1359 template<typename FastElementsAccessorSubclass,
1181 typename KindTraits> 1360 typename KindTraits>
1182 class FastDoubleElementsAccessor 1361 class FastDoubleElementsAccessor
1183 : public FastElementsAccessor<FastElementsAccessorSubclass, KindTraits> { 1362 : public FastElementsAccessor<FastElementsAccessorSubclass, KindTraits> {
1184 public: 1363 public:
1185 explicit FastDoubleElementsAccessor(const char* name) 1364 explicit FastDoubleElementsAccessor(const char* name)
1186 : FastElementsAccessor<FastElementsAccessorSubclass, 1365 : FastElementsAccessor<FastElementsAccessorSubclass,
1187 KindTraits>(name) {} 1366 KindTraits>(name) {}
1188 1367
1189 protected:
1190 static void CopyElementsImpl(FixedArrayBase* from, uint32_t from_start, 1368 static void CopyElementsImpl(FixedArrayBase* from, uint32_t from_start,
1191 FixedArrayBase* to, ElementsKind from_kind, 1369 FixedArrayBase* to, ElementsKind from_kind,
1192 uint32_t to_start, int packed_size, 1370 uint32_t to_start, int packed_size,
1193 int copy_size) { 1371 int copy_size) {
1194 DisallowHeapAllocation no_allocation; 1372 DisallowHeapAllocation no_allocation;
1195 switch (from_kind) { 1373 switch (from_kind) {
1196 case FAST_SMI_ELEMENTS: 1374 case FAST_SMI_ELEMENTS:
1197 CopyPackedSmiToDoubleElements(from, from_start, to, to_start, 1375 CopyPackedSmiToDoubleElements(from, from_start, to, to_start,
1198 packed_size, copy_size); 1376 packed_size, copy_size);
1199 break; 1377 break;
(...skipping 25 matching lines...) Expand all
1225 } 1403 }
1226 } 1404 }
1227 }; 1405 };
1228 1406
1229 1407
1230 class FastPackedDoubleElementsAccessor 1408 class FastPackedDoubleElementsAccessor
1231 : public FastDoubleElementsAccessor< 1409 : public FastDoubleElementsAccessor<
1232 FastPackedDoubleElementsAccessor, 1410 FastPackedDoubleElementsAccessor,
1233 ElementsKindTraits<FAST_DOUBLE_ELEMENTS> > { 1411 ElementsKindTraits<FAST_DOUBLE_ELEMENTS> > {
1234 public: 1412 public:
1235 friend class ElementsAccessorBase<FastPackedDoubleElementsAccessor,
1236 ElementsKindTraits<FAST_DOUBLE_ELEMENTS> >;
1237 explicit FastPackedDoubleElementsAccessor(const char* name) 1413 explicit FastPackedDoubleElementsAccessor(const char* name)
1238 : FastDoubleElementsAccessor< 1414 : FastDoubleElementsAccessor<
1239 FastPackedDoubleElementsAccessor, 1415 FastPackedDoubleElementsAccessor,
1240 ElementsKindTraits<FAST_DOUBLE_ELEMENTS> >(name) {} 1416 ElementsKindTraits<FAST_DOUBLE_ELEMENTS> >(name) {}
1241 }; 1417 };
1242 1418
1243 1419
1244 class FastHoleyDoubleElementsAccessor 1420 class FastHoleyDoubleElementsAccessor
1245 : public FastDoubleElementsAccessor< 1421 : public FastDoubleElementsAccessor<
1246 FastHoleyDoubleElementsAccessor, 1422 FastHoleyDoubleElementsAccessor,
1247 ElementsKindTraits<FAST_HOLEY_DOUBLE_ELEMENTS> > { 1423 ElementsKindTraits<FAST_HOLEY_DOUBLE_ELEMENTS> > {
1248 public: 1424 public:
1249 friend class ElementsAccessorBase<
1250 FastHoleyDoubleElementsAccessor,
1251 ElementsKindTraits<FAST_HOLEY_DOUBLE_ELEMENTS> >;
1252 explicit FastHoleyDoubleElementsAccessor(const char* name) 1425 explicit FastHoleyDoubleElementsAccessor(const char* name)
1253 : FastDoubleElementsAccessor< 1426 : FastDoubleElementsAccessor<
1254 FastHoleyDoubleElementsAccessor, 1427 FastHoleyDoubleElementsAccessor,
1255 ElementsKindTraits<FAST_HOLEY_DOUBLE_ELEMENTS> >(name) {} 1428 ElementsKindTraits<FAST_HOLEY_DOUBLE_ELEMENTS> >(name) {}
1256 }; 1429 };
1257 1430
1258 1431
1259 // Super class for all external element arrays. 1432 // Super class for all external element arrays.
1260 template<ElementsKind Kind> 1433 template<ElementsKind Kind>
1261 class TypedElementsAccessor 1434 class TypedElementsAccessor
1262 : public ElementsAccessorBase<TypedElementsAccessor<Kind>, 1435 : public ElementsAccessorBase<TypedElementsAccessor<Kind>,
1263 ElementsKindTraits<Kind> > { 1436 ElementsKindTraits<Kind> > {
1264 public: 1437 public:
1265 explicit TypedElementsAccessor(const char* name) 1438 explicit TypedElementsAccessor(const char* name)
1266 : ElementsAccessorBase<AccessorClass, 1439 : ElementsAccessorBase<AccessorClass,
1267 ElementsKindTraits<Kind> >(name) {} 1440 ElementsKindTraits<Kind> >(name) {}
1268 1441
1269 protected:
1270 typedef typename ElementsKindTraits<Kind>::BackingStore BackingStore; 1442 typedef typename ElementsKindTraits<Kind>::BackingStore BackingStore;
1271 typedef TypedElementsAccessor<Kind> AccessorClass; 1443 typedef TypedElementsAccessor<Kind> AccessorClass;
1272 1444
1273 friend class ElementsAccessorBase<AccessorClass,
1274 ElementsKindTraits<Kind> >;
1275
1276 static Handle<Object> GetImpl(Handle<JSObject> obj, uint32_t key, 1445 static Handle<Object> GetImpl(Handle<JSObject> obj, uint32_t key,
1277 Handle<FixedArrayBase> backing_store) { 1446 Handle<FixedArrayBase> backing_store) {
1278 if (key < AccessorClass::GetCapacityImpl(*obj, *backing_store)) { 1447 if (key < AccessorClass::GetCapacityImpl(*obj, *backing_store)) {
1279 return BackingStore::get(Handle<BackingStore>::cast(backing_store), key); 1448 return BackingStore::get(Handle<BackingStore>::cast(backing_store), key);
1280 } else { 1449 } else {
1281 return backing_store->GetIsolate()->factory()->undefined_value(); 1450 return backing_store->GetIsolate()->factory()->undefined_value();
1282 } 1451 }
1283 } 1452 }
1284 1453
1285 static PropertyDetails GetDetailsImpl(FixedArrayBase* backing_store, 1454 static PropertyDetails GetDetailsImpl(FixedArrayBase* backing_store,
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after
1324 #undef EXTERNAL_ELEMENTS_ACCESSOR 1493 #undef EXTERNAL_ELEMENTS_ACCESSOR
1325 1494
1326 #define FIXED_ELEMENTS_ACCESSOR(Type, type, TYPE, ctype, size) \ 1495 #define FIXED_ELEMENTS_ACCESSOR(Type, type, TYPE, ctype, size) \
1327 typedef TypedElementsAccessor<TYPE##_ELEMENTS > \ 1496 typedef TypedElementsAccessor<TYPE##_ELEMENTS > \
1328 Fixed##Type##ElementsAccessor; 1497 Fixed##Type##ElementsAccessor;
1329 1498
1330 TYPED_ARRAYS(FIXED_ELEMENTS_ACCESSOR) 1499 TYPED_ARRAYS(FIXED_ELEMENTS_ACCESSOR)
1331 #undef FIXED_ELEMENTS_ACCESSOR 1500 #undef FIXED_ELEMENTS_ACCESSOR
1332 1501
1333 1502
1334 class SlowSloppyArgumentsElementsAccessor;
1335
1336
1337 class DictionaryElementsAccessor
1338 : public ElementsAccessorBase<DictionaryElementsAccessor,
1339 ElementsKindTraits<DICTIONARY_ELEMENTS> > {
1340 public:
1341 explicit DictionaryElementsAccessor(const char* name)
1342 : ElementsAccessorBase<DictionaryElementsAccessor,
1343 ElementsKindTraits<DICTIONARY_ELEMENTS> >(name) {}
1344
1345 static void SetLengthImpl(Handle<JSArray> array, uint32_t length,
1346 Handle<FixedArrayBase> backing_store) {
1347 Handle<SeededNumberDictionary> dict =
1348 Handle<SeededNumberDictionary>::cast(backing_store);
1349 Isolate* isolate = array->GetIsolate();
1350 int capacity = dict->Capacity();
1351 uint32_t old_length = 0;
1352 CHECK(array->length()->ToArrayLength(&old_length));
1353 if (length < old_length) {
1354 if (dict->requires_slow_elements()) {
1355 // Find last non-deletable element in range of elements to be
1356 // deleted and adjust range accordingly.
1357 for (int i = 0; i < capacity; i++) {
1358 DisallowHeapAllocation no_gc;
1359 Object* key = dict->KeyAt(i);
1360 if (key->IsNumber()) {
1361 uint32_t number = static_cast<uint32_t>(key->Number());
1362 if (length <= number && number < old_length) {
1363 PropertyDetails details = dict->DetailsAt(i);
1364 if (!details.IsConfigurable()) length = number + 1;
1365 }
1366 }
1367 }
1368 }
1369
1370 if (length == 0) {
1371 // Flush the backing store.
1372 JSObject::ResetElements(array);
1373 } else {
1374 DisallowHeapAllocation no_gc;
1375 // Remove elements that should be deleted.
1376 int removed_entries = 0;
1377 Handle<Object> the_hole_value = isolate->factory()->the_hole_value();
1378 for (int i = 0; i < capacity; i++) {
1379 Object* key = dict->KeyAt(i);
1380 if (key->IsNumber()) {
1381 uint32_t number = static_cast<uint32_t>(key->Number());
1382 if (length <= number && number < old_length) {
1383 dict->SetEntry(i, the_hole_value, the_hole_value);
1384 removed_entries++;
1385 }
1386 }
1387 }
1388
1389 // Update the number of elements.
1390 dict->ElementsRemoved(removed_entries);
1391 }
1392 }
1393
1394 Handle<Object> length_obj = isolate->factory()->NewNumberFromUint(length);
1395 array->set_length(*length_obj);
1396 }
1397
1398 static void CopyElementsImpl(FixedArrayBase* from, uint32_t from_start,
1399 FixedArrayBase* to, ElementsKind from_kind,
1400 uint32_t to_start, int packed_size,
1401 int copy_size) {
1402 UNREACHABLE();
1403 }
1404
1405
1406 protected:
1407 friend class ElementsAccessorBase<DictionaryElementsAccessor,
1408 ElementsKindTraits<DICTIONARY_ELEMENTS> >;
1409 friend class SlowSloppyArgumentsElementsAccessor;
1410 friend class SloppyArgumentsElementsAccessor<
1411 SlowSloppyArgumentsElementsAccessor, DictionaryElementsAccessor,
1412 ElementsKindTraits<SLOW_SLOPPY_ARGUMENTS_ELEMENTS> >;
1413
1414 static void DeleteCommon(Handle<JSObject> obj, uint32_t key,
1415 LanguageMode language_mode) {
1416 Isolate* isolate = obj->GetIsolate();
1417 Handle<FixedArray> backing_store(FixedArray::cast(obj->elements()),
1418 isolate);
1419 bool is_arguments = obj->HasSloppyArgumentsElements();
1420 if (is_arguments) {
1421 backing_store = handle(FixedArray::cast(backing_store->get(1)), isolate);
1422 }
1423 Handle<SeededNumberDictionary> dictionary =
1424 Handle<SeededNumberDictionary>::cast(backing_store);
1425 int entry = dictionary->FindEntry(key);
1426 if (entry != SeededNumberDictionary::kNotFound) {
1427 Handle<Object> result =
1428 SeededNumberDictionary::DeleteProperty(dictionary, entry);
1429 USE(result);
1430 DCHECK(result->IsTrue());
1431 Handle<FixedArray> new_elements =
1432 SeededNumberDictionary::Shrink(dictionary, key);
1433
1434 if (is_arguments) {
1435 FixedArray::cast(obj->elements())->set(1, *new_elements);
1436 } else {
1437 obj->set_elements(*new_elements);
1438 }
1439 }
1440 }
1441
1442 virtual void Delete(Handle<JSObject> obj, uint32_t key,
1443 LanguageMode language_mode) final {
1444 DeleteCommon(obj, key, language_mode);
1445 }
1446
1447 static Handle<Object> GetImpl(Handle<JSObject> obj, uint32_t key,
1448 Handle<FixedArrayBase> store) {
1449 Handle<SeededNumberDictionary> backing_store =
1450 Handle<SeededNumberDictionary>::cast(store);
1451 Isolate* isolate = backing_store->GetIsolate();
1452 int entry = backing_store->FindEntry(key);
1453 if (entry != SeededNumberDictionary::kNotFound) {
1454 return handle(backing_store->ValueAt(entry), isolate);
1455 }
1456 return isolate->factory()->the_hole_value();
1457 }
1458
1459 static void SetImpl(FixedArrayBase* store, uint32_t key, Object* value) {
1460 SeededNumberDictionary* dictionary = SeededNumberDictionary::cast(store);
1461 int entry = dictionary->FindEntry(key);
1462 DCHECK_NE(SeededNumberDictionary::kNotFound, entry);
1463 dictionary->ValueAtPut(entry, value);
1464 }
1465
1466 static void ReconfigureImpl(Handle<JSObject> object,
1467 Handle<FixedArrayBase> store, uint32_t index,
1468 Handle<Object> value,
1469 PropertyAttributes attributes) {
1470 SeededNumberDictionary* dictionary = SeededNumberDictionary::cast(*store);
1471 if (attributes != NONE) dictionary->set_requires_slow_elements();
1472 dictionary->ValueAtPut(index, *value);
1473 PropertyDetails details = dictionary->DetailsAt(index);
1474 details = PropertyDetails(attributes, DATA, details.dictionary_index(),
1475 PropertyCellType::kNoCell);
1476 dictionary->DetailsAtPut(index, details);
1477 }
1478
1479 static void AddImpl(Handle<JSObject> object, uint32_t index,
1480 Handle<Object> value, PropertyAttributes attributes,
1481 uint32_t new_capacity) {
1482 PropertyDetails details(attributes, DATA, 0, PropertyCellType::kNoCell);
1483 Handle<SeededNumberDictionary> dictionary =
1484 object->HasFastElements()
1485 ? JSObject::NormalizeElements(object)
1486 : handle(SeededNumberDictionary::cast(object->elements()));
1487 Handle<SeededNumberDictionary> new_dictionary =
1488 SeededNumberDictionary::AddNumberEntry(dictionary, index, value,
1489 details);
1490 if (attributes != NONE) new_dictionary->set_requires_slow_elements();
1491 if (dictionary.is_identical_to(new_dictionary)) return;
1492 object->set_elements(*new_dictionary);
1493 }
1494
1495 static MaybeHandle<AccessorPair> GetAccessorPairImpl(
1496 Handle<JSObject> obj, uint32_t key, Handle<FixedArrayBase> store) {
1497 Handle<SeededNumberDictionary> backing_store =
1498 Handle<SeededNumberDictionary>::cast(store);
1499 int entry = backing_store->FindEntry(key);
1500 if (entry != SeededNumberDictionary::kNotFound &&
1501 backing_store->DetailsAt(entry).type() == ACCESSOR_CONSTANT &&
1502 backing_store->ValueAt(entry)->IsAccessorPair()) {
1503 return handle(AccessorPair::cast(backing_store->ValueAt(entry)));
1504 }
1505 return MaybeHandle<AccessorPair>();
1506 }
1507
1508 static bool HasIndexImpl(FixedArrayBase* store, uint32_t index) {
1509 DisallowHeapAllocation no_gc;
1510 SeededNumberDictionary* dict = SeededNumberDictionary::cast(store);
1511 Object* key = dict->KeyAt(index);
1512 return !key->IsTheHole();
1513 }
1514
1515 static uint32_t GetKeyForIndexImpl(FixedArrayBase* store, uint32_t index) {
1516 DisallowHeapAllocation no_gc;
1517 SeededNumberDictionary* dict = SeededNumberDictionary::cast(store);
1518 uint32_t result = 0;
1519 CHECK(dict->KeyAt(index)->ToArrayIndex(&result));
1520 return result;
1521 }
1522
1523 static uint32_t GetIndexForKeyImpl(JSObject* holder, FixedArrayBase* store,
1524 uint32_t key) {
1525 DisallowHeapAllocation no_gc;
1526 SeededNumberDictionary* dict = SeededNumberDictionary::cast(store);
1527 int entry = dict->FindEntry(key);
1528 return entry == SeededNumberDictionary::kNotFound
1529 ? kMaxUInt32
1530 : static_cast<uint32_t>(entry);
1531 }
1532
1533 static PropertyDetails GetDetailsImpl(FixedArrayBase* backing_store,
1534 uint32_t index) {
1535 return SeededNumberDictionary::cast(backing_store)->DetailsAt(index);
1536 }
1537 };
1538
1539
1540 template <typename SloppyArgumentsElementsAccessorSubclass, 1503 template <typename SloppyArgumentsElementsAccessorSubclass,
1541 typename ArgumentsAccessor, typename KindTraits> 1504 typename ArgumentsAccessor, typename KindTraits>
1542 class SloppyArgumentsElementsAccessor 1505 class SloppyArgumentsElementsAccessor
1543 : public ElementsAccessorBase<SloppyArgumentsElementsAccessorSubclass, 1506 : public ElementsAccessorBase<SloppyArgumentsElementsAccessorSubclass,
1544 KindTraits> { 1507 KindTraits> {
1545 public: 1508 public:
1546 explicit SloppyArgumentsElementsAccessor(const char* name) 1509 explicit SloppyArgumentsElementsAccessor(const char* name)
1547 : ElementsAccessorBase<SloppyArgumentsElementsAccessorSubclass, 1510 : ElementsAccessorBase<SloppyArgumentsElementsAccessorSubclass,
1548 KindTraits>(name) {} 1511 KindTraits>(name) {}
1549 1512
1550 protected:
1551 friend class ElementsAccessorBase<SloppyArgumentsElementsAccessorSubclass,
1552 KindTraits>;
1553
1554 static Handle<Object> GetImpl(Handle<JSObject> obj, uint32_t key, 1513 static Handle<Object> GetImpl(Handle<JSObject> obj, uint32_t key,
1555 Handle<FixedArrayBase> parameters) { 1514 Handle<FixedArrayBase> parameters) {
1556 Isolate* isolate = obj->GetIsolate(); 1515 Isolate* isolate = obj->GetIsolate();
1557 Handle<FixedArray> parameter_map = Handle<FixedArray>::cast(parameters); 1516 Handle<FixedArray> parameter_map = Handle<FixedArray>::cast(parameters);
1558 Handle<Object> probe(GetParameterMapArg(*parameter_map, key), isolate); 1517 Handle<Object> probe(GetParameterMapArg(*parameter_map, key), isolate);
1559 if (!probe->IsTheHole()) { 1518 if (!probe->IsTheHole()) {
1560 DisallowHeapAllocation no_gc; 1519 DisallowHeapAllocation no_gc;
1561 Context* context = Context::cast(parameter_map->get(0)); 1520 Context* context = Context::cast(parameter_map->get(0));
1562 int context_index = Handle<Smi>::cast(probe)->value(); 1521 int context_index = Handle<Smi>::cast(probe)->value();
1563 DCHECK(!context->get(context_index)->IsTheHole()); 1522 DCHECK(!context->get(context_index)->IsTheHole());
(...skipping 125 matching lines...) Expand 10 before | Expand all | Expand 10 after
1689 1648
1690 static Object* GetParameterMapArg(FixedArray* parameter_map, uint32_t key) { 1649 static Object* GetParameterMapArg(FixedArray* parameter_map, uint32_t key) {
1691 uint32_t length = parameter_map->length() - 2; 1650 uint32_t length = parameter_map->length() - 2;
1692 return key < length 1651 return key < length
1693 ? parameter_map->get(key + 2) 1652 ? parameter_map->get(key + 2)
1694 : Object::cast(parameter_map->GetHeap()->the_hole_value()); 1653 : Object::cast(parameter_map->GetHeap()->the_hole_value());
1695 } 1654 }
1696 }; 1655 };
1697 1656
1698 1657
1658 class SlowSloppyArgumentsElementsAccessor
1659 : public SloppyArgumentsElementsAccessor<
1660 SlowSloppyArgumentsElementsAccessor, DictionaryElementsAccessor,
1661 ElementsKindTraits<SLOW_SLOPPY_ARGUMENTS_ELEMENTS> > {
1662 public:
1663 explicit SlowSloppyArgumentsElementsAccessor(const char* name)
1664 : SloppyArgumentsElementsAccessor<
1665 SlowSloppyArgumentsElementsAccessor, DictionaryElementsAccessor,
1666 ElementsKindTraits<SLOW_SLOPPY_ARGUMENTS_ELEMENTS> >(name) {}
1667
1668 static void AddImpl(Handle<JSObject> object, uint32_t key,
1669 Handle<Object> value, PropertyAttributes attributes,
1670 uint32_t new_capacity) {
1671 Handle<FixedArray> parameter_map(FixedArray::cast(object->elements()));
1672 Handle<FixedArrayBase> old_elements(
1673 FixedArrayBase::cast(parameter_map->get(1)));
1674 Handle<SeededNumberDictionary> dictionary =
1675 old_elements->IsSeededNumberDictionary()
1676 ? Handle<SeededNumberDictionary>::cast(old_elements)
1677 : JSObject::NormalizeElements(object);
1678 PropertyDetails details(attributes, DATA, 0, PropertyCellType::kNoCell);
1679 Handle<SeededNumberDictionary> new_dictionary =
1680 SeededNumberDictionary::AddNumberEntry(dictionary, key, value, details);
1681 if (attributes != NONE) new_dictionary->set_requires_slow_elements();
1682 if (*dictionary != *new_dictionary) {
1683 FixedArray::cast(object->elements())->set(1, *new_dictionary);
1684 }
1685 }
1686
1687 static void ReconfigureImpl(Handle<JSObject> object,
1688 Handle<FixedArrayBase> store, uint32_t index,
1689 Handle<Object> value,
1690 PropertyAttributes attributes) {
1691 Handle<FixedArray> parameter_map = Handle<FixedArray>::cast(store);
1692 uint32_t length = parameter_map->length() - 2;
1693 if (index < length) {
1694 Object* probe = parameter_map->get(index + 2);
1695 DCHECK(!probe->IsTheHole());
1696 Context* context = Context::cast(parameter_map->get(0));
1697 int context_index = Smi::cast(probe)->value();
1698 DCHECK(!context->get(context_index)->IsTheHole());
1699 context->set(context_index, *value);
1700
1701 // Redefining attributes of an aliased element destroys fast aliasing.
1702 parameter_map->set_the_hole(index + 2);
1703 // For elements that are still writable we re-establish slow aliasing.
1704 if ((attributes & READ_ONLY) == 0) {
1705 Isolate* isolate = store->GetIsolate();
1706 value = isolate->factory()->NewAliasedArgumentsEntry(context_index);
1707 }
1708
1709 PropertyDetails details(attributes, DATA, 0, PropertyCellType::kNoCell);
1710 Handle<SeededNumberDictionary> arguments(
1711 SeededNumberDictionary::cast(parameter_map->get(1)));
1712 arguments = SeededNumberDictionary::AddNumberEntry(arguments, index,
1713 value, details);
1714 parameter_map->set(1, *arguments);
1715 } else {
1716 Handle<FixedArrayBase> arguments(
1717 FixedArrayBase::cast(parameter_map->get(1)));
1718 DictionaryElementsAccessor::ReconfigureImpl(
1719 object, arguments, index - length, value, attributes);
1720 }
1721 }
1722 };
1723
1724
1699 class FastSloppyArgumentsElementsAccessor 1725 class FastSloppyArgumentsElementsAccessor
1700 : public SloppyArgumentsElementsAccessor< 1726 : public SloppyArgumentsElementsAccessor<
1701 FastSloppyArgumentsElementsAccessor, FastHoleyObjectElementsAccessor, 1727 FastSloppyArgumentsElementsAccessor, FastHoleyObjectElementsAccessor,
1702 ElementsKindTraits<FAST_SLOPPY_ARGUMENTS_ELEMENTS> > { 1728 ElementsKindTraits<FAST_SLOPPY_ARGUMENTS_ELEMENTS> > {
1703 public: 1729 public:
1704 friend class SloppyArgumentsElementsAccessor<
1705 FastSloppyArgumentsElementsAccessor, FastHoleyObjectElementsAccessor,
1706 ElementsKindTraits<FAST_SLOPPY_ARGUMENTS_ELEMENTS> >;
1707 friend class ElementsAccessorBase<
1708 FastSloppyArgumentsElementsAccessor,
1709 ElementsKindTraits<FAST_SLOPPY_ARGUMENTS_ELEMENTS> >;
1710 explicit FastSloppyArgumentsElementsAccessor(const char* name) 1730 explicit FastSloppyArgumentsElementsAccessor(const char* name)
1711 : SloppyArgumentsElementsAccessor< 1731 : SloppyArgumentsElementsAccessor<
1712 FastSloppyArgumentsElementsAccessor, 1732 FastSloppyArgumentsElementsAccessor,
1713 FastHoleyObjectElementsAccessor, 1733 FastHoleyObjectElementsAccessor,
1714 ElementsKindTraits<FAST_SLOPPY_ARGUMENTS_ELEMENTS> >(name) {} 1734 ElementsKindTraits<FAST_SLOPPY_ARGUMENTS_ELEMENTS> >(name) {}
1715 1735
1716 protected:
1717 static void AddImpl(Handle<JSObject> object, uint32_t key, 1736 static void AddImpl(Handle<JSObject> object, uint32_t key,
1718 Handle<Object> value, PropertyAttributes attributes, 1737 Handle<Object> value, PropertyAttributes attributes,
1719 uint32_t new_capacity) { 1738 uint32_t new_capacity) {
1720 DCHECK_EQ(NONE, attributes); 1739 DCHECK_EQ(NONE, attributes);
1721 Handle<FixedArray> parameter_map(FixedArray::cast(object->elements())); 1740 Handle<FixedArray> parameter_map(FixedArray::cast(object->elements()));
1722 Handle<FixedArrayBase> old_elements( 1741 Handle<FixedArrayBase> old_elements(
1723 FixedArrayBase::cast(parameter_map->get(1))); 1742 FixedArrayBase::cast(parameter_map->get(1)));
1724 if (old_elements->IsSeededNumberDictionary() || 1743 if (old_elements->IsSeededNumberDictionary() ||
1725 static_cast<uint32_t>(old_elements->length()) < new_capacity) { 1744 static_cast<uint32_t>(old_elements->length()) < new_capacity) {
1726 GrowCapacityAndConvertImpl(object, new_capacity); 1745 GrowCapacityAndConvertImpl(object, new_capacity);
1727 } 1746 }
1728 SetImpl(object->elements(), key, *value); 1747 SetImpl(object->elements(), key, *value);
1729 } 1748 }
1730 1749
1731 static void ReconfigureImpl(Handle<JSObject> object, 1750 static void ReconfigureImpl(Handle<JSObject> object,
1732 Handle<FixedArrayBase> store, uint32_t index, 1751 Handle<FixedArrayBase> store, uint32_t index,
1733 Handle<Object> value, 1752 Handle<Object> value,
1734 PropertyAttributes attributes) { 1753 PropertyAttributes attributes) {
1735 Handle<SeededNumberDictionary> dictionary = 1754 Handle<SeededNumberDictionary> dictionary =
1736 JSObject::NormalizeElements(object); 1755 JSObject::NormalizeElements(object);
1737 FixedArray::cast(*store)->set(1, *dictionary); 1756 FixedArray::cast(*store)->set(1, *dictionary);
1738 uint32_t length = static_cast<uint32_t>(store->length()) - 2; 1757 uint32_t length = static_cast<uint32_t>(store->length()) - 2;
1739 if (index >= length) { 1758 if (index >= length) {
1740 index = dictionary->FindEntry(index - length) + length; 1759 index = dictionary->FindEntry(index - length) + length;
1741 } 1760 }
1742 object->GetElementsAccessor()->Reconfigure(object, store, index, value, 1761 SlowSloppyArgumentsElementsAccessor::ReconfigureImpl(object, store, index,
1743 attributes); 1762 value, attributes);
1744 } 1763 }
1745 1764
1746 static void CopyElementsImpl(FixedArrayBase* from, uint32_t from_start, 1765 static void CopyElementsImpl(FixedArrayBase* from, uint32_t from_start,
1747 FixedArrayBase* to, ElementsKind from_kind, 1766 FixedArrayBase* to, ElementsKind from_kind,
1748 uint32_t to_start, int packed_size, 1767 uint32_t to_start, int packed_size,
1749 int copy_size) { 1768 int copy_size) {
1750 DCHECK(!to->IsDictionary()); 1769 DCHECK(!to->IsDictionary());
1751 if (from_kind == SLOW_SLOPPY_ARGUMENTS_ELEMENTS) { 1770 if (from_kind == SLOW_SLOPPY_ARGUMENTS_ELEMENTS) {
1752 CopyDictionaryToObjectElements(from, from_start, to, FAST_HOLEY_ELEMENTS, 1771 CopyDictionaryToObjectElements(from, from_start, to, FAST_HOLEY_ELEMENTS,
1753 to_start, copy_size); 1772 to_start, copy_size);
(...skipping 17 matching lines...) Expand all
1771 ConvertElementsWithCapacity(object, old_elements, from_kind, capacity); 1790 ConvertElementsWithCapacity(object, old_elements, from_kind, capacity);
1772 Handle<Map> new_map = JSObject::GetElementsTransitionMap( 1791 Handle<Map> new_map = JSObject::GetElementsTransitionMap(
1773 object, FAST_SLOPPY_ARGUMENTS_ELEMENTS); 1792 object, FAST_SLOPPY_ARGUMENTS_ELEMENTS);
1774 JSObject::MigrateToMap(object, new_map); 1793 JSObject::MigrateToMap(object, new_map);
1775 parameter_map->set(1, *elements); 1794 parameter_map->set(1, *elements);
1776 JSObject::ValidateElements(object); 1795 JSObject::ValidateElements(object);
1777 } 1796 }
1778 }; 1797 };
1779 1798
1780 1799
1781 class SlowSloppyArgumentsElementsAccessor
1782 : public SloppyArgumentsElementsAccessor<
1783 SlowSloppyArgumentsElementsAccessor, DictionaryElementsAccessor,
1784 ElementsKindTraits<SLOW_SLOPPY_ARGUMENTS_ELEMENTS> > {
1785 public:
1786 friend class ElementsAccessorBase<
1787 SlowSloppyArgumentsElementsAccessor,
1788 ElementsKindTraits<SLOW_SLOPPY_ARGUMENTS_ELEMENTS> >;
1789 friend class SloppyArgumentsElementsAccessor<
1790 SlowSloppyArgumentsElementsAccessor, DictionaryElementsAccessor,
1791 ElementsKindTraits<SLOW_SLOPPY_ARGUMENTS_ELEMENTS> >;
1792 explicit SlowSloppyArgumentsElementsAccessor(const char* name)
1793 : SloppyArgumentsElementsAccessor<
1794 SlowSloppyArgumentsElementsAccessor, DictionaryElementsAccessor,
1795 ElementsKindTraits<SLOW_SLOPPY_ARGUMENTS_ELEMENTS> >(name) {}
1796
1797 protected:
1798 static void AddImpl(Handle<JSObject> object, uint32_t key,
1799 Handle<Object> value, PropertyAttributes attributes,
1800 uint32_t new_capacity) {
1801 Handle<FixedArray> parameter_map(FixedArray::cast(object->elements()));
1802 Handle<FixedArrayBase> old_elements(
1803 FixedArrayBase::cast(parameter_map->get(1)));
1804 Handle<SeededNumberDictionary> dictionary =
1805 old_elements->IsSeededNumberDictionary()
1806 ? Handle<SeededNumberDictionary>::cast(old_elements)
1807 : JSObject::NormalizeElements(object);
1808 PropertyDetails details(attributes, DATA, 0, PropertyCellType::kNoCell);
1809 Handle<SeededNumberDictionary> new_dictionary =
1810 SeededNumberDictionary::AddNumberEntry(dictionary, key, value, details);
1811 if (attributes != NONE) new_dictionary->set_requires_slow_elements();
1812 if (*dictionary != *new_dictionary) {
1813 FixedArray::cast(object->elements())->set(1, *new_dictionary);
1814 }
1815 }
1816
1817 static void ReconfigureImpl(Handle<JSObject> object,
1818 Handle<FixedArrayBase> store, uint32_t index,
1819 Handle<Object> value,
1820 PropertyAttributes attributes) {
1821 Handle<FixedArray> parameter_map = Handle<FixedArray>::cast(store);
1822 uint32_t length = parameter_map->length() - 2;
1823 if (index < length) {
1824 Object* probe = parameter_map->get(index + 2);
1825 DCHECK(!probe->IsTheHole());
1826 Context* context = Context::cast(parameter_map->get(0));
1827 int context_index = Smi::cast(probe)->value();
1828 DCHECK(!context->get(context_index)->IsTheHole());
1829 context->set(context_index, *value);
1830
1831 // Redefining attributes of an aliased element destroys fast aliasing.
1832 parameter_map->set_the_hole(index + 2);
1833 // For elements that are still writable we re-establish slow aliasing.
1834 if ((attributes & READ_ONLY) == 0) {
1835 Isolate* isolate = store->GetIsolate();
1836 value = isolate->factory()->NewAliasedArgumentsEntry(context_index);
1837 }
1838
1839 PropertyDetails details(attributes, DATA, 0, PropertyCellType::kNoCell);
1840 Handle<SeededNumberDictionary> arguments(
1841 SeededNumberDictionary::cast(parameter_map->get(1)));
1842 arguments = SeededNumberDictionary::AddNumberEntry(arguments, index,
1843 value, details);
1844 parameter_map->set(1, *arguments);
1845 } else {
1846 Handle<FixedArrayBase> arguments(
1847 FixedArrayBase::cast(parameter_map->get(1)));
1848 DictionaryElementsAccessor::ReconfigureImpl(
1849 object, arguments, index - length, value, attributes);
1850 }
1851 }
1852 };
1853
1854
1855 void ElementsAccessor::InitializeOncePerProcess() { 1800 void ElementsAccessor::InitializeOncePerProcess() {
1856 static ElementsAccessor* accessor_array[] = { 1801 static ElementsAccessor* accessor_array[] = {
1857 #define ACCESSOR_ARRAY(Class, Kind, Store) new Class(#Kind), 1802 #define ACCESSOR_ARRAY(Class, Kind, Store) new Class(#Kind),
1858 ELEMENTS_LIST(ACCESSOR_ARRAY) 1803 ELEMENTS_LIST(ACCESSOR_ARRAY)
1859 #undef ACCESSOR_ARRAY 1804 #undef ACCESSOR_ARRAY
1860 }; 1805 };
1861 1806
1862 STATIC_ASSERT((sizeof(accessor_array) / sizeof(*accessor_array)) == 1807 STATIC_ASSERT((sizeof(accessor_array) / sizeof(*accessor_array)) ==
1863 kElementsKindCount); 1808 kElementsKindCount);
1864 1809
(...skipping 141 matching lines...) Expand 10 before | Expand all | Expand 10 after
2006 break; 1951 break;
2007 } 1952 }
2008 1953
2009 array->set_elements(*elms); 1954 array->set_elements(*elms);
2010 array->set_length(Smi::FromInt(number_of_elements)); 1955 array->set_length(Smi::FromInt(number_of_elements));
2011 return array; 1956 return array;
2012 } 1957 }
2013 1958
2014 } // namespace internal 1959 } // namespace internal
2015 } // namespace v8 1960 } // namespace v8
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698