| Index: src/x64/macro-assembler-x64.cc
|
| ===================================================================
|
| --- src/x64/macro-assembler-x64.cc (revision 3911)
|
| +++ src/x64/macro-assembler-x64.cc (working copy)
|
| @@ -37,6 +37,15 @@
|
| namespace v8 {
|
| namespace internal {
|
|
|
| +const Register kCArgRegs[kCArgRegsCount] = {
|
| +#ifdef _WIN64
|
| + rcx, rdx, r8, r9
|
| +#else
|
| + rdi, rsi, rdx, rcx, r8, r9
|
| +#endif
|
| +};
|
| +
|
| +
|
| MacroAssembler::MacroAssembler(void* buffer, int size)
|
| : Assembler(buffer, size),
|
| generating_stub_(false),
|
| @@ -371,18 +380,35 @@
|
| // constant, we check that the actual number of arguments match the
|
| // expectation.
|
| if (f->nargs >= 0 && f->nargs != num_arguments) {
|
| - IllegalOperation(num_arguments);
|
| + int num_args_on_stack =
|
| + (Runtime::EXIT_FRAME_CALL == f->calling_convention) ? 0 : num_arguments;
|
| + IllegalOperation(num_args_on_stack);
|
| return;
|
| }
|
|
|
| - // TODO(1236192): Most runtime routines don't need the number of
|
| - // arguments passed in because it is constant. At some point we
|
| - // should remove this need and make the runtime routine entry code
|
| - // smarter.
|
| - movq(rax, Immediate(num_arguments));
|
| - movq(rbx, ExternalReference(f));
|
| - CEntryStub ces(f->result_size);
|
| - CallStub(&ces);
|
| + switch (f->calling_convention) {
|
| + case Runtime::EXIT_FRAME_CALL: {
|
| + // Arguments are expected to be pushed on stack in left-to-right order.
|
| + // The stub will pass reference to them as Arguments into the function.
|
| +
|
| + // TODO(1236192): Most runtime routines don't need the number of
|
| + // arguments passed in because it is constant. At some point we
|
| + // should remove this need and make the runtime routine entry code
|
| + // smarter.
|
| + movq(rax, Immediate(num_arguments));
|
| + movq(rbx, ExternalReference(f));
|
| + CEntryStub ces(f->result_size);
|
| + CallStub(&ces);
|
| + break;
|
| + }
|
| + case Runtime::DIRECT_CALL_NOT_FAILS:
|
| + // Arguments are expected to be put into the registers in order of
|
| + // kCArgRegs.
|
| + ASSERT(num_arguments <= kCArgRegsCount);
|
| + PrepareCallCFunction(num_arguments);
|
| + CallCFunction(ExternalReference(f), num_arguments);
|
| + break;
|
| + }
|
| }
|
|
|
|
|
| @@ -395,8 +421,30 @@
|
| CallStub(&stub);
|
| }
|
|
|
| +void MacroAssembler::TailCallRuntime(Runtime::FunctionId id,
|
| + int num_arguments,
|
| + int result_size) {
|
| + Runtime::Function* f = Runtime::FunctionForId(id);
|
|
|
| -void MacroAssembler::TailCallRuntime(ExternalReference const& ext,
|
| + ASSERT(f->nargs == -1 || f->nargs == num_arguments);
|
| + if (f->calling_convention == Runtime::EXIT_FRAME_CALL) {
|
| + TailCallExternalReference(ExternalReference(f), num_arguments, result_size);
|
| + } else if (f->calling_convention == Runtime::DIRECT_CALL_NOT_FAILS) {
|
| + // Move arguments to registers
|
| + ASSERT(kCArgRegsCount >= num_arguments);
|
| + pop(rax); // get return address
|
| + for (int i = 0; i < num_arguments; i++) {
|
| + pop(kCArgRegs[num_arguments - 1 - i]);
|
| + }
|
| + PrepareCallCFunction(num_arguments); // align stack
|
| + movq(kScratchRegister, ExternalReference(f));
|
| + push(rax); // return
|
| + jmp(kScratchRegister);
|
| + }
|
| +}
|
| +
|
| +
|
| +void MacroAssembler::TailCallExternalReference(ExternalReference const& ext,
|
| int num_arguments,
|
| int result_size) {
|
| // ----------- S t a t e -------------
|
|
|