From 0071bf92f619ac39d9fd3deed980ea7af96d20ad Mon Sep 17 00:00:00 2001 From: "antonm@chromium.org" Date: Wed, 22 Dec 2010 15:45:48 +0000 Subject: [PATCH] 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 --- src/builtins.cc | 68 +++++++++++++++++++++++-------------------------- 1 file changed, 32 insertions(+), 36 deletions(-) diff --git a/src/builtins.cc b/src/builtins.cc index 21381f15d5..0c76f6944f 100644 --- a/src/builtins.cc +++ b/src/builtins.cc @@ -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;