| Index: src/x64/builtins-x64.cc
|
| ===================================================================
|
| --- src/x64/builtins-x64.cc (revision 15486)
|
| +++ src/x64/builtins-x64.cc (working copy)
|
| @@ -38,8 +38,11 @@
|
|
|
|
|
| #define __ ACCESS_MASM(masm)
|
| +#define __k __
|
| +#define __q __
|
| +#define __a __
|
| +#define __a __
|
|
|
| -
|
| void Builtins::Generate_Adaptor(MacroAssembler* masm,
|
| CFunctionId id,
|
| BuiltinExtraArguments extra_args) {
|
| @@ -59,9 +62,9 @@
|
| int num_extra_args = 0;
|
| if (extra_args == NEEDS_CALLED_FUNCTION) {
|
| num_extra_args = 1;
|
| - __ pop(kScratchRegister); // Save return address.
|
| + __k pop(kScratchRegister); // Save return address.
|
| __ push(rdi);
|
| - __ push(kScratchRegister); // Restore return address.
|
| + __k push(kScratchRegister); // Restore return address.
|
| } else {
|
| ASSERT(extra_args == NO_EXTRA_ARGUMENTS);
|
| }
|
| @@ -429,10 +432,10 @@
|
| }
|
|
|
| // Remove caller arguments from the stack and return.
|
| - __ pop(rcx);
|
| + __k pop(rcx);
|
| SmiIndex index = masm->SmiToIndex(rbx, rbx, kPointerSizeLog2);
|
| __ lea(rsp, Operand(rsp, index.reg, index.scale, 1 * kPointerSize));
|
| - __ push(rcx);
|
| + __k push(rcx);
|
| Counters* counters = masm->isolate()->counters();
|
| __ IncrementCounter(counters->constructed_objects(), 1);
|
| __ ret(0);
|
| @@ -689,7 +692,7 @@
|
| // Tear down internal frame.
|
| }
|
|
|
| - __ pop(MemOperand(rsp, 0)); // Ignore state offset
|
| + __k pop(MemOperand(rsp, 0)); // Ignore state offset
|
| __ ret(0); // Return to IC Miss stub, continuation still on stack.
|
| }
|
|
|
| @@ -708,19 +711,19 @@
|
| }
|
|
|
| // Get the full codegen state from the stack and untag it.
|
| - __ SmiToInteger32(r10, Operand(rsp, 1 * kPointerSize));
|
| + __a SmiToInteger32(r10, Operand(rsp, 1 * kPointerSize));
|
|
|
| // Switch on the state.
|
| Label not_no_registers, not_tos_rax;
|
| __ cmpq(r10, Immediate(FullCodeGenerator::NO_REGISTERS));
|
| __ j(not_equal, ¬_no_registers, Label::kNear);
|
| - __ ret(1 * kPointerSize); // Remove state.
|
| + __q ret(1 * kPointerSize); // Remove state.
|
|
|
| __ bind(¬_no_registers);
|
| - __ movq(rax, Operand(rsp, 2 * kPointerSize));
|
| + __q movq(rax, Operand(rsp, 2 * kPointerSize));
|
| __ cmpq(r10, Immediate(FullCodeGenerator::TOS_REG));
|
| __ j(not_equal, ¬_tos_rax, Label::kNear);
|
| - __ ret(2 * kPointerSize); // Remove state, rax.
|
| + __a ret(2 * kPointerSize); // Remove state, rax.
|
|
|
| __ bind(¬_tos_rax);
|
| __ Abort("no cases left");
|
| @@ -771,9 +774,9 @@
|
| { Label done;
|
| __ testq(rax, rax);
|
| __ j(not_zero, &done);
|
| - __ pop(rbx);
|
| + __k pop(rbx);
|
| __ Push(masm->isolate()->factory()->undefined_value());
|
| - __ push(rbx);
|
| + __k push(rbx);
|
| __ incq(rax);
|
| __ bind(&done);
|
| }
|
| @@ -782,7 +785,7 @@
|
| // if it is a function.
|
| Label slow, non_function;
|
| // The function to call is at position n+1 on the stack.
|
| - __ movq(rdi, Operand(rsp, rax, times_pointer_size, 1 * kPointerSize));
|
| + __a movq(rdi, Operand(rsp, rax, times_pointer_size, 1 * kPointerSize));
|
| __ JumpIfSmi(rdi, &non_function);
|
| __ CmpObjectType(rdi, JS_FUNCTION_TYPE, rcx);
|
| __ j(not_equal, &slow);
|
| @@ -807,7 +810,7 @@
|
| __ j(not_zero, &shift_arguments);
|
|
|
| // Compute the receiver in non-strict mode.
|
| - __ movq(rbx, Operand(rsp, rax, times_pointer_size, 0));
|
| + __a movq(rbx, Operand(rsp, rax, times_pointer_size, 0));
|
| __ JumpIfSmi(rbx, &convert_to_object, Label::kNear);
|
|
|
| __ CompareRoot(rbx, Heap::kNullValueRootIndex);
|
| @@ -836,7 +839,7 @@
|
| }
|
|
|
| // Restore the function to rdi.
|
| - __ movq(rdi, Operand(rsp, rax, times_pointer_size, 1 * kPointerSize));
|
| + __a movq(rdi, Operand(rsp, rax, times_pointer_size, 1 * kPointerSize));
|
| __ jmp(&patch_receiver, Label::kNear);
|
|
|
| // Use the global receiver object from the called function as the
|
| @@ -850,8 +853,7 @@
|
| __ movq(rbx, FieldOperand(rbx, GlobalObject::kGlobalReceiverOffset));
|
|
|
| __ bind(&patch_receiver);
|
| - __ movq(Operand(rsp, rax, times_pointer_size, 0), rbx);
|
| -
|
| + __a movq(Operand(rsp, rax, times_pointer_size, 0), rbx);
|
| __ jmp(&shift_arguments);
|
| }
|
|
|
| @@ -867,7 +869,7 @@
|
| // CALL_NON_FUNCTION builtin expects the non-function callee as
|
| // receiver, so overwrite the first argument which will ultimately
|
| // become the receiver.
|
| - __ movq(Operand(rsp, rax, times_pointer_size, 0), rdi);
|
| + __a movq(Operand(rsp, rax, times_pointer_size, 0), rdi);
|
|
|
| // 4. Shift arguments and return address one slot down on the stack
|
| // (overwriting the original receiver). Adjust argument count to make
|
| @@ -875,12 +877,19 @@
|
| __ bind(&shift_arguments);
|
| { Label loop;
|
| __ movq(rcx, rax);
|
| +#ifdef V8_TARGET_ARCH_X32
|
| + __ incl(rcx); // HWRegSize = kPointerSize + kPointerSize
|
| +#endif
|
| __ bind(&loop);
|
| __ movq(rbx, Operand(rsp, rcx, times_pointer_size, 0));
|
| __ movq(Operand(rsp, rcx, times_pointer_size, 1 * kPointerSize), rbx);
|
| __ decq(rcx);
|
| __ j(not_sign, &loop); // While non-negative (to copy return address).
|
| +#ifndef V8_TARGET_ARCH_X32
|
| __ pop(rbx); // Discard copy of return address.
|
| +#else
|
| + __ leal(rsp, Operand(rsp, 4)); // Discard bottom-half of return address
|
| +#endif
|
| __ decq(rax); // One fewer argument (first argument is new receiver).
|
| }
|
|
|
| @@ -894,9 +903,9 @@
|
| __ cmpq(rdx, Immediate(1));
|
| __ j(not_equal, &non_proxy);
|
|
|
| - __ pop(rdx); // return address
|
| + __k pop(rdx); // return address
|
| __ push(rdi); // re-add proxy object as additional argument
|
| - __ push(rdx);
|
| + __k push(rdx);
|
| __ incq(rax);
|
| __ GetBuiltinEntry(rdx, Builtins::CALL_FUNCTION_PROXY);
|
| __ jmp(masm->isolate()->builtins()->ArgumentsAdaptorTrampoline(),
|
| @@ -913,9 +922,17 @@
|
| // expected arguments matches what we're providing. If so, jump
|
| // (tail-call) to the code in register edx without checking arguments.
|
| __ movq(rdx, FieldOperand(rdi, JSFunction::kSharedFunctionInfoOffset));
|
| +#ifndef V8_TARGET_ARCH_X32
|
| __ movsxlq(rbx,
|
| FieldOperand(rdx,
|
| SharedFunctionInfo::kFormalParameterCountOffset));
|
| +#else
|
| + // kFormalParameterCountOffset is not tagged in X64, while tagged in X32.
|
| + __ movl(rbx,
|
| + FieldOperand(rdx,
|
| + SharedFunctionInfo::kFormalParameterCountOffset));
|
| + __ SmiToInteger32(rbx, rbx);
|
| +#endif
|
| __ movq(rdx, FieldOperand(rdi, JSFunction::kCodeEntryOffset));
|
| __ SetCallKind(rcx, CALL_AS_METHOD);
|
| __ cmpq(rax, rbx);
|
| @@ -943,9 +960,15 @@
|
| // rbp[16] : function arguments
|
| // rbp[24] : receiver
|
| // rbp[32] : function
|
| +#ifndef V8_TARGET_ARCH_X32
|
| static const int kArgumentsOffset = 2 * kPointerSize;
|
| static const int kReceiverOffset = 3 * kPointerSize;
|
| static const int kFunctionOffset = 4 * kPointerSize;
|
| +#else
|
| + static const int kArgumentsOffset = 2 * kHWRegSize;
|
| + static const int kReceiverOffset = 2 * kHWRegSize + 1 * kPointerSize;
|
| + static const int kFunctionOffset = 2 * kHWRegSize + 2 * kPointerSize;
|
| +#endif
|
|
|
| __ push(Operand(rbp, kFunctionOffset));
|
| __ push(Operand(rbp, kArgumentsOffset));
|
| @@ -1180,10 +1203,10 @@
|
| Label no_arguments;
|
| __ testq(rax, rax);
|
| __ j(zero, &no_arguments);
|
| - __ movq(rbx, Operand(rsp, rax, times_pointer_size, 0));
|
| - __ pop(rcx);
|
| - __ lea(rsp, Operand(rsp, rax, times_pointer_size, kPointerSize));
|
| - __ push(rcx);
|
| + __a movq(rbx, Operand(rsp, rax, times_pointer_size, 0));
|
| + __k pop(rcx);
|
| + __ lea(rsp, Operand(rsp, rax, times_pointer_size, 1 * kPointerSize));
|
| + __k push(rcx);
|
| __ movq(rax, rbx);
|
|
|
| // Lookup the argument in the number to string cache.
|
| @@ -1268,9 +1291,9 @@
|
| // stack, and jump back to the case where the argument is a string.
|
| __ bind(&no_arguments);
|
| __ LoadRoot(rbx, Heap::kempty_stringRootIndex);
|
| - __ pop(rcx);
|
| - __ lea(rsp, Operand(rsp, kPointerSize));
|
| - __ push(rcx);
|
| + __k pop(rcx);
|
| + __ lea(rsp, Operand(rsp, 1 * kPointerSize));
|
| + __k push(rcx);
|
| __ jmp(&argument_is_string);
|
|
|
| // At this point the argument is already a string. Call runtime to
|
| @@ -1313,10 +1336,10 @@
|
| __ pop(rbp);
|
|
|
| // Remove caller arguments from the stack.
|
| - __ pop(rcx);
|
| + __k pop(rcx);
|
| SmiIndex index = masm->SmiToIndex(rbx, rbx, kPointerSizeLog2);
|
| __ lea(rsp, Operand(rsp, index.reg, index.scale, 1 * kPointerSize));
|
| - __ push(rcx);
|
| + __k push(rcx);
|
| }
|
|
|
|
|
| @@ -1427,7 +1450,7 @@
|
| __ bind(&skip);
|
| // Untag the AST id and push it on the stack.
|
| __ SmiToInteger32(rax, rax);
|
| - __ push(rax);
|
| + __k push(rax);
|
|
|
| // Generate the code for doing the frame-to-frame translation using
|
| // the deoptimizer infrastructure.
|
| @@ -1435,7 +1458,10 @@
|
| generator.Generate();
|
| }
|
|
|
| -
|
| +#undef __a
|
| +#undef __a
|
| +#undef __q
|
| +#undef __k
|
| #undef __
|
|
|
| } } // namespace v8::internal
|
|
|