# HG changeset patch # User phh # Date 1557514240 0 # Node ID e86bc9786d83a48744700745d8a2c8e0e4dc1c2b # Parent 32bc598624bd33a1a8847e84f791559f18a69a49 8223664: Add jtreg tests for 8223528, backport to jdk8u of 8176100 Summary: Add hotspot/test/runtime/jni directory with two tests for 8176100 Reviewed-by: kbarrett, coleenp, tschatzl diff -r 32bc598624bd -r e86bc9786d83 test/runtime/jni/CallWithJNIWeak/CallWithJNIWeak.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/runtime/jni/CallWithJNIWeak/CallWithJNIWeak.c Fri May 10 18:50:40 2019 +0000 @@ -0,0 +1,142 @@ +/* + * Copyright (c) 2017, 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. + */ + +#include + +/* + * Class: CallWithJNIWeak + * Method: testJNIFieldAccessors + * Signature: (LCallWithJNIWeak;)V + */ +JNIEXPORT void JNICALL +Java_CallWithJNIWeak_testJNIFieldAccessors(JNIEnv *env, jclass clazz, jobject this) { + // Make sure that we have a weak reference to the receiver + + jweak self = (*env)->NewWeakGlobalRef(env, this); + + jclass this_class = (*env)->GetObjectClass(env, self); + + jclass exception = (*env)->FindClass(env, "java/lang/RuntimeException"); + + jfieldID id_i = (*env)->GetFieldID(env, this_class, "i", "I"); + jfieldID id_j = (*env)->GetFieldID(env, this_class, "j", "J"); + jfieldID id_z = (*env)->GetFieldID(env, this_class, "z", "Z"); + jfieldID id_c = (*env)->GetFieldID(env, this_class, "c", "C"); + jfieldID id_s = (*env)->GetFieldID(env, this_class, "s", "S"); + jfieldID id_f = (*env)->GetFieldID(env, this_class, "f", "F"); + jfieldID id_d = (*env)->GetFieldID(env, this_class, "d", "D"); + jfieldID id_l = (*env)->GetFieldID(env, this_class, "l", "Ljava/lang/Object;"); + jvalue v; + +#define CHECK(variable, expected) \ + do { \ + if ((variable) != (expected)) { \ + (*env)->ThrowNew(env, exception, #variable" != " #expected); \ + return; \ + } \ + } while(0) + + // The values checked below must be kept in sync with the Java source file. + + v.i = (*env)->GetIntField(env, self, id_i); + CHECK(v.i, 1); + + v.j = (*env)->GetLongField(env, self, id_j); + CHECK(v.j, 2); + + v.z = (*env)->GetBooleanField(env, self, id_z); + CHECK(v.z, JNI_TRUE); + + v.c = (*env)->GetCharField(env, self, id_c); + CHECK(v.c, 'a'); + + v.s = (*env)->GetShortField(env, self, id_s); + CHECK(v.s, 3); + + v.f = (*env)->GetFloatField(env, self, id_f); + CHECK(v.f, 1.0f); + + v.d = (*env)->GetDoubleField(env, self, id_d); + CHECK(v.d, 2.0); + +#undef CHECK + + v.l = (*env)->GetObjectField(env, self, id_l); + if (v.l == NULL) { + (*env)->ThrowNew(env, exception, "Object field was null"); + return; + } + { + jclass clz = (*env)->GetObjectClass(env, v.l); + if (!(*env)->IsSameObject(env, clazz, clz)) { + (*env)->ThrowNew(env, exception, "Bad object class"); + } + } + + (*env)->DeleteWeakGlobalRef(env, self); +} + +/* + * Class: CallWithJNIWeak + * Method: runTests + * Signature: (LCallWithJNIWeak;)V + */ +JNIEXPORT void JNICALL +Java_CallWithJNIWeak_runTests(JNIEnv *env, jclass clazz, jobject this) { + jweak that = (*env)->NewWeakGlobalRef(env, this); + { + jmethodID method = (*env)->GetStaticMethodID(env, + clazz, "testJNIFieldAccessors", "(LCallWithJNIWeak;)V"); + (*env)->CallStaticVoidMethod(env, clazz, method, that); + if ((*env)->ExceptionCheck(env)) { + return; + } + } + + { + jmethodID method = (*env)->GetMethodID(env, clazz, "weakReceiverTest", "()V"); + (*env)->CallVoidMethod(env, that, method); + if ((*env)->ExceptionCheck(env)) { + return; + } + } + + { + jmethodID method = (*env)->GetMethodID(env, clazz, "synchonizedWeakReceiverTest", "()V"); + (*env)->CallVoidMethod(env, that, method); + if ((*env)->ExceptionCheck(env)) { + return; + } + } + (*env)->DeleteWeakGlobalRef(env, that); +} + +/* + * Class: CallWithJNIWeak + * Method: weakReceiverTest0 + * Signature: ()V + */ +JNIEXPORT void JNICALL +Java_CallWithJNIWeak_weakReceiverTest0(JNIEnv *env, jobject obj) { + (*env)->GetObjectClass(env, obj); +} diff -r 32bc598624bd -r e86bc9786d83 test/runtime/jni/CallWithJNIWeak/CallWithJNIWeak.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/runtime/jni/CallWithJNIWeak/CallWithJNIWeak.java Fri May 10 18:50:40 2019 +0000 @@ -0,0 +1,63 @@ +/* + * Copyright (c) 2017, 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. + */ + +public class CallWithJNIWeak { + static { + System.loadLibrary("CallWithJNIWeak"); + } + + private static native void testJNIFieldAccessors(CallWithJNIWeak o); + + // The field initializations must be kept in sync with the JNI code + // which reads verifies the values of these fields. + private int i = 1; + private long j = 2; + private boolean z = true; + private char c = 'a'; + private short s = 3; + private float f = 1.0f; + private double d = 2.0; + private Object l; + + private CallWithJNIWeak() { + this.l = this; + } + + private native void weakReceiverTest0(); + private void weakReceiverTest() { + weakReceiverTest0(); + } + + private synchronized void synchonizedWeakReceiverTest() { + this.notifyAll(); + } + + private static native void runTests(CallWithJNIWeak o); + + public static void main(String[] args) { + CallWithJNIWeak w = new CallWithJNIWeak(); + for (int i = 0; i < 20000; i++) { + runTests(w); + } + } +} diff -r 32bc598624bd -r e86bc9786d83 test/runtime/jni/CallWithJNIWeak/test.sh --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/runtime/jni/CallWithJNIWeak/test.sh Fri May 10 18:50:40 2019 +0000 @@ -0,0 +1,93 @@ +#!/bin/sh + +# +# Copyright (c) 1998, 2019, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2011 SAP AG. 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 test.sh +## @bug 8166188 +## @requires vm.opt.ExplicitGCInvokesConcurrent != true +## @summary Test call of native function with JNI weak global ref. +## @run shell test.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 +OS=`uname -s` +echo "Testing on " $OS +case "$OS" in + Linux) + cc_cmd=`which gcc` + if [ "x$cc_cmd" == "x" ]; then + echo "WARNING: gcc not found. Cannot execute test." 2>&1 + exit 0; + fi + ;; + Solaris) + cc_cmd=`which cc` + if [ "x$cc_cmd" == "x" ]; then + echo "WARNING: cc not found. Cannot execute test." 2>&1 + exit 0; + fi + ;; + *) + echo "Test passed; only valid for Linux and Solaris" + exit 0; + ;; +esac + +THIS_DIR=. + +cp ${TESTSRC}${FS}*.java ${THIS_DIR} +${TESTJAVA}${FS}bin${FS}javac *.java + +$cc_cmd -fPIC -shared -o libCallWithJNIWeak.so \ + -I${TESTJAVA}${FS}include -I${TESTJAVA}${FS}include${FS}linux \ + ${TESTSRC}${FS}CallWithJNIWeak.c + +LD_LIBRARY_PATH=${THIS_DIR} +echo LD_LIBRARY_PATH = ${LD_LIBRARY_PATH} +export LD_LIBRARY_PATH + +echo +echo ${TESTJAVA}${FS}bin${FS}java -cp ${THIS_DIR} -Xint CallWithJNIWeak +${TESTJAVA}${FS}bin${FS}java -cp ${THIS_DIR} -Xint CallWithJNIWeak +JAVA_RETVAL=$? + +if [ "$JAVA_RETVAL" == "0" ] +then + echo + echo ${TESTJAVA}${FS}bin${FS}java -cp ${THIS_DIR} -Xcomp CallWithJNIWeak + ${TESTJAVA}${FS}bin${FS}java -cp ${THIS_DIR} -Xcomp CallWithJNIWeak + + JAVA_RETVAL=$? +fi + +exit $JAVA_RETVAL diff -r 32bc598624bd -r e86bc9786d83 test/runtime/jni/ReturnJNIWeak/ReturnJNIWeak.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/runtime/jni/ReturnJNIWeak/ReturnJNIWeak.c Fri May 10 18:50:40 2019 +0000 @@ -0,0 +1,52 @@ +/* + * Copyright (c) 2017, 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. + */ + +/* + * Native support for ReturnJNIWeak test. + */ + +#include "jni.h" + +static jweak registered = NULL; + +JNIEXPORT void JNICALL +Java_ReturnJNIWeak_registerObject(JNIEnv* env, + jclass jclazz, + jobject value) { + // assert registered == NULL + registered = (*env)->NewWeakGlobalRef(env, value); +} + +JNIEXPORT void JNICALL +Java_ReturnJNIWeak_unregisterObject(JNIEnv* env, jclass jclazz) { + if (registered != NULL) { + (*env)->DeleteWeakGlobalRef(env, registered); + registered = NULL; + } +} + +JNIEXPORT jobject JNICALL +Java_ReturnJNIWeak_getObject(JNIEnv* env, jclass jclazz) { + // assert registered != NULL + return registered; +} diff -r 32bc598624bd -r e86bc9786d83 test/runtime/jni/ReturnJNIWeak/ReturnJNIWeak.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/runtime/jni/ReturnJNIWeak/ReturnJNIWeak.java Fri May 10 18:50:40 2019 +0000 @@ -0,0 +1,122 @@ +/* + * Copyright (c) 2017, 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. + */ + +public final class ReturnJNIWeak { + static { + System.loadLibrary("ReturnJNIWeak"); + } + + private static final class TestObject { + public final int value; + + public TestObject(int value) { + this.value = value; + } + } + + private static volatile TestObject testObject = null; + + private static native void registerObject(Object o); + private static native void unregisterObject(); + private static native Object getObject(); + + // Create the test object and record it both strongly and weakly. + private static void remember(int value) { + TestObject o = new TestObject(value); + registerObject(o); + testObject = o; + } + + // Remove both strong and weak references to the current test object. + private static void forget() { + unregisterObject(); + testObject = null; + } + + // Verify the weakly recorded object + private static void checkValue(int value) throws Exception { + Object o = getObject(); + if (o == null) { + throw new RuntimeException("Weak reference unexpectedly null"); + } + TestObject t = (TestObject)o; + if (t.value != value) { + throw new RuntimeException("Incorrect value"); + } + } + + // Verify we can create a weak reference and get it back. + private static void testSanity() throws Exception { + System.out.println("running testSanity"); + int value = 5; + try { + remember(value); + checkValue(value); + } finally { + forget(); + } + } + + // Verify weak ref value survives across collection if strong ref exists. + private static void testSurvival() throws Exception { + System.out.println("running testSurvival"); + int value = 10; + try { + remember(value); + checkValue(value); + System.gc(); + // Verify weak ref still has expected value. + checkValue(value); + } finally { + forget(); + } + } + + // Verify weak ref cleared if no strong ref exists. + private static void testClear() throws Exception { + System.out.println("running testClear"); + int value = 15; + try { + remember(value); + checkValue(value); + // Verify still good. + checkValue(value); + // Drop reference. + testObject = null; + System.gc(); + // Verify weak ref cleared as expected. + Object recorded = getObject(); + if (recorded != null) { + throw new RuntimeException("expected clear"); + } + } finally { + forget(); + } + } + + public static void main(String[] args) throws Exception { + testSanity(); + testSurvival(); + testClear(); + } +} diff -r 32bc598624bd -r e86bc9786d83 test/runtime/jni/ReturnJNIWeak/test.sh --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/runtime/jni/ReturnJNIWeak/test.sh Fri May 10 18:50:40 2019 +0000 @@ -0,0 +1,93 @@ +#!/bin/sh + +# +# Copyright (c) 1998, 2019, Oracle and/or its affiliates. All rights reserved. +# Copyright (c) 2011 SAP AG. 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 test.sh +## @bug 8166188 +## @requires vm.opt.ExplicitGCInvokesConcurrent != true +## @summary Test return of JNI weak global refs from native calls. +## @run shell test.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 +OS=`uname -s` +echo "Testing on " $OS +case "$OS" in + Linux) + cc_cmd=`which gcc` + if [ "x$cc_cmd" == "x" ]; then + echo "WARNING: gcc not found. Cannot execute test." 2>&1 + exit 0; + fi + ;; + Solaris) + cc_cmd=`which cc` + if [ "x$cc_cmd" == "x" ]; then + echo "WARNING: cc not found. Cannot execute test." 2>&1 + exit 0; + fi + ;; + *) + echo "Test passed; only valid for Linux and Solaris" + exit 0; + ;; +esac + +THIS_DIR=. + +cp ${TESTSRC}${FS}*.java ${THIS_DIR} +${TESTJAVA}${FS}bin${FS}javac *.java + +$cc_cmd -fPIC -shared -o libReturnJNIWeak.so \ + -I${TESTJAVA}${FS}include -I${TESTJAVA}${FS}include${FS}linux \ + ${TESTSRC}${FS}ReturnJNIWeak.c + +LD_LIBRARY_PATH=${THIS_DIR} +echo LD_LIBRARY_PATH = ${LD_LIBRARY_PATH} +export LD_LIBRARY_PATH + +echo +echo ${TESTJAVA}${FS}bin${FS}java -cp ${THIS_DIR} -Xint ReturnJNIWeak +${TESTJAVA}${FS}bin${FS}java -cp ${THIS_DIR} -Xint ReturnJNIWeak +JAVA_RETVAL=$? + +if [ "$JAVA_RETVAL" == "0" ] +then + echo + echo ${TESTJAVA}${FS}bin${FS}java -cp ${THIS_DIR} -Xcomp ReturnJNIWeak + ${TESTJAVA}${FS}bin${FS}java -cp ${THIS_DIR} -Xcomp ReturnJNIWeak + + JAVA_RETVAL=$? +fi + +exit $JAVA_RETVAL