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 1019 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1030 typename KindTraits> | 1030 typename KindTraits> |
1031 class FastElementsAccessor | 1031 class FastElementsAccessor |
1032 : public ElementsAccessorBase<FastElementsAccessorSubclass, KindTraits> { | 1032 : public ElementsAccessorBase<FastElementsAccessorSubclass, KindTraits> { |
1033 public: | 1033 public: |
1034 explicit FastElementsAccessor(const char* name) | 1034 explicit FastElementsAccessor(const char* name) |
1035 : ElementsAccessorBase<FastElementsAccessorSubclass, | 1035 : ElementsAccessorBase<FastElementsAccessorSubclass, |
1036 KindTraits>(name) {} | 1036 KindTraits>(name) {} |
1037 | 1037 |
1038 typedef typename KindTraits::BackingStore BackingStore; | 1038 typedef typename KindTraits::BackingStore BackingStore; |
1039 | 1039 |
| 1040 static void DeleteAtEnd(Handle<JSObject> obj, |
| 1041 Handle<BackingStore> backing_store, uint32_t entry) { |
| 1042 uint32_t length = static_cast<uint32_t>(backing_store->length()); |
| 1043 Heap* heap = obj->GetHeap(); |
| 1044 for (; entry > 0; entry--) { |
| 1045 if (!backing_store->is_the_hole(entry - 1)) break; |
| 1046 } |
| 1047 if (entry == 0) { |
| 1048 FixedArray* empty = heap->empty_fixed_array(); |
| 1049 if (obj->HasFastArgumentsElements()) { |
| 1050 FixedArray::cast(obj->elements())->set(1, empty); |
| 1051 } else { |
| 1052 obj->set_elements(empty); |
| 1053 } |
| 1054 return; |
| 1055 } |
| 1056 |
| 1057 heap->RightTrimFixedArray<Heap::CONCURRENT_TO_SWEEPER>(*backing_store, |
| 1058 length - entry); |
| 1059 } |
| 1060 |
1040 static void DeleteCommon(Handle<JSObject> obj, uint32_t entry, | 1061 static void DeleteCommon(Handle<JSObject> obj, uint32_t entry, |
1041 Handle<FixedArrayBase> store) { | 1062 Handle<FixedArrayBase> store) { |
1042 DCHECK(obj->HasFastSmiOrObjectElements() || | 1063 DCHECK(obj->HasFastSmiOrObjectElements() || |
1043 obj->HasFastDoubleElements() || | 1064 obj->HasFastDoubleElements() || |
1044 obj->HasFastArgumentsElements()); | 1065 obj->HasFastArgumentsElements()); |
1045 Handle<BackingStore> backing_store = Handle<BackingStore>::cast(store); | 1066 Handle<BackingStore> backing_store = Handle<BackingStore>::cast(store); |
| 1067 if (!obj->IsJSArray() && |
| 1068 entry == static_cast<uint32_t>(store->length()) - 1) { |
| 1069 DeleteAtEnd(obj, backing_store, entry); |
| 1070 return; |
| 1071 } |
| 1072 |
1046 backing_store->set_the_hole(entry); | 1073 backing_store->set_the_hole(entry); |
1047 | 1074 |
1048 // TODO(verwaest): Move this out of elements.cc. | 1075 // TODO(verwaest): Move this out of elements.cc. |
1049 // If an old space backing store is larger than a certain size and | 1076 // If an old space backing store is larger than a certain size and |
1050 // has too few used values, normalize it. | 1077 // has too few used values, normalize it. |
1051 // To avoid doing the check on every delete we require at least | 1078 // To avoid doing the check on every delete we require at least |
1052 // one adjacent hole to the value being deleted. | 1079 // one adjacent hole to the value being deleted. |
1053 const int kMinLengthForSparsenessCheck = 64; | 1080 const int kMinLengthForSparsenessCheck = 64; |
1054 if (backing_store->length() < kMinLengthForSparsenessCheck) return; | 1081 if (backing_store->length() < kMinLengthForSparsenessCheck) return; |
1055 if (backing_store->GetHeap()->InNewSpace(*backing_store)) return; | 1082 if (backing_store->GetHeap()->InNewSpace(*backing_store)) return; |
1056 uint32_t length = 0; | 1083 uint32_t length = 0; |
1057 if (obj->IsJSArray()) { | 1084 if (obj->IsJSArray()) { |
1058 JSArray::cast(*obj)->length()->ToArrayLength(&length); | 1085 JSArray::cast(*obj)->length()->ToArrayLength(&length); |
1059 } else { | 1086 } else { |
1060 length = static_cast<uint32_t>(store->length()); | 1087 length = static_cast<uint32_t>(store->length()); |
1061 } | 1088 } |
1062 if ((entry > 0 && backing_store->is_the_hole(entry - 1)) || | 1089 if ((entry > 0 && backing_store->is_the_hole(entry - 1)) || |
1063 (entry + 1 < length && backing_store->is_the_hole(entry + 1))) { | 1090 (entry + 1 < length && backing_store->is_the_hole(entry + 1))) { |
| 1091 if (!obj->IsJSArray()) { |
| 1092 uint32_t i; |
| 1093 for (i = entry + 1; i < length; i++) { |
| 1094 if (!backing_store->is_the_hole(i)) break; |
| 1095 } |
| 1096 if (i == length) { |
| 1097 DeleteAtEnd(obj, backing_store, entry); |
| 1098 return; |
| 1099 } |
| 1100 } |
1064 int num_used = 0; | 1101 int num_used = 0; |
1065 for (int i = 0; i < backing_store->length(); ++i) { | 1102 for (int i = 0; i < backing_store->length(); ++i) { |
1066 if (!backing_store->is_the_hole(i)) ++num_used; | 1103 if (!backing_store->is_the_hole(i)) ++num_used; |
1067 // Bail out early if more than 1/4 is used. | 1104 // Bail out early if more than 1/4 is used. |
1068 if (4 * num_used > backing_store->length()) break; | 1105 if (4 * num_used > backing_store->length()) break; |
1069 } | 1106 } |
1070 if (4 * num_used <= backing_store->length()) { | 1107 if (4 * num_used <= backing_store->length()) { |
1071 JSObject::NormalizeElements(obj); | 1108 JSObject::NormalizeElements(obj); |
1072 } | 1109 } |
1073 } | 1110 } |
(...skipping 824 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1898 #define ACCESSOR_DELETE(Class, Kind, Store) delete elements_accessors_[Kind]; | 1935 #define ACCESSOR_DELETE(Class, Kind, Store) delete elements_accessors_[Kind]; |
1899 ELEMENTS_LIST(ACCESSOR_DELETE) | 1936 ELEMENTS_LIST(ACCESSOR_DELETE) |
1900 #undef ACCESSOR_DELETE | 1937 #undef ACCESSOR_DELETE |
1901 elements_accessors_ = NULL; | 1938 elements_accessors_ = NULL; |
1902 } | 1939 } |
1903 | 1940 |
1904 | 1941 |
1905 ElementsAccessor** ElementsAccessor::elements_accessors_ = NULL; | 1942 ElementsAccessor** ElementsAccessor::elements_accessors_ = NULL; |
1906 } // namespace internal | 1943 } // namespace internal |
1907 } // namespace v8 | 1944 } // namespace v8 |
OLD | NEW |