Do not turn source array elements into writable if doing Array.slice.
Array.slice doesn't mutate original array, so it's fine with read only data. Plus nuke unnecessary cast. Review URL: http://codereview.chromium.org/5972004 git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@6113 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
This commit is contained in:
parent
c5916f552f
commit
0071bf92f6
@ -380,7 +380,7 @@ static inline MaybeObject* EnsureJSArrayWithWritableFastElements(
|
||||
Object* receiver) {
|
||||
if (!receiver->IsJSArray()) return NULL;
|
||||
JSArray* array = JSArray::cast(receiver);
|
||||
HeapObject* elms = HeapObject::cast(array->elements());
|
||||
HeapObject* elms = array->elements();
|
||||
if (elms->map() == Heap::fixed_array_map()) return elms;
|
||||
if (elms->map() == Heap::fixed_cow_array_map()) {
|
||||
return array->EnsureWritableFastElements();
|
||||
@ -613,42 +613,38 @@ BUILTIN(ArraySlice) {
|
||||
Object* receiver = *args.receiver();
|
||||
FixedArray* elms;
|
||||
int len = -1;
|
||||
{ MaybeObject* maybe_elms_obj =
|
||||
EnsureJSArrayWithWritableFastElements(receiver);
|
||||
Object* elms_obj;
|
||||
if (maybe_elms_obj != NULL && maybe_elms_obj->ToObject(&elms_obj)) {
|
||||
if (!IsJSArrayFastElementMovingAllowed(JSArray::cast(receiver))) {
|
||||
return CallJsBuiltin("ArraySlice", args);
|
||||
}
|
||||
elms = FixedArray::cast(elms_obj);
|
||||
JSArray* array = JSArray::cast(receiver);
|
||||
ASSERT(array->HasFastElements());
|
||||
|
||||
len = Smi::cast(array->length())->value();
|
||||
} else {
|
||||
// Array.slice(arguments, ...) is quite a common idiom (notably more
|
||||
// than 50% of invocations in Web apps). Treat it in C++ as well.
|
||||
Map* arguments_map =
|
||||
Top::context()->global_context()->arguments_boilerplate()->map();
|
||||
|
||||
bool is_arguments_object_with_fast_elements =
|
||||
receiver->IsJSObject()
|
||||
&& JSObject::cast(receiver)->map() == arguments_map
|
||||
&& JSObject::cast(receiver)->HasFastElements();
|
||||
if (!is_arguments_object_with_fast_elements) {
|
||||
return CallJsBuiltin("ArraySlice", args);
|
||||
}
|
||||
elms = FixedArray::cast(JSObject::cast(receiver)->elements());
|
||||
len = elms->length();
|
||||
#ifdef DEBUG
|
||||
// Arguments object by construction should have no holes, check it.
|
||||
if (FLAG_enable_slow_asserts) {
|
||||
for (int i = 0; i < len; i++) {
|
||||
ASSERT(elms->get(i) != Heap::the_hole_value());
|
||||
}
|
||||
}
|
||||
#endif
|
||||
if (receiver->IsJSArray()) {
|
||||
JSArray* array = JSArray::cast(receiver);
|
||||
if (!array->HasFastElements() ||
|
||||
!IsJSArrayFastElementMovingAllowed(array)) {
|
||||
return CallJsBuiltin("ArraySlice", args);
|
||||
}
|
||||
|
||||
elms = FixedArray::cast(array->elements());
|
||||
len = Smi::cast(array->length())->value();
|
||||
} else {
|
||||
// Array.slice(arguments, ...) is quite a common idiom (notably more
|
||||
// than 50% of invocations in Web apps). Treat it in C++ as well.
|
||||
Map* arguments_map =
|
||||
Top::context()->global_context()->arguments_boilerplate()->map();
|
||||
|
||||
bool is_arguments_object_with_fast_elements =
|
||||
receiver->IsJSObject()
|
||||
&& JSObject::cast(receiver)->map() == arguments_map
|
||||
&& JSObject::cast(receiver)->HasFastElements();
|
||||
if (!is_arguments_object_with_fast_elements) {
|
||||
return CallJsBuiltin("ArraySlice", args);
|
||||
}
|
||||
elms = FixedArray::cast(JSObject::cast(receiver)->elements());
|
||||
len = elms->length();
|
||||
#ifdef DEBUG
|
||||
// Arguments object by construction should have no holes, check it.
|
||||
if (FLAG_enable_slow_asserts) {
|
||||
for (int i = 0; i < len; i++) {
|
||||
ASSERT(elms->get(i) != Heap::the_hole_value());
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
ASSERT(len >= 0);
|
||||
int n_arguments = args.length() - 1;
|
||||
|
Loading…
Reference in New Issue
Block a user