| OLD | NEW |
| 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 700 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 711 JSObject::PrintElementsTransition(stdout, object, from_kind, old_elements, | 711 JSObject::PrintElementsTransition(stdout, object, from_kind, old_elements, |
| 712 to_kind, elements); | 712 to_kind, elements); |
| 713 } | 713 } |
| 714 } | 714 } |
| 715 | 715 |
| 716 virtual void GrowCapacityAndConvert(Handle<JSObject> object, | 716 virtual void GrowCapacityAndConvert(Handle<JSObject> object, |
| 717 uint32_t capacity) final { | 717 uint32_t capacity) final { |
| 718 ElementsAccessorSubclass::GrowCapacityAndConvertImpl(object, capacity); | 718 ElementsAccessorSubclass::GrowCapacityAndConvertImpl(object, capacity); |
| 719 } | 719 } |
| 720 | 720 |
| 721 virtual void Delete(Handle<JSObject> obj, uint32_t key, | 721 virtual void Delete(Handle<JSObject> obj, uint32_t index) final { |
| 722 LanguageMode language_mode) override = 0; | 722 ElementsAccessorSubclass::DeleteImpl(obj, index); |
| 723 } |
| 723 | 724 |
| 724 static void CopyElementsImpl(FixedArrayBase* from, uint32_t from_start, | 725 static void CopyElementsImpl(FixedArrayBase* from, uint32_t from_start, |
| 725 FixedArrayBase* to, ElementsKind from_kind, | 726 FixedArrayBase* to, ElementsKind from_kind, |
| 726 uint32_t to_start, int packed_size, | 727 uint32_t to_start, int packed_size, |
| 727 int copy_size) { | 728 int copy_size) { |
| 728 UNREACHABLE(); | 729 UNREACHABLE(); |
| 729 } | 730 } |
| 730 | 731 |
| 731 virtual void CopyElements(Handle<FixedArrayBase> from, uint32_t from_start, | 732 virtual void CopyElements(Handle<FixedArrayBase> from, uint32_t from_start, |
| 732 ElementsKind from_kind, Handle<FixedArrayBase> to, | 733 ElementsKind from_kind, Handle<FixedArrayBase> to, |
| (...skipping 236 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 969 } | 970 } |
| 970 | 971 |
| 971 static void CopyElementsImpl(FixedArrayBase* from, uint32_t from_start, | 972 static void CopyElementsImpl(FixedArrayBase* from, uint32_t from_start, |
| 972 FixedArrayBase* to, ElementsKind from_kind, | 973 FixedArrayBase* to, ElementsKind from_kind, |
| 973 uint32_t to_start, int packed_size, | 974 uint32_t to_start, int packed_size, |
| 974 int copy_size) { | 975 int copy_size) { |
| 975 UNREACHABLE(); | 976 UNREACHABLE(); |
| 976 } | 977 } |
| 977 | 978 |
| 978 | 979 |
| 979 static void DeleteCommon(Handle<JSObject> obj, uint32_t key, | 980 static void DeleteImpl(Handle<JSObject> obj, uint32_t index) { |
| 980 LanguageMode language_mode) { | 981 // TODO(verwaest): Remove reliance on key in Shrink. |
| 981 Isolate* isolate = obj->GetIsolate(); | 982 Handle<SeededNumberDictionary> dict( |
| 982 Handle<FixedArray> backing_store(FixedArray::cast(obj->elements()), | 983 SeededNumberDictionary::cast(obj->elements())); |
| 983 isolate); | 984 uint32_t key = GetKeyForIndexImpl(*dict, index); |
| 984 bool is_arguments = obj->HasSloppyArgumentsElements(); | 985 Handle<Object> result = SeededNumberDictionary::DeleteProperty(dict, index); |
| 985 if (is_arguments) { | 986 USE(result); |
| 986 backing_store = handle(FixedArray::cast(backing_store->get(1)), isolate); | 987 DCHECK(result->IsTrue()); |
| 987 } | 988 Handle<FixedArray> new_elements = SeededNumberDictionary::Shrink(dict, key); |
| 988 Handle<SeededNumberDictionary> dictionary = | 989 obj->set_elements(*new_elements); |
| 989 Handle<SeededNumberDictionary>::cast(backing_store); | |
| 990 int entry = dictionary->FindEntry(key); | |
| 991 if (entry != SeededNumberDictionary::kNotFound) { | |
| 992 Handle<Object> result = | |
| 993 SeededNumberDictionary::DeleteProperty(dictionary, entry); | |
| 994 USE(result); | |
| 995 DCHECK(result->IsTrue()); | |
| 996 Handle<FixedArray> new_elements = | |
| 997 SeededNumberDictionary::Shrink(dictionary, key); | |
| 998 | |
| 999 if (is_arguments) { | |
| 1000 FixedArray::cast(obj->elements())->set(1, *new_elements); | |
| 1001 } else { | |
| 1002 obj->set_elements(*new_elements); | |
| 1003 } | |
| 1004 } | |
| 1005 } | |
| 1006 | |
| 1007 virtual void Delete(Handle<JSObject> obj, uint32_t key, | |
| 1008 LanguageMode language_mode) final { | |
| 1009 DeleteCommon(obj, key, language_mode); | |
| 1010 } | 990 } |
| 1011 | 991 |
| 1012 static Handle<Object> GetImpl(Handle<JSObject> obj, uint32_t key, | 992 static Handle<Object> GetImpl(Handle<JSObject> obj, uint32_t key, |
| 1013 Handle<FixedArrayBase> store) { | 993 Handle<FixedArrayBase> store) { |
| 1014 Handle<SeededNumberDictionary> backing_store = | 994 Handle<SeededNumberDictionary> backing_store = |
| 1015 Handle<SeededNumberDictionary>::cast(store); | 995 Handle<SeededNumberDictionary>::cast(store); |
| 1016 Isolate* isolate = backing_store->GetIsolate(); | 996 Isolate* isolate = backing_store->GetIsolate(); |
| 1017 int entry = backing_store->FindEntry(key); | 997 int entry = backing_store->FindEntry(key); |
| 1018 if (entry != SeededNumberDictionary::kNotFound) { | 998 if (entry != SeededNumberDictionary::kNotFound) { |
| 1019 return handle(backing_store->ValueAt(entry), isolate); | 999 return handle(backing_store->ValueAt(entry), isolate); |
| (...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1094 typename KindTraits> | 1074 typename KindTraits> |
| 1095 class FastElementsAccessor | 1075 class FastElementsAccessor |
| 1096 : public ElementsAccessorBase<FastElementsAccessorSubclass, KindTraits> { | 1076 : public ElementsAccessorBase<FastElementsAccessorSubclass, KindTraits> { |
| 1097 public: | 1077 public: |
| 1098 explicit FastElementsAccessor(const char* name) | 1078 explicit FastElementsAccessor(const char* name) |
| 1099 : ElementsAccessorBase<FastElementsAccessorSubclass, | 1079 : ElementsAccessorBase<FastElementsAccessorSubclass, |
| 1100 KindTraits>(name) {} | 1080 KindTraits>(name) {} |
| 1101 | 1081 |
| 1102 typedef typename KindTraits::BackingStore BackingStore; | 1082 typedef typename KindTraits::BackingStore BackingStore; |
| 1103 | 1083 |
| 1104 static void DeleteCommon(Handle<JSObject> obj, uint32_t key, | 1084 static void DeleteCommon(Handle<JSObject> obj, uint32_t index, |
| 1105 LanguageMode language_mode) { | 1085 Handle<FixedArrayBase> store) { |
| 1106 DCHECK(obj->HasFastSmiOrObjectElements() || | 1086 DCHECK(obj->HasFastSmiOrObjectElements() || |
| 1107 obj->HasFastDoubleElements() || | 1087 obj->HasFastDoubleElements() || |
| 1108 obj->HasFastArgumentsElements()); | 1088 obj->HasFastArgumentsElements()); |
| 1109 Isolate* isolate = obj->GetIsolate(); | 1089 Handle<BackingStore> backing_store = Handle<BackingStore>::cast(store); |
| 1110 Heap* heap = obj->GetHeap(); | 1090 backing_store->set_the_hole(index); |
| 1111 Handle<FixedArrayBase> elements(obj->elements()); | |
| 1112 if (*elements == heap->empty_fixed_array()) return; | |
| 1113 | 1091 |
| 1114 Handle<BackingStore> backing_store = Handle<BackingStore>::cast(elements); | 1092 // TODO(verwaest): Move this out of elements.cc. |
| 1115 bool is_sloppy_arguments_elements_map = | 1093 // If an old space backing store is larger than a certain size and |
| 1116 backing_store->map() == heap->sloppy_arguments_elements_map(); | 1094 // has too few used values, normalize it. |
| 1117 if (is_sloppy_arguments_elements_map) { | 1095 // To avoid doing the check on every delete we require at least |
| 1118 backing_store = handle( | 1096 // one adjacent hole to the value being deleted. |
| 1119 BackingStore::cast(Handle<FixedArray>::cast(backing_store)->get(1)), | 1097 const int kMinLengthForSparsenessCheck = 64; |
| 1120 isolate); | 1098 if (backing_store->length() < kMinLengthForSparsenessCheck) return; |
| 1099 if (backing_store->GetHeap()->InNewSpace(*backing_store)) return; |
| 1100 uint32_t length = 0; |
| 1101 if (obj->IsJSArray()) { |
| 1102 JSArray::cast(*obj)->length()->ToArrayLength(&length); |
| 1103 } else { |
| 1104 length = static_cast<uint32_t>(store->length()); |
| 1121 } | 1105 } |
| 1122 uint32_t length = static_cast<uint32_t>( | 1106 if ((index > 0 && backing_store->is_the_hole(index - 1)) || |
| 1123 obj->IsJSArray() | 1107 (index + 1 < length && backing_store->is_the_hole(index + 1))) { |
| 1124 ? Smi::cast(Handle<JSArray>::cast(obj)->length())->value() | 1108 int num_used = 0; |
| 1125 : backing_store->length()); | 1109 for (int i = 0; i < backing_store->length(); ++i) { |
| 1126 if (key < length) { | 1110 if (!backing_store->is_the_hole(i)) ++num_used; |
| 1127 if (!is_sloppy_arguments_elements_map) { | 1111 // Bail out early if more than 1/4 is used. |
| 1128 ElementsKind kind = KindTraits::Kind; | 1112 if (4 * num_used > backing_store->length()) break; |
| 1129 if (IsFastPackedElementsKind(kind)) { | |
| 1130 JSObject::TransitionElementsKind(obj, GetHoleyElementsKind(kind)); | |
| 1131 } | |
| 1132 if (IsFastSmiOrObjectElementsKind(KindTraits::Kind)) { | |
| 1133 Handle<Object> writable = JSObject::EnsureWritableFastElements(obj); | |
| 1134 backing_store = Handle<BackingStore>::cast(writable); | |
| 1135 } | |
| 1136 } | 1113 } |
| 1137 backing_store->set_the_hole(key); | 1114 if (4 * num_used <= backing_store->length()) { |
| 1138 // If an old space backing store is larger than a certain size and | 1115 JSObject::NormalizeElements(obj); |
| 1139 // has too few used values, normalize it. | |
| 1140 // To avoid doing the check on every delete we require at least | |
| 1141 // one adjacent hole to the value being deleted. | |
| 1142 const int kMinLengthForSparsenessCheck = 64; | |
| 1143 if (backing_store->length() >= kMinLengthForSparsenessCheck && | |
| 1144 !heap->InNewSpace(*backing_store) && | |
| 1145 ((key > 0 && backing_store->is_the_hole(key - 1)) || | |
| 1146 (key + 1 < length && backing_store->is_the_hole(key + 1)))) { | |
| 1147 int num_used = 0; | |
| 1148 for (int i = 0; i < backing_store->length(); ++i) { | |
| 1149 if (!backing_store->is_the_hole(i)) ++num_used; | |
| 1150 // Bail out early if more than 1/4 is used. | |
| 1151 if (4 * num_used > backing_store->length()) break; | |
| 1152 } | |
| 1153 if (4 * num_used <= backing_store->length()) { | |
| 1154 JSObject::NormalizeElements(obj); | |
| 1155 } | |
| 1156 } | 1116 } |
| 1157 } | 1117 } |
| 1158 } | 1118 } |
| 1159 | 1119 |
| 1160 static void ReconfigureImpl(Handle<JSObject> object, | 1120 static void ReconfigureImpl(Handle<JSObject> object, |
| 1161 Handle<FixedArrayBase> store, uint32_t index, | 1121 Handle<FixedArrayBase> store, uint32_t index, |
| 1162 Handle<Object> value, | 1122 Handle<Object> value, |
| 1163 PropertyAttributes attributes) { | 1123 PropertyAttributes attributes) { |
| 1164 Handle<SeededNumberDictionary> dictionary = | 1124 Handle<SeededNumberDictionary> dictionary = |
| 1165 JSObject::NormalizeElements(object); | 1125 JSObject::NormalizeElements(object); |
| (...skipping 20 matching lines...) Expand all Loading... |
| 1186 JSObject::TransitionElementsKind(object, to_kind); | 1146 JSObject::TransitionElementsKind(object, to_kind); |
| 1187 } | 1147 } |
| 1188 if (IsFastSmiOrObjectElementsKind(from_kind)) { | 1148 if (IsFastSmiOrObjectElementsKind(from_kind)) { |
| 1189 DCHECK(IsFastSmiOrObjectElementsKind(to_kind)); | 1149 DCHECK(IsFastSmiOrObjectElementsKind(to_kind)); |
| 1190 JSObject::EnsureWritableFastElements(object); | 1150 JSObject::EnsureWritableFastElements(object); |
| 1191 } | 1151 } |
| 1192 } | 1152 } |
| 1193 FastElementsAccessorSubclass::SetImpl(object->elements(), index, *value); | 1153 FastElementsAccessorSubclass::SetImpl(object->elements(), index, *value); |
| 1194 } | 1154 } |
| 1195 | 1155 |
| 1196 virtual void Delete(Handle<JSObject> obj, uint32_t key, | 1156 static void DeleteImpl(Handle<JSObject> obj, uint32_t index) { |
| 1197 LanguageMode language_mode) final { | 1157 ElementsKind kind = KindTraits::Kind; |
| 1198 DeleteCommon(obj, key, language_mode); | 1158 if (IsFastPackedElementsKind(kind)) { |
| 1159 JSObject::TransitionElementsKind(obj, GetHoleyElementsKind(kind)); |
| 1160 } |
| 1161 if (IsFastSmiOrObjectElementsKind(KindTraits::Kind)) { |
| 1162 JSObject::EnsureWritableFastElements(obj); |
| 1163 } |
| 1164 DeleteCommon(obj, index, handle(obj->elements())); |
| 1199 } | 1165 } |
| 1200 | 1166 |
| 1201 static bool HasIndexImpl(FixedArrayBase* backing_store, uint32_t index) { | 1167 static bool HasIndexImpl(FixedArrayBase* backing_store, uint32_t index) { |
| 1202 return !BackingStore::cast(backing_store)->is_the_hole(index); | 1168 return !BackingStore::cast(backing_store)->is_the_hole(index); |
| 1203 } | 1169 } |
| 1204 | 1170 |
| 1205 static void ValidateContents(Handle<JSObject> holder, int length) { | 1171 static void ValidateContents(Handle<JSObject> holder, int length) { |
| 1206 #if DEBUG | 1172 #if DEBUG |
| 1207 Isolate* isolate = holder->GetIsolate(); | 1173 Isolate* isolate = holder->GetIsolate(); |
| 1208 HandleScope scope(isolate); | 1174 HandleScope scope(isolate); |
| (...skipping 220 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1429 uint32_t index) { | 1395 uint32_t index) { |
| 1430 return PropertyDetails(DONT_DELETE, DATA, 0, PropertyCellType::kNoCell); | 1396 return PropertyDetails(DONT_DELETE, DATA, 0, PropertyCellType::kNoCell); |
| 1431 } | 1397 } |
| 1432 | 1398 |
| 1433 static void SetLengthImpl(Handle<JSArray> array, uint32_t length, | 1399 static void SetLengthImpl(Handle<JSArray> array, uint32_t length, |
| 1434 Handle<FixedArrayBase> backing_store) { | 1400 Handle<FixedArrayBase> backing_store) { |
| 1435 // External arrays do not support changing their length. | 1401 // External arrays do not support changing their length. |
| 1436 UNREACHABLE(); | 1402 UNREACHABLE(); |
| 1437 } | 1403 } |
| 1438 | 1404 |
| 1439 virtual void Delete(Handle<JSObject> obj, uint32_t key, | 1405 static void DeleteImpl(Handle<JSObject> obj, uint32_t index) { |
| 1440 LanguageMode language_mode) final { | 1406 UNREACHABLE(); |
| 1441 // External arrays always ignore deletes. | |
| 1442 } | 1407 } |
| 1443 | 1408 |
| 1444 static uint32_t GetIndexForKeyImpl(JSObject* holder, | 1409 static uint32_t GetIndexForKeyImpl(JSObject* holder, |
| 1445 FixedArrayBase* backing_store, | 1410 FixedArrayBase* backing_store, |
| 1446 uint32_t key) { | 1411 uint32_t key) { |
| 1447 return key < AccessorClass::GetCapacityImpl(holder, backing_store) | 1412 return key < AccessorClass::GetCapacityImpl(holder, backing_store) |
| 1448 ? key | 1413 ? key |
| 1449 : kMaxUInt32; | 1414 : kMaxUInt32; |
| 1450 } | 1415 } |
| 1451 | 1416 |
| (...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1507 Context* context = Context::cast(parameter_map->get(0)); | 1472 Context* context = Context::cast(parameter_map->get(0)); |
| 1508 int context_index = entry->aliased_context_slot(); | 1473 int context_index = entry->aliased_context_slot(); |
| 1509 DCHECK(!context->get(context_index)->IsTheHole()); | 1474 DCHECK(!context->get(context_index)->IsTheHole()); |
| 1510 return handle(context->get(context_index), isolate); | 1475 return handle(context->get(context_index), isolate); |
| 1511 } else { | 1476 } else { |
| 1512 return result; | 1477 return result; |
| 1513 } | 1478 } |
| 1514 } | 1479 } |
| 1515 } | 1480 } |
| 1516 | 1481 |
| 1517 virtual void Delete(Handle<JSObject> obj, uint32_t key, | |
| 1518 LanguageMode language_mode) final { | |
| 1519 FixedArray* parameter_map = FixedArray::cast(obj->elements()); | |
| 1520 if (!GetParameterMapArg(parameter_map, key)->IsTheHole()) { | |
| 1521 // TODO(kmillikin): We could check if this was the last aliased | |
| 1522 // parameter, and revert to normal elements in that case. That | |
| 1523 // would enable GC of the context. | |
| 1524 parameter_map->set_the_hole(key + 2); | |
| 1525 } else { | |
| 1526 ArgumentsAccessor::DeleteCommon(obj, key, language_mode); | |
| 1527 } | |
| 1528 } | |
| 1529 | |
| 1530 static void GrowCapacityAndConvertImpl(Handle<JSObject> object, | 1482 static void GrowCapacityAndConvertImpl(Handle<JSObject> object, |
| 1531 uint32_t capacity) { | 1483 uint32_t capacity) { |
| 1532 UNREACHABLE(); | 1484 UNREACHABLE(); |
| 1533 } | 1485 } |
| 1534 | 1486 |
| 1535 static void SetImpl(FixedArrayBase* store, uint32_t key, Object* value) { | 1487 static void SetImpl(FixedArrayBase* store, uint32_t key, Object* value) { |
| 1536 FixedArray* parameter_map = FixedArray::cast(store); | 1488 FixedArray* parameter_map = FixedArray::cast(store); |
| 1537 Object* probe = GetParameterMapArg(parameter_map, key); | 1489 Object* probe = GetParameterMapArg(parameter_map, key); |
| 1538 if (!probe->IsTheHole()) { | 1490 if (!probe->IsTheHole()) { |
| 1539 Context* context = Context::cast(parameter_map->get(0)); | 1491 Context* context = Context::cast(parameter_map->get(0)); |
| (...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1605 FixedArray* arguments = FixedArray::cast(parameter_map->get(1)); | 1557 FixedArray* arguments = FixedArray::cast(parameter_map->get(1)); |
| 1606 return ArgumentsAccessor::GetDetailsImpl(arguments, index); | 1558 return ArgumentsAccessor::GetDetailsImpl(arguments, index); |
| 1607 } | 1559 } |
| 1608 | 1560 |
| 1609 static Object* GetParameterMapArg(FixedArray* parameter_map, uint32_t key) { | 1561 static Object* GetParameterMapArg(FixedArray* parameter_map, uint32_t key) { |
| 1610 uint32_t length = parameter_map->length() - 2; | 1562 uint32_t length = parameter_map->length() - 2; |
| 1611 return key < length | 1563 return key < length |
| 1612 ? parameter_map->get(key + 2) | 1564 ? parameter_map->get(key + 2) |
| 1613 : Object::cast(parameter_map->GetHeap()->the_hole_value()); | 1565 : Object::cast(parameter_map->GetHeap()->the_hole_value()); |
| 1614 } | 1566 } |
| 1567 |
| 1568 static void DeleteImpl(Handle<JSObject> obj, uint32_t index) { |
| 1569 FixedArray* parameter_map = FixedArray::cast(obj->elements()); |
| 1570 uint32_t length = static_cast<uint32_t>(parameter_map->length()) - 2; |
| 1571 if (index < length) { |
| 1572 // TODO(kmillikin): We could check if this was the last aliased |
| 1573 // parameter, and revert to normal elements in that case. That |
| 1574 // would enable GC of the context. |
| 1575 parameter_map->set_the_hole(index + 2); |
| 1576 } else { |
| 1577 SloppyArgumentsElementsAccessorSubclass::DeleteFromArguments( |
| 1578 obj, index - length); |
| 1579 } |
| 1580 } |
| 1615 }; | 1581 }; |
| 1616 | 1582 |
| 1617 | 1583 |
| 1618 class SlowSloppyArgumentsElementsAccessor | 1584 class SlowSloppyArgumentsElementsAccessor |
| 1619 : public SloppyArgumentsElementsAccessor< | 1585 : public SloppyArgumentsElementsAccessor< |
| 1620 SlowSloppyArgumentsElementsAccessor, DictionaryElementsAccessor, | 1586 SlowSloppyArgumentsElementsAccessor, DictionaryElementsAccessor, |
| 1621 ElementsKindTraits<SLOW_SLOPPY_ARGUMENTS_ELEMENTS> > { | 1587 ElementsKindTraits<SLOW_SLOPPY_ARGUMENTS_ELEMENTS> > { |
| 1622 public: | 1588 public: |
| 1623 explicit SlowSloppyArgumentsElementsAccessor(const char* name) | 1589 explicit SlowSloppyArgumentsElementsAccessor(const char* name) |
| 1624 : SloppyArgumentsElementsAccessor< | 1590 : SloppyArgumentsElementsAccessor< |
| 1625 SlowSloppyArgumentsElementsAccessor, DictionaryElementsAccessor, | 1591 SlowSloppyArgumentsElementsAccessor, DictionaryElementsAccessor, |
| 1626 ElementsKindTraits<SLOW_SLOPPY_ARGUMENTS_ELEMENTS> >(name) {} | 1592 ElementsKindTraits<SLOW_SLOPPY_ARGUMENTS_ELEMENTS> >(name) {} |
| 1627 | 1593 |
| 1594 static void DeleteFromArguments(Handle<JSObject> obj, uint32_t index) { |
| 1595 Handle<FixedArray> parameter_map(FixedArray::cast(obj->elements())); |
| 1596 Handle<SeededNumberDictionary> dict( |
| 1597 SeededNumberDictionary::cast(parameter_map->get(1))); |
| 1598 // TODO(verwaest): Remove reliance on key in Shrink. |
| 1599 uint32_t key = GetKeyForIndexImpl(*dict, index); |
| 1600 Handle<Object> result = SeededNumberDictionary::DeleteProperty(dict, index); |
| 1601 USE(result); |
| 1602 DCHECK(result->IsTrue()); |
| 1603 Handle<FixedArray> new_elements = SeededNumberDictionary::Shrink(dict, key); |
| 1604 parameter_map->set(1, *new_elements); |
| 1605 } |
| 1606 |
| 1628 static void AddImpl(Handle<JSObject> object, uint32_t key, | 1607 static void AddImpl(Handle<JSObject> object, uint32_t key, |
| 1629 Handle<Object> value, PropertyAttributes attributes, | 1608 Handle<Object> value, PropertyAttributes attributes, |
| 1630 uint32_t new_capacity) { | 1609 uint32_t new_capacity) { |
| 1631 Handle<FixedArray> parameter_map(FixedArray::cast(object->elements())); | 1610 Handle<FixedArray> parameter_map(FixedArray::cast(object->elements())); |
| 1632 Handle<FixedArrayBase> old_elements( | 1611 Handle<FixedArrayBase> old_elements( |
| 1633 FixedArrayBase::cast(parameter_map->get(1))); | 1612 FixedArrayBase::cast(parameter_map->get(1))); |
| 1634 Handle<SeededNumberDictionary> dictionary = | 1613 Handle<SeededNumberDictionary> dictionary = |
| 1635 old_elements->IsSeededNumberDictionary() | 1614 old_elements->IsSeededNumberDictionary() |
| 1636 ? Handle<SeededNumberDictionary>::cast(old_elements) | 1615 ? Handle<SeededNumberDictionary>::cast(old_elements) |
| 1637 : JSObject::NormalizeElements(object); | 1616 : JSObject::NormalizeElements(object); |
| (...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1686 : public SloppyArgumentsElementsAccessor< | 1665 : public SloppyArgumentsElementsAccessor< |
| 1687 FastSloppyArgumentsElementsAccessor, FastHoleyObjectElementsAccessor, | 1666 FastSloppyArgumentsElementsAccessor, FastHoleyObjectElementsAccessor, |
| 1688 ElementsKindTraits<FAST_SLOPPY_ARGUMENTS_ELEMENTS> > { | 1667 ElementsKindTraits<FAST_SLOPPY_ARGUMENTS_ELEMENTS> > { |
| 1689 public: | 1668 public: |
| 1690 explicit FastSloppyArgumentsElementsAccessor(const char* name) | 1669 explicit FastSloppyArgumentsElementsAccessor(const char* name) |
| 1691 : SloppyArgumentsElementsAccessor< | 1670 : SloppyArgumentsElementsAccessor< |
| 1692 FastSloppyArgumentsElementsAccessor, | 1671 FastSloppyArgumentsElementsAccessor, |
| 1693 FastHoleyObjectElementsAccessor, | 1672 FastHoleyObjectElementsAccessor, |
| 1694 ElementsKindTraits<FAST_SLOPPY_ARGUMENTS_ELEMENTS> >(name) {} | 1673 ElementsKindTraits<FAST_SLOPPY_ARGUMENTS_ELEMENTS> >(name) {} |
| 1695 | 1674 |
| 1675 static void DeleteFromArguments(Handle<JSObject> obj, uint32_t index) { |
| 1676 FixedArray* parameter_map = FixedArray::cast(obj->elements()); |
| 1677 Handle<FixedArray> arguments(FixedArray::cast(parameter_map->get(1))); |
| 1678 FastHoleyObjectElementsAccessor::DeleteCommon(obj, index, arguments); |
| 1679 } |
| 1680 |
| 1696 static void AddImpl(Handle<JSObject> object, uint32_t key, | 1681 static void AddImpl(Handle<JSObject> object, uint32_t key, |
| 1697 Handle<Object> value, PropertyAttributes attributes, | 1682 Handle<Object> value, PropertyAttributes attributes, |
| 1698 uint32_t new_capacity) { | 1683 uint32_t new_capacity) { |
| 1699 DCHECK_EQ(NONE, attributes); | 1684 DCHECK_EQ(NONE, attributes); |
| 1700 Handle<FixedArray> parameter_map(FixedArray::cast(object->elements())); | 1685 Handle<FixedArray> parameter_map(FixedArray::cast(object->elements())); |
| 1701 Handle<FixedArrayBase> old_elements( | 1686 Handle<FixedArrayBase> old_elements( |
| 1702 FixedArrayBase::cast(parameter_map->get(1))); | 1687 FixedArrayBase::cast(parameter_map->get(1))); |
| 1703 if (old_elements->IsSeededNumberDictionary() || | 1688 if (old_elements->IsSeededNumberDictionary() || |
| 1704 static_cast<uint32_t>(old_elements->length()) < new_capacity) { | 1689 static_cast<uint32_t>(old_elements->length()) < new_capacity) { |
| 1705 GrowCapacityAndConvertImpl(object, new_capacity); | 1690 GrowCapacityAndConvertImpl(object, new_capacity); |
| (...skipping 205 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1911 break; | 1896 break; |
| 1912 } | 1897 } |
| 1913 | 1898 |
| 1914 array->set_elements(*elms); | 1899 array->set_elements(*elms); |
| 1915 array->set_length(Smi::FromInt(number_of_elements)); | 1900 array->set_length(Smi::FromInt(number_of_elements)); |
| 1916 return array; | 1901 return array; |
| 1917 } | 1902 } |
| 1918 | 1903 |
| 1919 } // namespace internal | 1904 } // namespace internal |
| 1920 } // namespace v8 | 1905 } // namespace v8 |
| OLD | NEW |