Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(47)

Unified Diff: src/builtins.cc

Issue 1716833002: [runtime] Speed up C++ version of ArrayPush (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: add TODO for Toon's comment Created 4 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « no previous file | src/debug/liveedit.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/builtins.cc
diff --git a/src/builtins.cc b/src/builtins.cc
index ae07df23cbc6bbf4f5eec43268608c8bd67aaa4c..5fd258a605b5fb6c3d3e313fb241f71d8a25dc68 100644
--- a/src/builtins.cc
+++ b/src/builtins.cc
@@ -238,55 +238,57 @@ inline bool IsJSArrayFastElementMovingAllowed(Isolate* isolate,
return PrototypeHasNoElements(&iter);
}
-
-// Returns empty handle if not applicable.
+// Returns |false| if not applicable.
MUST_USE_RESULT
-inline MaybeHandle<FixedArrayBase> EnsureJSArrayWithWritableFastElements(
- Isolate* isolate, Handle<Object> receiver, Arguments* args,
- int first_added_arg) {
- // We explicitly add a HandleScope to avoid creating several copies of the
- // same handle which would otherwise cause issue when left-trimming later-on.
- HandleScope scope(isolate);
- if (!receiver->IsJSArray()) return MaybeHandle<FixedArrayBase>();
+inline bool EnsureJSArrayWithWritableFastElements(Isolate* isolate,
+ Handle<Object> receiver,
+ Arguments* args,
+ int first_added_arg) {
+ if (!receiver->IsJSArray()) return false;
Handle<JSArray> array = Handle<JSArray>::cast(receiver);
// If there may be elements accessors in the prototype chain, the fast path
// cannot be used if there arguments to add to the array.
Heap* heap = isolate->heap();
if (args != NULL && !IsJSArrayFastElementMovingAllowed(isolate, *array)) {
- return MaybeHandle<FixedArrayBase>();
+ return false;
}
- if (array->map()->is_observed()) return MaybeHandle<FixedArrayBase>();
- if (!array->map()->is_extensible()) return MaybeHandle<FixedArrayBase>();
- Handle<FixedArrayBase> elms(array->elements(), isolate);
- Map* map = elms->map();
+ if (array->map()->is_observed()) return false;
+ if (!array->map()->is_extensible()) return false;
+ Map* map = array->elements()->map();
if (map == heap->fixed_array_map()) {
if (args == NULL || array->HasFastObjectElements()) {
- return scope.CloseAndEscape(elms);
+ return true;
}
} else if (map == heap->fixed_cow_array_map()) {
- elms = JSObject::EnsureWritableFastElements(array);
+ // Use a short-lived HandleScope to avoid creating several copies of the
+ // elements handle which would cause issues when left-trimming later-on.
+ HandleScope scope(isolate);
+ // TODO(jkummerow/verwaest): Move this call (or this entire function?)
+ // into the ElementsAccessor so it's only done when needed (e.g. ArrayPush
+ // can skip it because it must grow the backing store anyway).
+ JSObject::EnsureWritableFastElements(array);
if (args == NULL || array->HasFastObjectElements()) {
- return scope.CloseAndEscape(elms);
+ return true;
}
} else if (map == heap->fixed_double_array_map()) {
if (args == NULL) {
- return scope.CloseAndEscape(elms);
+ return true;
}
} else {
- return MaybeHandle<FixedArrayBase>();
+ return false;
}
// Adding elements to the array prototype would break code that makes sure
// it has no elements. Handle that elsewhere.
if (isolate->IsAnyInitialArrayPrototype(array)) {
- return MaybeHandle<FixedArrayBase>();
+ return false;
}
// Need to ensure that the arguments passed in args can be contained in
// the array.
int args_length = args->length();
if (first_added_arg >= args_length) {
- return scope.CloseAndEscape(elms);
+ return true;
}
ElementsKind origin_kind = array->map()->elements_kind();
@@ -309,10 +311,12 @@ inline MaybeHandle<FixedArrayBase> EnsureJSArrayWithWritableFastElements(
}
}
if (target_kind != origin_kind) {
+ // Use a short-lived HandleScope to avoid creating several copies of the
+ // elements handle which would cause issues when left-trimming later-on.
+ HandleScope scope(isolate);
JSObject::TransitionElementsKind(array, target_kind);
- elms = handle(array->elements(), isolate);
}
- return scope.CloseAndEscape(elms);
+ return true;
}
@@ -352,10 +356,7 @@ BUILTIN(EmptyFunction) { return isolate->heap()->undefined_value(); }
BUILTIN(ArrayPush) {
HandleScope scope(isolate);
Handle<Object> receiver = args.receiver();
- MaybeHandle<FixedArrayBase> maybe_elms_obj =
- EnsureJSArrayWithWritableFastElements(isolate, receiver, &args, 1);
- Handle<FixedArrayBase> elms_obj;
- if (!maybe_elms_obj.ToHandle(&elms_obj)) {
+ if (!EnsureJSArrayWithWritableFastElements(isolate, receiver, &args, 1)) {
return CallJsIntrinsic(isolate, isolate->array_push(), args);
}
// Fast Elements Path
@@ -365,13 +366,14 @@ BUILTIN(ArrayPush) {
if (push_size == 0) {
return Smi::FromInt(len);
}
- if (push_size > 0 &&
- JSArray::WouldChangeReadOnlyLength(array, len + push_size)) {
+ DCHECK(push_size > 0);
+ if (JSArray::HasReadOnlyLength(array)) {
return CallJsIntrinsic(isolate, isolate->array_push(), args);
}
DCHECK(!array->map()->is_observed());
ElementsAccessor* accessor = array->GetElementsAccessor();
- int new_length = accessor->Push(array, elms_obj, &args, push_size);
+ int new_length = accessor->Push(array, handle(array->elements(), isolate),
+ &args, push_size);
return Smi::FromInt(new_length);
}
@@ -379,10 +381,7 @@ BUILTIN(ArrayPush) {
BUILTIN(ArrayPop) {
HandleScope scope(isolate);
Handle<Object> receiver = args.receiver();
- MaybeHandle<FixedArrayBase> maybe_elms_obj =
- EnsureJSArrayWithWritableFastElements(isolate, receiver, NULL, 0);
- Handle<FixedArrayBase> elms_obj;
- if (!maybe_elms_obj.ToHandle(&elms_obj)) {
+ if (!EnsureJSArrayWithWritableFastElements(isolate, receiver, NULL, 0)) {
return CallJsIntrinsic(isolate, isolate->array_pop(), args);
}
@@ -399,7 +398,8 @@ BUILTIN(ArrayPop) {
Handle<Object> result;
if (IsJSArrayFastElementMovingAllowed(isolate, JSArray::cast(*receiver))) {
// Fast Elements Path
- result = array->GetElementsAccessor()->Pop(array, elms_obj);
+ result = array->GetElementsAccessor()->Pop(
+ array, handle(array->elements(), isolate));
} else {
// Use Slow Lookup otherwise
uint32_t new_length = len - 1;
@@ -415,10 +415,7 @@ BUILTIN(ArrayShift) {
HandleScope scope(isolate);
Heap* heap = isolate->heap();
Handle<Object> receiver = args.receiver();
- MaybeHandle<FixedArrayBase> maybe_elms_obj =
- EnsureJSArrayWithWritableFastElements(isolate, receiver, NULL, 0);
- Handle<FixedArrayBase> elms_obj;
- if (!maybe_elms_obj.ToHandle(&elms_obj) ||
+ if (!EnsureJSArrayWithWritableFastElements(isolate, receiver, NULL, 0) ||
!IsJSArrayFastElementMovingAllowed(isolate, JSArray::cast(*receiver))) {
return CallJsIntrinsic(isolate, isolate->array_shift(), args);
}
@@ -432,7 +429,8 @@ BUILTIN(ArrayShift) {
return CallJsIntrinsic(isolate, isolate->array_shift(), args);
}
- Handle<Object> first = array->GetElementsAccessor()->Shift(array, elms_obj);
+ Handle<Object> first = array->GetElementsAccessor()->Shift(
+ array, handle(array->elements(), isolate));
return *first;
}
@@ -440,10 +438,7 @@ BUILTIN(ArrayShift) {
BUILTIN(ArrayUnshift) {
HandleScope scope(isolate);
Handle<Object> receiver = args.receiver();
- MaybeHandle<FixedArrayBase> maybe_elms_obj =
- EnsureJSArrayWithWritableFastElements(isolate, receiver, &args, 1);
- Handle<FixedArrayBase> elms_obj;
- if (!maybe_elms_obj.ToHandle(&elms_obj)) {
+ if (!EnsureJSArrayWithWritableFastElements(isolate, receiver, &args, 1)) {
return CallJsIntrinsic(isolate, isolate->array_unshift(), args);
}
Handle<JSArray> array = Handle<JSArray>::cast(receiver);
@@ -461,7 +456,8 @@ BUILTIN(ArrayUnshift) {
}
ElementsAccessor* accessor = array->GetElementsAccessor();
- int new_length = accessor->Unshift(array, elms_obj, &args, to_add);
+ int new_length = accessor->Unshift(array, handle(array->elements(), isolate),
+ &args, to_add);
return Smi::FromInt(new_length);
}
@@ -558,13 +554,10 @@ BUILTIN(ArraySlice) {
BUILTIN(ArraySplice) {
HandleScope scope(isolate);
Handle<Object> receiver = args.receiver();
- MaybeHandle<FixedArrayBase> maybe_elms_obj =
- EnsureJSArrayWithWritableFastElements(isolate, receiver, &args, 3);
- Handle<FixedArrayBase> elms_obj;
- if (!maybe_elms_obj.ToHandle(&elms_obj) ||
- // If this is a subclass of Array, then call out to JS
+ if (!EnsureJSArrayWithWritableFastElements(isolate, receiver, &args, 3) ||
+ // If this is a subclass of Array, then call out to JS.
!JSArray::cast(*receiver)->map()->new_target_is_base() ||
- // If anything with @@species has been messed with, call out to JS
+ // If anything with @@species has been messed with, call out to JS.
!isolate->IsArraySpeciesLookupChainIntact()) {
return CallJsIntrinsic(isolate, isolate->array_splice(), args);
}
@@ -613,8 +606,9 @@ BUILTIN(ArraySplice) {
return CallJsIntrinsic(isolate, isolate->array_splice(), args);
}
ElementsAccessor* accessor = array->GetElementsAccessor();
- Handle<JSArray> result_array = accessor->Splice(
- array, elms_obj, actual_start, actual_delete_count, &args, add_count);
+ Handle<JSArray> result_array =
+ accessor->Splice(array, handle(array->elements(), isolate), actual_start,
+ actual_delete_count, &args, add_count);
return *result_array;
}
« no previous file with comments | « no previous file | src/debug/liveedit.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698