From: dslomov@chromium.org Date: Tue, 30 Apr 2013 11:34:43 +0000 (+0000) Subject: Accurate function prototypes for native calls from ARM simulator. X-Git-Tag: upstream/4.7.83~14386 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=acf1a7c91c952a91f5a2d77fbfbdddba99a8f452;p=platform%2Fupstream%2Fv8.git Accurate function prototypes for native calls from ARM simulator. This is a resubmit of codereview.chromium.org/13818012 with the following modifications: - src/x64/code-stubs-x64.cc for changes specific to Win64 calling conventions. - src/sampler.cc for Native Client support BUG=v8:2614 Committed: https://code.google.com/p/v8/source/detail?r=14491 Review URL: https://codereview.chromium.org/14305029 Patch from Brad Chen . git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@14494 ce2b1a6d-e550-0410-aec6-3dcde31c8c00 --- diff --git a/src/arguments.h b/src/arguments.h index f8fb00c57..1423d5642 100644 --- a/src/arguments.h +++ b/src/arguments.h @@ -115,15 +115,18 @@ class CustomArguments : public Relocatable { #define DECLARE_RUNTIME_FUNCTION(Type, Name) \ -Type Name(Arguments args, Isolate* isolate) - - -#define RUNTIME_FUNCTION(Type, Name) \ -Type Name(Arguments args, Isolate* isolate) - - -#define RUNTIME_ARGUMENTS(isolate, args) args, isolate - +Type Name(int args_length, Object** args_object, Isolate* isolate) + +#define RUNTIME_FUNCTION(Type, Name) \ +static Type __RT_impl_##Name(Arguments args, Isolate* isolate); \ +Type Name(int args_length, Object** args_object, Isolate* isolate) { \ + Arguments args(args_length, args_object); \ + return __RT_impl_##Name(args, isolate); \ +} \ +static Type __RT_impl_##Name(Arguments args, Isolate* isolate) + +#define RUNTIME_ARGUMENTS(isolate, args) \ + args.length(), args.arguments(), isolate } } // namespace v8::internal diff --git a/src/arm/code-stubs-arm.cc b/src/arm/code-stubs-arm.cc index cc6caca3d..7b7fae392 100644 --- a/src/arm/code-stubs-arm.cc +++ b/src/arm/code-stubs-arm.cc @@ -30,6 +30,7 @@ #if defined(V8_TARGET_ARCH_ARM) #include "bootstrapper.h" +#include "builtins-decls.h" #include "code-stubs.h" #include "regexp-macro-assembler.h" #include "stub-cache.h" diff --git a/src/arm/simulator-arm.cc b/src/arm/simulator-arm.cc index 036fd7f87..af65bc70b 100644 --- a/src/arm/simulator-arm.cc +++ b/src/arm/simulator-arm.cc @@ -975,12 +975,14 @@ ReturnType Simulator::GetFromVFPRegister(int reg_index) { } -// For use in calls that take two double values, constructed either +// Runtime FP routines take up to two double arguments and zero +// or one integer arguments. All are consructed here. // from r0-r3 or d0 and d1. -void Simulator::GetFpArgs(double* x, double* y) { +void Simulator::GetFpArgs(double* x, double* y, int32_t* z) { if (use_eabi_hardfloat()) { *x = vfp_registers_[0]; *y = vfp_registers_[1]; + *z = registers_[1]; } else { // We use a char buffer to get around the strict-aliasing rules which // otherwise allow the compiler to optimize away the copy. @@ -988,44 +990,12 @@ void Simulator::GetFpArgs(double* x, double* y) { // Registers 0 and 1 -> x. OS::MemCopy(buffer, registers_, sizeof(*x)); OS::MemCopy(x, buffer, sizeof(*x)); - // Registers 2 and 3 -> y. - OS::MemCopy(buffer, registers_ + 2, sizeof(*y)); - OS::MemCopy(y, buffer, sizeof(*y)); - } -} - -// For use in calls that take one double value, constructed either -// from r0 and r1 or d0. -void Simulator::GetFpArgs(double* x) { - if (use_eabi_hardfloat()) { - *x = vfp_registers_[0]; - } else { - // We use a char buffer to get around the strict-aliasing rules which - // otherwise allow the compiler to optimize away the copy. - char buffer[sizeof(*x)]; - // Registers 0 and 1 -> x. - OS::MemCopy(buffer, registers_, sizeof(*x)); - OS::MemCopy(x, buffer, sizeof(*x)); - } -} - - -// For use in calls that take one double value constructed either -// from r0 and r1 or d0 and one integer value. -void Simulator::GetFpArgs(double* x, int32_t* y) { - if (use_eabi_hardfloat()) { - *x = vfp_registers_[0]; - *y = registers_[1]; - } else { - // We use a char buffer to get around the strict-aliasing rules which - // otherwise allow the compiler to optimize away the copy. - char buffer[sizeof(*x)]; - // Registers 0 and 1 -> x. - OS::MemCopy(buffer, registers_, sizeof(*x)); - OS::MemCopy(x, buffer, sizeof(*x)); - // Register 2 -> y. + // Register 2 and 3 -> y. OS::MemCopy(buffer, registers_ + 2, sizeof(*y)); OS::MemCopy(y, buffer, sizeof(*y)); + // Register 2 -> z + memcpy(buffer, registers_ + 2, sizeof(*z)); + memcpy(z, buffer, sizeof(*z)); } } @@ -1648,10 +1618,12 @@ typedef int64_t (*SimulatorRuntimeCall)(int32_t arg0, int32_t arg3, int32_t arg4, int32_t arg5); -typedef double (*SimulatorRuntimeFPCall)(int32_t arg0, - int32_t arg1, - int32_t arg2, - int32_t arg3); + +// These prototypes handle the four types of FP calls. +typedef int64_t (*SimulatorRuntimeCompareCall)(double darg0, double darg1); +typedef double (*SimulatorRuntimeFPFPCall)(double darg0, double darg1); +typedef double (*SimulatorRuntimeFPCall)(double darg0); +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). @@ -1717,27 +1689,27 @@ void Simulator::SoftwareInterrupt(Instruction* instr) { intptr_t external = reinterpret_cast(redirection->external_function()); if (fp_call) { + double dval0, dval1; // one or two double parameters + int32_t ival; // zero or one integer parameters + int64_t iresult = 0; // integer return value + double dresult = 0; // double return value + GetFpArgs(&dval0, &dval1, &ival); if (::v8::internal::FLAG_trace_sim || !stack_aligned) { - SimulatorRuntimeFPCall target = - reinterpret_cast(external); - double dval0, dval1; - int32_t ival; + SimulatorRuntimeCall generic_target = + reinterpret_cast(external); switch (redirection->type()) { case ExternalReference::BUILTIN_FP_FP_CALL: case ExternalReference::BUILTIN_COMPARE_CALL: - GetFpArgs(&dval0, &dval1); PrintF("Call to host function at %p with args %f, %f", - FUNCTION_ADDR(target), dval0, dval1); + FUNCTION_ADDR(generic_target), dval0, dval1); break; case ExternalReference::BUILTIN_FP_CALL: - GetFpArgs(&dval0); PrintF("Call to host function at %p with arg %f", - FUNCTION_ADDR(target), dval0); + FUNCTION_ADDR(generic_target), dval0); break; case ExternalReference::BUILTIN_FP_INT_CALL: - GetFpArgs(&dval0, &ival); PrintF("Call to host function at %p with args %f, %d", - FUNCTION_ADDR(target), dval0, ival); + FUNCTION_ADDR(generic_target), dval0, ival); break; default: UNREACHABLE(); @@ -1749,22 +1721,54 @@ void Simulator::SoftwareInterrupt(Instruction* instr) { PrintF("\n"); } CHECK(stack_aligned); - if (redirection->type() != ExternalReference::BUILTIN_COMPARE_CALL) { + switch (redirection->type()) { + case ExternalReference::BUILTIN_COMPARE_CALL: { + SimulatorRuntimeCompareCall target = + reinterpret_cast(external); + iresult = target(dval0, dval1); + set_register(r0, static_cast(iresult)); + set_register(r1, static_cast(iresult >> 32)); + break; + } + case ExternalReference::BUILTIN_FP_FP_CALL: { + SimulatorRuntimeFPFPCall target = + reinterpret_cast(external); + dresult = target(dval0, dval1); + SetFpResult(dresult); + break; + } + case ExternalReference::BUILTIN_FP_CALL: { SimulatorRuntimeFPCall target = - reinterpret_cast(external); - double result = target(arg0, arg1, arg2, arg3); - SetFpResult(result); - } else { - SimulatorRuntimeCall target = - reinterpret_cast(external); - int64_t result = target(arg0, arg1, arg2, arg3, arg4, arg5); - int32_t lo_res = static_cast(result); - int32_t hi_res = static_cast(result >> 32); - if (::v8::internal::FLAG_trace_sim) { - PrintF("Returned %08x\n", lo_res); + reinterpret_cast(external); + dresult = target(dval0); + SetFpResult(dresult); + break; + } + case ExternalReference::BUILTIN_FP_INT_CALL: { + SimulatorRuntimeFPIntCall target = + reinterpret_cast(external); + dresult = target(dval0, ival); + SetFpResult(dresult); + break; + } + default: + UNREACHABLE(); + break; + } + if (::v8::internal::FLAG_trace_sim || !stack_aligned) { + switch (redirection->type()) { + case ExternalReference::BUILTIN_COMPARE_CALL: + PrintF("Returned %08x\n", static_cast(iresult)); + break; + case ExternalReference::BUILTIN_FP_FP_CALL: + case ExternalReference::BUILTIN_FP_CALL: + case ExternalReference::BUILTIN_FP_INT_CALL: + PrintF("Returned %f\n", dresult); + break; + default: + UNREACHABLE(); + break; } - set_register(r0, lo_res); - set_register(r1, hi_res); } } else if (redirection->type() == ExternalReference::DIRECT_API_CALL) { SimulatorRuntimeDirectApiCall target = diff --git a/src/arm/simulator-arm.h b/src/arm/simulator-arm.h index 674ff42d6..45ae999b5 100644 --- a/src/arm/simulator-arm.h +++ b/src/arm/simulator-arm.h @@ -348,10 +348,8 @@ class Simulator { void* external_function, v8::internal::ExternalReference::Type type); - // For use in calls that take double value arguments. - void GetFpArgs(double* x, double* y); - void GetFpArgs(double* x); - void GetFpArgs(double* x, int32_t* y); + // Handle arguments and return value for runtime FP functions. + void GetFpArgs(double* x, double* y, int32_t* z); void SetFpResult(const double& result); void TrashCallerSaveRegisters(); diff --git a/src/atomicops_internals_x86_gcc.h b/src/atomicops_internals_x86_gcc.h index 6e55b5018..e58d598fb 100644 --- a/src/atomicops_internals_x86_gcc.h +++ b/src/atomicops_internals_x86_gcc.h @@ -168,7 +168,7 @@ inline Atomic32 Release_Load(volatile const Atomic32* ptr) { return *ptr; } -#if defined(__x86_64__) +#if defined(__x86_64__) && defined(V8_HOST_ARCH_64_BIT) // 64-bit low-level operations on 64-bit platform. diff --git a/src/builtins-decls.h b/src/builtins-decls.h new file mode 100644 index 000000000..beb5dd1e8 --- /dev/null +++ b/src/builtins-decls.h @@ -0,0 +1,40 @@ +// Copyright 2013 the V8 project authors. All rights reserved. +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following +// disclaimer in the documentation and/or other materials provided +// with the distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +#ifndef V8_BUILTINS_DECLS_H_ +#define V8_BUILTINS_DECLS_H_ + +#include "arguments.h" + +namespace v8 { +namespace internal { + +DECLARE_RUNTIME_FUNCTION(MaybeObject*, ArrayConstructor_StubFailure); + +} } // namespace v8::internal + +#endif // V8_BUILTINS_DECLS_H_ diff --git a/src/builtins.cc b/src/builtins.cc index 3d8ac71e3..149a64926 100644 --- a/src/builtins.cc +++ b/src/builtins.cc @@ -125,23 +125,31 @@ BUILTIN_LIST_C(DEF_ARG_TYPE) #ifdef DEBUG -#define BUILTIN(name) \ - MUST_USE_RESULT static MaybeObject* Builtin_Impl_##name( \ - name##ArgumentsType args, Isolate* isolate); \ - MUST_USE_RESULT static MaybeObject* Builtin_##name( \ - name##ArgumentsType args, Isolate* isolate) { \ - ASSERT(isolate == Isolate::Current()); \ - args.Verify(); \ - return Builtin_Impl_##name(args, isolate); \ - } \ - MUST_USE_RESULT static MaybeObject* Builtin_Impl_##name( \ +#define BUILTIN(name) \ + MUST_USE_RESULT static MaybeObject* Builtin_Impl_##name( \ + name##ArgumentsType args, Isolate* isolate); \ + MUST_USE_RESULT static MaybeObject* Builtin_##name( \ + int args_length, Object** args_object, Isolate* isolate) { \ + name##ArgumentsType args(args_length, args_object); \ + ASSERT(isolate == Isolate::Current()); \ + args.Verify(); \ + return Builtin_Impl_##name(args, isolate); \ + } \ + MUST_USE_RESULT static MaybeObject* Builtin_Impl_##name( \ name##ArgumentsType args, Isolate* isolate) #else // For release mode. -#define BUILTIN(name) \ - static MaybeObject* Builtin_##name(name##ArgumentsType args, Isolate* isolate) - +#define BUILTIN(name) \ + static MaybeObject* Builtin_impl##name( \ + name##ArgumentsType args, Isolate* isolate); \ + static MaybeObject* Builtin_##name( \ + int args_length, Object** args_object, Isolate* isolate) { \ + name##ArgumentsType args(args_length, args_object); \ + return Builtin_impl##name(args, isolate); \ + } \ + static MaybeObject* Builtin_impl##name( \ + name##ArgumentsType args, Isolate* isolate) #endif diff --git a/src/builtins.h b/src/builtins.h index 96eb85639..8df48a840 100644 --- a/src/builtins.h +++ b/src/builtins.h @@ -276,8 +276,6 @@ enum BuiltinExtraArguments { V(APPLY_PREPARE, 1) \ V(APPLY_OVERFLOW, 1) -MaybeObject* ArrayConstructor_StubFailure(Arguments args, Isolate* isolate); - class BuiltinFunctionTable; class ObjectVisitor; diff --git a/src/ia32/code-stubs-ia32.cc b/src/ia32/code-stubs-ia32.cc index 96d241186..62e90e3da 100644 --- a/src/ia32/code-stubs-ia32.cc +++ b/src/ia32/code-stubs-ia32.cc @@ -30,6 +30,7 @@ #if defined(V8_TARGET_ARCH_IA32) #include "bootstrapper.h" +#include "builtins-decls.h" #include "code-stubs.h" #include "isolate.h" #include "jsregexp.h" diff --git a/src/mips/code-stubs-mips.cc b/src/mips/code-stubs-mips.cc index 946b84a9a..6257207a9 100644 --- a/src/mips/code-stubs-mips.cc +++ b/src/mips/code-stubs-mips.cc @@ -30,6 +30,7 @@ #if defined(V8_TARGET_ARCH_MIPS) #include "bootstrapper.h" +#include "builtins-decls.h" #include "code-stubs.h" #include "codegen.h" #include "regexp-macro-assembler.h" diff --git a/src/sampler.cc b/src/sampler.cc index e271470bd..da186b6ce 100644 --- a/src/sampler.cc +++ b/src/sampler.cc @@ -26,7 +26,8 @@ // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #if defined(__linux__) || defined(__FreeBSD__) || defined(__OpenBSD__) \ - || defined(__NetBSD__) || defined(__sun) || defined(__ANDROID__) + || defined(__NetBSD__) || defined(__sun) || defined(__ANDROID__) \ + || defined(__native_client__) #define USE_SIGNALS diff --git a/src/x64/code-stubs-x64.cc b/src/x64/code-stubs-x64.cc index 3a9a0234e..aba2a3835 100644 --- a/src/x64/code-stubs-x64.cc +++ b/src/x64/code-stubs-x64.cc @@ -30,6 +30,7 @@ #if defined(V8_TARGET_ARCH_X64) #include "bootstrapper.h" +#include "builtins-decls.h" #include "code-stubs.h" #include "regexp-macro-assembler.h" #include "stub-cache.h" @@ -4106,22 +4107,23 @@ void CEntryStub::GenerateCore(MacroAssembler* masm, // Call C function. #ifdef _WIN64 - // Windows 64-bit ABI passes arguments in rcx, rdx, r8, r9 - // Store Arguments object on stack, below the 4 WIN64 ABI parameter slots. - __ movq(StackSpaceOperand(0), r14); // argc. - __ movq(StackSpaceOperand(1), r15); // argv. + // Windows 64-bit ABI passes arguments in rcx, rdx, r8, r9. + // Pass argv and argc as two parameters. The arguments object will + // be created by stubs declared by DECLARE_RUNTIME_FUNCTION(). if (result_size_ < 2) { // Pass a pointer to the Arguments object as the first argument. // Return result in single register (rax). - __ lea(rcx, StackSpaceOperand(0)); - __ LoadAddress(rdx, ExternalReference::isolate_address(masm->isolate())); + __ movq(rcx, r14); // argc. + __ movq(rdx, r15); // argv. + __ movq(r8, ExternalReference::isolate_address(masm->isolate())); } else { ASSERT_EQ(2, result_size_); // Pass a pointer to the result location as the first argument. __ lea(rcx, StackSpaceOperand(2)); // Pass a pointer to the Arguments object as the second argument. - __ lea(rdx, StackSpaceOperand(0)); - __ LoadAddress(r8, ExternalReference::isolate_address(masm->isolate())); + __ movq(rdx, r14); // argc. + __ movq(r8, r15); // argv. + __ movq(r9, ExternalReference::isolate_address(masm->isolate())); } #else // _WIN64 diff --git a/test/cctest/cctest.status b/test/cctest/cctest.status index 616f7124d..a2da44882 100644 --- a/test/cctest/cctest.status +++ b/test/cctest/cctest.status @@ -103,3 +103,6 @@ test-log/ProfLazyMode: SKIP test-debug/DebuggerAgent: SKIP test-debug/DebuggerAgentProtocolOverflowHeader: SKIP test-sockets/Socket: SKIP + +# Profiling doesn't work on Native Client. +test-cpu-profiler/*