Index: src/elements.cc |
diff --git a/src/elements.cc b/src/elements.cc |
index 20d4264deff660e667670759ccc64a1879476918..9e03bfb688e3d08a79ea6ec588bc2ee252e70424 100644 |
--- a/src/elements.cc |
+++ b/src/elements.cc |
@@ -1708,107 +1708,87 @@ void ElementsAccessor::TearDown() { |
template <typename ElementsAccessorSubclass, typename ElementsKindTraits> |
-MUST_USE_RESULT |
-MaybeHandle<Object> ElementsAccessorBase<ElementsAccessorSubclass, |
- ElementsKindTraits>:: |
- SetLengthImpl(Handle<JSObject> obj, |
- Handle<Object> length, |
- Handle<FixedArrayBase> backing_store) { |
- Isolate* isolate = obj->GetIsolate(); |
+MUST_USE_RESULT MaybeHandle<Object> ElementsAccessorBase< |
+ ElementsAccessorSubclass, |
+ ElementsKindTraits>::SetLengthImpl(Handle<JSObject> obj, |
+ Handle<Object> length_obj, |
+ Handle<FixedArrayBase> backing_store) { |
Handle<JSArray> array = Handle<JSArray>::cast(obj); |
- // Fast case: The new length fits into a Smi. |
- Handle<Object> smi_length; |
- |
- if (Object::ToSmi(isolate, length).ToHandle(&smi_length) && |
- smi_length->IsSmi()) { |
- const int value = Handle<Smi>::cast(smi_length)->value(); |
- if (value >= 0) { |
- Handle<Object> new_length = ElementsAccessorSubclass:: |
- SetLengthWithoutNormalize(backing_store, array, smi_length, value); |
- DCHECK(!new_length.is_null()); |
- |
- // even though the proposed length was a smi, new_length could |
- // still be a heap number because SetLengthWithoutNormalize doesn't |
- // allow the array length property to drop below the index of |
- // non-deletable elements. |
- DCHECK(new_length->IsSmi() || new_length->IsHeapNumber() || |
- new_length->IsUndefined()); |
- if (new_length->IsSmi()) { |
- array->set_length(*Handle<Smi>::cast(new_length)); |
- return array; |
- } else if (new_length->IsHeapNumber()) { |
- array->set_length(*new_length); |
- return array; |
- } |
- } else { |
- return ThrowArrayLengthRangeError(isolate); |
+ uint32_t length = 0; |
+ CHECK(length_obj->ToArrayLength(&length)); |
+ // Fast case: length fits in a smi. |
+ if (length <= Smi::kMaxValue) { |
+ Handle<Smi> smi(Smi::FromInt(length), obj->GetIsolate()); |
+ Handle<Object> new_length = |
+ ElementsAccessorSubclass::SetLengthWithoutNormalize(backing_store, |
+ array, smi, length); |
+ DCHECK(!new_length.is_null()); |
+ |
+ // Even though the proposed length was a smi, new_length could |
+ // still be a heap number because SetLengthWithoutNormalize doesn't |
+ // allow the array length property to drop below the index of |
+ // non-deletable elements. |
+ DCHECK(new_length->IsSmi() || new_length->IsHeapNumber() || |
+ new_length->IsUndefined()); |
+ if (new_length->IsSmi()) { |
+ array->set_length(*Handle<Smi>::cast(new_length)); |
+ return array; |
+ } else if (new_length->IsHeapNumber()) { |
+ array->set_length(*new_length); |
+ return array; |
} |
} |
// Slow case: The new length does not fit into a Smi or conversion |
// to slow elements is needed for other reasons. |
- if (length->IsNumber()) { |
- uint32_t value; |
- if (length->ToArrayLength(&value)) { |
- Handle<SeededNumberDictionary> dictionary = |
- JSObject::NormalizeElements(array); |
- DCHECK(!dictionary.is_null()); |
- |
- Handle<Object> new_length = DictionaryElementsAccessor:: |
- SetLengthWithoutNormalize(dictionary, array, length, value); |
- DCHECK(!new_length.is_null()); |
- |
- DCHECK(new_length->IsNumber()); |
- array->set_length(*new_length); |
- return array; |
- } else { |
- return ThrowArrayLengthRangeError(isolate); |
- } |
- } |
+ Handle<SeededNumberDictionary> dictionary = |
+ JSObject::NormalizeElements(array); |
+ DCHECK(!dictionary.is_null()); |
- // Fall-back case: The new length is not a number so make the array |
- // size one and set only element to length. |
- Handle<FixedArray> new_backing_store = isolate->factory()->NewFixedArray(1); |
- new_backing_store->set(0, *length); |
- JSArray::SetContent(array, new_backing_store); |
+ Handle<Object> new_length = |
+ DictionaryElementsAccessor::SetLengthWithoutNormalize(dictionary, array, |
+ length_obj, length); |
+ DCHECK(!new_length.is_null()); |
+ |
+ DCHECK(new_length->IsNumber()); |
+ array->set_length(*new_length); |
return array; |
} |
MaybeHandle<Object> ArrayConstructInitializeElements(Handle<JSArray> array, |
Arguments* args) { |
- // Optimize the case where there is one argument and the argument is a |
- // small smi. |
- if (args->length() == 1) { |
- Handle<Object> obj = args->at<Object>(0); |
- if (obj->IsSmi()) { |
- int len = Handle<Smi>::cast(obj)->value(); |
- if (len > 0 && len < JSObject::kInitialMaxFastElementArray) { |
- ElementsKind elements_kind = array->GetElementsKind(); |
- JSArray::Initialize(array, len, len); |
- |
- if (!IsFastHoleyElementsKind(elements_kind)) { |
- elements_kind = GetHoleyElementsKind(elements_kind); |
- JSObject::TransitionElementsKind(array, elements_kind); |
- } |
- return array; |
- } else if (len == 0) { |
- JSArray::Initialize(array, JSArray::kPreallocatedArrayElements); |
- return array; |
+ if (args->length() == 0) { |
+ // Optimize the case where there are no parameters passed. |
+ JSArray::Initialize(array, JSArray::kPreallocatedArrayElements); |
+ return array; |
+ |
+ } else if (args->length() == 1 && args->at<Object>(0)->IsNumber()) { |
+ uint32_t length; |
+ if (!args->at<Object>(0)->ToArrayLength(&length)) { |
+ return ThrowArrayLengthRangeError(array->GetIsolate()); |
+ } |
+ |
+ // Optimize the case where there is one argument and the argument is a small |
+ // smi. |
+ if (length > 0 && length < JSObject::kInitialMaxFastElementArray) { |
+ ElementsKind elements_kind = array->GetElementsKind(); |
+ JSArray::Initialize(array, length, length); |
+ |
+ if (!IsFastHoleyElementsKind(elements_kind)) { |
+ elements_kind = GetHoleyElementsKind(elements_kind); |
+ JSObject::TransitionElementsKind(array, elements_kind); |
} |
+ return array; |
+ } else if (length == 0) { |
+ JSArray::Initialize(array, JSArray::kPreallocatedArrayElements); |
+ return array; |
} |
// Take the argument as the length. |
JSArray::Initialize(array, 0); |
- |
- return JSArray::SetElementsLength(array, obj); |
- } |
- |
- // Optimize the case where there are no parameters passed. |
- if (args->length() == 0) { |
- JSArray::Initialize(array, JSArray::kPreallocatedArrayElements); |
- return array; |
+ return JSArray::SetElementsLength(array, args->at<Object>(0)); |
} |
Factory* factory = array->GetIsolate()->factory(); |