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

Side by Side Diff: src/elements.cc

Issue 1221713003: Distinguish slow from fast sloppy arguments (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: 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
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 29 matching lines...) Expand all
40 // - FixedInt8ElementsAccessor 40 // - FixedInt8ElementsAccessor
41 // - FixedUint16ElementsAccessor 41 // - FixedUint16ElementsAccessor
42 // - FixedInt16ElementsAccessor 42 // - FixedInt16ElementsAccessor
43 // - FixedUint32ElementsAccessor 43 // - FixedUint32ElementsAccessor
44 // - FixedInt32ElementsAccessor 44 // - FixedInt32ElementsAccessor
45 // - FixedFloat32ElementsAccessor 45 // - FixedFloat32ElementsAccessor
46 // - FixedFloat64ElementsAccessor 46 // - FixedFloat64ElementsAccessor
47 // - FixedUint8ClampedElementsAccessor 47 // - FixedUint8ClampedElementsAccessor
48 // - DictionaryElementsAccessor 48 // - DictionaryElementsAccessor
49 // - SloppyArgumentsElementsAccessor 49 // - SloppyArgumentsElementsAccessor
50 // - FastSloppyArgumentsElementsAccessor
51 // - SlowSloppyArgumentsElementsAccessor
50 52
51 53
52 namespace v8 { 54 namespace v8 {
53 namespace internal { 55 namespace internal {
54 56
55 57
56 static const int kPackedSizeNotKnown = -1; 58 static const int kPackedSizeNotKnown = -1;
57 59
58 60
59 // First argument in list is the accessor class, the second argument is the 61 // First argument in list is the accessor class, the second argument is the
60 // accessor ElementsKind, and the third is the backing store class. Use the 62 // accessor ElementsKind, and the third is the backing store class. Use the
61 // fast element handler for smi-only arrays. The implementation is currently 63 // fast element handler for smi-only arrays. The implementation is currently
62 // identical. Note that the order must match that of the ElementsKind enum for 64 // identical. Note that the order must match that of the ElementsKind enum for
63 // the |accessor_array[]| below to work. 65 // the |accessor_array[]| below to work.
64 #define ELEMENTS_LIST(V) \ 66 #define ELEMENTS_LIST(V) \
65 V(FastPackedSmiElementsAccessor, FAST_SMI_ELEMENTS, FixedArray) \ 67 V(FastPackedSmiElementsAccessor, FAST_SMI_ELEMENTS, FixedArray) \
66 V(FastHoleySmiElementsAccessor, FAST_HOLEY_SMI_ELEMENTS, \ 68 V(FastHoleySmiElementsAccessor, FAST_HOLEY_SMI_ELEMENTS, FixedArray) \
67 FixedArray) \ 69 V(FastPackedObjectElementsAccessor, FAST_ELEMENTS, FixedArray) \
68 V(FastPackedObjectElementsAccessor, FAST_ELEMENTS, FixedArray) \ 70 V(FastHoleyObjectElementsAccessor, FAST_HOLEY_ELEMENTS, FixedArray) \
69 V(FastHoleyObjectElementsAccessor, FAST_HOLEY_ELEMENTS, FixedArray) \ 71 V(FastPackedDoubleElementsAccessor, FAST_DOUBLE_ELEMENTS, FixedDoubleArray) \
70 V(FastPackedDoubleElementsAccessor, FAST_DOUBLE_ELEMENTS, \ 72 V(FastHoleyDoubleElementsAccessor, FAST_HOLEY_DOUBLE_ELEMENTS, \
71 FixedDoubleArray) \ 73 FixedDoubleArray) \
72 V(FastHoleyDoubleElementsAccessor, FAST_HOLEY_DOUBLE_ELEMENTS, \ 74 V(DictionaryElementsAccessor, DICTIONARY_ELEMENTS, SeededNumberDictionary) \
73 FixedDoubleArray) \ 75 V(FastSloppyArgumentsElementsAccessor, FAST_SLOPPY_ARGUMENTS_ELEMENTS, \
74 V(DictionaryElementsAccessor, DICTIONARY_ELEMENTS, \ 76 FixedArray) \
75 SeededNumberDictionary) \ 77 V(SlowSloppyArgumentsElementsAccessor, SLOW_SLOPPY_ARGUMENTS_ELEMENTS, \
76 V(SloppyArgumentsElementsAccessor, SLOPPY_ARGUMENTS_ELEMENTS, \ 78 FixedArray) \
77 FixedArray) \ 79 V(ExternalInt8ElementsAccessor, EXTERNAL_INT8_ELEMENTS, ExternalInt8Array) \
78 V(ExternalInt8ElementsAccessor, EXTERNAL_INT8_ELEMENTS, \ 80 V(ExternalUint8ElementsAccessor, EXTERNAL_UINT8_ELEMENTS, \
79 ExternalInt8Array) \ 81 ExternalUint8Array) \
80 V(ExternalUint8ElementsAccessor, \ 82 V(ExternalInt16ElementsAccessor, EXTERNAL_INT16_ELEMENTS, \
81 EXTERNAL_UINT8_ELEMENTS, ExternalUint8Array) \ 83 ExternalInt16Array) \
82 V(ExternalInt16ElementsAccessor, EXTERNAL_INT16_ELEMENTS, \ 84 V(ExternalUint16ElementsAccessor, EXTERNAL_UINT16_ELEMENTS, \
83 ExternalInt16Array) \ 85 ExternalUint16Array) \
84 V(ExternalUint16ElementsAccessor, \ 86 V(ExternalInt32ElementsAccessor, EXTERNAL_INT32_ELEMENTS, \
85 EXTERNAL_UINT16_ELEMENTS, ExternalUint16Array) \ 87 ExternalInt32Array) \
86 V(ExternalInt32ElementsAccessor, EXTERNAL_INT32_ELEMENTS, \ 88 V(ExternalUint32ElementsAccessor, EXTERNAL_UINT32_ELEMENTS, \
87 ExternalInt32Array) \ 89 ExternalUint32Array) \
88 V(ExternalUint32ElementsAccessor, \ 90 V(ExternalFloat32ElementsAccessor, EXTERNAL_FLOAT32_ELEMENTS, \
89 EXTERNAL_UINT32_ELEMENTS, ExternalUint32Array) \ 91 ExternalFloat32Array) \
90 V(ExternalFloat32ElementsAccessor, \ 92 V(ExternalFloat64ElementsAccessor, EXTERNAL_FLOAT64_ELEMENTS, \
91 EXTERNAL_FLOAT32_ELEMENTS, ExternalFloat32Array) \ 93 ExternalFloat64Array) \
92 V(ExternalFloat64ElementsAccessor, \ 94 V(ExternalUint8ClampedElementsAccessor, EXTERNAL_UINT8_CLAMPED_ELEMENTS, \
93 EXTERNAL_FLOAT64_ELEMENTS, ExternalFloat64Array) \ 95 ExternalUint8ClampedArray) \
94 V(ExternalUint8ClampedElementsAccessor, \ 96 V(FixedUint8ElementsAccessor, UINT8_ELEMENTS, FixedUint8Array) \
95 EXTERNAL_UINT8_CLAMPED_ELEMENTS, \ 97 V(FixedInt8ElementsAccessor, INT8_ELEMENTS, FixedInt8Array) \
96 ExternalUint8ClampedArray) \ 98 V(FixedUint16ElementsAccessor, UINT16_ELEMENTS, FixedUint16Array) \
97 V(FixedUint8ElementsAccessor, UINT8_ELEMENTS, FixedUint8Array) \ 99 V(FixedInt16ElementsAccessor, INT16_ELEMENTS, FixedInt16Array) \
98 V(FixedInt8ElementsAccessor, INT8_ELEMENTS, FixedInt8Array) \ 100 V(FixedUint32ElementsAccessor, UINT32_ELEMENTS, FixedUint32Array) \
99 V(FixedUint16ElementsAccessor, UINT16_ELEMENTS, FixedUint16Array) \ 101 V(FixedInt32ElementsAccessor, INT32_ELEMENTS, FixedInt32Array) \
100 V(FixedInt16ElementsAccessor, INT16_ELEMENTS, FixedInt16Array) \ 102 V(FixedFloat32ElementsAccessor, FLOAT32_ELEMENTS, FixedFloat32Array) \
101 V(FixedUint32ElementsAccessor, UINT32_ELEMENTS, FixedUint32Array) \ 103 V(FixedFloat64ElementsAccessor, FLOAT64_ELEMENTS, FixedFloat64Array) \
102 V(FixedInt32ElementsAccessor, INT32_ELEMENTS, FixedInt32Array) \ 104 V(FixedUint8ClampedElementsAccessor, UINT8_CLAMPED_ELEMENTS, \
103 V(FixedFloat32ElementsAccessor, FLOAT32_ELEMENTS, FixedFloat32Array) \
104 V(FixedFloat64ElementsAccessor, FLOAT64_ELEMENTS, FixedFloat64Array) \
105 V(FixedUint8ClampedElementsAccessor, UINT8_CLAMPED_ELEMENTS, \
106 FixedUint8ClampedArray) 105 FixedUint8ClampedArray)
107 106
108 107
109 template<ElementsKind Kind> class ElementsKindTraits { 108 template<ElementsKind Kind> class ElementsKindTraits {
110 public: 109 public:
111 typedef FixedArrayBase BackingStore; 110 typedef FixedArrayBase BackingStore;
112 }; 111 };
113 112
114 #define ELEMENTS_TRAITS(Class, KindParam, Store) \ 113 #define ELEMENTS_TRAITS(Class, KindParam, Store) \
115 template<> class ElementsKindTraits<KindParam> { \ 114 template<> class ElementsKindTraits<KindParam> { \
(...skipping 427 matching lines...) Expand 10 before | Expand all | Expand 10 after
543 // } 542 // }
544 // 543 //
545 // This is an example of the Curiously Recurring Template Pattern (see 544 // This is an example of the Curiously Recurring Template Pattern (see
546 // http://en.wikipedia.org/wiki/Curiously_recurring_template_pattern). We use 545 // http://en.wikipedia.org/wiki/Curiously_recurring_template_pattern). We use
547 // CRTP to guarantee aggressive compile time optimizations (i.e. inlining and 546 // CRTP to guarantee aggressive compile time optimizations (i.e. inlining and
548 // specialization of SomeElementsAccessor methods). 547 // specialization of SomeElementsAccessor methods).
549 template <typename ElementsAccessorSubclass, 548 template <typename ElementsAccessorSubclass,
550 typename ElementsTraitsParam> 549 typename ElementsTraitsParam>
551 class ElementsAccessorBase : public ElementsAccessor { 550 class ElementsAccessorBase : public ElementsAccessor {
552 protected: 551 protected:
552 friend class SloppyArgumentsElementsAccessor<
553 FastSloppyArgumentsElementsAccessor, FastHoleyObjectElementsAccessor,
554 ElementsKindTraits<FAST_SLOPPY_ARGUMENTS_ELEMENTS> >;
553 explicit ElementsAccessorBase(const char* name) 555 explicit ElementsAccessorBase(const char* name)
554 : ElementsAccessor(name) { } 556 : ElementsAccessor(name) { }
555 557
556 typedef ElementsTraitsParam ElementsTraits; 558 typedef ElementsTraitsParam ElementsTraits;
557 typedef typename ElementsTraitsParam::BackingStore BackingStore; 559 typedef typename ElementsTraitsParam::BackingStore BackingStore;
558 560
559 static ElementsKind kind() { return ElementsTraits::Kind; } 561 static ElementsKind kind() { return ElementsTraits::Kind; }
560 562
561 static void ValidateContents(Handle<JSObject> holder, int length) { 563 static void ValidateContents(Handle<JSObject> holder, int length) {
562 } 564 }
(...skipping 364 matching lines...) Expand 10 before | Expand all | Expand 10 after
927 typename KindTraits> 929 typename KindTraits>
928 class FastElementsAccessor 930 class FastElementsAccessor
929 : public ElementsAccessorBase<FastElementsAccessorSubclass, KindTraits> { 931 : public ElementsAccessorBase<FastElementsAccessorSubclass, KindTraits> {
930 public: 932 public:
931 explicit FastElementsAccessor(const char* name) 933 explicit FastElementsAccessor(const char* name)
932 : ElementsAccessorBase<FastElementsAccessorSubclass, 934 : ElementsAccessorBase<FastElementsAccessorSubclass,
933 KindTraits>(name) {} 935 KindTraits>(name) {}
934 936
935 protected: 937 protected:
936 friend class ElementsAccessorBase<FastElementsAccessorSubclass, KindTraits>; 938 friend class ElementsAccessorBase<FastElementsAccessorSubclass, KindTraits>;
937 friend class SloppyArgumentsElementsAccessor; 939 friend class FastSloppyArgumentsElementsAccessor;
940 friend class SloppyArgumentsElementsAccessor<
941 FastSloppyArgumentsElementsAccessor, FastHoleyObjectElementsAccessor,
942 ElementsKindTraits<FAST_SLOPPY_ARGUMENTS_ELEMENTS> >;
938 943
939 typedef typename KindTraits::BackingStore BackingStore; 944 typedef typename KindTraits::BackingStore BackingStore;
940 945
941 static void DeleteCommon(Handle<JSObject> obj, uint32_t key, 946 static void DeleteCommon(Handle<JSObject> obj, uint32_t key,
942 LanguageMode language_mode) { 947 LanguageMode language_mode) {
943 DCHECK(obj->HasFastSmiOrObjectElements() || 948 DCHECK(obj->HasFastSmiOrObjectElements() ||
944 obj->HasFastDoubleElements() || 949 obj->HasFastDoubleElements() ||
945 obj->HasFastArgumentsElements()); 950 obj->HasFastArgumentsElements());
946 Isolate* isolate = obj->GetIsolate(); 951 Isolate* isolate = obj->GetIsolate();
947 Heap* heap = obj->GetHeap(); 952 Heap* heap = obj->GetHeap();
(...skipping 111 matching lines...) Expand 10 before | Expand all | Expand 10 after
1059 DCHECK(BackingStore::get(backing_store, i)->IsSmi() || 1064 DCHECK(BackingStore::get(backing_store, i)->IsSmi() ||
1060 (IsFastHoleyElementsKind(KindTraits::Kind) && 1065 (IsFastHoleyElementsKind(KindTraits::Kind) &&
1061 backing_store->is_the_hole(i))); 1066 backing_store->is_the_hole(i)));
1062 } 1067 }
1063 } 1068 }
1064 #endif 1069 #endif
1065 } 1070 }
1066 }; 1071 };
1067 1072
1068 1073
1069 static inline ElementsKind ElementsKindForArray(FixedArrayBase* array) {
1070 switch (array->map()->instance_type()) {
1071 case FIXED_ARRAY_TYPE:
1072 if (array->IsDictionary()) {
1073 return DICTIONARY_ELEMENTS;
1074 } else {
1075 return FAST_HOLEY_ELEMENTS;
1076 }
1077 case FIXED_DOUBLE_ARRAY_TYPE:
1078 return FAST_HOLEY_DOUBLE_ELEMENTS;
1079
1080 #define TYPED_ARRAY_CASE(Type, type, TYPE, ctype, size) \
1081 case EXTERNAL_##TYPE##_ARRAY_TYPE: \
1082 return EXTERNAL_##TYPE##_ELEMENTS; \
1083 case FIXED_##TYPE##_ARRAY_TYPE: \
1084 return TYPE##_ELEMENTS;
1085
1086 TYPED_ARRAYS(TYPED_ARRAY_CASE)
1087 #undef TYPED_ARRAY_CASE
1088
1089 default:
1090 UNREACHABLE();
1091 }
1092 return FAST_HOLEY_ELEMENTS;
1093 }
1094
1095
1096 template<typename FastElementsAccessorSubclass, 1074 template<typename FastElementsAccessorSubclass,
1097 typename KindTraits> 1075 typename KindTraits>
1098 class FastSmiOrObjectElementsAccessor 1076 class FastSmiOrObjectElementsAccessor
1099 : public FastElementsAccessor<FastElementsAccessorSubclass, KindTraits> { 1077 : public FastElementsAccessor<FastElementsAccessorSubclass, KindTraits> {
1100 public: 1078 public:
1101 explicit FastSmiOrObjectElementsAccessor(const char* name) 1079 explicit FastSmiOrObjectElementsAccessor(const char* name)
1102 : FastElementsAccessor<FastElementsAccessorSubclass, 1080 : FastElementsAccessor<FastElementsAccessorSubclass,
1103 KindTraits>(name) {} 1081 KindTraits>(name) {}
1104 1082
1105 // NOTE: this method violates the handlified function signature convention: 1083 // NOTE: this method violates the handlified function signature convention:
(...skipping 19 matching lines...) Expand all
1125 case FAST_HOLEY_DOUBLE_ELEMENTS: { 1103 case FAST_HOLEY_DOUBLE_ELEMENTS: {
1126 AllowHeapAllocation allow_allocation; 1104 AllowHeapAllocation allow_allocation;
1127 CopyDoubleToObjectElements( 1105 CopyDoubleToObjectElements(
1128 from, from_start, to, to_kind, to_start, copy_size); 1106 from, from_start, to, to_kind, to_start, copy_size);
1129 break; 1107 break;
1130 } 1108 }
1131 case DICTIONARY_ELEMENTS: 1109 case DICTIONARY_ELEMENTS:
1132 CopyDictionaryToObjectElements(from, from_start, to, to_kind, to_start, 1110 CopyDictionaryToObjectElements(from, from_start, to, to_kind, to_start,
1133 copy_size); 1111 copy_size);
1134 break; 1112 break;
1135 case SLOPPY_ARGUMENTS_ELEMENTS: { 1113 case FAST_SLOPPY_ARGUMENTS_ELEMENTS:
1136 // TODO(verwaest): This is a temporary hack to support extending 1114 case SLOW_SLOPPY_ARGUMENTS_ELEMENTS:
1137 // SLOPPY_ARGUMENTS_ELEMENTS in GrowCapacityAndConvert. 1115 UNREACHABLE();
1138 // This case should be UNREACHABLE().
1139 FixedArray* parameter_map = FixedArray::cast(from);
1140 FixedArrayBase* arguments = FixedArrayBase::cast(parameter_map->get(1));
1141 ElementsKind from_kind = ElementsKindForArray(arguments);
1142 CopyElementsImpl(arguments, from_start, to, from_kind,
1143 to_start, packed_size, copy_size);
1144 break;
1145 }
1146 #define TYPED_ARRAY_CASE(Type, type, TYPE, ctype, size) \ 1116 #define TYPED_ARRAY_CASE(Type, type, TYPE, ctype, size) \
1147 case EXTERNAL_##TYPE##_ELEMENTS: \ 1117 case EXTERNAL_##TYPE##_ELEMENTS: \
1148 case TYPE##_ELEMENTS: \ 1118 case TYPE##_ELEMENTS: \
1149 UNREACHABLE(); 1119 UNREACHABLE();
1150 TYPED_ARRAYS(TYPED_ARRAY_CASE) 1120 TYPED_ARRAYS(TYPED_ARRAY_CASE)
1151 #undef TYPED_ARRAY_CASE 1121 #undef TYPED_ARRAY_CASE
1152 } 1122 }
1153 } 1123 }
1154 }; 1124 };
1155 1125
(...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after
1230 CopyDoubleToDoubleElements(from, from_start, to, to_start, copy_size); 1200 CopyDoubleToDoubleElements(from, from_start, to, to_start, copy_size);
1231 break; 1201 break;
1232 case FAST_ELEMENTS: 1202 case FAST_ELEMENTS:
1233 case FAST_HOLEY_ELEMENTS: 1203 case FAST_HOLEY_ELEMENTS:
1234 CopyObjectToDoubleElements(from, from_start, to, to_start, copy_size); 1204 CopyObjectToDoubleElements(from, from_start, to, to_start, copy_size);
1235 break; 1205 break;
1236 case DICTIONARY_ELEMENTS: 1206 case DICTIONARY_ELEMENTS:
1237 CopyDictionaryToDoubleElements(from, from_start, to, to_start, 1207 CopyDictionaryToDoubleElements(from, from_start, to, to_start,
1238 copy_size); 1208 copy_size);
1239 break; 1209 break;
1240 case SLOPPY_ARGUMENTS_ELEMENTS: 1210 case FAST_SLOPPY_ARGUMENTS_ELEMENTS:
1211 case SLOW_SLOPPY_ARGUMENTS_ELEMENTS:
1241 UNREACHABLE(); 1212 UNREACHABLE();
1242 1213
1243 #define TYPED_ARRAY_CASE(Type, type, TYPE, ctype, size) \ 1214 #define TYPED_ARRAY_CASE(Type, type, TYPE, ctype, size) \
1244 case EXTERNAL_##TYPE##_ELEMENTS: \ 1215 case EXTERNAL_##TYPE##_ELEMENTS: \
1245 case TYPE##_ELEMENTS: \ 1216 case TYPE##_ELEMENTS: \
1246 UNREACHABLE(); 1217 UNREACHABLE();
1247 TYPED_ARRAYS(TYPED_ARRAY_CASE) 1218 TYPED_ARRAYS(TYPED_ARRAY_CASE)
1248 #undef TYPED_ARRAY_CASE 1219 #undef TYPED_ARRAY_CASE
1249 } 1220 }
1250 } 1221 }
(...skipping 159 matching lines...) Expand 10 before | Expand all | Expand 10 after
1410 1381
1411 // Update the number of elements. 1382 // Update the number of elements.
1412 dict->ElementsRemoved(removed_entries); 1383 dict->ElementsRemoved(removed_entries);
1413 } 1384 }
1414 } 1385 }
1415 1386
1416 Handle<Object> length_obj = isolate->factory()->NewNumberFromUint(length); 1387 Handle<Object> length_obj = isolate->factory()->NewNumberFromUint(length);
1417 array->set_length(*length_obj); 1388 array->set_length(*length_obj);
1418 } 1389 }
1419 1390
1391 static void CopyElementsImpl(FixedArrayBase* from, uint32_t from_start,
1392 FixedArrayBase* to, ElementsKind from_kind,
1393 uint32_t to_start, int packed_size,
1394 int copy_size) {
1395 UNREACHABLE();
1396 }
1397
1398
1399 protected:
1400 friend class ElementsAccessorBase<DictionaryElementsAccessor,
1401 ElementsKindTraits<DICTIONARY_ELEMENTS> >;
1402 friend class SlowSloppyArgumentsElementsAccessor;
1403 friend class SloppyArgumentsElementsAccessor<
1404 SlowSloppyArgumentsElementsAccessor, DictionaryElementsAccessor,
1405 ElementsKindTraits<SLOW_SLOPPY_ARGUMENTS_ELEMENTS> >;
1406
1420 static void DeleteCommon(Handle<JSObject> obj, uint32_t key, 1407 static void DeleteCommon(Handle<JSObject> obj, uint32_t key,
1421 LanguageMode language_mode) { 1408 LanguageMode language_mode) {
1422 Isolate* isolate = obj->GetIsolate(); 1409 Isolate* isolate = obj->GetIsolate();
1423 Handle<FixedArray> backing_store(FixedArray::cast(obj->elements()), 1410 Handle<FixedArray> backing_store(FixedArray::cast(obj->elements()),
1424 isolate); 1411 isolate);
1425 bool is_arguments = 1412 bool is_arguments = obj->HasSloppyArgumentsElements();
1426 (obj->GetElementsKind() == SLOPPY_ARGUMENTS_ELEMENTS);
1427 if (is_arguments) { 1413 if (is_arguments) {
1428 backing_store = handle(FixedArray::cast(backing_store->get(1)), isolate); 1414 backing_store = handle(FixedArray::cast(backing_store->get(1)), isolate);
1429 } 1415 }
1430 Handle<SeededNumberDictionary> dictionary = 1416 Handle<SeededNumberDictionary> dictionary =
1431 Handle<SeededNumberDictionary>::cast(backing_store); 1417 Handle<SeededNumberDictionary>::cast(backing_store);
1432 int entry = dictionary->FindEntry(key); 1418 int entry = dictionary->FindEntry(key);
1433 if (entry != SeededNumberDictionary::kNotFound) { 1419 if (entry != SeededNumberDictionary::kNotFound) {
1434 Handle<Object> result = 1420 Handle<Object> result =
1435 SeededNumberDictionary::DeleteProperty(dictionary, entry); 1421 SeededNumberDictionary::DeleteProperty(dictionary, entry);
1436 USE(result); 1422 USE(result);
1437 DCHECK(result->IsTrue()); 1423 DCHECK(result->IsTrue());
1438 Handle<FixedArray> new_elements = 1424 Handle<FixedArray> new_elements =
1439 SeededNumberDictionary::Shrink(dictionary, key); 1425 SeededNumberDictionary::Shrink(dictionary, key);
1440 1426
1441 if (is_arguments) { 1427 if (is_arguments) {
1442 FixedArray::cast(obj->elements())->set(1, *new_elements); 1428 FixedArray::cast(obj->elements())->set(1, *new_elements);
1443 } else { 1429 } else {
1444 obj->set_elements(*new_elements); 1430 obj->set_elements(*new_elements);
1445 } 1431 }
1446 } 1432 }
1447 } 1433 }
1448 1434
1449 static void CopyElementsImpl(FixedArrayBase* from, uint32_t from_start,
1450 FixedArrayBase* to, ElementsKind from_kind,
1451 uint32_t to_start, int packed_size,
1452 int copy_size) {
1453 UNREACHABLE();
1454 }
1455
1456
1457 protected:
1458 friend class ElementsAccessorBase<DictionaryElementsAccessor,
1459 ElementsKindTraits<DICTIONARY_ELEMENTS> >;
1460
1461 virtual void Delete(Handle<JSObject> obj, uint32_t key, 1435 virtual void Delete(Handle<JSObject> obj, uint32_t key,
1462 LanguageMode language_mode) final { 1436 LanguageMode language_mode) final {
1463 DeleteCommon(obj, key, language_mode); 1437 DeleteCommon(obj, key, language_mode);
1464 } 1438 }
1465 1439
1466 static Handle<Object> GetImpl(Handle<JSObject> obj, uint32_t key, 1440 static Handle<Object> GetImpl(Handle<JSObject> obj, uint32_t key,
1467 Handle<FixedArrayBase> store) { 1441 Handle<FixedArrayBase> store) {
1468 Handle<SeededNumberDictionary> backing_store = 1442 Handle<SeededNumberDictionary> backing_store =
1469 Handle<SeededNumberDictionary>::cast(store); 1443 Handle<SeededNumberDictionary>::cast(store);
1470 Isolate* isolate = backing_store->GetIsolate(); 1444 Isolate* isolate = backing_store->GetIsolate();
(...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after
1549 : static_cast<uint32_t>(entry); 1523 : static_cast<uint32_t>(entry);
1550 } 1524 }
1551 1525
1552 static PropertyDetails GetDetailsImpl(FixedArrayBase* backing_store, 1526 static PropertyDetails GetDetailsImpl(FixedArrayBase* backing_store,
1553 uint32_t index) { 1527 uint32_t index) {
1554 return SeededNumberDictionary::cast(backing_store)->DetailsAt(index); 1528 return SeededNumberDictionary::cast(backing_store)->DetailsAt(index);
1555 } 1529 }
1556 }; 1530 };
1557 1531
1558 1532
1559 class SloppyArgumentsElementsAccessor : public ElementsAccessorBase< 1533 template <typename SloppyArgumentsElementsAccessorSubclass,
1560 SloppyArgumentsElementsAccessor, 1534 typename ArgumentsAccessor, typename KindTraits>
1561 ElementsKindTraits<SLOPPY_ARGUMENTS_ELEMENTS> > { 1535 class SloppyArgumentsElementsAccessor
1536 : public ElementsAccessorBase<SloppyArgumentsElementsAccessorSubclass,
1537 KindTraits> {
1562 public: 1538 public:
1563 explicit SloppyArgumentsElementsAccessor(const char* name) 1539 explicit SloppyArgumentsElementsAccessor(const char* name)
1564 : ElementsAccessorBase< 1540 : ElementsAccessorBase<SloppyArgumentsElementsAccessorSubclass,
1565 SloppyArgumentsElementsAccessor, 1541 KindTraits>(name) {}
1566 ElementsKindTraits<SLOPPY_ARGUMENTS_ELEMENTS> >(name) {} 1542
1567 protected: 1543 protected:
1568 friend class ElementsAccessorBase< 1544 friend class ElementsAccessorBase<SloppyArgumentsElementsAccessorSubclass,
1569 SloppyArgumentsElementsAccessor, 1545 KindTraits>;
1570 ElementsKindTraits<SLOPPY_ARGUMENTS_ELEMENTS> >;
1571 1546
1572 static Handle<Object> GetImpl(Handle<JSObject> obj, uint32_t key, 1547 static Handle<Object> GetImpl(Handle<JSObject> obj, uint32_t key,
1573 Handle<FixedArrayBase> parameters) { 1548 Handle<FixedArrayBase> parameters) {
1574 Isolate* isolate = obj->GetIsolate(); 1549 Isolate* isolate = obj->GetIsolate();
1575 Handle<FixedArray> parameter_map = Handle<FixedArray>::cast(parameters); 1550 Handle<FixedArray> parameter_map = Handle<FixedArray>::cast(parameters);
1576 Handle<Object> probe(GetParameterMapArg(*parameter_map, key), isolate); 1551 Handle<Object> probe(GetParameterMapArg(*parameter_map, key), isolate);
1577 if (!probe->IsTheHole()) { 1552 if (!probe->IsTheHole()) {
1578 DisallowHeapAllocation no_gc; 1553 DisallowHeapAllocation no_gc;
1579 Context* context = Context::cast(parameter_map->get(0)); 1554 Context* context = Context::cast(parameter_map->get(0));
1580 int context_index = Handle<Smi>::cast(probe)->value(); 1555 int context_index = Handle<Smi>::cast(probe)->value();
1581 DCHECK(!context->get(context_index)->IsTheHole()); 1556 DCHECK(!context->get(context_index)->IsTheHole());
1582 return handle(context->get(context_index), isolate); 1557 return handle(context->get(context_index), isolate);
1583 } else { 1558 } else {
1584 // Object is not mapped, defer to the arguments. 1559 // Object is not mapped, defer to the arguments.
1585 Handle<FixedArray> arguments(FixedArray::cast(parameter_map->get(1)), 1560 Handle<FixedArray> arguments(FixedArray::cast(parameter_map->get(1)),
1586 isolate); 1561 isolate);
1587 Handle<Object> result = 1562 Handle<Object> result = ArgumentsAccessor::GetImpl(obj, key, arguments);
1588 ElementsAccessor::ForArray(arguments)->Get(obj, key, arguments);
1589 // Elements of the arguments object in slow mode might be slow aliases. 1563 // Elements of the arguments object in slow mode might be slow aliases.
1590 if (result->IsAliasedArgumentsEntry()) { 1564 if (result->IsAliasedArgumentsEntry()) {
1591 DisallowHeapAllocation no_gc; 1565 DisallowHeapAllocation no_gc;
1592 AliasedArgumentsEntry* entry = AliasedArgumentsEntry::cast(*result); 1566 AliasedArgumentsEntry* entry = AliasedArgumentsEntry::cast(*result);
1593 Context* context = Context::cast(parameter_map->get(0)); 1567 Context* context = Context::cast(parameter_map->get(0));
1594 int context_index = entry->aliased_context_slot(); 1568 int context_index = entry->aliased_context_slot();
1595 DCHECK(!context->get(context_index)->IsTheHole()); 1569 DCHECK(!context->get(context_index)->IsTheHole());
1596 return handle(context->get(context_index), isolate); 1570 return handle(context->get(context_index), isolate);
1597 } else { 1571 } else {
1598 return result; 1572 return result;
1599 } 1573 }
1600 } 1574 }
1601 } 1575 }
1602 1576
1603 static void GrowCapacityAndConvertImpl(Handle<JSObject> object, 1577 static void GrowCapacityAndConvertImpl(Handle<JSObject> object,
1604 uint32_t capacity) { 1578 uint32_t capacity) {
1605 Handle<FixedArray> parameter_map(FixedArray::cast(object->elements())); 1579 UNREACHABLE();
1606 Handle<FixedArray> old_elements(FixedArray::cast(parameter_map->get(1)));
1607 ElementsKind from_kind = old_elements->IsDictionary() ? DICTIONARY_ELEMENTS
1608 : FAST_HOLEY_ELEMENTS;
1609 // This method should only be called if there's a reason to update the
1610 // elements.
1611 DCHECK(IsDictionaryElementsKind(from_kind) ||
1612 static_cast<uint32_t>(old_elements->length()) < capacity);
1613 Handle<FixedArrayBase> elements =
1614 ConvertElementsWithCapacity(object, old_elements, from_kind, capacity);
1615 parameter_map->set(1, *elements);
1616 JSObject::ValidateElements(object);
1617 } 1580 }
1618 1581
1619 static void SetImpl(FixedArrayBase* store, uint32_t key, Object* value) { 1582 static void SetImpl(FixedArrayBase* store, uint32_t key, Object* value) {
1620 FixedArray* parameter_map = FixedArray::cast(store); 1583 FixedArray* parameter_map = FixedArray::cast(store);
1621 Object* probe = GetParameterMapArg(parameter_map, key); 1584 Object* probe = GetParameterMapArg(parameter_map, key);
1622 if (!probe->IsTheHole()) { 1585 if (!probe->IsTheHole()) {
1623 Context* context = Context::cast(parameter_map->get(0)); 1586 Context* context = Context::cast(parameter_map->get(0));
1624 int context_index = Smi::cast(probe)->value(); 1587 int context_index = Smi::cast(probe)->value();
1625 DCHECK(!context->get(context_index)->IsTheHole()); 1588 DCHECK(!context->get(context_index)->IsTheHole());
1626 context->set(context_index, value); 1589 context->set(context_index, value);
1627 } else { 1590 } else {
1628 FixedArray* arguments = FixedArray::cast(parameter_map->get(1)); 1591 FixedArray* arguments = FixedArray::cast(parameter_map->get(1));
1629 ElementsAccessor::ForArray(arguments)->Set(arguments, key, value); 1592 ArgumentsAccessor::SetImpl(arguments, key, value);
1630 } 1593 }
1631 } 1594 }
1632 1595
1633 static void ReconfigureImpl(Handle<JSObject> object,
1634 Handle<FixedArrayBase> store, uint32_t index,
1635 Handle<Object> value,
1636 PropertyAttributes attributes) {
1637 Handle<FixedArray> parameter_map = Handle<FixedArray>::cast(store);
1638 uint32_t length = parameter_map->length() - 2;
1639 if (index < length) {
1640 Object* probe = parameter_map->get(index + 2);
1641 DCHECK(!probe->IsTheHole());
1642 Context* context = Context::cast(parameter_map->get(0));
1643 int context_index = Smi::cast(probe)->value();
1644 DCHECK(!context->get(context_index)->IsTheHole());
1645 context->set(context_index, *value);
1646
1647 // Redefining attributes of an aliased element destroys fast aliasing.
1648 parameter_map->set_the_hole(index + 2);
1649 // For elements that are still writable we re-establish slow aliasing.
1650 if ((attributes & READ_ONLY) == 0) {
1651 Isolate* isolate = store->GetIsolate();
1652 value = isolate->factory()->NewAliasedArgumentsEntry(context_index);
1653 }
1654
1655 PropertyDetails details(attributes, DATA, 0, PropertyCellType::kNoCell);
1656 Handle<SeededNumberDictionary> arguments =
1657 parameter_map->get(1)->IsSeededNumberDictionary()
1658 ? handle(SeededNumberDictionary::cast(parameter_map->get(1)))
1659 : JSObject::NormalizeElements(object);
1660 arguments = SeededNumberDictionary::AddNumberEntry(arguments, index,
1661 value, details);
1662 parameter_map->set(1, *arguments);
1663 } else {
1664 Handle<FixedArrayBase> arguments(
1665 FixedArrayBase::cast(parameter_map->get(1)));
1666 ElementsAccessor::ForArray(arguments)
1667 ->Reconfigure(object, arguments, index - length, value, attributes);
1668 }
1669 }
1670
1671 static void AddImpl(Handle<JSObject> object, uint32_t key,
1672 Handle<Object> value, PropertyAttributes attributes,
1673 uint32_t new_capacity) {
1674 DCHECK_EQ(NONE, attributes);
1675 Handle<FixedArray> parameter_map(FixedArray::cast(object->elements()));
1676 Handle<FixedArrayBase> old_elements(
1677 FixedArrayBase::cast(parameter_map->get(1)));
1678 if (old_elements->IsSeededNumberDictionary() ||
1679 static_cast<uint32_t>(old_elements->length()) < new_capacity) {
1680 GrowCapacityAndConvertImpl(object, new_capacity);
1681 }
1682 SetImpl(object->elements(), key, *value);
1683 }
1684
1685 static MaybeHandle<AccessorPair> GetAccessorPairImpl( 1596 static MaybeHandle<AccessorPair> GetAccessorPairImpl(
1686 Handle<JSObject> obj, uint32_t key, Handle<FixedArrayBase> parameters) { 1597 Handle<JSObject> obj, uint32_t key, Handle<FixedArrayBase> parameters) {
1687 Handle<FixedArray> parameter_map = Handle<FixedArray>::cast(parameters); 1598 Handle<FixedArray> parameter_map = Handle<FixedArray>::cast(parameters);
1688 Handle<Object> probe(GetParameterMapArg(*parameter_map, key), 1599 Handle<Object> probe(GetParameterMapArg(*parameter_map, key),
1689 obj->GetIsolate()); 1600 obj->GetIsolate());
1690 if (!probe->IsTheHole()) { 1601 if (!probe->IsTheHole()) {
1691 return MaybeHandle<AccessorPair>(); 1602 return MaybeHandle<AccessorPair>();
1692 } else { 1603 } else {
1693 // If not aliased, check the arguments. 1604 // If not aliased, check the arguments.
1694 Handle<FixedArray> arguments(FixedArray::cast(parameter_map->get(1))); 1605 Handle<FixedArray> arguments(FixedArray::cast(parameter_map->get(1)));
1695 return ElementsAccessor::ForArray(arguments) 1606 return ArgumentsAccessor::GetAccessorPairImpl(obj, key, arguments);
1696 ->GetAccessorPair(obj, key, arguments);
1697 } 1607 }
1698 } 1608 }
1699 1609
1700 static void SetLengthImpl(Handle<JSArray> array, uint32_t length, 1610 static void SetLengthImpl(Handle<JSArray> array, uint32_t length,
1701 Handle<FixedArrayBase> parameter_map) { 1611 Handle<FixedArrayBase> parameter_map) {
1702 // Sloppy arguments objects are not arrays. 1612 // Sloppy arguments objects are not arrays.
1703 UNREACHABLE(); 1613 UNREACHABLE();
1704 } 1614 }
1705 1615
1706 virtual void Delete(Handle<JSObject> obj, uint32_t key,
1707 LanguageMode language_mode) final {
1708 Isolate* isolate = obj->GetIsolate();
1709 Handle<FixedArray> parameter_map(FixedArray::cast(obj->elements()));
1710 Handle<Object> probe(GetParameterMapArg(*parameter_map, key), isolate);
1711 if (!probe->IsTheHole()) {
1712 // TODO(kmillikin): We could check if this was the last aliased
1713 // parameter, and revert to normal elements in that case. That
1714 // would enable GC of the context.
1715 parameter_map->set_the_hole(key + 2);
1716 } else {
1717 Handle<FixedArray> arguments(FixedArray::cast(parameter_map->get(1)));
1718 if (arguments->IsDictionary()) {
1719 DictionaryElementsAccessor::DeleteCommon(obj, key, language_mode);
1720 } else {
1721 // It's difficult to access the version of DeleteCommon that is declared
1722 // in the templatized super class, call the concrete implementation in
1723 // the class for the most generalized ElementsKind subclass.
1724 FastHoleyObjectElementsAccessor::DeleteCommon(obj, key, language_mode);
1725 }
1726 }
1727 }
1728
1729 static void CopyElementsImpl(FixedArrayBase* from, uint32_t from_start,
1730 FixedArrayBase* to, ElementsKind from_kind,
1731 uint32_t to_start, int packed_size,
1732 int copy_size) {
1733 DCHECK(!to->IsDictionary());
1734 if (from_kind == DICTIONARY_ELEMENTS) {
1735 CopyDictionaryToObjectElements(from, from_start, to, FAST_HOLEY_ELEMENTS,
1736 to_start, copy_size);
1737 } else {
1738 DCHECK_EQ(FAST_HOLEY_ELEMENTS, from_kind);
1739 CopyObjectToObjectElements(from, from_kind, from_start, to,
1740 FAST_HOLEY_ELEMENTS, to_start, copy_size);
1741 }
1742 }
1743
1744 static uint32_t GetCapacityImpl(JSObject* holder, 1616 static uint32_t GetCapacityImpl(JSObject* holder,
1745 FixedArrayBase* backing_store) { 1617 FixedArrayBase* backing_store) {
1746 FixedArray* parameter_map = FixedArray::cast(backing_store); 1618 FixedArray* parameter_map = FixedArray::cast(backing_store);
1747 FixedArrayBase* arguments = FixedArrayBase::cast(parameter_map->get(1)); 1619 FixedArrayBase* arguments = FixedArrayBase::cast(parameter_map->get(1));
1748 return parameter_map->length() - 2 + 1620 return parameter_map->length() - 2 +
1749 ForArray(arguments)->GetCapacity(holder, arguments); 1621 ArgumentsAccessor::GetCapacityImpl(holder, arguments);
1750 } 1622 }
1751 1623
1752 static bool HasIndexImpl(FixedArrayBase* parameters, uint32_t index) { 1624 static bool HasIndexImpl(FixedArrayBase* parameters, uint32_t index) {
1753 FixedArray* parameter_map = FixedArray::cast(parameters); 1625 FixedArray* parameter_map = FixedArray::cast(parameters);
1754 uint32_t length = parameter_map->length() - 2; 1626 uint32_t length = parameter_map->length() - 2;
1755 if (index < length) { 1627 if (index < length) {
1756 return !GetParameterMapArg(parameter_map, index)->IsTheHole(); 1628 return !GetParameterMapArg(parameter_map, index)->IsTheHole();
1757 } 1629 }
1758 1630
1759 FixedArrayBase* arguments = FixedArrayBase::cast(parameter_map->get(1)); 1631 FixedArrayBase* arguments = FixedArrayBase::cast(parameter_map->get(1));
1760 return ForArray(arguments)->HasIndex(arguments, index - length); 1632 return ArgumentsAccessor::HasIndexImpl(arguments, index - length);
1761 } 1633 }
1762 1634
1763 static uint32_t GetKeyForIndexImpl(FixedArrayBase* parameters, 1635 static uint32_t GetKeyForIndexImpl(FixedArrayBase* parameters,
1764 uint32_t index) { 1636 uint32_t index) {
1765 FixedArray* parameter_map = FixedArray::cast(parameters); 1637 FixedArray* parameter_map = FixedArray::cast(parameters);
1766 uint32_t length = parameter_map->length() - 2; 1638 uint32_t length = parameter_map->length() - 2;
1767 if (index < length) return index; 1639 if (index < length) return index;
1768 1640
1769 FixedArray* arguments = FixedArray::cast(parameter_map->get(1)); 1641 FixedArray* arguments = FixedArray::cast(parameter_map->get(1));
1770 return ForArray(arguments)->GetKeyForIndex(arguments, index - length); 1642 return ArgumentsAccessor::GetKeyForIndexImpl(arguments, index - length);
1771 } 1643 }
1772 1644
1773 static uint32_t GetIndexForKeyImpl(JSObject* holder, 1645 static uint32_t GetIndexForKeyImpl(JSObject* holder,
1774 FixedArrayBase* parameters, uint32_t key) { 1646 FixedArrayBase* parameters, uint32_t key) {
1775 FixedArray* parameter_map = FixedArray::cast(parameters); 1647 FixedArray* parameter_map = FixedArray::cast(parameters);
1776 Object* probe = GetParameterMapArg(parameter_map, key); 1648 Object* probe = GetParameterMapArg(parameter_map, key);
1777 if (!probe->IsTheHole()) return key; 1649 if (!probe->IsTheHole()) return key;
1778 1650
1779 FixedArray* arguments = FixedArray::cast(parameter_map->get(1)); 1651 FixedArray* arguments = FixedArray::cast(parameter_map->get(1));
1780 uint32_t index = ElementsAccessor::ForArray(arguments) 1652 uint32_t index =
1781 ->GetIndexForKey(holder, arguments, key); 1653 ArgumentsAccessor::GetIndexForKeyImpl(holder, arguments, key);
1782 if (index == kMaxUInt32) return index; 1654 if (index == kMaxUInt32) return index;
1783 return (parameter_map->length() - 2) + index; 1655 return (parameter_map->length() - 2) + index;
1784 } 1656 }
1785 1657
1786 static PropertyDetails GetDetailsImpl(FixedArrayBase* parameters, 1658 static PropertyDetails GetDetailsImpl(FixedArrayBase* parameters,
1787 uint32_t index) { 1659 uint32_t index) {
1788 FixedArray* parameter_map = FixedArray::cast(parameters); 1660 FixedArray* parameter_map = FixedArray::cast(parameters);
1789 uint32_t length = parameter_map->length() - 2; 1661 uint32_t length = parameter_map->length() - 2;
1790 if (index < length) { 1662 if (index < length) {
1791 return PropertyDetails(NONE, DATA, 0, PropertyCellType::kNoCell); 1663 return PropertyDetails(NONE, DATA, 0, PropertyCellType::kNoCell);
1792 } 1664 }
1793 index -= length; 1665 index -= length;
1794 FixedArray* arguments = FixedArray::cast(parameter_map->get(1)); 1666 FixedArray* arguments = FixedArray::cast(parameter_map->get(1));
1795 return ElementsAccessor::ForArray(arguments)->GetDetails(arguments, index); 1667 return ArgumentsAccessor::GetDetailsImpl(arguments, index);
1796 } 1668 }
1797 1669
1798 private:
1799 static Object* GetParameterMapArg(FixedArray* parameter_map, uint32_t key) { 1670 static Object* GetParameterMapArg(FixedArray* parameter_map, uint32_t key) {
1800 uint32_t length = parameter_map->length() - 2; 1671 uint32_t length = parameter_map->length() - 2;
1801 return key < length 1672 return key < length
1802 ? parameter_map->get(key + 2) 1673 ? parameter_map->get(key + 2)
1803 : Object::cast(parameter_map->GetHeap()->the_hole_value()); 1674 : Object::cast(parameter_map->GetHeap()->the_hole_value());
1804 } 1675 }
1805 }; 1676 };
1806 1677
1807 1678
1808 ElementsAccessor* ElementsAccessor::ForArray(FixedArrayBase* array) { 1679 class FastSloppyArgumentsElementsAccessor
1809 return elements_accessors_[ElementsKindForArray(array)]; 1680 : public SloppyArgumentsElementsAccessor<
1810 } 1681 FastSloppyArgumentsElementsAccessor, FastHoleyObjectElementsAccessor,
1682 ElementsKindTraits<FAST_SLOPPY_ARGUMENTS_ELEMENTS> > {
1683 public:
1684 friend class SloppyArgumentsElementsAccessor<
1685 FastSloppyArgumentsElementsAccessor, FastHoleyObjectElementsAccessor,
1686 ElementsKindTraits<FAST_SLOPPY_ARGUMENTS_ELEMENTS> >;
1687 friend class ElementsAccessorBase<
1688 FastSloppyArgumentsElementsAccessor,
1689 ElementsKindTraits<FAST_SLOPPY_ARGUMENTS_ELEMENTS> >;
1690 explicit FastSloppyArgumentsElementsAccessor(const char* name)
1691 : SloppyArgumentsElementsAccessor<
1692 FastSloppyArgumentsElementsAccessor,
1693 FastHoleyObjectElementsAccessor,
1694 ElementsKindTraits<FAST_SLOPPY_ARGUMENTS_ELEMENTS> >(name) {}
1695
1696 protected:
1697 static void AddImpl(Handle<JSObject> object, uint32_t key,
1698 Handle<Object> value, PropertyAttributes attributes,
1699 uint32_t new_capacity) {
1700 DCHECK_EQ(NONE, attributes);
1701 Handle<FixedArray> parameter_map(FixedArray::cast(object->elements()));
1702 Handle<FixedArrayBase> old_elements(
1703 FixedArrayBase::cast(parameter_map->get(1)));
1704 if (old_elements->IsSeededNumberDictionary() ||
1705 static_cast<uint32_t>(old_elements->length()) < new_capacity) {
1706 GrowCapacityAndConvertImpl(object, new_capacity);
1707 }
1708 SetImpl(object->elements(), key, *value);
1709 }
1710
1711 static void ReconfigureImpl(Handle<JSObject> object,
1712 Handle<FixedArrayBase> store, uint32_t index,
1713 Handle<Object> value,
1714 PropertyAttributes attributes) {
1715 Handle<SeededNumberDictionary> dictionary =
1716 JSObject::NormalizeElements(object);
1717 FixedArray::cast(*store)->set(1, *dictionary);
1718 uint32_t length = static_cast<uint32_t>(store->length()) - 2;
1719 if (index >= length) {
1720 index = dictionary->FindEntry(index - length) + length;
1721 }
1722 object->GetElementsAccessor()->Reconfigure(object, store, index, value,
1723 attributes);
1724 }
1725
1726 virtual void Delete(Handle<JSObject> obj, uint32_t key,
1727 LanguageMode language_mode) final {
1728 FixedArray* parameter_map = FixedArray::cast(obj->elements());
1729 if (!GetParameterMapArg(parameter_map, key)->IsTheHole()) {
1730 // TODO(kmillikin): We could check if this was the last aliased
1731 // parameter, and revert to normal elements in that case. That
1732 // would enable GC of the context.
1733 parameter_map->set_the_hole(key + 2);
1734 } else {
1735 FastHoleyObjectElementsAccessor::DeleteCommon(obj, key, language_mode);
Igor Sheludko 2015/07/02 13:28:42 You can put the implementation of this to the pare
Toon Verwaest 2015/07/02 13:49:01 Done.
1736 }
1737 }
1738
1739 static void CopyElementsImpl(FixedArrayBase* from, uint32_t from_start,
1740 FixedArrayBase* to, ElementsKind from_kind,
1741 uint32_t to_start, int packed_size,
1742 int copy_size) {
1743 DCHECK(!to->IsDictionary());
1744 if (from_kind == SLOW_SLOPPY_ARGUMENTS_ELEMENTS) {
1745 CopyDictionaryToObjectElements(from, from_start, to, FAST_HOLEY_ELEMENTS,
1746 to_start, copy_size);
1747 } else {
1748 DCHECK_EQ(FAST_SLOPPY_ARGUMENTS_ELEMENTS, from_kind);
1749 CopyObjectToObjectElements(from, FAST_HOLEY_ELEMENTS, from_start, to,
1750 FAST_HOLEY_ELEMENTS, to_start, copy_size);
1751 }
1752 }
1753
1754 static void GrowCapacityAndConvertImpl(Handle<JSObject> object,
1755 uint32_t capacity) {
1756 Handle<FixedArray> parameter_map(FixedArray::cast(object->elements()));
1757 Handle<FixedArray> old_elements(FixedArray::cast(parameter_map->get(1)));
1758 ElementsKind from_kind = object->GetElementsKind();
1759 // This method should only be called if there's a reason to update the
1760 // elements.
1761 DCHECK(from_kind == SLOW_SLOPPY_ARGUMENTS_ELEMENTS ||
1762 static_cast<uint32_t>(old_elements->length()) < capacity);
1763 Handle<FixedArrayBase> elements =
1764 ConvertElementsWithCapacity(object, old_elements, from_kind, capacity);
1765 Handle<Map> new_map = JSObject::GetElementsTransitionMap(
1766 object, FAST_SLOPPY_ARGUMENTS_ELEMENTS);
1767 JSObject::MigrateToMap(object, new_map);
1768 parameter_map->set(1, *elements);
1769 JSObject::ValidateElements(object);
1770 }
1771 };
1811 1772
1812 1773
1813 ElementsAccessor* ElementsAccessor::ForArray(Handle<FixedArrayBase> array) { 1774 class SlowSloppyArgumentsElementsAccessor
1814 return ForArray(*array); 1775 : public SloppyArgumentsElementsAccessor<
1815 } 1776 SlowSloppyArgumentsElementsAccessor, DictionaryElementsAccessor,
1777 ElementsKindTraits<SLOW_SLOPPY_ARGUMENTS_ELEMENTS> > {
1778 public:
1779 friend class ElementsAccessorBase<
1780 SlowSloppyArgumentsElementsAccessor,
1781 ElementsKindTraits<SLOW_SLOPPY_ARGUMENTS_ELEMENTS> >;
1782 friend class SloppyArgumentsElementsAccessor<
1783 SlowSloppyArgumentsElementsAccessor, DictionaryElementsAccessor,
1784 ElementsKindTraits<SLOW_SLOPPY_ARGUMENTS_ELEMENTS> >;
1785 explicit SlowSloppyArgumentsElementsAccessor(const char* name)
1786 : SloppyArgumentsElementsAccessor<
1787 SlowSloppyArgumentsElementsAccessor, DictionaryElementsAccessor,
1788 ElementsKindTraits<SLOW_SLOPPY_ARGUMENTS_ELEMENTS> >(name) {}
1789
1790 protected:
1791 static void AddImpl(Handle<JSObject> object, uint32_t key,
1792 Handle<Object> value, PropertyAttributes attributes,
1793 uint32_t new_capacity) {
1794 Handle<FixedArray> parameter_map(FixedArray::cast(object->elements()));
1795 Handle<FixedArrayBase> old_elements(
1796 FixedArrayBase::cast(parameter_map->get(1)));
1797 Handle<SeededNumberDictionary> dictionary =
1798 old_elements->IsSeededNumberDictionary()
1799 ? Handle<SeededNumberDictionary>::cast(old_elements)
1800 : JSObject::NormalizeElements(object);
1801 PropertyDetails details(attributes, DATA, 0, PropertyCellType::kNoCell);
1802 Handle<SeededNumberDictionary> new_dictionary =
1803 SeededNumberDictionary::AddNumberEntry(dictionary, key, value, details);
1804 if (attributes != NONE) new_dictionary->set_requires_slow_elements();
1805 if (*dictionary != *new_dictionary) {
1806 FixedArray::cast(object->elements())->set(1, *new_dictionary);
1807 }
1808 }
1809
1810 static void ReconfigureImpl(Handle<JSObject> object,
1811 Handle<FixedArrayBase> store, uint32_t index,
1812 Handle<Object> value,
1813 PropertyAttributes attributes) {
1814 Handle<FixedArray> parameter_map = Handle<FixedArray>::cast(store);
1815 uint32_t length = parameter_map->length() - 2;
1816 if (index < length) {
1817 Object* probe = parameter_map->get(index + 2);
1818 DCHECK(!probe->IsTheHole());
1819 Context* context = Context::cast(parameter_map->get(0));
1820 int context_index = Smi::cast(probe)->value();
1821 DCHECK(!context->get(context_index)->IsTheHole());
1822 context->set(context_index, *value);
1823
1824 // Redefining attributes of an aliased element destroys fast aliasing.
1825 parameter_map->set_the_hole(index + 2);
1826 // For elements that are still writable we re-establish slow aliasing.
1827 if ((attributes & READ_ONLY) == 0) {
1828 Isolate* isolate = store->GetIsolate();
1829 value = isolate->factory()->NewAliasedArgumentsEntry(context_index);
1830 }
1831
1832 PropertyDetails details(attributes, DATA, 0, PropertyCellType::kNoCell);
1833 Handle<SeededNumberDictionary> arguments(
1834 SeededNumberDictionary::cast(parameter_map->get(1)));
1835 arguments = SeededNumberDictionary::AddNumberEntry(arguments, index,
1836 value, details);
1837 parameter_map->set(1, *arguments);
1838 } else {
1839 Handle<FixedArrayBase> arguments(
1840 FixedArrayBase::cast(parameter_map->get(1)));
1841 DictionaryElementsAccessor::ReconfigureImpl(
1842 object, arguments, index - length, value, attributes);
1843 }
1844 }
1845
1846 virtual void Delete(Handle<JSObject> obj, uint32_t key,
1847 LanguageMode language_mode) final {
1848 FixedArray* parameter_map = FixedArray::cast(obj->elements());
1849 if (!GetParameterMapArg(parameter_map, key)->IsTheHole()) {
1850 // TODO(kmillikin): We could check if this was the last aliased
1851 // parameter, and revert to normal elements in that case. That
1852 // would enable GC of the context.
1853 parameter_map->set_the_hole(key + 2);
1854 } else {
1855 DictionaryElementsAccessor::DeleteCommon(obj, key, language_mode);
1856 }
1857 }
1858 };
1816 1859
1817 1860
1818 void ElementsAccessor::InitializeOncePerProcess() { 1861 void ElementsAccessor::InitializeOncePerProcess() {
1819 static ElementsAccessor* accessor_array[] = { 1862 static ElementsAccessor* accessor_array[] = {
1820 #define ACCESSOR_ARRAY(Class, Kind, Store) new Class(#Kind), 1863 #define ACCESSOR_ARRAY(Class, Kind, Store) new Class(#Kind),
1821 ELEMENTS_LIST(ACCESSOR_ARRAY) 1864 ELEMENTS_LIST(ACCESSOR_ARRAY)
1822 #undef ACCESSOR_ARRAY 1865 #undef ACCESSOR_ARRAY
1823 }; 1866 };
1824 1867
1825 STATIC_ASSERT((sizeof(accessor_array) / sizeof(*accessor_array)) == 1868 STATIC_ASSERT((sizeof(accessor_array) / sizeof(*accessor_array)) ==
(...skipping 143 matching lines...) Expand 10 before | Expand all | Expand 10 after
1969 break; 2012 break;
1970 } 2013 }
1971 2014
1972 array->set_elements(*elms); 2015 array->set_elements(*elms);
1973 array->set_length(Smi::FromInt(number_of_elements)); 2016 array->set_length(Smi::FromInt(number_of_elements));
1974 return array; 2017 return array;
1975 } 2018 }
1976 2019
1977 } // namespace internal 2020 } // namespace internal
1978 } // namespace v8 2021 } // namespace v8
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698