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

Unified Diff: src/builtins.cc

Issue 1815663002: Speed up PrototypeHasNoElements and drop the "fast" path before, it's now slower. (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/objects.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 1c27415907854b1751275958b4cda49e350674f4..7c4124b0b3b028d9d2fe0e4b1d15f3caec2b36d4 100644
--- a/src/builtins.cc
+++ b/src/builtins.cc
@@ -214,57 +214,38 @@ inline bool GetSloppyArgumentsLength(Isolate* isolate, Handle<JSObject> object,
return *out <= object->elements()->length();
}
-
-inline bool PrototypeHasNoElements(PrototypeIterator* iter) {
+inline bool PrototypeHasNoElements(Isolate* isolate, JSObject* object) {
DisallowHeapAllocation no_gc;
- for (; !iter->IsAtEnd(); iter->Advance()) {
- if (iter->GetCurrent()->IsJSProxy()) return false;
- JSObject* current = iter->GetCurrent<JSObject>();
- if (current->IsAccessCheckNeeded()) return false;
- if (current->HasIndexedInterceptor()) return false;
- if (current->HasStringWrapperElements()) return false;
- if (current->elements()->length() != 0) return false;
+ HeapObject* prototype = HeapObject::cast(object->map()->prototype());
+ HeapObject* null = isolate->heap()->null_value();
+ HeapObject* empty = isolate->heap()->empty_fixed_array();
+ while (prototype != null) {
+ Map* map = prototype->map();
+ if (map->instance_type() <= LAST_CUSTOM_ELEMENTS_RECEIVER) return false;
+ if (JSObject::cast(prototype)->elements() != empty) return false;
+ prototype = HeapObject::cast(map->prototype());
}
return true;
}
inline bool IsJSArrayFastElementMovingAllowed(Isolate* isolate,
JSArray* receiver) {
- DisallowHeapAllocation no_gc;
- // If the array prototype chain is intact (and free of elements), and if the
- // receiver's prototype is the array prototype, then we are done.
- Object* prototype = receiver->map()->prototype();
- if (prototype->IsJSArray() &&
- isolate->is_initial_array_prototype(JSArray::cast(prototype)) &&
- isolate->IsFastArrayConstructorPrototypeChainIntact()) {
- return true;
- }
- // Slow case.
- PrototypeIterator iter(isolate, receiver);
- return PrototypeHasNoElements(&iter);
+ return PrototypeHasNoElements(isolate, receiver);
}
inline bool HasSimpleElements(JSObject* current) {
- if (current->IsAccessCheckNeeded()) return false;
- if (current->HasIndexedInterceptor()) return false;
- if (current->HasStringWrapperElements()) return false;
- if (current->GetElementsAccessor()->HasAccessors(current)) return false;
- return true;
+ return current->map()->instance_type() > LAST_CUSTOM_ELEMENTS_RECEIVER &&
+ !current->GetElementsAccessor()->HasAccessors(current);
}
inline bool HasOnlySimpleReceiverElements(Isolate* isolate,
- JSReceiver* receiver) {
+ JSObject* receiver) {
// Check that we have no accessors on the receiver's elements.
- JSObject* object = JSObject::cast(receiver);
- if (!HasSimpleElements(object)) return false;
- // Check that ther are not elements on the prototype.
- DisallowHeapAllocation no_gc;
- PrototypeIterator iter(isolate, receiver);
- return PrototypeHasNoElements(&iter);
+ if (!HasSimpleElements(receiver)) return false;
+ return PrototypeHasNoElements(isolate, receiver);
}
inline bool HasOnlySimpleElements(Isolate* isolate, JSReceiver* receiver) {
- // Check that ther are not elements on the prototype.
DisallowHeapAllocation no_gc;
PrototypeIterator iter(isolate, receiver,
PrototypeIterator::START_AT_RECEIVER);
@@ -284,17 +265,16 @@ inline bool EnsureJSArrayWithWritableFastElements(Isolate* isolate,
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.
- if (args != nullptr && !IsJSArrayFastElementMovingAllowed(isolate, *array)) {
- return false;
- }
ElementsKind origin_kind = array->GetElementsKind();
if (IsDictionaryElementsKind(origin_kind)) return false;
if (array->map()->is_observed()) return false;
if (!array->map()->is_extensible()) return false;
if (args == nullptr) return true;
+ // If there may be elements accessors in the prototype chain, the fast path
+ // cannot be used if there arguments to add to the array.
+ if (!IsJSArrayFastElementMovingAllowed(isolate, *array)) 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 false;
@@ -308,10 +288,8 @@ inline bool EnsureJSArrayWithWritableFastElements(Isolate* isolate,
ElementsKind target_kind = origin_kind;
{
DisallowHeapAllocation no_gc;
- int arg_count = args_length - first_added_arg;
- Object** arguments = args->arguments() - first_added_arg - (arg_count - 1);
- for (int i = 0; i < arg_count; i++) {
- Object* arg = arguments[i];
+ for (int i = first_added_arg; i < args_length; i++) {
+ Object* arg = (*args)[i];
if (arg->IsHeapObject()) {
if (arg->IsHeapNumber()) {
target_kind = FAST_DOUBLE_ELEMENTS;
« no previous file with comments | « no previous file | src/objects.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698