Index: src/elements.cc |
diff --git a/src/elements.cc b/src/elements.cc |
index 3080c0376e317fdf2ebea005be7ddf756b037124..f1cddc45fd7b8104b073ec1d616ec10669608ad2 100644 |
--- a/src/elements.cc |
+++ b/src/elements.cc |
@@ -862,55 +862,6 @@ class FastElementsAccessor |
typedef typename KindTraits::BackingStore BackingStore; |
- // Adjusts the length of the fast backing store. |
- static uint32_t SetLengthWithoutNormalize( |
- Handle<FixedArrayBase> backing_store, Handle<JSArray> array, |
- uint32_t length) { |
- Isolate* isolate = array->GetIsolate(); |
- uint32_t old_capacity = backing_store->length(); |
- Handle<Object> old_length(array->length(), isolate); |
- bool same_or_smaller_size = old_length->IsSmi() && |
- static_cast<uint32_t>(Handle<Smi>::cast(old_length)->value()) >= length; |
- ElementsKind kind = array->GetElementsKind(); |
- |
- if (!same_or_smaller_size && IsFastElementsKind(kind) && |
- !IsFastHoleyElementsKind(kind)) { |
- kind = GetHoleyElementsKind(kind); |
- JSObject::TransitionElementsKind(array, kind); |
- } |
- |
- // Check whether the backing store should be shrunk. |
- if (length <= old_capacity) { |
- if (array->HasFastSmiOrObjectElements()) { |
- backing_store = JSObject::EnsureWritableFastElements(array); |
- } |
- if (2 * length <= old_capacity) { |
- // If more than half the elements won't be used, trim the array. |
- if (length == 0) { |
- array->initialize_elements(); |
- } else { |
- isolate->heap()->RightTrimFixedArray<Heap::CONCURRENT_TO_SWEEPER>( |
- *backing_store, old_capacity - length); |
- } |
- } else { |
- // Otherwise, fill the unused tail with holes. |
- int old_length = FastD2IChecked(array->length()->Number()); |
- for (int i = length; i < old_length; i++) { |
- Handle<BackingStore>::cast(backing_store)->set_the_hole(i); |
- } |
- } |
- return length; |
- } |
- |
- // Check whether the backing store should be expanded. |
- uint32_t min = JSObject::NewElementsCapacity(old_capacity); |
- uint32_t new_capacity = length > min ? length : min; |
- FastElementsAccessorSubclass::SetFastElementsCapacityAndLength( |
- array, new_capacity, length); |
- JSObject::ValidateElements(array); |
- return length; |
- } |
- |
static void DeleteCommon(Handle<JSObject> obj, uint32_t key, |
LanguageMode language_mode) { |
DCHECK(obj->HasFastSmiOrObjectElements() || |
@@ -1321,33 +1272,13 @@ class DictionaryElementsAccessor |
static void SetLengthImpl(Handle<JSArray> array, uint32_t length, |
Handle<FixedArrayBase> backing_store) { |
- uint32_t new_length = |
- SetLengthWithoutNormalize(backing_store, array, length); |
- // SetLengthWithoutNormalize does not allow length to drop below the last |
- // non-deletable element. |
- DCHECK_GE(new_length, length); |
- if (new_length <= Smi::kMaxValue) { |
- array->set_length(Smi::FromInt(new_length)); |
- } else { |
- Isolate* isolate = array->GetIsolate(); |
- Handle<Object> length_obj = |
- isolate->factory()->NewNumberFromUint(new_length); |
- array->set_length(*length_obj); |
- } |
- } |
- |
- // Adjusts the length of the dictionary backing store and returns the new |
- // length according to ES5 section 15.4.5.2 behavior. |
- static uint32_t SetLengthWithoutNormalize(Handle<FixedArrayBase> store, |
- Handle<JSArray> array, |
- uint32_t length) { |
Handle<SeededNumberDictionary> dict = |
- Handle<SeededNumberDictionary>::cast(store); |
+ Handle<SeededNumberDictionary>::cast(backing_store); |
Isolate* isolate = array->GetIsolate(); |
int capacity = dict->Capacity(); |
uint32_t old_length = 0; |
CHECK(array->length()->ToArrayLength(&old_length)); |
- if (length < old_length) { |
+ if (dict->requires_slow_elements() && length < old_length) { |
// Find last non-deletable element in range of elements to be |
// deleted and adjust range accordingly. |
for (int i = 0; i < capacity; i++) { |
@@ -1385,7 +1316,14 @@ class DictionaryElementsAccessor |
// Update the number of elements. |
dict->ElementsRemoved(removed_entries); |
} |
- return length; |
+ |
+ if (length <= Smi::kMaxValue) { |
+ array->set_length(Smi::FromInt(length)); |
+ } else { |
+ Isolate* isolate = array->GetIsolate(); |
brucedawson
2015/06/22 17:12:35
This declaration of 'isolate' shadows a seemingly
|
+ Handle<Object> length_obj = isolate->factory()->NewNumberFromUint(length); |
+ array->set_length(*length_obj); |
+ } |
} |
static void DeleteCommon(Handle<JSObject> obj, uint32_t key, |
@@ -1707,23 +1645,46 @@ template <typename ElementsAccessorSubclass, typename ElementsKindTraits> |
void ElementsAccessorBase<ElementsAccessorSubclass, ElementsKindTraits>:: |
SetLengthImpl(Handle<JSArray> array, uint32_t length, |
Handle<FixedArrayBase> backing_store) { |
- // Normalize if the length does not fit in a smi. Fast mode arrays only |
- // support smi length. |
- if (JSArray::SetLengthWouldNormalize(array->GetHeap(), length)) { |
- Handle<SeededNumberDictionary> dictionary = |
- JSObject::NormalizeElements(array); |
- DCHECK(!dictionary.is_null()); |
- DictionaryElementsAccessor::SetLengthImpl(array, length, dictionary); |
+ DCHECK(!JSArray::SetLengthWouldNormalize(array->GetHeap(), length)); |
+ DCHECK(IsFastElementsKind(array->GetElementsKind())); |
+ uint32_t old_length = 0; |
+ CHECK(array->length()->ToArrayIndex(&old_length)); |
+ |
+ if (old_length < length) { |
+ ElementsKind kind = array->GetElementsKind(); |
+ if (!IsFastHoleyElementsKind(kind)) { |
+ kind = GetHoleyElementsKind(kind); |
+ JSObject::TransitionElementsKind(array, kind); |
+ } |
+ } |
+ |
+ // Check whether the backing store should be shrunk. |
+ uint32_t capacity = backing_store->length(); |
+ if (length == 0) { |
+ array->initialize_elements(); |
+ } else if (length <= capacity) { |
+ if (array->HasFastSmiOrObjectElements()) { |
+ backing_store = JSObject::EnsureWritableFastElements(array); |
+ } |
+ if (2 * length <= capacity) { |
+ // If more than half the elements won't be used, trim the array. |
+ array->GetHeap()->RightTrimFixedArray<Heap::CONCURRENT_TO_SWEEPER>( |
+ *backing_store, capacity - length); |
+ } else { |
+ // Otherwise, fill the unused tail with holes. |
+ for (uint32_t i = length; i < old_length; i++) { |
+ BackingStore::cast(*backing_store)->set_the_hole(i); |
+ } |
+ } |
} else { |
-#ifdef DEBUG |
- uint32_t max = Smi::kMaxValue; |
- DCHECK_LE(length, max); |
-#endif |
- uint32_t new_length = ElementsAccessorSubclass::SetLengthWithoutNormalize( |
- backing_store, array, length); |
- DCHECK_EQ(length, new_length); |
- array->set_length(Smi::FromInt(new_length)); |
+ // Check whether the backing store should be expanded. |
+ capacity = Max(length, JSObject::NewElementsCapacity(capacity)); |
+ ElementsAccessorSubclass::SetFastElementsCapacityAndLength(array, capacity, |
+ length); |
} |
+ |
+ array->set_length(Smi::FromInt(length)); |
+ JSObject::ValidateElements(array); |
} |