diff --git a/jdk/src/share/classes/java/lang/Class.java b/jdk/src/share/classes/java/lang/Class.java index ed7fa95e121..cd26ab11791 100644 --- a/jdk/src/share/classes/java/lang/Class.java +++ b/jdk/src/share/classes/java/lang/Class.java @@ -134,10 +134,11 @@ public final class Class implements java.io.Serializable, * This constructor is not used and prevents the default constructor being * generated. */ - private Class(ClassLoader loader) { + private Class(ClassLoader loader, Class arrayComponentType) { // Initialize final field for classLoader. The initialization value of non-null // prevents future JIT optimizations from assuming this final field is null. classLoader = loader; + componentType = arrayComponentType; } /** @@ -917,7 +918,16 @@ public final class Class implements java.io.Serializable, * @see java.lang.reflect.Array * @since 1.1 */ - public native Class getComponentType(); + public Class getComponentType() { + // Only return for array types. Storage may be reused for Class for instance types. + if (isArray()) { + return componentType; + } else { + return null; + } + } + + private final Class componentType; /** diff --git a/jdk/src/share/javavm/export/jvm.h b/jdk/src/share/javavm/export/jvm.h index 396ca68558e..f3ac9286cdc 100644 --- a/jdk/src/share/javavm/export/jvm.h +++ b/jdk/src/share/javavm/export/jvm.h @@ -444,9 +444,6 @@ JVM_IsArrayClass(JNIEnv *env, jclass cls); JNIEXPORT jboolean JNICALL JVM_IsPrimitiveClass(JNIEnv *env, jclass cls); -JNIEXPORT jclass JNICALL -JVM_GetComponentType(JNIEnv *env, jclass cls); - JNIEXPORT jint JNICALL JVM_GetClassModifiers(JNIEnv *env, jclass cls); diff --git a/jdk/src/share/native/java/lang/Class.c b/jdk/src/share/native/java/lang/Class.c index c5e717fe0df..98726d38ebd 100644 --- a/jdk/src/share/native/java/lang/Class.c +++ b/jdk/src/share/native/java/lang/Class.c @@ -60,7 +60,6 @@ static JNINativeMethod methods[] = { {"setSigners", "([" OBJ ")V", (void *)&JVM_SetClassSigners}, {"isArray", "()Z", (void *)&JVM_IsArrayClass}, {"isPrimitive", "()Z", (void *)&JVM_IsPrimitiveClass}, - {"getComponentType", "()" CLS, (void *)&JVM_GetComponentType}, {"getModifiers", "()I", (void *)&JVM_GetClassModifiers}, {"getDeclaredFields0","(Z)[" FLD, (void *)&JVM_GetClassDeclaredFields}, {"getDeclaredMethods0","(Z)[" MHD, (void *)&JVM_GetClassDeclaredMethods}, diff --git a/jdk/test/java/lang/instrument/RedefineMethodDelInvoke.sh b/jdk/test/java/lang/instrument/RedefineMethodDelInvoke.sh new file mode 100644 index 00000000000..f1f9ac6db7e --- /dev/null +++ b/jdk/test/java/lang/instrument/RedefineMethodDelInvoke.sh @@ -0,0 +1,98 @@ +# +# Copyright (c) 2014, 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 8042796 +# @summary jvmtiRedefineClasses.cpp: guarantee(false) failed: OLD and/or OBSOLETE method(s) found +# @author Daniel D. Daugherty +# @author Serguei Spitsyn +# +# @run shell MakeJAR3.sh RedefineMethodDelInvokeAgent 'Can-Redefine-Classes: true' +# @run build RedefineMethodDelInvokeApp +# @run shell RedefineMethodDelInvoke.sh +# + +if [ "${TESTJAVA}" = "" ] +then + echo "TESTJAVA not set. Test cannot execute. Failed." + exit 1 +fi + +if [ "${COMPILEJAVA}" = "" ] +then + COMPILEJAVA="${TESTJAVA}" +fi +echo "COMPILEJAVA=${COMPILEJAVA}" + +if [ "${TESTSRC}" = "" ] +then + echo "TESTSRC not set. Test cannot execute. Failed." + exit 1 +fi + +if [ "${TESTCLASSES}" = "" ] +then + echo "TESTCLASSES not set. Test cannot execute. Failed." + exit 1 +fi + +JAVAC="${COMPILEJAVA}"/bin/javac +JAVA="${TESTJAVA}"/bin/java + +cp "${TESTSRC}"/RedefineMethodDelInvokeTarget_1.java \ + RedefineMethodDelInvokeTarget.java +"${JAVAC}" ${TESTJAVACOPTS} ${TESTTOOLVMOPTS} -d . RedefineMethodDelInvokeTarget.java +mv RedefineMethodDelInvokeTarget.java RedefineMethodDelInvokeTarget_1.java +mv RedefineMethodDelInvokeTarget.class RedefineMethodDelInvokeTarget_1.class + +cp "${TESTSRC}"/RedefineMethodDelInvokeTarget_2.java \ + RedefineMethodDelInvokeTarget.java +"${JAVAC}" ${TESTJAVACOPTS} ${TESTTOOLVMOPTS} -d . RedefineMethodDelInvokeTarget.java +mv RedefineMethodDelInvokeTarget.java RedefineMethodDelInvokeTarget_2.java +mv RedefineMethodDelInvokeTarget.class RedefineMethodDelInvokeTarget_2.class + +"${JAVA}" ${TESTVMOPTS} -javaagent:RedefineMethodDelInvokeAgent.jar \ + -classpath "${TESTCLASSES}" RedefineMethodDelInvokeApp > output.log 2>&1 + +result=$? +if [ "$result" = 0 ]; then + echo "The test returned expected exit code: $result" +else + echo "FAIL: the test returned unexpected exit code: $result" + exit $result +fi + +cat output.log + +MESG="Exception" +grep "$MESG" output.log +result=$? +if [ "$result" = 0 ]; then + echo "FAIL: found '$MESG' in the test output" + result=1 +else + echo "PASS: did NOT find '$MESG' in the test output" + result=0 +fi + +exit $result diff --git a/jdk/test/java/lang/instrument/RedefineMethodDelInvokeAgent.java b/jdk/test/java/lang/instrument/RedefineMethodDelInvokeAgent.java new file mode 100644 index 00000000000..2a3532f794e --- /dev/null +++ b/jdk/test/java/lang/instrument/RedefineMethodDelInvokeAgent.java @@ -0,0 +1,43 @@ +/* + * Copyright (c) 2014, 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. + */ + +import java.lang.instrument.Instrumentation; + +public class RedefineMethodDelInvokeAgent { + private static Instrumentation instrumentation; + + private RedefineMethodDelInvokeAgent() { + } + + public static void premain(String agentArgs, Instrumentation inst) { + System.out.println("Hello from RedefineMethodDelInvokeAgent!"); + System.out.println("isRedefineClassesSupported()=" + + inst.isRedefineClassesSupported()); + + instrumentation = inst; + } + + public static Instrumentation getInstrumentation() { + return instrumentation; + } +} diff --git a/jdk/test/java/lang/instrument/RedefineMethodDelInvokeApp.java b/jdk/test/java/lang/instrument/RedefineMethodDelInvokeApp.java new file mode 100644 index 00000000000..1cd354e85e5 --- /dev/null +++ b/jdk/test/java/lang/instrument/RedefineMethodDelInvokeApp.java @@ -0,0 +1,75 @@ +/* + * Copyright (c) 2014, 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. + */ + +import java.io.*; +import java.lang.instrument.*; + +public class RedefineMethodDelInvokeApp { + public static void main(String args[]) { + System.out.println("Hello from RedefineMethodDelInvokeApp!"); + + try { + new RedefineMethodDelInvokeApp().doTest(); + } catch (Exception ex) { + System.out.println("Exception has been caught"); + ex.printStackTrace(); + System.exit(1); + } + System.exit(0); + } + + private void doTest() throws Exception { + RedefineMethodDelInvokeTarget target = + new RedefineMethodDelInvokeTarget(); + + System.out.println("RedefineMethodDelInvokeApp: invoking myMethod0(), myMethod1(), myMethod2()"); + target.test(); + + // delete myMethod2() + do_redefine(1); + + System.out.println("RedefineMethodDelInvokeApp: invoking myMethod0(), myMethod1()"); + target.test(); + + // delete myMethod1() + do_redefine(2); + + System.out.println("RedefineMethodDelInvokeApp: invoking myMethod0()"); + target.test(); + } + + private static void do_redefine(int counter) throws Exception { + File f = new File("RedefineMethodDelInvokeTarget_" + counter + + ".class"); + System.out.println("Reading test class from " + f); + InputStream redefineStream = new FileInputStream(f); + + byte[] redefineBuffer = NamedBuffer.loadBufferFromStream(redefineStream); + + ClassDefinition redefineParamBlock = new ClassDefinition( + RedefineMethodDelInvokeTarget.class, redefineBuffer); + + RedefineMethodDelInvokeAgent.getInstrumentation().redefineClasses( + new ClassDefinition[] {redefineParamBlock}); + } +} diff --git a/jdk/test/java/lang/instrument/RedefineMethodDelInvokeTarget.java b/jdk/test/java/lang/instrument/RedefineMethodDelInvokeTarget.java new file mode 100644 index 00000000000..5bfcae45552 --- /dev/null +++ b/jdk/test/java/lang/instrument/RedefineMethodDelInvokeTarget.java @@ -0,0 +1,42 @@ +/* + * Copyright (c) 2014, 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 RedefineMethodDelInvokeTarget { + public void test() { + myMethod0(); + } + + public static void myMethod0() { + System.out.println("Target 0: myMethod0: Calling myMethod1()"); + myMethod1(); + } + + private static void myMethod1() { + System.out.println("Target 0: myMethod1: Calling myMethod2()"); + myMethod2(); + } + + private static void myMethod2() { + System.out.println("Target 0: myMethod2"); + } +} diff --git a/jdk/test/java/lang/instrument/RedefineMethodDelInvokeTarget_1.java b/jdk/test/java/lang/instrument/RedefineMethodDelInvokeTarget_1.java new file mode 100644 index 00000000000..170e41eba5a --- /dev/null +++ b/jdk/test/java/lang/instrument/RedefineMethodDelInvokeTarget_1.java @@ -0,0 +1,37 @@ +/* + * Copyright (c) 2014, 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 RedefineMethodDelInvokeTarget { + public void test() { + myMethod0(); + } + + public static void myMethod0() { + System.out.println("Target 1: myMethod0: Calling myMethod1()"); + myMethod1(); + } + + private static void myMethod1() { + System.out.println("Target 1: myMethod1"); + } +} diff --git a/jdk/test/java/lang/instrument/RedefineMethodDelInvokeTarget_2.java b/jdk/test/java/lang/instrument/RedefineMethodDelInvokeTarget_2.java new file mode 100644 index 00000000000..2513c52f528 --- /dev/null +++ b/jdk/test/java/lang/instrument/RedefineMethodDelInvokeTarget_2.java @@ -0,0 +1,32 @@ +/* + * Copyright (c) 2014, 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 RedefineMethodDelInvokeTarget { + public void test() { + myMethod0(); + } + + public static void myMethod0() { + System.out.println("Target 2: myMethod0"); + } +}