Index: src/x64/stub-cache-x64.cc |
diff --git a/src/x64/stub-cache-x64.cc b/src/x64/stub-cache-x64.cc |
index dbfd419290c692b61758bacb58d9e76dcea55668..53e9f886f4a946954f52619c70f38b447eb3a983 100644 |
--- a/src/x64/stub-cache-x64.cc |
+++ b/src/x64/stub-cache-x64.cc |
@@ -1534,6 +1534,77 @@ Handle<Code> CallStubCompiler::CompileCallField(Handle<JSObject> object, |
} |
+Handle<Code> CallStubCompiler::CompileArrayPopCall( |
+ Handle<Object> object, |
+ Handle<JSObject> holder, |
+ Handle<Cell> cell, |
+ Handle<JSFunction> function, |
+ Handle<String> name, |
+ Code::StubType type) { |
+ // If object is not an array or is observed or sealed, bail out to regular |
+ // call. |
+ if (!object->IsJSArray() || |
+ !cell.is_null() || |
+ Handle<JSArray>::cast(object)->map()->is_observed() || |
+ !Handle<JSArray>::cast(object)->map()->is_extensible()) { |
+ return Handle<Code>::null(); |
+ } |
+ |
+ Label miss, return_undefined, call_builtin; |
+ |
+ HandlerFrontendHeader(object, holder, name, RECEIVER_MAP_CHECK, &miss); |
+ |
+ // Get the elements array of the object. |
+ __ movp(rbx, FieldOperand(rdx, JSArray::kElementsOffset)); |
+ |
+ // Check that the elements are in fast mode and writable. |
+ __ CompareRoot(FieldOperand(rbx, HeapObject::kMapOffset), |
+ Heap::kFixedArrayMapRootIndex); |
+ __ j(not_equal, &call_builtin); |
+ |
+ // Get the array's length into rcx and calculate new length. |
+ __ SmiToInteger32(rcx, FieldOperand(rdx, JSArray::kLengthOffset)); |
+ __ subl(rcx, Immediate(1)); |
+ __ j(negative, &return_undefined); |
+ |
+ // Get the last element. |
+ __ LoadRoot(r9, Heap::kTheHoleValueRootIndex); |
+ __ movp(rax, FieldOperand(rbx, |
+ rcx, times_pointer_size, |
+ FixedArray::kHeaderSize)); |
+ // Check if element is already the hole. |
+ __ cmpq(rax, r9); |
+ // If so, call slow-case to also check prototypes for value. |
+ __ j(equal, &call_builtin); |
+ |
+ // Set the array's length. |
+ __ Integer32ToSmiField(FieldOperand(rdx, JSArray::kLengthOffset), rcx); |
+ |
+ // Fill with the hole and return original value. |
+ __ movp(FieldOperand(rbx, |
+ rcx, times_pointer_size, |
+ FixedArray::kHeaderSize), |
+ r9); |
+ const int argc = arguments().immediate(); |
+ __ ret((argc + 1) * kPointerSize); |
+ |
+ __ bind(&return_undefined); |
+ __ LoadRoot(rax, Heap::kUndefinedValueRootIndex); |
+ __ ret((argc + 1) * kPointerSize); |
+ |
+ __ bind(&call_builtin); |
+ __ TailCallExternalReference( |
+ ExternalReference(Builtins::c_ArrayPop, isolate()), |
+ argc + 1, |
+ 1); |
+ |
+ HandlerFrontendFooter(&miss); |
+ |
+ // Return the generated code. |
+ return GetCode(type, name); |
+} |
+ |
+ |
Handle<Code> CallStubCompiler::CompileFastApiCall( |
const CallOptimization& optimization, |
Handle<Object> object, |