Index: src/objects.cc |
diff --git a/src/objects.cc b/src/objects.cc |
index ae5aa78cae57fc078a87ed41d290a3c9b10a1597..2323484ee565a2bd0b2dbef150c82a1625e71710 100644 |
--- a/src/objects.cc |
+++ b/src/objects.cc |
@@ -8188,10 +8188,13 @@ MaybeObject* JSObject::SetFastElementsCapacityAndLength( |
Map* new_map = NULL; |
if (elements()->map() != heap->non_strict_arguments_elements_map()) { |
Object* object; |
+ // The resized array has FAST_SMI_ONLY_ELEMENTS if the capacity mode forces |
+ // it, or if it's allowed and the old elements array contained only SMIs. |
bool has_fast_smi_only_elements = |
- (set_capacity_mode == kAllowSmiOnlyElements) && |
- (elements()->map()->has_fast_smi_only_elements() || |
- elements() == heap->empty_fixed_array()); |
+ (set_capacity_mode == kForceSmiOnlyElements) || |
+ ((set_capacity_mode == kAllowSmiOnlyElements) && |
+ (elements()->map()->has_fast_smi_only_elements() || |
+ elements() == heap->empty_fixed_array())); |
ElementsKind elements_kind = has_fast_smi_only_elements |
? FAST_SMI_ONLY_ELEMENTS |
: FAST_ELEMENTS; |
@@ -9241,11 +9244,20 @@ MaybeObject* JSObject::SetDictionaryElement(uint32_t index, |
} else { |
new_length = dictionary->max_number_key() + 1; |
} |
- MaybeObject* result = CanConvertToFastDoubleElements() |
+ SetFastElementsCapacityMode set_capacity_mode = FLAG_smi_only_arrays |
+ ? kAllowSmiOnlyElements |
+ : kDontAllowSmiOnlyElements; |
+ bool has_smi_only_elements = false; |
+ bool should_convert_to_fast_double_elements = |
+ ShouldConvertToFastDoubleElements(&has_smi_only_elements); |
+ if (has_smi_only_elements) { |
+ set_capacity_mode = kForceSmiOnlyElements; |
+ } |
+ MaybeObject* result = should_convert_to_fast_double_elements |
? SetFastDoubleElementsCapacityAndLength(new_length, new_length) |
: SetFastElementsCapacityAndLength(new_length, |
new_length, |
- kDontAllowSmiOnlyElements); |
+ set_capacity_mode); |
if (result->IsFailure()) return result; |
#ifdef DEBUG |
if (FLAG_trace_normalization) { |
@@ -9724,17 +9736,25 @@ bool JSObject::ShouldConvertToFastElements() { |
} |
-bool JSObject::CanConvertToFastDoubleElements() { |
+bool JSObject::ShouldConvertToFastDoubleElements( |
+ bool* has_smi_only_elements) { |
+ *has_smi_only_elements = false; |
if (FLAG_unbox_double_arrays) { |
ASSERT(HasDictionaryElements()); |
NumberDictionary* dictionary = NumberDictionary::cast(elements()); |
+ bool found_double = false; |
for (int i = 0; i < dictionary->Capacity(); i++) { |
Object* key = dictionary->KeyAt(i); |
if (key->IsNumber()) { |
- if (!dictionary->ValueAt(i)->IsNumber()) return false; |
+ Object* value = dictionary->ValueAt(i); |
+ if (!value->IsNumber()) return false; |
+ if (!value->IsSmi()) { |
+ found_double = true; |
+ } |
} |
} |
- return true; |
+ *has_smi_only_elements = !found_double; |
+ return found_double; |
} else { |
return false; |
} |