Commit d4f01b8a authored by bmeurer's avatar bmeurer Committed by Commit bot

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

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

R=yangguo@chromium.org

Review-Url: https://codereview.chromium.org/2510043004
Cr-Commit-Position: refs/heads/master@{#41108}
parent 80339771
......@@ -2193,7 +2193,8 @@ void Builtins::Generate_Apply(MacroAssembler* masm) {
// 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);
// Load the map of argumentsList into ecx.
......@@ -2237,6 +2238,22 @@ void Builtins::Generate_Apply(MacroAssembler* masm) {
__ mov(eax, ecx);
__ 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.
__ bind(&create_array);
__ mov(ecx, FieldOperand(ecx, Map::kBitField2Offset));
......@@ -2244,10 +2261,12 @@ void Builtins::Generate_Apply(MacroAssembler* masm) {
STATIC_ASSERT(FAST_SMI_ELEMENTS == 0);
STATIC_ASSERT(FAST_HOLEY_SMI_ELEMENTS == 1);
STATIC_ASSERT(FAST_ELEMENTS == 2);
__ cmp(ecx, Immediate(FAST_ELEMENTS));
__ j(above, &create_runtime);
STATIC_ASSERT(FAST_HOLEY_ELEMENTS == 3);
__ 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));
__ SmiUntag(ebx);
__ mov(eax, FieldOperand(eax, JSArray::kElementsOffset));
......@@ -2287,18 +2306,26 @@ void Builtins::Generate_Apply(MacroAssembler* masm) {
// Push arguments onto the stack (thisArgument is already on the stack).
{
__ movd(xmm0, edx);
__ movd(xmm1, edi);
__ PopReturnAddressTo(edx);
__ Move(ecx, Immediate(0));
Label done, loop;
Label done, push, loop;
__ bind(&loop);
__ cmp(ecx, ebx);
__ j(equal, &done, Label::kNear);
__ Push(
FieldOperand(eax, ecx, times_pointer_size, FixedArray::kHeaderSize));
// Turn the hole into undefined as we go.
__ mov(edi,
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);
__ jmp(&loop);
__ bind(&done);
__ PushReturnAddressFrom(edx);
__ movd(edi, xmm1);
__ movd(edx, xmm0);
__ Move(eax, ebx);
}
......
......@@ -2292,7 +2292,8 @@ void Builtins::Generate_Apply(MacroAssembler* masm) {
// 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(rax, &create_runtime);
// Load the map of argumentsList into rcx.
......@@ -2335,6 +2336,21 @@ void Builtins::Generate_Apply(MacroAssembler* masm) {
__ movp(rax, rcx);
__ jmp(&done_create);
__ bind(&create_holey_array);
// For holey JSArrays we need to check that the array prototype chain
// protector is intact and our prototype is the Array.prototype actually.
__ movp(rcx, FieldOperand(rax, HeapObject::kMapOffset));
__ movp(rcx, FieldOperand(rcx, Map::kPrototypeOffset));
__ cmpp(rcx, ContextOperand(rbx, Context::INITIAL_ARRAY_PROTOTYPE_INDEX));
__ j(not_equal, &create_runtime);
__ LoadRoot(rcx, Heap::kArrayProtectorRootIndex);
__ Cmp(FieldOperand(rcx, PropertyCell::kValueOffset),
Smi::FromInt(Isolate::kProtectorValid));
__ j(not_equal, &create_runtime);
__ SmiToInteger32(rbx, FieldOperand(rax, JSArray::kLengthOffset));
__ movp(rax, FieldOperand(rax, JSArray::kElementsOffset));
__ jmp(&done_create);
// Try to create the list from a JSArray object.
__ bind(&create_array);
__ movzxbp(rcx, FieldOperand(rcx, Map::kBitField2Offset));
......@@ -2342,10 +2358,12 @@ void Builtins::Generate_Apply(MacroAssembler* masm) {
STATIC_ASSERT(FAST_SMI_ELEMENTS == 0);
STATIC_ASSERT(FAST_HOLEY_SMI_ELEMENTS == 1);
STATIC_ASSERT(FAST_ELEMENTS == 2);
__ cmpl(rcx, Immediate(FAST_ELEMENTS));
__ j(above, &create_runtime);
STATIC_ASSERT(FAST_HOLEY_ELEMENTS == 3);
__ cmpl(rcx, Immediate(FAST_HOLEY_SMI_ELEMENTS));
__ j(equal, &create_runtime);
__ j(equal, &create_holey_array);
__ cmpl(rcx, Immediate(FAST_HOLEY_ELEMENTS));
__ j(equal, &create_holey_array);
__ j(above, &create_runtime);
__ SmiToInteger32(rbx, FieldOperand(rax, JSArray::kLengthOffset));
__ movp(rax, FieldOperand(rax, JSArray::kElementsOffset));
......@@ -2383,12 +2401,18 @@ void Builtins::Generate_Apply(MacroAssembler* masm) {
{
__ PopReturnAddressTo(r8);
__ Set(rcx, 0);
Label done, loop;
Label done, push, loop;
__ bind(&loop);
__ cmpl(rcx, rbx);
__ j(equal, &done, Label::kNear);
__ Push(
FieldOperand(rax, rcx, times_pointer_size, FixedArray::kHeaderSize));
// Turn the hole into undefined as we go.
__ movp(r9, FieldOperand(rax, rcx, times_pointer_size,
FixedArray::kHeaderSize));
__ CompareRoot(r9, Heap::kTheHoleValueRootIndex);
__ j(not_equal, &push, Label::kNear);
__ LoadRoot(r9, Heap::kUndefinedValueRootIndex);
__ bind(&push);
__ Push(r9);
__ incl(rcx);
__ jmp(&loop);
__ bind(&done);
......
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