diff --git a/src/builtins.cc b/src/builtins.cc index a9690a78307..37286c6fa55 100644 --- a/src/builtins.cc +++ b/src/builtins.cc @@ -218,7 +218,7 @@ inline bool GetSloppyArgumentsLength(Isolate* isolate, Handle object, } -bool PrototypeHasNoElements(PrototypeIterator* iter) { +inline bool PrototypeHasNoElements(PrototypeIterator* iter) { DisallowHeapAllocation no_gc; for (; !iter->IsAtEnd(); iter->Advance()) { if (iter->GetCurrent()->IsJSProxy()) return false; @@ -396,13 +396,18 @@ BUILTIN(ArrayPop) { return CallJsIntrinsic(isolate, isolate->array_pop(), args); } - uint32_t new_length = len - 1; - Handle element; - ASSIGN_RETURN_FAILURE_ON_EXCEPTION( - isolate, element, Object::GetElement(isolate, array, new_length)); - - JSArray::SetLength(array, new_length); - return *element; + Handle result; + if (IsJSArrayFastElementMovingAllowed(isolate, JSArray::cast(*receiver))) { + // Fast Elements Path + result = array->GetElementsAccessor()->Pop(array, elms_obj); + } else { + // Use Slow Lookup otherwise + uint32_t new_length = len - 1; + ASSIGN_RETURN_FAILURE_ON_EXCEPTION( + isolate, result, Object::GetElement(isolate, array, new_length)); + JSArray::SetLength(array, new_length); + } + return *result; } diff --git a/src/elements-kind.h b/src/elements-kind.h index 0254a4fb59b..d8234097c43 100644 --- a/src/elements-kind.h +++ b/src/elements-kind.h @@ -158,9 +158,8 @@ inline bool IsHoleyElementsKind(ElementsKind kind) { inline bool IsFastPackedElementsKind(ElementsKind kind) { - return kind == FAST_SMI_ELEMENTS || - kind == FAST_DOUBLE_ELEMENTS || - kind == FAST_ELEMENTS; + return kind == FAST_SMI_ELEMENTS || kind == FAST_DOUBLE_ELEMENTS || + kind == FAST_ELEMENTS; } diff --git a/src/elements.cc b/src/elements.cc index d17efafcebb..2cf64c52f74 100644 --- a/src/elements.cc +++ b/src/elements.cc @@ -639,6 +639,16 @@ class ElementsAccessorBase : public ElementsAccessor { return Handle(); } + virtual Handle Pop(Handle receiver, + Handle backing_store) final { + return ElementsAccessorSubclass::PopImpl(receiver, backing_store); + } + + static Handle PopImpl(Handle receiver, + Handle backing_store) { + UNREACHABLE(); + return Handle(); + } virtual void SetLength(Handle array, uint32_t length) final { ElementsAccessorSubclass::SetLengthImpl(array, length, @@ -1219,6 +1229,21 @@ class FastElementsAccessor #endif } + static Handle PopImpl(Handle receiver, + Handle backing_store) { + uint32_t new_length = + static_cast(Smi::cast(receiver->length())->value()) - 1; + Handle result = + FastElementsAccessorSubclass::GetImpl(backing_store, new_length); + FastElementsAccessorSubclass::SetLengthImpl(receiver, new_length, + backing_store); + + if (IsHoleyElementsKind(KindTraits::Kind) && result->IsTheHole()) { + result = receiver->GetIsolate()->factory()->undefined_value(); + } + return result; + } + static uint32_t PushImpl(Handle receiver, Handle backing_store, Object** objects, uint32_t push_size, diff --git a/src/elements.h b/src/elements.h index f5a9b3e23a6..6022375e20d 100644 --- a/src/elements.h +++ b/src/elements.h @@ -145,6 +145,9 @@ class ElementsAccessor { uint32_t start, uint32_t delete_count, Arguments args, uint32_t add_count) = 0; + virtual Handle Pop(Handle receiver, + Handle backing_store) = 0; + protected: friend class LookupIterator;