From: palfia@homejinni.com Date: Sat, 25 May 2013 17:10:42 +0000 (+0000) Subject: MIPS: Fix DIRECT_API_CALL_NEW and DIRECT_GETTER_CALL_NEW call. X-Git-Tag: upstream/4.7.83~14120 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=f2350072bd0a4eef1bbaeb253a1532473a9b6504;p=platform%2Fupstream%2Fv8.git MIPS: Fix DIRECT_API_CALL_NEW and DIRECT_GETTER_CALL_NEW call. This commit fixes the register usage of DIRECT_API_CALL_NEW and DIRECT_GETTER_CALL_NEW: * These functions expect arguments in a0-a1 and not in a1-a2 as the and DIRECT_API_CALL and DIRECT_GETTER_CALL do. * Fixes the simulator to expect *_NEW arguments in a0-a1. * Adds more comment to simulator to better explain the register usage. TEST=cctest/test-api/LoadICFastApi_DirectCall_GCMoveStub,cctest/test-api/SimpleCallback BUG= Review URL: https://codereview.chromium.org/15813005 git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@14813 ce2b1a6d-e550-0410-aec6-3dcde31c8c00 --- diff --git a/src/mips/macro-assembler-mips.cc b/src/mips/macro-assembler-mips.cc index e3c8b33a9..2e1dea8f0 100644 --- a/src/mips/macro-assembler-mips.cc +++ b/src/mips/macro-assembler-mips.cc @@ -3944,7 +3944,9 @@ void MacroAssembler::CallApiFunctionAndReturn(ExternalReference function, // (4 bytes) will be placed. This is also built into the Simulator. // Set up the pointer to the returned value (a0). It was allocated in // EnterExitFrame. - addiu(a0, fp, ExitFrameConstants::kStackSpaceOffset); + if (returns_handle) { + addiu(a0, fp, ExitFrameConstants::kStackSpaceOffset); + } // Native call returns to the DirectCEntry stub which redirects to the // return address pushed on stack (could have moved after GC). diff --git a/src/mips/simulator-mips.cc b/src/mips/simulator-mips.cc index 18e78a5ab..baf042c3b 100644 --- a/src/mips/simulator-mips.cc +++ b/src/mips/simulator-mips.cc @@ -1387,12 +1387,19 @@ typedef double (*SimulatorRuntimeFPIntCall)(double darg0, int32_t arg0); // This signature supports direct call in to API function native callback // (refer to InvocationCallback in v8.h). +// NOTE: the O32 abi requires a0 to hold a special pointer when returning a +// struct from the function (which is currently the case). This means we pass +// the first argument in a1 instead of a0. typedef v8::Handle (*SimulatorRuntimeDirectApiCall)(int32_t arg0); +// Here, we pass the first argument in a0, because this function +// does not return a struct. typedef void (*SimulatorRuntimeDirectApiCallNew)(int32_t arg0); // This signature supports direct call to accessor getter callback. +// See comment at SimulatorRuntimeDirectApiCall. typedef v8::Handle (*SimulatorRuntimeDirectGetterCall)(int32_t arg0, int32_t arg1); +// See comment at SimulatorRuntimeDirectApiCallNew. typedef void (*SimulatorRuntimeDirectGetterCallNew)(int32_t arg0, int32_t arg1); @@ -1542,40 +1549,50 @@ void Simulator::SoftwareInterrupt(Instruction* instr) { } else if ( redirection->type() == ExternalReference::DIRECT_API_CALL || redirection->type() == ExternalReference::DIRECT_API_CALL_NEW) { - // See DirectCEntryStub::GenerateCall for explanation of register usage. - if (::v8::internal::FLAG_trace_sim) { - PrintF("Call to host function at %p args %08x\n", - reinterpret_cast(external), arg1); - } if (redirection->type() == ExternalReference::DIRECT_API_CALL) { + // See comment at type definition of SimulatorRuntimeDirectApiCall + // for explanation of register usage. + if (::v8::internal::FLAG_trace_sim) { + PrintF("Call to host function at %p args %08x\n", + reinterpret_cast(external), arg1); + } SimulatorRuntimeDirectApiCall target = reinterpret_cast(external); v8::Handle result = target(arg1); *(reinterpret_cast(arg0)) = reinterpret_cast(*result); set_register(v0, arg0); } else { + if (::v8::internal::FLAG_trace_sim) { + PrintF("Call to host function at %p args %08x\n", + reinterpret_cast(external), arg0); + } SimulatorRuntimeDirectApiCallNew target = reinterpret_cast(external); - target(arg1); + target(arg0); } } else if ( redirection->type() == ExternalReference::DIRECT_GETTER_CALL || redirection->type() == ExternalReference::DIRECT_GETTER_CALL_NEW) { - // See DirectCEntryStub::GenerateCall for explanation of register usage. - if (::v8::internal::FLAG_trace_sim) { - PrintF("Call to host function at %p args %08x %08x\n", - reinterpret_cast(external), arg1, arg2); - } if (redirection->type() == ExternalReference::DIRECT_GETTER_CALL) { + // See comment at type definition of SimulatorRuntimeDirectGetterCall + // for explanation of register usage. + if (::v8::internal::FLAG_trace_sim) { + PrintF("Call to host function at %p args %08x %08x\n", + reinterpret_cast(external), arg1, arg2); + } SimulatorRuntimeDirectGetterCall target = reinterpret_cast(external); v8::Handle result = target(arg1, arg2); *(reinterpret_cast(arg0)) = reinterpret_cast(*result); set_register(v0, arg0); } else { + if (::v8::internal::FLAG_trace_sim) { + PrintF("Call to host function at %p args %08x %08x\n", + reinterpret_cast(external), arg0, arg1); + } SimulatorRuntimeDirectGetterCallNew target = reinterpret_cast(external); - target(arg1, arg2); + target(arg0, arg1); } } else { SimulatorRuntimeCall target = diff --git a/src/mips/stub-cache-mips.cc b/src/mips/stub-cache-mips.cc index d95f3becb..7e7a3f77e 100644 --- a/src/mips/stub-cache-mips.cc +++ b/src/mips/stub-cache-mips.cc @@ -924,28 +924,31 @@ static void GenerateFastApiDirectCall(MacroAssembler* masm, // NOTE: the O32 abi requires a0 to hold a special pointer when returning a // struct from the function (which is currently the case). This means we pass - // the first argument in a1 instead of a0. TryCallApiFunctionAndReturn - // will handle setting up a0. + // the first argument in a1 instead of a0, if returns_handle is true. + // CallApiFunctionAndReturn will set up a0. - // a1 = v8::Arguments& + Address function_address = v8::ToCData
(api_call_info->callback()); + bool returns_handle = + !CallbackTable::ReturnsVoid(masm->isolate(), function_address); + + Register first_arg = returns_handle ? a1 : a0; + + // first_arg = v8::Arguments& // Arguments is built at sp + 1 (sp is a reserved spot for ra). - __ Addu(a1, sp, kPointerSize); + __ Addu(first_arg, sp, kPointerSize); // v8::Arguments::implicit_args_ - __ sw(a2, MemOperand(a1, 0 * kPointerSize)); + __ sw(a2, MemOperand(first_arg, 0 * kPointerSize)); // v8::Arguments::values_ __ Addu(t0, a2, Operand(argc * kPointerSize)); - __ sw(t0, MemOperand(a1, 1 * kPointerSize)); + __ sw(t0, MemOperand(first_arg, 1 * kPointerSize)); // v8::Arguments::length_ = argc __ li(t0, Operand(argc)); - __ sw(t0, MemOperand(a1, 2 * kPointerSize)); + __ sw(t0, MemOperand(first_arg, 2 * kPointerSize)); // v8::Arguments::is_construct_call = 0 - __ sw(zero_reg, MemOperand(a1, 3 * kPointerSize)); + __ sw(zero_reg, MemOperand(first_arg, 3 * kPointerSize)); const int kStackUnwindSpace = argc + kFastApiCallArguments + 1; - Address function_address = v8::ToCData
(api_call_info->callback()); - bool returns_handle = - !CallbackTable::ReturnsVoid(masm->isolate(), function_address); ApiFunction fun(function_address); ExternalReference::Type type = returns_handle ? @@ -1442,13 +1445,20 @@ void BaseLoadStubCompiler::GenerateLoadCallback( __ sw(scratch4(), MemOperand(sp, 1 * kPointerSize)); __ sw(name(), MemOperand(sp, 0 * kPointerSize)); + Address getter_address = v8::ToCData
(callback->getter()); + bool returns_handle = + !CallbackTable::ReturnsVoid(isolate(), getter_address); + + Register first_arg = returns_handle ? a1 : a0; + Register second_arg = returns_handle ? a2 : a1; + __ mov(a2, scratch2()); // Saved in case scratch2 == a1. - __ mov(a1, sp); // a1 (first argument - see note below) = Handle + __ mov(first_arg, sp); // (first argument - see note below) = Handle // NOTE: the O32 abi requires a0 to hold a special pointer when returning a // struct from the function (which is currently the case). This means we pass - // the arguments in a1-a2 instead of a0-a1. TryCallApiFunctionAndReturn - // will handle setting up a0. + // the arguments in a1-a2 instead of a0-a1, if returns_handle is true. + // CallApiFunctionAndReturn will set up a0. const int kApiStackSpace = 1; FrameScope frame_scope(masm(), StackFrame::MANUAL); @@ -1457,13 +1467,10 @@ void BaseLoadStubCompiler::GenerateLoadCallback( // Create AccessorInfo instance on the stack above the exit frame with // scratch2 (internal::Object** args_) as the data. __ sw(a2, MemOperand(sp, kPointerSize)); - // a2 (second argument - see note above) = AccessorInfo& - __ Addu(a2, sp, kPointerSize); + // (second argument - see note above) = AccessorInfo& + __ Addu(second_arg, sp, kPointerSize); const int kStackUnwindSpace = kFastApiCallArguments + 1; - Address getter_address = v8::ToCData
(callback->getter()); - bool returns_handle = - !CallbackTable::ReturnsVoid(isolate(), getter_address); ApiFunction fun(getter_address); ExternalReference::Type type = returns_handle ?