| 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); | 
| } | 
|  | 
|  |