Index: src/runtime.cc |
diff --git a/src/runtime.cc b/src/runtime.cc |
index 67d7c64d1dff1b5f31aaa6069e1e3d5b21fcd1fd..017890580ed67f8716cc030ebe136225b7505110 100644 |
--- a/src/runtime.cc |
+++ b/src/runtime.cc |
@@ -428,6 +428,23 @@ static Handle<Object> CreateObjectLiteralBoilerplate( |
} |
+MaybeObject* TransitionElements(Handle<Object> object, |
+ ElementsKind to_kind, |
+ Isolate* isolate) { |
+ HandleScope scope(isolate); |
+ if (!object->IsJSObject()) return isolate->ThrowIllegalOperation(); |
+ ElementsKind from_kind = |
+ Handle<JSObject>::cast(object)->map()->elements_kind(); |
+ if (Map::IsValidElementsTransition(from_kind, to_kind)) { |
+ Handle<Object> result = JSObject::TransitionElementsKind( |
+ Handle<JSObject>::cast(object), to_kind); |
+ if (result.is_null()) return isolate->ThrowIllegalOperation(); |
+ return *result; |
+ } |
+ return isolate->ThrowIllegalOperation(); |
+} |
+ |
+ |
static const int kSmiOnlyLiteralMinimumLength = 1024; |
@@ -446,25 +463,13 @@ Handle<Object> Runtime::CreateArrayLiteralBoilerplate( |
Handle<FixedArrayBase> constant_elements_values( |
FixedArrayBase::cast(elements->get(1))); |
- ASSERT(FLAG_smi_only_arrays || constant_elements_kind == FAST_ELEMENTS || |
- constant_elements_kind == FAST_SMI_ONLY_ELEMENTS); |
- bool allow_literal_kind_transition = FLAG_smi_only_arrays && |
- constant_elements_kind > object->GetElementsKind(); |
- |
- if (!FLAG_smi_only_arrays && |
- constant_elements_values->length() > kSmiOnlyLiteralMinimumLength && |
- constant_elements_kind != object->GetElementsKind()) { |
- allow_literal_kind_transition = true; |
- } |
- |
- // If the ElementsKind of the constant values of the array literal are less |
- // specific than the ElementsKind of the boilerplate array object, change the |
- // boilerplate array object's map to reflect that kind. |
- if (allow_literal_kind_transition) { |
- Handle<Map> transitioned_array_map = |
- isolate->factory()->GetElementsTransitionMap(object, |
- constant_elements_kind); |
- object->set_map(*transitioned_array_map); |
+ Context* global_context = isolate->context()->global_context(); |
+ if (constant_elements_kind == FAST_SMI_ONLY_ELEMENTS) { |
+ object->set_map(Map::cast(global_context->smi_js_array_map())); |
+ } else if (constant_elements_kind == FAST_DOUBLE_ELEMENTS) { |
+ object->set_map(Map::cast(global_context->double_js_array_map())); |
+ } else { |
+ object->set_map(Map::cast(global_context->object_js_array_map())); |
} |
Handle<FixedArrayBase> copied_elements_values; |
@@ -509,6 +514,16 @@ Handle<Object> Runtime::CreateArrayLiteralBoilerplate( |
} |
object->set_elements(*copied_elements_values); |
object->set_length(Smi::FromInt(copied_elements_values->length())); |
+ |
+ // Ensure that the boilerplate object has FAST_ELEMENTS, unless the flag is |
+ // on or the object is larger than the threshold. |
+ if (!FLAG_smi_only_arrays && |
+ constant_elements_values->length() < kSmiOnlyLiteralMinimumLength) { |
+ if (object->GetElementsKind() != FAST_ELEMENTS) { |
+ CHECK(!TransitionElements(object, FAST_ELEMENTS, isolate)->IsFailure()); |
+ } |
+ } |
+ |
return object; |
} |
@@ -4202,23 +4217,6 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_GetProperty) { |
} |
-MaybeObject* TransitionElements(Handle<Object> object, |
- ElementsKind to_kind, |
- Isolate* isolate) { |
- HandleScope scope(isolate); |
- if (!object->IsJSObject()) return isolate->ThrowIllegalOperation(); |
- ElementsKind from_kind = |
- Handle<JSObject>::cast(object)->map()->elements_kind(); |
- if (Map::IsValidElementsTransition(from_kind, to_kind)) { |
- Handle<Object> result = JSObject::TransitionElementsKind( |
- Handle<JSObject>::cast(object), to_kind); |
- if (result.is_null()) return isolate->ThrowIllegalOperation(); |
- return *result; |
- } |
- return isolate->ThrowIllegalOperation(); |
-} |
- |
- |
// KeyedStringGetProperty is called from KeyedLoadIC::GenerateGeneric. |
RUNTIME_FUNCTION(MaybeObject*, Runtime_KeyedGetProperty) { |
NoHandleAllocation ha; |
@@ -10231,7 +10229,7 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_MoveArrayContents) { |
} else { |
elements_kind = DICTIONARY_ELEMENTS; |
} |
- maybe_new_map = to->GetElementsTransitionMap(elements_kind); |
+ maybe_new_map = to->GetElementsTransitionMap(isolate, elements_kind); |
Object* new_map; |
if (!maybe_new_map->ToObject(&new_map)) return maybe_new_map; |
to->set_map(Map::cast(new_map)); |