Commit 7d230e27 authored by zhengxing.li's avatar zhengxing.li Committed by Commit bot

X87: [x86] Also deal with holey arrays in the Apply builtin.

  port d4f01b8a (r41108)

  original commit message:
  Add fast paths for holey smi and object arrays to
  Function.prototype.apply, Reflect.apply and Reflect.construct.

BUG=

Review-Url: https://codereview.chromium.org/2519303002
Cr-Commit-Position: refs/heads/master@{#41203}
parent 38092c41
...@@ -2168,7 +2168,8 @@ void Builtins::Generate_Apply(MacroAssembler* masm) { ...@@ -2168,7 +2168,8 @@ void Builtins::Generate_Apply(MacroAssembler* masm) {
// Create the list of arguments from the array-like argumentsList. // Create the list of arguments from the array-like argumentsList.
{ {
Label create_arguments, create_array, create_runtime, done_create; Label create_arguments, create_array, create_holey_array, create_runtime,
done_create;
__ JumpIfSmi(eax, &create_runtime); __ JumpIfSmi(eax, &create_runtime);
// Load the map of argumentsList into ecx. // Load the map of argumentsList into ecx.
...@@ -2212,6 +2213,22 @@ void Builtins::Generate_Apply(MacroAssembler* masm) { ...@@ -2212,6 +2213,22 @@ void Builtins::Generate_Apply(MacroAssembler* masm) {
__ mov(eax, ecx); __ mov(eax, ecx);
__ jmp(&done_create); __ jmp(&done_create);
// For holey JSArrays we need to check that the array prototype chain
// protector is intact and our prototype is the Array.prototype actually.
__ bind(&create_holey_array);
__ mov(ecx, FieldOperand(eax, HeapObject::kMapOffset));
__ mov(ecx, FieldOperand(ecx, Map::kPrototypeOffset));
__ cmp(ecx, ContextOperand(ebx, Context::INITIAL_ARRAY_PROTOTYPE_INDEX));
__ j(not_equal, &create_runtime);
__ LoadRoot(ecx, Heap::kArrayProtectorRootIndex);
__ cmp(FieldOperand(ecx, PropertyCell::kValueOffset),
Immediate(Smi::FromInt(Isolate::kProtectorValid)));
__ j(not_equal, &create_runtime);
__ mov(ebx, FieldOperand(eax, JSArray::kLengthOffset));
__ SmiUntag(ebx);
__ mov(eax, FieldOperand(eax, JSArray::kElementsOffset));
__ jmp(&done_create);
// Try to create the list from a JSArray object. // Try to create the list from a JSArray object.
__ bind(&create_array); __ bind(&create_array);
__ mov(ecx, FieldOperand(ecx, Map::kBitField2Offset)); __ mov(ecx, FieldOperand(ecx, Map::kBitField2Offset));
...@@ -2219,10 +2236,12 @@ void Builtins::Generate_Apply(MacroAssembler* masm) { ...@@ -2219,10 +2236,12 @@ void Builtins::Generate_Apply(MacroAssembler* masm) {
STATIC_ASSERT(FAST_SMI_ELEMENTS == 0); STATIC_ASSERT(FAST_SMI_ELEMENTS == 0);
STATIC_ASSERT(FAST_HOLEY_SMI_ELEMENTS == 1); STATIC_ASSERT(FAST_HOLEY_SMI_ELEMENTS == 1);
STATIC_ASSERT(FAST_ELEMENTS == 2); STATIC_ASSERT(FAST_ELEMENTS == 2);
__ cmp(ecx, Immediate(FAST_ELEMENTS)); STATIC_ASSERT(FAST_HOLEY_ELEMENTS == 3);
__ j(above, &create_runtime);
__ cmp(ecx, Immediate(FAST_HOLEY_SMI_ELEMENTS)); __ cmp(ecx, Immediate(FAST_HOLEY_SMI_ELEMENTS));
__ j(equal, &create_runtime); __ j(equal, &create_holey_array, Label::kNear);
__ cmp(ecx, Immediate(FAST_HOLEY_ELEMENTS));
__ j(equal, &create_holey_array, Label::kNear);
__ j(above, &create_runtime);
__ mov(ebx, FieldOperand(eax, JSArray::kLengthOffset)); __ mov(ebx, FieldOperand(eax, JSArray::kLengthOffset));
__ SmiUntag(ebx); __ SmiUntag(ebx);
__ mov(eax, FieldOperand(eax, JSArray::kElementsOffset)); __ mov(eax, FieldOperand(eax, JSArray::kElementsOffset));
...@@ -2261,26 +2280,38 @@ void Builtins::Generate_Apply(MacroAssembler* masm) { ...@@ -2261,26 +2280,38 @@ void Builtins::Generate_Apply(MacroAssembler* masm) {
// Push arguments onto the stack (thisArgument is already on the stack). // Push arguments onto the stack (thisArgument is already on the stack).
{ {
// Save edx/edi to stX0/stX1.
__ push(edx); __ push(edx);
__ push(edi);
__ fld_s(MemOperand(esp, 0)); __ fld_s(MemOperand(esp, 0));
__ lea(esp, Operand(esp, kFloatSize)); __ fld_s(MemOperand(esp, 4));
__ lea(esp, Operand(esp, 2 * kFloatSize));
__ PopReturnAddressTo(edx); __ PopReturnAddressTo(edx);
__ Move(ecx, Immediate(0)); __ Move(ecx, Immediate(0));
Label done, loop; Label done, push, loop;
__ bind(&loop); __ bind(&loop);
__ cmp(ecx, ebx); __ cmp(ecx, ebx);
__ j(equal, &done, Label::kNear); __ j(equal, &done, Label::kNear);
__ Push( // Turn the hole into undefined as we go.
__ mov(edi,
FieldOperand(eax, ecx, times_pointer_size, FixedArray::kHeaderSize)); FieldOperand(eax, ecx, times_pointer_size, FixedArray::kHeaderSize));
__ CompareRoot(edi, Heap::kTheHoleValueRootIndex);
__ j(not_equal, &push, Label::kNear);
__ LoadRoot(edi, Heap::kUndefinedValueRootIndex);
__ bind(&push);
__ Push(edi);
__ inc(ecx); __ inc(ecx);
__ jmp(&loop); __ jmp(&loop);
__ bind(&done); __ bind(&done);
__ PushReturnAddressFrom(edx); __ PushReturnAddressFrom(edx);
__ lea(esp, Operand(esp, -kFloatSize)); // Restore edx/edi from stX0/stX1.
__ lea(esp, Operand(esp, -2 * kFloatSize));
__ fstp_s(MemOperand(esp, 0)); __ fstp_s(MemOperand(esp, 0));
__ fstp_s(MemOperand(esp, 4));
__ pop(edx); __ pop(edx);
__ pop(edi);
__ Move(eax, ebx); __ Move(eax, ebx);
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment