| Index: src/x64/virtual-frame-x64.cc
|
| ===================================================================
|
| --- src/x64/virtual-frame-x64.cc (revision 3911)
|
| +++ src/x64/virtual-frame-x64.cc (working copy)
|
| @@ -976,9 +976,41 @@
|
|
|
|
|
| Result VirtualFrame::CallRuntime(Runtime::Function* f, int arg_count) {
|
| - PrepareForCall(arg_count, arg_count);
|
| - ASSERT(cgen()->HasValidEntryRegisters());
|
| - __ CallRuntime(f, arg_count);
|
| + if (Runtime::DIRECT_CALL_NOT_FAILS == f->calling_convention) {
|
| + ASSERT(height() >= arg_count);
|
| + if (arg_count > kCArgRegsCount) {
|
| + Forget(arg_count);
|
| + return Result(Factory::undefined_value());
|
| + }
|
| +
|
| + for (int i = arg_count - 1; i >= 0; i--) {
|
| + Result arg = Pop();
|
| + Register reg = kCArgRegs[i];
|
| + if (RegisterAllocator::IsReserved(reg)) {
|
| + arg.ToRegister();
|
| + __ movq(reg, arg.reg());
|
| + arg.Unuse();
|
| + } else {
|
| + arg.ToRegister(reg);
|
| + arg.Unuse();
|
| + }
|
| + }
|
| +
|
| + // TODO(serya): do not spill out C callee saved registers
|
| + PrepareForCall(0, 0);
|
| +
|
| + ASSERT(cgen()->HasValidEntryRegisters());
|
| + __ CallRuntime(f, arg_count);
|
| + if ((1 << rsi.code()) & kCCallerSaved) {
|
| + RestoreContextRegister();
|
| + }
|
| + } else {
|
| + ASSERT(Runtime::EXIT_FRAME_CALL == f->calling_convention);
|
| + PrepareForCall(arg_count, arg_count);
|
| + ASSERT(cgen()->HasValidEntryRegisters());
|
| + __ CallRuntime(f, arg_count);
|
| + }
|
| +
|
| Result result = cgen()->allocator()->Allocate(rax);
|
| ASSERT(result.is_valid());
|
| return result;
|
| @@ -986,12 +1018,7 @@
|
|
|
|
|
| Result VirtualFrame::CallRuntime(Runtime::FunctionId id, int arg_count) {
|
| - PrepareForCall(arg_count, arg_count);
|
| - ASSERT(cgen()->HasValidEntryRegisters());
|
| - __ CallRuntime(id, arg_count);
|
| - Result result = cgen()->allocator()->Allocate(rax);
|
| - ASSERT(result.is_valid());
|
| - return result;
|
| + return CallRuntime(Runtime::FunctionForId(id), arg_count);
|
| }
|
|
|
|
|
|
|