Index: src/runtime.cc |
diff --git a/src/runtime.cc b/src/runtime.cc |
index e473f3718903283c150c873e45a0142398a8996d..66c477fa46d82701834cccdd95246e0c140b314b 100644 |
--- a/src/runtime.cc |
+++ b/src/runtime.cc |
@@ -177,6 +177,7 @@ MUST_USE_RESULT static MaybeObject* DeepCopyBoilerplate(Isolate* isolate, |
// Pixel elements cannot be created using an object literal. |
ASSERT(!copy->HasExternalArrayElements()); |
switch (copy->GetElementsKind()) { |
+ case FAST_SMI_ONLY_ELEMENTS: |
case FAST_ELEMENTS: { |
FixedArray* elements = FixedArray::cast(copy->elements()); |
if (elements->map() == heap->fixed_cow_array_map()) { |
@@ -189,6 +190,9 @@ MUST_USE_RESULT static MaybeObject* DeepCopyBoilerplate(Isolate* isolate, |
} else { |
for (int i = 0; i < elements->length(); i++) { |
Object* value = elements->get(i); |
+ ASSERT(value->IsSmi() || |
+ value->IsTheHole() || |
+ (copy->GetElementsKind() == FAST_ELEMENTS)); |
if (value->IsJSObject()) { |
JSObject* js_object = JSObject::cast(value); |
{ MaybeObject* maybe_result = DeepCopyBoilerplate(isolate, |
@@ -432,6 +436,7 @@ static Handle<Object> CreateArrayLiteralBoilerplate( |
is_cow ? elements : isolate->factory()->CopyFixedArray(elements); |
Handle<FixedArray> content = Handle<FixedArray>::cast(copied_elements); |
+ bool has_non_constant_subexpression = true; |
if (is_cow) { |
#ifdef DEBUG |
// Copy-on-write arrays must be shallow (and simple). |
@@ -449,12 +454,21 @@ static Handle<Object> CreateArrayLiteralBoilerplate( |
CreateLiteralBoilerplate(isolate, literals, fa); |
if (result.is_null()) return result; |
content->set(i, *result); |
+ } else { |
+ has_non_constant_subexpression = true; |
} |
} |
} |
// Set the elements. |
- Handle<JSArray>::cast(object)->SetContent(*content); |
+ Handle<JSArray> js_object(Handle<JSArray>::cast(object)); |
+ isolate->factory()->SetContent(js_object, content); |
+ |
+ // To simplify the code that fills in non-constant expressions, assume that |
+ // any array literal that has non-constant expressions has non smi elements. |
+ if (has_non_constant_subexpression && js_object->HasFastSmiOnlyElements()) { |
+ isolate->factory()->EnsureCanContainNonSmiElements(js_object); |
+ } |
return object; |
} |
@@ -2287,7 +2301,8 @@ class FixedArrayBuilder { |
public: |
explicit FixedArrayBuilder(Isolate* isolate, int initial_capacity) |
: array_(isolate->factory()->NewFixedArrayWithHoles(initial_capacity)), |
- length_(0) { |
+ length_(0), |
+ has_non_smi_elements_(false) { |
// Require a non-zero initial size. Ensures that doubling the size to |
// extend the array will work. |
ASSERT(initial_capacity > 0); |
@@ -2295,7 +2310,8 @@ class FixedArrayBuilder { |
explicit FixedArrayBuilder(Handle<FixedArray> backing_store) |
: array_(backing_store), |
- length_(0) { |
+ length_(0), |
+ has_non_smi_elements_(false) { |
// Require a non-zero initial size. Ensures that doubling the size to |
// extend the array will work. |
ASSERT(backing_store->length() > 0); |
@@ -2323,12 +2339,15 @@ class FixedArrayBuilder { |
} |
void Add(Object* value) { |
+ ASSERT(!value->IsSmi()); |
ASSERT(length_ < capacity()); |
array_->set(length_, value); |
length_++; |
+ has_non_smi_elements_ = true; |
} |
void Add(Smi* value) { |
+ ASSERT(value->IsSmi()); |
ASSERT(length_ < capacity()); |
array_->set(length_, value); |
length_++; |
@@ -2353,7 +2372,7 @@ class FixedArrayBuilder { |
} |
Handle<JSArray> ToJSArray(Handle<JSArray> target_array) { |
- target_array->set_elements(*array_); |
+ FACTORY->SetContent(target_array, array_); |
target_array->set_length(Smi::FromInt(length_)); |
return target_array; |
} |
@@ -2361,6 +2380,7 @@ class FixedArrayBuilder { |
private: |
Handle<FixedArray> array_; |
int length_; |
+ bool has_non_smi_elements_; |
}; |
@@ -6190,6 +6210,8 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_StringSplit) { |
int part_count = indices.length(); |
Handle<JSArray> result = isolate->factory()->NewJSArray(part_count); |
+ MaybeObject* maybe_result = result->EnsureCanContainNonSmiElements(); |
+ if (maybe_result->IsFailure()) return maybe_result; |
result->set_length(Smi::FromInt(part_count)); |
ASSERT(result->HasFastElements()); |
@@ -6564,6 +6586,9 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_StringBuilderConcat) { |
// This assumption is used by the slice encoding in one or two smis. |
ASSERT(Smi::kMaxValue >= String::kMaxLength); |
+ MaybeObject* maybe_result = array->EnsureCanContainNonSmiElements(); |
+ if (maybe_result->IsFailure()) return maybe_result; |
+ |
int special_length = special->length(); |
if (!array->HasFastElements()) { |
return isolate->Throw(isolate->heap()->illegal_argument_symbol()); |
@@ -6791,7 +6816,8 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_SparseJoinWithSeparator) { |
NoHandleAllocation ha; |
ASSERT(args.length() == 3); |
CONVERT_CHECKED(JSArray, elements_array, args[0]); |
- RUNTIME_ASSERT(elements_array->HasFastElements()); |
+ RUNTIME_ASSERT(elements_array->HasFastElements() || |
+ elements_array->HasFastSmiOnlyElements()); |
CONVERT_NUMBER_CHECKED(uint32_t, array_length, Uint32, args[1]); |
CONVERT_CHECKED(String, separator, args[2]); |
// elements_array is fast-mode JSarray of alternating positions |
@@ -9047,6 +9073,10 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_DateParseString) { |
FlattenString(str); |
CONVERT_ARG_CHECKED(JSArray, output, 1); |
+ |
+ MaybeObject* maybe_result_array = |
+ output->EnsureCanContainNonSmiElements(); |
+ if (maybe_result_array->IsFailure()) return maybe_result_array; |
RUNTIME_ASSERT(output->HasFastElements()); |
AssertNoAllocation no_allocation; |
@@ -9347,7 +9377,7 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_PushIfAbsent) { |
ASSERT(args.length() == 2); |
CONVERT_CHECKED(JSArray, array, args[0]); |
CONVERT_CHECKED(JSObject, element, args[1]); |
- RUNTIME_ASSERT(array->HasFastElements()); |
+ RUNTIME_ASSERT(array->HasFastElements() || array->HasFastSmiOnlyElements()); |
int length = Smi::cast(array->length())->value(); |
FixedArray* elements = FixedArray::cast(array->elements()); |
for (int i = 0; i < length; i++) { |
@@ -9578,6 +9608,7 @@ static void CollectElementIndices(Handle<JSObject> object, |
List<uint32_t>* indices) { |
ElementsKind kind = object->GetElementsKind(); |
switch (kind) { |
+ case FAST_SMI_ONLY_ELEMENTS: |
case FAST_ELEMENTS: { |
Handle<FixedArray> elements(FixedArray::cast(object->elements())); |
uint32_t length = static_cast<uint32_t>(elements->length()); |
@@ -9697,6 +9728,7 @@ static bool IterateElements(Isolate* isolate, |
ArrayConcatVisitor* visitor) { |
uint32_t length = static_cast<uint32_t>(receiver->length()->Number()); |
switch (receiver->GetElementsKind()) { |
+ case FAST_SMI_ONLY_ELEMENTS: |
case FAST_ELEMENTS: { |
// Run through the elements FixedArray and use HasElement and GetElement |
// to check the prototype for missing elements. |
@@ -10020,7 +10052,9 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_GetArrayKeys) { |
} |
return *isolate->factory()->NewJSArrayWithElements(keys); |
} else { |
- ASSERT(array->HasFastElements() || array->HasFastDoubleElements()); |
+ ASSERT(array->HasFastElements() || |
+ array->HasFastSmiOnlyElements() || |
+ array->HasFastDoubleElements()); |
Handle<FixedArray> single_interval = isolate->factory()->NewFixedArray(2); |
// -1 means start of array. |
single_interval->set(0, Smi::FromInt(-1)); |
@@ -11922,7 +11956,7 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_DebugGetLoadedScripts) { |
// Return result as a JS array. |
Handle<JSObject> result = |
isolate->factory()->NewJSObject(isolate->array_function()); |
- Handle<JSArray>::cast(result)->SetContent(*instances); |
+ isolate->factory()->SetContent(Handle<JSArray>::cast(result), instances); |
return *result; |
} |
@@ -12039,12 +12073,10 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_DebugReferencedBy) { |
// Return result as JS array. |
Object* result; |
- { MaybeObject* maybe_result = isolate->heap()->AllocateJSObject( |
+ MaybeObject* maybe_result = isolate->heap()->AllocateJSObject( |
isolate->context()->global_context()->array_function()); |
- if (!maybe_result->ToObject(&result)) return maybe_result; |
- } |
- JSArray::cast(result)->SetContent(instances); |
- return result; |
+ if (!maybe_result->ToObject(&result)) return maybe_result; |
+ return JSArray::cast(result)->SetContent(instances); |
} |
@@ -12112,8 +12144,7 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_DebugConstructedBy) { |
isolate->context()->global_context()->array_function()); |
if (!maybe_result->ToObject(&result)) return maybe_result; |
} |
- JSArray::cast(result)->SetContent(instances); |
- return result; |
+ return JSArray::cast(result)->SetContent(instances); |
} |
@@ -13068,6 +13099,7 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_IS_VAR) { |
return isolate->heap()->ToBoolean(obj->Has##Name()); \ |
} |
+ELEMENTS_KIND_CHECK_RUNTIME_FUNCTION(FastSmiOnlyElements) |
ELEMENTS_KIND_CHECK_RUNTIME_FUNCTION(FastElements) |
ELEMENTS_KIND_CHECK_RUNTIME_FUNCTION(FastDoubleElements) |
ELEMENTS_KIND_CHECK_RUNTIME_FUNCTION(DictionaryElements) |