From e3b1fe2c146370c0bb4e7464a0aa801bbd4334e4 Mon Sep 17 00:00:00 2001 From: "vegorov@chromium.org" Date: Tue, 5 Jul 2011 11:36:52 +0000 Subject: [PATCH] Fix ABI for API calls on ia32. Instead of relying on eax value after the call load returned handle value directly from the slot that was preallocated for it. R=vitalyr@chromium.org Review URL: http://codereview.chromium.org/7307004 git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@8533 ce2b1a6d-e550-0410-aec6-3dcde31c8c00 --- src/ia32/macro-assembler-ia32.cc | 26 ++++++++++++-------------- src/ia32/macro-assembler-ia32.h | 8 ++++---- src/ia32/stub-cache-ia32.cc | 4 ++-- 3 files changed, 18 insertions(+), 20 deletions(-) diff --git a/src/ia32/macro-assembler-ia32.cc b/src/ia32/macro-assembler-ia32.cc index feb82684e..020acded7 100644 --- a/src/ia32/macro-assembler-ia32.cc +++ b/src/ia32/macro-assembler-ia32.cc @@ -1412,32 +1412,30 @@ Operand ApiParameterOperand(int index) { } -void MacroAssembler::PrepareCallApiFunction(int argc, Register scratch) { +void MacroAssembler::PrepareCallApiFunction(int argc) { if (kReturnHandlesDirectly) { EnterApiExitFrame(argc); // When handles are returned directly we don't have to allocate extra // space for and pass an out parameter. + if (emit_debug_code()) { + mov(esi, Immediate(BitCast(kZapValue))); + } } else { // We allocate two additional slots: return value and pointer to it. EnterApiExitFrame(argc + 2); // The argument slots are filled as follows: // - // n + 1: output cell + // n + 1: output slot // n: arg n // ... // 1: arg1 - // 0: pointer to the output cell - // - // Note that this is one more "argument" than the function expects - // so the out cell will have to be popped explicitly after returning - // from the function. The out cell contains Handle. + // 0: pointer to the output slot - // pointer to out cell. - lea(scratch, Operand(esp, (argc + 1) * kPointerSize)); - mov(Operand(esp, 0 * kPointerSize), scratch); // output. + lea(esi, Operand(esp, (argc + 1) * kPointerSize)); + mov(Operand(esp, 0 * kPointerSize), esi); if (emit_debug_code()) { - mov(Operand(esp, (argc + 1) * kPointerSize), Immediate(0)); // out cell. + mov(Operand(esi, 0), Immediate(0)); } } } @@ -1461,9 +1459,9 @@ MaybeObject* MacroAssembler::TryCallApiFunctionAndReturn(ApiFunction* function, call(function->address(), RelocInfo::RUNTIME_ENTRY); if (!kReturnHandlesDirectly) { - // The returned value is a pointer to the handle holding the result. - // Dereference this to get to the location. - mov(eax, Operand(eax, 0)); + // PrepareCallApiFunction saved pointer to the output slot into + // callee-save register esi. + mov(eax, Operand(esi, 0)); } Label empty_handle; diff --git a/src/ia32/macro-assembler-ia32.h b/src/ia32/macro-assembler-ia32.h index a638517da..837c500e9 100644 --- a/src/ia32/macro-assembler-ia32.h +++ b/src/ia32/macro-assembler-ia32.h @@ -558,10 +558,10 @@ class MacroAssembler: public Assembler { // Prepares stack to put arguments (aligns and so on). Reserves // space for return value if needed (assumes the return value is a handle). - // Uses callee-saved esi to restore stack state after call. Arguments must be - // stored in ApiParameterOperand(0), ApiParameterOperand(1) etc. Saves - // context (esi). - void PrepareCallApiFunction(int argc, Register scratch); + // Arguments must be stored in ApiParameterOperand(0), ApiParameterOperand(1) + // etc. Saves context (esi). If space was reserved for return value then + // stores the pointer to the reserved slot into esi. + void PrepareCallApiFunction(int argc); // Calls an API function. Allocates HandleScope, extracts // returned value from handle and propagates exceptions. diff --git a/src/ia32/stub-cache-ia32.cc b/src/ia32/stub-cache-ia32.cc index 3bce00076..e53cc0839 100644 --- a/src/ia32/stub-cache-ia32.cc +++ b/src/ia32/stub-cache-ia32.cc @@ -459,7 +459,7 @@ static MaybeObject* GenerateFastApiCall(MacroAssembler* masm, // it's not controlled by GC. const int kApiStackSpace = 4; - __ PrepareCallApiFunction(kApiArgc + kApiStackSpace, ebx); + __ PrepareCallApiFunction(kApiArgc + kApiStackSpace); __ mov(ApiParameterOperand(1), eax); // v8::Arguments::implicit_args_. __ add(Operand(eax), Immediate(argc * kPointerSize)); @@ -1082,7 +1082,7 @@ MaybeObject* StubCompiler::GenerateLoadCallback(JSObject* object, const int kStackSpace = 5; const int kApiArgc = 2; - __ PrepareCallApiFunction(kApiArgc, eax); + __ PrepareCallApiFunction(kApiArgc); __ mov(ApiParameterOperand(0), ebx); // name. __ add(Operand(ebx), Immediate(kPointerSize)); __ mov(ApiParameterOperand(1), ebx); // arguments pointer. -- 2.34.1