# HG changeset patch # User adinn # Date 1479493190 18000 # Fri Nov 18 13:19:50 2016 -0500 # Node ID 2ab0ba56ac3abe18c73d214d4fd0279a1c7c512e # Parent fff29c78ee406a290e5b79dc14a1b1a98de1d0f4 8165673: AArch64: Fix JNI floating point argument handling Reviewed-by: aph, adinn Contributed-by: ningsheng.jian@linaro.org diff --git a/src/cpu/aarch64/vm/interpreterRT_aarch64.cpp b/src/cpu/aarch64/vm/interpreterRT_aarch64.cpp --- a/src/cpu/aarch64/vm/interpreterRT_aarch64.cpp +++ b/src/cpu/aarch64/vm/interpreterRT_aarch64.cpp @@ -1,6 +1,6 @@ /* * Copyright (c) 2013, Red Hat Inc. - * Copyright (c) 2003, 2010, Oracle and/or its affiliates. + * Copyright (c) 2003, 2016, Oracle and/or its affiliates. * All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * @@ -131,8 +131,8 @@ if (_num_fp_args < Argument::n_float_register_parameters_c) { __ ldrs(as_FloatRegister(_num_fp_args++), src); } else { - __ ldrh(r0, src); - __ strh(r0, Address(to(), _stack_offset)); + __ ldrw(r0, src); + __ strw(r0, Address(to(), _stack_offset)); _stack_offset += wordSize; _num_fp_args++; } @@ -350,7 +350,7 @@ _num_fp_args++; } else { *_to++ = from_obj; - _num_int_args++; + _num_fp_args++; } } @@ -365,7 +365,7 @@ _num_fp_args++; } else { *_to++ = from_obj; - _num_int_args++; + _num_fp_args++; } } diff --git a/src/cpu/aarch64/vm/sharedRuntime_aarch64.cpp b/src/cpu/aarch64/vm/sharedRuntime_aarch64.cpp --- a/src/cpu/aarch64/vm/sharedRuntime_aarch64.cpp +++ b/src/cpu/aarch64/vm/sharedRuntime_aarch64.cpp @@ -978,7 +978,16 @@ // A float arg may have to do float reg int reg conversion static void float_move(MacroAssembler* masm, VMRegPair src, VMRegPair dst) { - if (src.first() != dst.first()) { + assert(src.first()->is_stack() && dst.first()->is_stack() || + src.first()->is_reg() && dst.first()->is_reg(), "Unexpected error"); + if (src.first()->is_stack()) { + if (dst.first()->is_stack()) { + __ ldrw(rscratch1, Address(rfp, reg2offset_in(src.first()))); + __ strw(rscratch1, Address(sp, reg2offset_out(dst.first()))); + } else { + ShouldNotReachHere(); + } + } else if (src.first() != dst.first()) { if (src.is_single_phys_reg() && dst.is_single_phys_reg()) __ fmovs(dst.first()->as_FloatRegister(), src.first()->as_FloatRegister()); else @@ -1012,7 +1021,16 @@ // A double move static void double_move(MacroAssembler* masm, VMRegPair src, VMRegPair dst) { - if (src.first() != dst.first()) { + assert(src.first()->is_stack() && dst.first()->is_stack() || + src.first()->is_reg() && dst.first()->is_reg(), "Unexpected error"); + if (src.first()->is_stack()) { + if (dst.first()->is_stack()) { + __ ldr(rscratch1, Address(rfp, reg2offset_in(src.first()))); + __ str(rscratch1, Address(sp, reg2offset_out(dst.first()))); + } else { + ShouldNotReachHere(); + } + } else if (src.first() != dst.first()) { if (src.is_single_phys_reg() && dst.is_single_phys_reg()) __ fmovd(dst.first()->as_FloatRegister(), src.first()->as_FloatRegister()); else diff --git a/test/compiler/floatingpoint/TestFloatJNIArgs.java b/test/compiler/floatingpoint/TestFloatJNIArgs.java new file mode 100644 --- /dev/null +++ b/test/compiler/floatingpoint/TestFloatJNIArgs.java @@ -0,0 +1,86 @@ +/* + * Copyright (c) 2015, 2016 SAP SE. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +public class TestFloatJNIArgs { + static { + try { + System.loadLibrary("TestFloatJNIArgs"); + } catch (UnsatisfiedLinkError e) { + System.out.println("could not load native lib: " + e); + } + } + + public static native float add15floats( + float f1, float f2, float f3, float f4, + float f5, float f6, float f7, float f8, + float f9, float f10, float f11, float f12, + float f13, float f14, float f15); + + public static native float add10floats( + float f1, float f2, float f3, float f4, + float f5, float f6, float f7, float f8, + float f9, float f10); + + public static native float addFloatsInts( + float f1, float f2, float f3, float f4, + float f5, float f6, float f7, float f8, + float f9, float f10, float f11, float f12, + float f13, float f14, float f15, int a16, int a17); + + public static native double add15doubles( + double d1, double d2, double d3, double d4, + double d5, double d6, double d7, double d8, + double d9, double d10, double d11, double d12, + double d13, double d14, double d15); + + static void test() throws Exception { + float sum = TestFloatJNIArgs.add15floats(1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, + 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f); + if (sum != 15.0f) { + throw new Error("Passed 15 times 1.0f to jni function which didn't add them properly: " + sum); + } + + float sum1 = TestFloatJNIArgs.add10floats(1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f); + if (sum1 != 10.0f) { + throw new Error("Passed 10 times 1.0f to jni function which didn't add them properly: " + sum1); + } + + float sum2 = TestFloatJNIArgs.addFloatsInts(1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, + 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1, 1); + if (sum2 != 17.0f) { + throw new Error("Passed 17 times 1 to jni function which didn't add them properly: " + sum2); + } + + double dsum = TestFloatJNIArgs.add15doubles(1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, + 1.0, 1.0, 1.0, 1.0, 1.0, 1.0); + if (dsum != 15.0) { + throw new Error("Passed 15 times 1.0 to jni function which didn't add them properly: " + dsum); + } + } + + public static void main(String[] args) throws Exception { + for (int i = 0; i < 200; ++i) { + test(); + } + } +} diff --git a/test/compiler/floatingpoint/TestFloatJNIArgs.sh b/test/compiler/floatingpoint/TestFloatJNIArgs.sh new file mode 100644 --- /dev/null +++ b/test/compiler/floatingpoint/TestFloatJNIArgs.sh @@ -0,0 +1,104 @@ +#!/bin/sh + +# +# Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved. +# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. +# +# This code is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License version 2 only, as +# published by the Free Software Foundation. +# +# This code is distributed in the hope that it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +# version 2 for more details (a copy is included in the LICENSE file that +# accompanied this code). +# +# You should have received a copy of the GNU General Public License version +# 2 along with this work; if not, write to the Free Software Foundation, +# Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. +# +# Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA +# or visit www.oracle.com if you need additional information or have any +# questions. +# + +## +## @test +## @bug 8165673 +## @summary regression test for passing float args to a jni function. +## @run shell/timeout=30 TestFloatJNIArgs.sh +## + +if [ "${TESTSRC}" = "" ] +then + TESTSRC=${PWD} + echo "TESTSRC not set. Using "${TESTSRC}" as default" +fi +echo "TESTSRC=${TESTSRC}" +## Adding common setup Variables for running shell tests. +. ${TESTSRC}/../../test_env.sh + +# set platform-dependent variables +if [ $VM_OS == "linux" -a $VM_CPU == "aarch64" ]; then + echo "Testing on linux-aarch64" + gcc_cmd=`which gcc` + if [ "x$gcc_cmd" == "x" ]; then + echo "WARNING: gcc not found. Cannot execute test." 2>&1 + exit 0; + fi +else + echo "Test passed; only valid for linux-aarch64" + exit 0; +fi + +THIS_DIR=. + +cp ${TESTSRC}${FS}*.java ${THIS_DIR} +${TESTJAVA}${FS}bin${FS}javac *.java + +$gcc_cmd -O1 -DLINUX -fPIC -shared \ + -o ${THIS_DIR}${FS}libTestFloatJNIArgs.so \ + -I${TESTJAVA}${FS}include \ + -I${TESTJAVA}${FS}include${FS}linux \ + ${TESTSRC}${FS}libTestFloatJNIArgs.c + +# run the java test in the background +cmd="${TESTJAVA}${FS}bin${FS}java -Xint \ + -Djava.library.path=${THIS_DIR}${FS} TestFloatJNIArgs" + +echo "$cmd" +eval $cmd + +if [ $? -ne 0 ] +then + echo "Test Failed" + exit 1 +fi + +cmd="${TESTJAVA}${FS}bin${FS}java -XX:+TieredCompilation -Xcomp \ + -Djava.library.path=${THIS_DIR}${FS} TestFloatJNIArgs" + +echo "$cmd" +eval $cmd + +if [ $? -ne 0 ] +then + echo "Test Failed" + exit 1 +fi + +cmd="${TESTJAVA}${FS}bin${FS}java -XX:-TieredCompilation -Xcomp \ + -Djava.library.path=${THIS_DIR}${FS} TestFloatJNIArgs" + +echo "$cmd" +eval $cmd + +if [ $? -ne 0 ] +then + echo "Test Failed" + exit 1 +fi + +echo "Test Passed" +exit 0 diff --git a/test/compiler/floatingpoint/libTestFloatJNIArgs.c b/test/compiler/floatingpoint/libTestFloatJNIArgs.c new file mode 100644 --- /dev/null +++ b/test/compiler/floatingpoint/libTestFloatJNIArgs.c @@ -0,0 +1,68 @@ +/* + * Copyright (c) 2015, 2016. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +JNIEXPORT jfloat JNICALL Java_TestFloatJNIArgs_add15floats + (JNIEnv *env, jclass cls, + jfloat f1, jfloat f2, jfloat f3, jfloat f4, + jfloat f5, jfloat f6, jfloat f7, jfloat f8, + jfloat f9, jfloat f10, jfloat f11, jfloat f12, + jfloat f13, jfloat f14, jfloat f15) { + return f1 + f2 + f3 + f4 + f5 + f6 + f7 + f8 + f9 + f10 + f11 + f12 + f13 + f14 + f15; +} + +JNIEXPORT jfloat JNICALL Java_TestFloatJNIArgs_add10floats + (JNIEnv *env, jclass cls, + jfloat f1, jfloat f2, jfloat f3, jfloat f4, + jfloat f5, jfloat f6, jfloat f7, jfloat f8, + jfloat f9, jfloat f10) { + return f1 + f2 + f3 + f4 + f5 + f6 + f7 + f8 + f9 + f10; +} + +JNIEXPORT jfloat JNICALL Java_TestFloatJNIArgs_addFloatsInts + (JNIEnv *env, jclass cls, + jfloat f1, jfloat f2, jfloat f3, jfloat f4, + jfloat f5, jfloat f6, jfloat f7, jfloat f8, + jfloat f9, jfloat f10, jfloat f11, jfloat f12, + jfloat f13, jfloat f14, jfloat f15, jint a16, jint a17) { + return f1 + f2 + f3 + f4 + f5 + f6 + f7 + f8 + f9 + f10 + f11 + f12 + f13 + f14 + f15 + a16 + a17; +} + +JNIEXPORT jdouble JNICALL Java_TestFloatJNIArgs_add15doubles + (JNIEnv *env, jclass cls, + jdouble f1, jdouble f2, jdouble f3, jdouble f4, + jdouble f5, jdouble f6, jdouble f7, jdouble f8, + jdouble f9, jdouble f10, jdouble f11, jdouble f12, + jdouble f13, jdouble f14, jdouble f15) { + return f1 + f2 + f3 + f4 + f5 + f6 + f7 + f8 + f9 + f10 + f11 + f12 + f13 + f14 + f15; +} + + +#ifdef __cplusplus +} +#endif diff --git a/test/test_env.sh b/test/test_env.sh --- a/test/test_env.sh +++ b/test/test_env.sh @@ -186,6 +186,11 @@ then VM_CPU="ia64" fi +grep "aarch64" vm_version.out > ${NULL} +if [ $? = 0 ] +then + VM_CPU="aarch64" +fi export VM_TYPE VM_BITS VM_OS VM_CPU echo "VM_TYPE=${VM_TYPE}" echo "VM_BITS=${VM_BITS}"