| Index: src/x64/code-stubs-x64.cc
|
| diff --git a/src/x64/code-stubs-x64.cc b/src/x64/code-stubs-x64.cc
|
| index 60042f0fa00caad9ef5e3e7ad4644a3a8a3d5045..f315eac436efb0bf50974d53dac21a7f28887c95 100644
|
| --- a/src/x64/code-stubs-x64.cc
|
| +++ b/src/x64/code-stubs-x64.cc
|
| @@ -596,47 +596,46 @@ void ArgumentsAccessStub::GenerateReadElement(MacroAssembler* masm) {
|
|
|
|
|
| void ArgumentsAccessStub::GenerateNewSloppyFast(MacroAssembler* masm) {
|
| - // Stack layout:
|
| - // rsp[0] : return address
|
| - // rsp[8] : number of parameters (tagged)
|
| - // rsp[16] : receiver displacement
|
| - // rsp[24] : function
|
| + // rcx : number of parameters (tagged)
|
| + // rdx : parameters pointer
|
| + // rdi : function
|
| + // rsp[0] : return address
|
| // Registers used over the whole function:
|
| // rbx: the mapped parameter count (untagged)
|
| // rax: the allocated object (tagged).
|
| Factory* factory = isolate()->factory();
|
|
|
| - StackArgumentsAccessor args(rsp, 3, ARGUMENTS_DONT_CONTAIN_RECEIVER);
|
| - __ SmiToInteger64(rbx, args.GetArgumentOperand(2));
|
| + DCHECK(rdi.is(ArgumentsAccessNewDescriptor::function()));
|
| + DCHECK(rcx.is(ArgumentsAccessNewDescriptor::parameter_count()));
|
| + DCHECK(rdx.is(ArgumentsAccessNewDescriptor::parameter_pointer()));
|
| +
|
| + __ SmiToInteger64(rbx, rcx);
|
| // rbx = parameter count (untagged)
|
|
|
| // Check if the calling frame is an arguments adaptor frame.
|
| - Label runtime;
|
| - Label adaptor_frame, try_allocate;
|
| - __ movp(rdx, Operand(rbp, StandardFrameConstants::kCallerFPOffset));
|
| - __ movp(rcx, Operand(rdx, StandardFrameConstants::kContextOffset));
|
| - __ Cmp(rcx, Smi::FromInt(StackFrame::ARGUMENTS_ADAPTOR));
|
| + Label adaptor_frame, try_allocate, runtime;
|
| + __ movp(rax, Operand(rbp, StandardFrameConstants::kCallerFPOffset));
|
| + __ movp(r8, Operand(rax, StandardFrameConstants::kContextOffset));
|
| + __ Cmp(r8, Smi::FromInt(StackFrame::ARGUMENTS_ADAPTOR));
|
| __ j(equal, &adaptor_frame);
|
|
|
| // No adaptor, parameter count = argument count.
|
| - __ movp(rcx, rbx);
|
| + __ movp(r11, rbx);
|
| __ jmp(&try_allocate, Label::kNear);
|
|
|
| // We have an adaptor frame. Patch the parameters pointer.
|
| __ bind(&adaptor_frame);
|
| - __ SmiToInteger64(rcx,
|
| - Operand(rdx,
|
| - ArgumentsAdaptorFrameConstants::kLengthOffset));
|
| - __ leap(rdx, Operand(rdx, rcx, times_pointer_size,
|
| - StandardFrameConstants::kCallerSPOffset));
|
| - __ movp(args.GetArgumentOperand(1), rdx);
|
| + __ SmiToInteger64(
|
| + r11, Operand(rax, ArgumentsAdaptorFrameConstants::kLengthOffset));
|
| + __ leap(rdx, Operand(rax, r11, times_pointer_size,
|
| + StandardFrameConstants::kCallerSPOffset));
|
|
|
| // rbx = parameter count (untagged)
|
| - // rcx = argument count (untagged)
|
| - // Compute the mapped parameter count = min(rbx, rcx) in rbx.
|
| - __ cmpp(rbx, rcx);
|
| + // r11 = argument count (untagged)
|
| + // Compute the mapped parameter count = min(rbx, r11) in rbx.
|
| + __ cmpp(rbx, r11);
|
| __ j(less_equal, &try_allocate, Label::kNear);
|
| - __ movp(rbx, rcx);
|
| + __ movp(rbx, r11);
|
|
|
| __ bind(&try_allocate);
|
|
|
| @@ -652,66 +651,65 @@ void ArgumentsAccessStub::GenerateNewSloppyFast(MacroAssembler* masm) {
|
| __ bind(&no_parameter_map);
|
|
|
| // 2. Backing store.
|
| - __ leap(r8, Operand(r8, rcx, times_pointer_size, FixedArray::kHeaderSize));
|
| + __ leap(r8, Operand(r8, r11, times_pointer_size, FixedArray::kHeaderSize));
|
|
|
| // 3. Arguments object.
|
| __ addp(r8, Immediate(Heap::kSloppyArgumentsObjectSize));
|
|
|
| // Do the allocation of all three objects in one go.
|
| - __ Allocate(r8, rax, rdx, rdi, &runtime, TAG_OBJECT);
|
| + __ Allocate(r8, rax, r9, no_reg, &runtime, TAG_OBJECT);
|
|
|
| // rax = address of new object(s) (tagged)
|
| - // rcx = argument count (untagged)
|
| - // Get the arguments map from the current native context into rdi.
|
| + // r11 = argument count (untagged)
|
| + // Get the arguments map from the current native context into r9.
|
| Label has_mapped_parameters, instantiate;
|
| - __ movp(rdi, Operand(rsi, Context::SlotOffset(Context::GLOBAL_OBJECT_INDEX)));
|
| - __ movp(rdi, FieldOperand(rdi, GlobalObject::kNativeContextOffset));
|
| + __ movp(r9, Operand(rsi, Context::SlotOffset(Context::GLOBAL_OBJECT_INDEX)));
|
| + __ movp(r9, FieldOperand(r9, GlobalObject::kNativeContextOffset));
|
| __ testp(rbx, rbx);
|
| __ j(not_zero, &has_mapped_parameters, Label::kNear);
|
|
|
| const int kIndex = Context::SLOPPY_ARGUMENTS_MAP_INDEX;
|
| - __ movp(rdi, Operand(rdi, Context::SlotOffset(kIndex)));
|
| + __ movp(r9, Operand(r9, Context::SlotOffset(kIndex)));
|
| __ jmp(&instantiate, Label::kNear);
|
|
|
| const int kAliasedIndex = Context::FAST_ALIASED_ARGUMENTS_MAP_INDEX;
|
| __ bind(&has_mapped_parameters);
|
| - __ movp(rdi, Operand(rdi, Context::SlotOffset(kAliasedIndex)));
|
| + __ movp(r9, Operand(r9, Context::SlotOffset(kAliasedIndex)));
|
| __ bind(&instantiate);
|
|
|
| // rax = address of new object (tagged)
|
| // rbx = mapped parameter count (untagged)
|
| - // rcx = argument count (untagged)
|
| - // rdi = address of arguments map (tagged)
|
| - __ movp(FieldOperand(rax, JSObject::kMapOffset), rdi);
|
| + // r11 = argument count (untagged)
|
| + // r9 = address of arguments map (tagged)
|
| + __ movp(FieldOperand(rax, JSObject::kMapOffset), r9);
|
| __ LoadRoot(kScratchRegister, Heap::kEmptyFixedArrayRootIndex);
|
| __ movp(FieldOperand(rax, JSObject::kPropertiesOffset), kScratchRegister);
|
| __ movp(FieldOperand(rax, JSObject::kElementsOffset), kScratchRegister);
|
|
|
| // Set up the callee in-object property.
|
| STATIC_ASSERT(Heap::kArgumentsCalleeIndex == 1);
|
| - __ movp(rdx, args.GetArgumentOperand(0));
|
| - __ AssertNotSmi(rdx);
|
| + __ AssertNotSmi(rdi);
|
| __ movp(FieldOperand(rax, JSObject::kHeaderSize +
|
| - Heap::kArgumentsCalleeIndex * kPointerSize),
|
| - rdx);
|
| + Heap::kArgumentsCalleeIndex * kPointerSize),
|
| + rdi);
|
|
|
| // Use the length (smi tagged) and set that as an in-object property too.
|
| - // Note: rcx is tagged from here on.
|
| + // Note: r11 is tagged from here on.
|
| STATIC_ASSERT(Heap::kArgumentsLengthIndex == 0);
|
| - __ Integer32ToSmi(rcx, rcx);
|
| + __ Integer32ToSmi(r11, r11);
|
| __ movp(FieldOperand(rax, JSObject::kHeaderSize +
|
| - Heap::kArgumentsLengthIndex * kPointerSize),
|
| - rcx);
|
| + Heap::kArgumentsLengthIndex * kPointerSize),
|
| + r11);
|
|
|
| // Set up the elements pointer in the allocated arguments object.
|
| - // If we allocated a parameter map, edi will point there, otherwise to the
|
| + // If we allocated a parameter map, rdi will point there, otherwise to the
|
| // backing store.
|
| __ leap(rdi, Operand(rax, Heap::kSloppyArgumentsObjectSize));
|
| __ movp(FieldOperand(rax, JSObject::kElementsOffset), rdi);
|
|
|
| // rax = address of new object (tagged)
|
| // rbx = mapped parameter count (untagged)
|
| - // rcx = argument count (tagged)
|
| + // r11 = argument count (tagged)
|
| // rdi = address of parameter map or backing store (tagged)
|
|
|
| // Initialize parameter map. If there are no mapped arguments, we're done.
|
| @@ -741,48 +739,42 @@ void ArgumentsAccessStub::GenerateNewSloppyFast(MacroAssembler* masm) {
|
| // Load tagged parameter count into r9.
|
| __ Integer32ToSmi(r9, rbx);
|
| __ Move(r8, Smi::FromInt(Context::MIN_CONTEXT_SLOTS));
|
| - __ addp(r8, args.GetArgumentOperand(2));
|
| + __ addp(r8, rcx);
|
| __ subp(r8, r9);
|
| - __ Move(r11, factory->the_hole_value());
|
| - __ movp(rdx, rdi);
|
| + __ movp(rcx, rdi);
|
| __ leap(rdi, Operand(rdi, rbx, times_pointer_size, kParameterMapHeaderSize));
|
| - // r9 = loop variable (tagged)
|
| + __ SmiToInteger64(r9, r9);
|
| + // r9 = loop variable (untagged)
|
| // r8 = mapping index (tagged)
|
| - // r11 = the hole value
|
| - // rdx = address of parameter map (tagged)
|
| + // rcx = address of parameter map (tagged)
|
| // rdi = address of backing store (tagged)
|
| __ jmp(¶meters_test, Label::kNear);
|
|
|
| __ bind(¶meters_loop);
|
| - __ SmiSubConstant(r9, r9, Smi::FromInt(1));
|
| - __ SmiToInteger64(kScratchRegister, r9);
|
| - __ movp(FieldOperand(rdx, kScratchRegister,
|
| - times_pointer_size,
|
| - kParameterMapHeaderSize),
|
| + __ subp(r9, Immediate(1));
|
| + __ LoadRoot(kScratchRegister, Heap::kTheHoleValueRootIndex);
|
| + __ movp(FieldOperand(rcx, r9, times_pointer_size, kParameterMapHeaderSize),
|
| r8);
|
| - __ movp(FieldOperand(rdi, kScratchRegister,
|
| - times_pointer_size,
|
| - FixedArray::kHeaderSize),
|
| - r11);
|
| + __ movp(FieldOperand(rdi, r9, times_pointer_size, FixedArray::kHeaderSize),
|
| + kScratchRegister);
|
| __ SmiAddConstant(r8, r8, Smi::FromInt(1));
|
| __ bind(¶meters_test);
|
| - __ SmiTest(r9);
|
| + __ testp(r9, r9);
|
| __ j(not_zero, ¶meters_loop, Label::kNear);
|
|
|
| __ bind(&skip_parameter_map);
|
|
|
| - // rcx = argument count (tagged)
|
| + // r11 = argument count (tagged)
|
| // rdi = address of backing store (tagged)
|
| // Copy arguments header and remaining slots (if there are any).
|
| __ Move(FieldOperand(rdi, FixedArray::kMapOffset),
|
| factory->fixed_array_map());
|
| - __ movp(FieldOperand(rdi, FixedArray::kLengthOffset), rcx);
|
| + __ movp(FieldOperand(rdi, FixedArray::kLengthOffset), r11);
|
|
|
| Label arguments_loop, arguments_test;
|
| __ movp(r8, rbx);
|
| - __ movp(rdx, args.GetArgumentOperand(1));
|
| - // Untag rcx for the loop below.
|
| - __ SmiToInteger64(rcx, rcx);
|
| + // Untag r11 for the loop below.
|
| + __ SmiToInteger64(r11, r11);
|
| __ leap(kScratchRegister, Operand(r8, times_pointer_size, 0));
|
| __ subp(rdx, kScratchRegister);
|
| __ jmp(&arguments_test, Label::kNear);
|
| @@ -797,44 +789,55 @@ void ArgumentsAccessStub::GenerateNewSloppyFast(MacroAssembler* masm) {
|
| __ addp(r8, Immediate(1));
|
|
|
| __ bind(&arguments_test);
|
| - __ cmpp(r8, rcx);
|
| + __ cmpp(r8, r11);
|
| __ j(less, &arguments_loop, Label::kNear);
|
|
|
| - // Return and remove the on-stack parameters.
|
| - __ ret(3 * kPointerSize);
|
| + // Return.
|
| + __ ret(0);
|
|
|
| // Do the runtime call to allocate the arguments object.
|
| - // rcx = argument count (untagged)
|
| + // r11 = argument count (untagged)
|
| __ bind(&runtime);
|
| - __ Integer32ToSmi(rcx, rcx);
|
| - __ movp(args.GetArgumentOperand(2), rcx); // Patch argument count.
|
| + __ Integer32ToSmi(r11, r11);
|
| + __ PopReturnAddressTo(rax);
|
| + __ Push(rdi); // Push function.
|
| + __ Push(rdx); // Push parameters pointer.
|
| + __ Push(r11); // Push parameter count.
|
| + __ PushReturnAddressFrom(rax);
|
| __ TailCallRuntime(Runtime::kNewSloppyArguments, 3, 1);
|
| }
|
|
|
|
|
| void ArgumentsAccessStub::GenerateNewSloppySlow(MacroAssembler* masm) {
|
| - // rsp[0] : return address
|
| - // rsp[8] : number of parameters
|
| - // rsp[16] : receiver displacement
|
| - // rsp[24] : function
|
| + // rcx : number of parameters (tagged)
|
| + // rdx : parameters pointer
|
| + // rdi : function
|
| + // rsp[0] : return address
|
| +
|
| + DCHECK(rdi.is(ArgumentsAccessNewDescriptor::function()));
|
| + DCHECK(rcx.is(ArgumentsAccessNewDescriptor::parameter_count()));
|
| + DCHECK(rdx.is(ArgumentsAccessNewDescriptor::parameter_pointer()));
|
|
|
| // Check if the calling frame is an arguments adaptor frame.
|
| Label runtime;
|
| - __ movp(rdx, Operand(rbp, StandardFrameConstants::kCallerFPOffset));
|
| - __ movp(rcx, Operand(rdx, StandardFrameConstants::kContextOffset));
|
| - __ Cmp(rcx, Smi::FromInt(StackFrame::ARGUMENTS_ADAPTOR));
|
| + __ movp(rbx, Operand(rbp, StandardFrameConstants::kCallerFPOffset));
|
| + __ movp(rax, Operand(rbx, StandardFrameConstants::kContextOffset));
|
| + __ Cmp(rax, Smi::FromInt(StackFrame::ARGUMENTS_ADAPTOR));
|
| __ j(not_equal, &runtime);
|
|
|
| // Patch the arguments.length and the parameters pointer.
|
| StackArgumentsAccessor args(rsp, 3, ARGUMENTS_DONT_CONTAIN_RECEIVER);
|
| - __ movp(rcx, Operand(rdx, ArgumentsAdaptorFrameConstants::kLengthOffset));
|
| - __ movp(args.GetArgumentOperand(2), rcx);
|
| - __ SmiToInteger64(rcx, rcx);
|
| - __ leap(rdx, Operand(rdx, rcx, times_pointer_size,
|
| - StandardFrameConstants::kCallerSPOffset));
|
| - __ movp(args.GetArgumentOperand(1), rdx);
|
| + __ movp(rcx, Operand(rbx, ArgumentsAdaptorFrameConstants::kLengthOffset));
|
| + __ SmiToInteger64(rax, rcx);
|
| + __ leap(rdx, Operand(rbx, rax, times_pointer_size,
|
| + StandardFrameConstants::kCallerSPOffset));
|
|
|
| __ bind(&runtime);
|
| + __ PopReturnAddressTo(rax);
|
| + __ Push(rdi); // Push function.
|
| + __ Push(rdx); // Push parameters pointer.
|
| + __ Push(rcx); // Push parameter count.
|
| + __ PushReturnAddressFrom(rax);
|
| __ TailCallRuntime(Runtime::kNewSloppyArguments, 3, 1);
|
| }
|
|
|
| @@ -901,46 +904,45 @@ void LoadIndexedStringStub::Generate(MacroAssembler* masm) {
|
|
|
|
|
| void ArgumentsAccessStub::GenerateNewStrict(MacroAssembler* masm) {
|
| - // rsp[0] : return address
|
| - // rsp[8] : number of parameters
|
| - // rsp[16] : receiver displacement
|
| - // rsp[24] : function
|
| + // rcx : number of parameters (tagged)
|
| + // rdx : parameters pointer
|
| + // rdi : function
|
| + // rsp[0] : return address
|
| +
|
| + DCHECK(rdi.is(ArgumentsAccessNewDescriptor::function()));
|
| + DCHECK(rcx.is(ArgumentsAccessNewDescriptor::parameter_count()));
|
| + DCHECK(rdx.is(ArgumentsAccessNewDescriptor::parameter_pointer()));
|
|
|
| // Check if the calling frame is an arguments adaptor frame.
|
| Label adaptor_frame, try_allocate, runtime;
|
| - __ movp(rdx, Operand(rbp, StandardFrameConstants::kCallerFPOffset));
|
| - __ movp(rcx, Operand(rdx, StandardFrameConstants::kContextOffset));
|
| - __ Cmp(rcx, Smi::FromInt(StackFrame::ARGUMENTS_ADAPTOR));
|
| + __ movp(rbx, Operand(rbp, StandardFrameConstants::kCallerFPOffset));
|
| + __ movp(rax, Operand(rbx, StandardFrameConstants::kContextOffset));
|
| + __ Cmp(rax, Smi::FromInt(StackFrame::ARGUMENTS_ADAPTOR));
|
| __ j(equal, &adaptor_frame);
|
|
|
| // Get the length from the frame.
|
| - StackArgumentsAccessor args(rsp, 3, ARGUMENTS_DONT_CONTAIN_RECEIVER);
|
| - __ movp(rcx, args.GetArgumentOperand(2));
|
| - __ SmiToInteger64(rcx, rcx);
|
| + __ SmiToInteger64(rax, rcx);
|
| __ jmp(&try_allocate);
|
|
|
| // Patch the arguments.length and the parameters pointer.
|
| __ bind(&adaptor_frame);
|
| - __ movp(rcx, Operand(rdx, ArgumentsAdaptorFrameConstants::kLengthOffset));
|
| -
|
| - __ movp(args.GetArgumentOperand(2), rcx);
|
| - __ SmiToInteger64(rcx, rcx);
|
| - __ leap(rdx, Operand(rdx, rcx, times_pointer_size,
|
| - StandardFrameConstants::kCallerSPOffset));
|
| - __ movp(args.GetArgumentOperand(1), rdx);
|
| + __ movp(rcx, Operand(rbx, ArgumentsAdaptorFrameConstants::kLengthOffset));
|
| + __ SmiToInteger64(rax, rcx);
|
| + __ leap(rdx, Operand(rbx, rax, times_pointer_size,
|
| + StandardFrameConstants::kCallerSPOffset));
|
|
|
| // Try the new space allocation. Start out with computing the size of
|
| // the arguments object and the elements array.
|
| Label add_arguments_object;
|
| __ bind(&try_allocate);
|
| - __ testp(rcx, rcx);
|
| + __ testp(rax, rax);
|
| __ j(zero, &add_arguments_object, Label::kNear);
|
| - __ leap(rcx, Operand(rcx, times_pointer_size, FixedArray::kHeaderSize));
|
| + __ leap(rax, Operand(rax, times_pointer_size, FixedArray::kHeaderSize));
|
| __ bind(&add_arguments_object);
|
| - __ addp(rcx, Immediate(Heap::kStrictArgumentsObjectSize));
|
| + __ addp(rax, Immediate(Heap::kStrictArgumentsObjectSize));
|
|
|
| // Do the allocation of both objects in one go.
|
| - __ Allocate(rcx, rax, rdx, rbx, &runtime, TAG_OBJECT);
|
| + __ Allocate(rax, rax, rbx, no_reg, &runtime, TAG_OBJECT);
|
|
|
| // Get the arguments map from the current native context.
|
| __ movp(rdi, Operand(rsi, Context::SlotOffset(Context::GLOBAL_OBJECT_INDEX)));
|
| @@ -955,7 +957,6 @@ void ArgumentsAccessStub::GenerateNewStrict(MacroAssembler* masm) {
|
|
|
| // Get the length (smi tagged) and set that as an in-object property too.
|
| STATIC_ASSERT(Heap::kArgumentsLengthIndex == 0);
|
| - __ movp(rcx, args.GetArgumentOperand(2));
|
| __ movp(FieldOperand(rax, JSObject::kHeaderSize +
|
| Heap::kArgumentsLengthIndex * kPointerSize),
|
| rcx);
|
| @@ -965,18 +966,14 @@ void ArgumentsAccessStub::GenerateNewStrict(MacroAssembler* masm) {
|
| __ testp(rcx, rcx);
|
| __ j(zero, &done);
|
|
|
| - // Get the parameters pointer from the stack.
|
| - __ movp(rdx, args.GetArgumentOperand(1));
|
| -
|
| // Set up the elements pointer in the allocated arguments object and
|
| // initialize the header in the elements fixed array.
|
| __ leap(rdi, Operand(rax, Heap::kStrictArgumentsObjectSize));
|
| __ movp(FieldOperand(rax, JSObject::kElementsOffset), rdi);
|
| __ LoadRoot(kScratchRegister, Heap::kFixedArrayMapRootIndex);
|
| __ movp(FieldOperand(rdi, FixedArray::kMapOffset), kScratchRegister);
|
| -
|
| -
|
| __ movp(FieldOperand(rdi, FixedArray::kLengthOffset), rcx);
|
| +
|
| // Untag the length for the loop below.
|
| __ SmiToInteger64(rcx, rcx);
|
|
|
| @@ -990,12 +987,17 @@ void ArgumentsAccessStub::GenerateNewStrict(MacroAssembler* masm) {
|
| __ decp(rcx);
|
| __ j(not_zero, &loop);
|
|
|
| - // Return and remove the on-stack parameters.
|
| + // Return.
|
| __ bind(&done);
|
| - __ ret(3 * kPointerSize);
|
| + __ ret(0);
|
|
|
| // Do the runtime call to allocate the arguments object.
|
| __ bind(&runtime);
|
| + __ PopReturnAddressTo(rax);
|
| + __ Push(rdi); // Push function.
|
| + __ Push(rdx); // Push parameters pointer.
|
| + __ Push(rcx); // Push parameter count.
|
| + __ PushReturnAddressFrom(rax);
|
| __ TailCallRuntime(Runtime::kNewStrictArguments, 3, 1);
|
| }
|
|
|
|
|