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; |