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

Side by Side Diff: src/elements.cc

Issue 1157093003: Handle Delete of element with LookupIterator (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Rebase, fix all strong-mode handling Created 5 years, 6 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 | « src/elements.h ('k') | src/lookup.h » ('j') | 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 651 matching lines...) Expand 10 before | Expand all | Expand 10 after
662 SetFastElementsCapacityAndLength(array, capacity, length); 662 SetFastElementsCapacityAndLength(array, capacity, length);
663 } 663 }
664 664
665 static void SetFastElementsCapacityAndLength( 665 static void SetFastElementsCapacityAndLength(
666 Handle<JSObject> obj, 666 Handle<JSObject> obj,
667 int capacity, 667 int capacity,
668 int length) { 668 int length) {
669 UNIMPLEMENTED(); 669 UNIMPLEMENTED();
670 } 670 }
671 671
672 MUST_USE_RESULT virtual MaybeHandle<Object> Delete( 672 virtual void Delete(Handle<JSObject> obj, uint32_t key,
673 Handle<JSObject> obj, uint32_t key, 673 LanguageMode language_mode) override = 0;
674 LanguageMode language_mode) override = 0;
675 674
676 static void CopyElementsImpl(FixedArrayBase* from, uint32_t from_start, 675 static void CopyElementsImpl(FixedArrayBase* from, uint32_t from_start,
677 FixedArrayBase* to, ElementsKind from_kind, 676 FixedArrayBase* to, ElementsKind from_kind,
678 uint32_t to_start, int packed_size, 677 uint32_t to_start, int packed_size,
679 int copy_size) { 678 int copy_size) {
680 UNREACHABLE(); 679 UNREACHABLE();
681 } 680 }
682 681
683 virtual void CopyElements(Handle<FixedArrayBase> from, uint32_t from_start, 682 virtual void CopyElements(Handle<FixedArrayBase> from, uint32_t from_start,
684 ElementsKind from_kind, Handle<FixedArrayBase> to, 683 ElementsKind from_kind, Handle<FixedArrayBase> to,
(...skipping 227 matching lines...) Expand 10 before | Expand all | Expand 10 after
912 911
913 // Check whether the backing store should be expanded. 912 // Check whether the backing store should be expanded.
914 uint32_t min = JSObject::NewElementsCapacity(old_capacity); 913 uint32_t min = JSObject::NewElementsCapacity(old_capacity);
915 uint32_t new_capacity = length > min ? length : min; 914 uint32_t new_capacity = length > min ? length : min;
916 FastElementsAccessorSubclass::SetFastElementsCapacityAndLength( 915 FastElementsAccessorSubclass::SetFastElementsCapacityAndLength(
917 array, new_capacity, length); 916 array, new_capacity, length);
918 JSObject::ValidateElements(array); 917 JSObject::ValidateElements(array);
919 return length_object; 918 return length_object;
920 } 919 }
921 920
922 static MaybeHandle<Object> DeleteCommon(Handle<JSObject> obj, uint32_t key, 921 static void DeleteCommon(Handle<JSObject> obj, uint32_t key,
923 LanguageMode language_mode) { 922 LanguageMode language_mode) {
924 DCHECK(obj->HasFastSmiOrObjectElements() || 923 DCHECK(obj->HasFastSmiOrObjectElements() ||
925 obj->HasFastDoubleElements() || 924 obj->HasFastDoubleElements() ||
926 obj->HasFastArgumentsElements()); 925 obj->HasFastArgumentsElements());
927 Isolate* isolate = obj->GetIsolate(); 926 Isolate* isolate = obj->GetIsolate();
928 Heap* heap = obj->GetHeap(); 927 Heap* heap = obj->GetHeap();
929 Handle<FixedArrayBase> elements(obj->elements()); 928 Handle<FixedArrayBase> elements(obj->elements());
930 if (*elements == heap->empty_fixed_array()) { 929 if (*elements == heap->empty_fixed_array()) return;
931 return isolate->factory()->true_value(); 930
932 }
933 Handle<BackingStore> backing_store = Handle<BackingStore>::cast(elements); 931 Handle<BackingStore> backing_store = Handle<BackingStore>::cast(elements);
934 bool is_sloppy_arguments_elements_map = 932 bool is_sloppy_arguments_elements_map =
935 backing_store->map() == heap->sloppy_arguments_elements_map(); 933 backing_store->map() == heap->sloppy_arguments_elements_map();
936 if (is_sloppy_arguments_elements_map) { 934 if (is_sloppy_arguments_elements_map) {
937 backing_store = handle( 935 backing_store = handle(
938 BackingStore::cast(Handle<FixedArray>::cast(backing_store)->get(1)), 936 BackingStore::cast(Handle<FixedArray>::cast(backing_store)->get(1)),
939 isolate); 937 isolate);
940 } 938 }
941 uint32_t length = static_cast<uint32_t>( 939 uint32_t length = static_cast<uint32_t>(
942 obj->IsJSArray() 940 obj->IsJSArray()
943 ? Smi::cast(Handle<JSArray>::cast(obj)->length())->value() 941 ? Smi::cast(Handle<JSArray>::cast(obj)->length())->value()
944 : backing_store->length()); 942 : backing_store->length());
945 if (key < length) { 943 if (key < length) {
946 if (obj->map()->is_strong() && !backing_store->is_the_hole(key)) {
947 if (is_strict(language_mode)) {
948 Handle<Object> name = isolate->factory()->NewNumberFromUint(key);
949 THROW_NEW_ERROR(
950 isolate,
951 NewTypeError(MessageTemplate::kStrongDeleteProperty, obj, name),
952 Object);
953 }
954 return isolate->factory()->false_value();
955 }
956 if (!is_sloppy_arguments_elements_map) { 944 if (!is_sloppy_arguments_elements_map) {
957 ElementsKind kind = KindTraits::Kind; 945 ElementsKind kind = KindTraits::Kind;
958 if (IsFastPackedElementsKind(kind)) { 946 if (IsFastPackedElementsKind(kind)) {
959 JSObject::TransitionElementsKind(obj, GetHoleyElementsKind(kind)); 947 JSObject::TransitionElementsKind(obj, GetHoleyElementsKind(kind));
960 } 948 }
961 if (IsFastSmiOrObjectElementsKind(KindTraits::Kind)) { 949 if (IsFastSmiOrObjectElementsKind(KindTraits::Kind)) {
962 Handle<Object> writable = JSObject::EnsureWritableFastElements(obj); 950 Handle<Object> writable = JSObject::EnsureWritableFastElements(obj);
963 backing_store = Handle<BackingStore>::cast(writable); 951 backing_store = Handle<BackingStore>::cast(writable);
964 } 952 }
965 } 953 }
(...skipping 11 matching lines...) Expand all
977 for (int i = 0; i < backing_store->length(); ++i) { 965 for (int i = 0; i < backing_store->length(); ++i) {
978 if (!backing_store->is_the_hole(i)) ++num_used; 966 if (!backing_store->is_the_hole(i)) ++num_used;
979 // Bail out early if more than 1/4 is used. 967 // Bail out early if more than 1/4 is used.
980 if (4 * num_used > backing_store->length()) break; 968 if (4 * num_used > backing_store->length()) break;
981 } 969 }
982 if (4 * num_used <= backing_store->length()) { 970 if (4 * num_used <= backing_store->length()) {
983 JSObject::NormalizeElements(obj); 971 JSObject::NormalizeElements(obj);
984 } 972 }
985 } 973 }
986 } 974 }
987 return isolate->factory()->true_value();
988 } 975 }
989 976
990 virtual MaybeHandle<Object> Delete(Handle<JSObject> obj, uint32_t key, 977 virtual void Delete(Handle<JSObject> obj, uint32_t key,
991 LanguageMode language_mode) final { 978 LanguageMode language_mode) final {
992 return DeleteCommon(obj, key, language_mode); 979 DeleteCommon(obj, key, language_mode);
993 } 980 }
994 981
995 static bool HasElementImpl( 982 static bool HasElementImpl(
996 Handle<JSObject> holder, 983 Handle<JSObject> holder,
997 uint32_t key, 984 uint32_t key,
998 Handle<FixedArrayBase> backing_store) { 985 Handle<FixedArrayBase> backing_store) {
999 if (key >= static_cast<uint32_t>(backing_store->length())) { 986 if (key >= static_cast<uint32_t>(backing_store->length())) {
1000 return false; 987 return false;
1001 } 988 }
1002 return !Handle<BackingStore>::cast(backing_store)->is_the_hole(key); 989 return !Handle<BackingStore>::cast(backing_store)->is_the_hole(key);
(...skipping 296 matching lines...) Expand 10 before | Expand all | Expand 10 after
1299 1286
1300 MUST_USE_RESULT static MaybeHandle<Object> SetLengthImpl( 1287 MUST_USE_RESULT static MaybeHandle<Object> SetLengthImpl(
1301 Handle<JSObject> obj, 1288 Handle<JSObject> obj,
1302 Handle<Object> length, 1289 Handle<Object> length,
1303 Handle<FixedArrayBase> backing_store) { 1290 Handle<FixedArrayBase> backing_store) {
1304 // External arrays do not support changing their length. 1291 // External arrays do not support changing their length.
1305 UNREACHABLE(); 1292 UNREACHABLE();
1306 return obj; 1293 return obj;
1307 } 1294 }
1308 1295
1309 MUST_USE_RESULT virtual MaybeHandle<Object> Delete( 1296 virtual void Delete(Handle<JSObject> obj, uint32_t key,
1310 Handle<JSObject> obj, uint32_t key, LanguageMode language_mode) final { 1297 LanguageMode language_mode) final {
1311 // External arrays always ignore deletes. 1298 // External arrays always ignore deletes.
1312 return obj->GetIsolate()->factory()->true_value();
1313 } 1299 }
1314 1300
1315 static bool HasElementImpl(Handle<JSObject> holder, uint32_t key, 1301 static bool HasElementImpl(Handle<JSObject> holder, uint32_t key,
1316 Handle<FixedArrayBase> backing_store) { 1302 Handle<FixedArrayBase> backing_store) {
1317 uint32_t capacity = AccessorClass::GetCapacityImpl(*holder, *backing_store); 1303 uint32_t capacity = AccessorClass::GetCapacityImpl(*holder, *backing_store);
1318 return key < capacity; 1304 return key < capacity;
1319 } 1305 }
1320 1306
1321 static uint32_t GetCapacityImpl(JSObject* holder, 1307 static uint32_t GetCapacityImpl(JSObject* holder,
1322 FixedArrayBase* backing_store) { 1308 FixedArrayBase* backing_store) {
(...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after
1402 } 1388 }
1403 } 1389 }
1404 } 1390 }
1405 1391
1406 // Update the number of elements. 1392 // Update the number of elements.
1407 dict->ElementsRemoved(removed_entries); 1393 dict->ElementsRemoved(removed_entries);
1408 } 1394 }
1409 return length_object; 1395 return length_object;
1410 } 1396 }
1411 1397
1412 MUST_USE_RESULT static MaybeHandle<Object> DeleteCommon( 1398 static void DeleteCommon(Handle<JSObject> obj, uint32_t key,
1413 Handle<JSObject> obj, uint32_t key, LanguageMode language_mode) { 1399 LanguageMode language_mode) {
1414 Isolate* isolate = obj->GetIsolate(); 1400 Isolate* isolate = obj->GetIsolate();
1415 Handle<FixedArray> backing_store(FixedArray::cast(obj->elements()), 1401 Handle<FixedArray> backing_store(FixedArray::cast(obj->elements()),
1416 isolate); 1402 isolate);
1417 bool is_arguments = 1403 bool is_arguments =
1418 (obj->GetElementsKind() == SLOPPY_ARGUMENTS_ELEMENTS); 1404 (obj->GetElementsKind() == SLOPPY_ARGUMENTS_ELEMENTS);
1419 if (is_arguments) { 1405 if (is_arguments) {
1420 backing_store = handle(FixedArray::cast(backing_store->get(1)), isolate); 1406 backing_store = handle(FixedArray::cast(backing_store->get(1)), isolate);
1421 } 1407 }
1422 Handle<SeededNumberDictionary> dictionary = 1408 Handle<SeededNumberDictionary> dictionary =
1423 Handle<SeededNumberDictionary>::cast(backing_store); 1409 Handle<SeededNumberDictionary>::cast(backing_store);
1424 int entry = dictionary->FindEntry(key); 1410 int entry = dictionary->FindEntry(key);
1425 if (entry != SeededNumberDictionary::kNotFound) { 1411 if (entry != SeededNumberDictionary::kNotFound) {
1426 Handle<Object> result; 1412 Handle<Object> result =
1427 bool strong = obj->map()->is_strong(); 1413 SeededNumberDictionary::DeleteProperty(dictionary, entry);
1428 if (!strong) { 1414 USE(result);
1429 result = SeededNumberDictionary::DeleteProperty(dictionary, entry); 1415 DCHECK(result->IsTrue());
1430 }
1431 if (strong || *result == *isolate->factory()->false_value()) {
1432 // Fail if the property is not configurable, or on a strong object.
1433 if (is_strict(language_mode)) {
1434 Handle<Object> name = isolate->factory()->NewNumberFromUint(key);
1435 if (strong) {
1436 THROW_NEW_ERROR(
1437 isolate,
1438 NewTypeError(MessageTemplate::kStrongDeleteProperty, obj, name),
1439 Object);
1440 }
1441 THROW_NEW_ERROR(
1442 isolate,
1443 NewTypeError(MessageTemplate::kStrictDeleteProperty, name, obj),
1444 Object);
1445 }
1446 return isolate->factory()->false_value();
1447 }
1448 Handle<FixedArray> new_elements = 1416 Handle<FixedArray> new_elements =
1449 SeededNumberDictionary::Shrink(dictionary, key); 1417 SeededNumberDictionary::Shrink(dictionary, key);
1450 1418
1451 if (is_arguments) { 1419 if (is_arguments) {
1452 FixedArray::cast(obj->elements())->set(1, *new_elements); 1420 FixedArray::cast(obj->elements())->set(1, *new_elements);
1453 } else { 1421 } else {
1454 obj->set_elements(*new_elements); 1422 obj->set_elements(*new_elements);
1455 } 1423 }
1456 } 1424 }
1457 return isolate->factory()->true_value();
1458 } 1425 }
1459 1426
1460 static void CopyElementsImpl(FixedArrayBase* from, uint32_t from_start, 1427 static void CopyElementsImpl(FixedArrayBase* from, uint32_t from_start,
1461 FixedArrayBase* to, ElementsKind from_kind, 1428 FixedArrayBase* to, ElementsKind from_kind,
1462 uint32_t to_start, int packed_size, 1429 uint32_t to_start, int packed_size,
1463 int copy_size) { 1430 int copy_size) {
1464 UNREACHABLE(); 1431 UNREACHABLE();
1465 } 1432 }
1466 1433
1467 1434
1468 protected: 1435 protected:
1469 friend class ElementsAccessorBase<DictionaryElementsAccessor, 1436 friend class ElementsAccessorBase<DictionaryElementsAccessor,
1470 ElementsKindTraits<DICTIONARY_ELEMENTS> >; 1437 ElementsKindTraits<DICTIONARY_ELEMENTS> >;
1471 1438
1472 MUST_USE_RESULT virtual MaybeHandle<Object> Delete( 1439 virtual void Delete(Handle<JSObject> obj, uint32_t key,
1473 Handle<JSObject> obj, uint32_t key, LanguageMode language_mode) final { 1440 LanguageMode language_mode) final {
1474 return DeleteCommon(obj, key, language_mode); 1441 DeleteCommon(obj, key, language_mode);
1475 } 1442 }
1476 1443
1477 static Handle<Object> GetImpl(Handle<JSObject> obj, uint32_t key, 1444 static Handle<Object> GetImpl(Handle<JSObject> obj, uint32_t key,
1478 Handle<FixedArrayBase> store) { 1445 Handle<FixedArrayBase> store) {
1479 Handle<SeededNumberDictionary> backing_store = 1446 Handle<SeededNumberDictionary> backing_store =
1480 Handle<SeededNumberDictionary>::cast(store); 1447 Handle<SeededNumberDictionary>::cast(store);
1481 Isolate* isolate = backing_store->GetIsolate(); 1448 Isolate* isolate = backing_store->GetIsolate();
1482 int entry = backing_store->FindEntry(key); 1449 int entry = backing_store->FindEntry(key);
1483 if (entry != SeededNumberDictionary::kNotFound) { 1450 if (entry != SeededNumberDictionary::kNotFound) {
1484 return handle(backing_store->ValueAt(entry), isolate); 1451 return handle(backing_store->ValueAt(entry), isolate);
(...skipping 139 matching lines...) Expand 10 before | Expand all | Expand 10 after
1624 MUST_USE_RESULT static MaybeHandle<Object> SetLengthImpl( 1591 MUST_USE_RESULT static MaybeHandle<Object> SetLengthImpl(
1625 Handle<JSObject> obj, 1592 Handle<JSObject> obj,
1626 Handle<Object> length, 1593 Handle<Object> length,
1627 Handle<FixedArrayBase> parameter_map) { 1594 Handle<FixedArrayBase> parameter_map) {
1628 // TODO(mstarzinger): This was never implemented but will be used once we 1595 // TODO(mstarzinger): This was never implemented but will be used once we
1629 // correctly implement [[DefineOwnProperty]] on arrays. 1596 // correctly implement [[DefineOwnProperty]] on arrays.
1630 UNIMPLEMENTED(); 1597 UNIMPLEMENTED();
1631 return obj; 1598 return obj;
1632 } 1599 }
1633 1600
1634 MUST_USE_RESULT virtual MaybeHandle<Object> Delete( 1601 virtual void Delete(Handle<JSObject> obj, uint32_t key,
1635 Handle<JSObject> obj, uint32_t key, LanguageMode language_mode) final { 1602 LanguageMode language_mode) final {
1636 Isolate* isolate = obj->GetIsolate(); 1603 Isolate* isolate = obj->GetIsolate();
1637 Handle<FixedArray> parameter_map(FixedArray::cast(obj->elements())); 1604 Handle<FixedArray> parameter_map(FixedArray::cast(obj->elements()));
1638 Handle<Object> probe(GetParameterMapArg(*parameter_map, key), isolate); 1605 Handle<Object> probe(GetParameterMapArg(*parameter_map, key), isolate);
1639 if (!probe->IsTheHole()) { 1606 if (!probe->IsTheHole()) {
1640 // TODO(kmillikin): We could check if this was the last aliased 1607 // TODO(kmillikin): We could check if this was the last aliased
1641 // parameter, and revert to normal elements in that case. That 1608 // parameter, and revert to normal elements in that case. That
1642 // would enable GC of the context. 1609 // would enable GC of the context.
1643 parameter_map->set_the_hole(key + 2); 1610 parameter_map->set_the_hole(key + 2);
1644 } else { 1611 } else {
1645 Handle<FixedArray> arguments(FixedArray::cast(parameter_map->get(1))); 1612 Handle<FixedArray> arguments(FixedArray::cast(parameter_map->get(1)));
1646 if (arguments->IsDictionary()) { 1613 if (arguments->IsDictionary()) {
1647 return DictionaryElementsAccessor::DeleteCommon(obj, key, 1614 DictionaryElementsAccessor::DeleteCommon(obj, key, language_mode);
1648 language_mode);
1649 } else { 1615 } else {
1650 // It's difficult to access the version of DeleteCommon that is declared 1616 // It's difficult to access the version of DeleteCommon that is declared
1651 // in the templatized super class, call the concrete implementation in 1617 // in the templatized super class, call the concrete implementation in
1652 // the class for the most generalized ElementsKind subclass. 1618 // the class for the most generalized ElementsKind subclass.
1653 return FastHoleyObjectElementsAccessor::DeleteCommon(obj, key, 1619 FastHoleyObjectElementsAccessor::DeleteCommon(obj, key, language_mode);
1654 language_mode);
1655 } 1620 }
1656 } 1621 }
1657 return isolate->factory()->true_value();
1658 } 1622 }
1659 1623
1660 static void CopyElementsImpl(FixedArrayBase* from, uint32_t from_start, 1624 static void CopyElementsImpl(FixedArrayBase* from, uint32_t from_start,
1661 FixedArrayBase* to, ElementsKind from_kind, 1625 FixedArrayBase* to, ElementsKind from_kind,
1662 uint32_t to_start, int packed_size, 1626 uint32_t to_start, int packed_size,
1663 int copy_size) { 1627 int copy_size) {
1664 UNREACHABLE(); 1628 UNREACHABLE();
1665 } 1629 }
1666 1630
1667 static uint32_t GetCapacityImpl(JSObject* holder, 1631 static uint32_t GetCapacityImpl(JSObject* holder,
(...skipping 248 matching lines...) Expand 10 before | Expand all | Expand 10 after
1916 break; 1880 break;
1917 } 1881 }
1918 1882
1919 array->set_elements(*elms); 1883 array->set_elements(*elms);
1920 array->set_length(Smi::FromInt(number_of_elements)); 1884 array->set_length(Smi::FromInt(number_of_elements));
1921 return array; 1885 return array;
1922 } 1886 }
1923 1887
1924 } // namespace internal 1888 } // namespace internal
1925 } // namespace v8 1889 } // namespace v8
OLDNEW
« no previous file with comments | « src/elements.h ('k') | src/lookup.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698