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

Unified Diff: src/builtins.cc

Issue 1770793002: Move EnsureFastWritableElements into the elements accessor. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Created 4 years, 9 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/elements.h » ('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 18f398d7d6192fdb8f9ed8a90f60309dbaa4e5bc..a85edc834251da617f2d8170cd9ba42b119f39bb 100644
--- a/src/builtins.cc
+++ b/src/builtins.cc
@@ -248,51 +248,25 @@ inline bool EnsureJSArrayWithWritableFastElements(Isolate* isolate,
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)) {
+ if (args != nullptr && !IsJSArrayFastElementMovingAllowed(isolate, *array)) {
return false;
}
+ ElementsKind origin_kind = array->map()->elements_kind();
+ if (IsDictionaryElementsKind(origin_kind)) return false;
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 true;
- }
- } else if (map == heap->fixed_cow_array_map()) {
- // 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 true;
- }
- } else if (map == heap->fixed_double_array_map()) {
- if (args == NULL) {
- return true;
- }
- } else {
- return false;
- }
+ if (args == nullptr) return true;
// Adding elements to the array prototype would break code that makes sure
// it has no elements. Handle that elsewhere.
- if (isolate->IsAnyInitialArrayPrototype(array)) {
- return false;
- }
+ if (isolate->IsAnyInitialArrayPrototype(array)) 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 true;
- }
+ if (first_added_arg >= args_length) return true;
- ElementsKind origin_kind = array->map()->elements_kind();
- DCHECK(!IsFastObjectElementsKind(origin_kind));
+ if (IsFastObjectElementsKind(origin_kind)) return true;
ElementsKind target_kind = origin_kind;
{
DisallowHeapAllocation no_gc;
@@ -437,20 +411,20 @@ BUILTIN(ArrayPush) {
return CallJsIntrinsic(isolate, isolate->array_push(), args);
}
// Fast Elements Path
- int push_size = args.length() - 1;
+ int to_add = args.length() - 1;
Handle<JSArray> array = Handle<JSArray>::cast(receiver);
int len = Smi::cast(array->length())->value();
- if (push_size == 0) {
- return Smi::FromInt(len);
- }
- DCHECK(push_size > 0);
+ if (to_add == 0) return Smi::FromInt(len);
+
+ // Currently fixed arrays cannot grow too big, so we should never hit this.
+ DCHECK_LE(to_add, Smi::kMaxValue - Smi::cast(array->length())->value());
+
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, handle(array->elements(), isolate),
- &args, push_size);
+ int new_length = accessor->Push(array, &args, to_add);
return Smi::FromInt(new_length);
}
@@ -458,7 +432,7 @@ BUILTIN(ArrayPush) {
BUILTIN(ArrayPop) {
HandleScope scope(isolate);
Handle<Object> receiver = args.receiver();
- if (!EnsureJSArrayWithWritableFastElements(isolate, receiver, NULL, 0)) {
+ if (!EnsureJSArrayWithWritableFastElements(isolate, receiver, nullptr, 0)) {
return CallJsIntrinsic(isolate, isolate->array_pop(), args);
}
@@ -475,8 +449,7 @@ BUILTIN(ArrayPop) {
Handle<Object> result;
if (IsJSArrayFastElementMovingAllowed(isolate, JSArray::cast(*receiver))) {
// Fast Elements Path
- result = array->GetElementsAccessor()->Pop(
- array, handle(array->elements(), isolate));
+ result = array->GetElementsAccessor()->Pop(array);
} else {
// Use Slow Lookup otherwise
uint32_t new_length = len - 1;
@@ -492,7 +465,7 @@ BUILTIN(ArrayShift) {
HandleScope scope(isolate);
Heap* heap = isolate->heap();
Handle<Object> receiver = args.receiver();
- if (!EnsureJSArrayWithWritableFastElements(isolate, receiver, NULL, 0) ||
+ if (!EnsureJSArrayWithWritableFastElements(isolate, receiver, nullptr, 0) ||
!IsJSArrayFastElementMovingAllowed(isolate, JSArray::cast(*receiver))) {
return CallJsIntrinsic(isolate, isolate->array_shift(), args);
}
@@ -506,8 +479,7 @@ BUILTIN(ArrayShift) {
return CallJsIntrinsic(isolate, isolate->array_shift(), args);
}
- Handle<Object> first = array->GetElementsAccessor()->Shift(
- array, handle(array->elements(), isolate));
+ Handle<Object> first = array->GetElementsAccessor()->Shift(array);
return *first;
}
@@ -521,20 +493,17 @@ BUILTIN(ArrayUnshift) {
Handle<JSArray> array = Handle<JSArray>::cast(receiver);
DCHECK(!array->map()->is_observed());
int to_add = args.length() - 1;
- if (to_add == 0) {
- return array->length();
- }
- // Currently fixed arrays cannot grow too big, so
- // we should never hit this case.
- DCHECK(to_add <= (Smi::kMaxValue - Smi::cast(array->length())->value()));
+ if (to_add == 0) return array->length();
- if (to_add > 0 && JSArray::HasReadOnlyLength(array)) {
+ // Currently fixed arrays cannot grow too big, so we should never hit this.
+ DCHECK_LE(to_add, Smi::kMaxValue - Smi::cast(array->length())->value());
+
+ if (JSArray::HasReadOnlyLength(array)) {
return CallJsIntrinsic(isolate, isolate->array_unshift(), args);
}
ElementsAccessor* accessor = array->GetElementsAccessor();
- int new_length = accessor->Unshift(array, handle(array->elements(), isolate),
- &args, to_add);
+ int new_length = accessor->Unshift(array, &args, to_add);
return Smi::FromInt(new_length);
}
@@ -542,12 +511,9 @@ BUILTIN(ArrayUnshift) {
BUILTIN(ArraySlice) {
HandleScope scope(isolate);
Handle<Object> receiver = args.receiver();
- Handle<JSObject> object;
- Handle<FixedArrayBase> elms_obj;
int len = -1;
int relative_start = 0;
int relative_end = 0;
- bool is_sloppy_arguments = false;
if (receiver->IsJSArray()) {
DisallowHeapAllocation no_gc;
@@ -561,22 +527,18 @@ BUILTIN(ArraySlice) {
return CallJsIntrinsic(isolate, isolate->array_slice(), args);
}
len = Smi::cast(array->length())->value();
- object = Handle<JSObject>::cast(receiver);
- elms_obj = handle(array->elements(), isolate);
} else if (receiver->IsJSObject() &&
GetSloppyArgumentsLength(isolate, Handle<JSObject>::cast(receiver),
&len)) {
+ DCHECK_EQ(FAST_ELEMENTS, JSObject::cast(*receiver)->GetElementsKind());
// Array.prototype.slice(arguments, ...) is quite a common idiom
// (notably more than 50% of invocations in Web apps).
// Treat it in C++ as well.
- is_sloppy_arguments = true;
- object = Handle<JSObject>::cast(receiver);
- elms_obj = handle(object->elements(), isolate);
} else {
AllowHeapAllocation allow_allocation;
return CallJsIntrinsic(isolate, isolate->array_slice(), args);
}
- DCHECK(len >= 0);
+ DCHECK_LE(0, len);
int argument_count = args.length() - 1;
// Note carefully chosen defaults---if argument is missing,
// it's undefined which gets converted to 0 for relative_start
@@ -609,22 +571,9 @@ BUILTIN(ArraySlice) {
uint32_t actual_end =
(relative_end < 0) ? Max(len + relative_end, 0) : Min(relative_end, len);
- if (actual_end <= actual_start) {
- Handle<JSArray> result_array = isolate->factory()->NewJSArray(
- GetPackedElementsKind(object->GetElementsKind()), 0, 0);
- return *result_array;
- }
-
+ Handle<JSObject> object = Handle<JSObject>::cast(receiver);
ElementsAccessor* accessor = object->GetElementsAccessor();
- if (is_sloppy_arguments &&
- !accessor->IsPacked(object, elms_obj, actual_start, actual_end)) {
- // Don't deal with arguments with holes in C++
- AllowHeapAllocation allow_allocation;
- return CallJsIntrinsic(isolate, isolate->array_slice(), args);
- }
- Handle<JSArray> result_array =
- accessor->Slice(object, elms_obj, actual_start, actual_end);
- return *result_array;
+ return *accessor->Slice(object, actual_start, actual_end);
}
@@ -683,9 +632,8 @@ BUILTIN(ArraySplice) {
return CallJsIntrinsic(isolate, isolate->array_splice(), args);
}
ElementsAccessor* accessor = array->GetElementsAccessor();
- Handle<JSArray> result_array =
- accessor->Splice(array, handle(array->elements(), isolate), actual_start,
- actual_delete_count, &args, add_count);
+ Handle<JSArray> result_array = accessor->Splice(
+ array, actual_start, actual_delete_count, &args, add_count);
return *result_array;
}
« no previous file with comments | « no previous file | src/elements.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698