8228596: Class redefinition fails when condy instructions are removed

Make sure has_dynamic_constant flag value gets copied to merged constant pool, when it is set to TRUE

Reviewed-by: coleenp, dcubed, sspitsyn
This commit is contained in:
Harold Seigel 2019-07-29 09:57:37 -04:00
parent f5b92a4ca7
commit 3d6ba9735f
3 changed files with 112 additions and 0 deletions

View File

@ -1623,6 +1623,11 @@ jvmtiError VM_RedefineClasses::merge_cp_and_rewrite(
return JVMTI_ERROR_INTERNAL;
}
if (old_cp->has_dynamic_constant()) {
merge_cp->set_has_dynamic_constant();
scratch_cp->set_has_dynamic_constant();
}
log_info(redefine, class, constantpool)("merge_cp_len=%d, index_map_len=%d", merge_cp_length, _index_map_count);
if (_index_map_count == 0) {
@ -3246,6 +3251,10 @@ void VM_RedefineClasses::set_new_constant_pool(
// reference to the cp holder is needed for copy_operands()
smaller_cp->set_pool_holder(scratch_class);
if (scratch_cp->has_dynamic_constant()) {
smaller_cp->set_has_dynamic_constant();
}
scratch_cp->copy_cp_to(1, scratch_cp_length - 1, smaller_cp, 1, THREAD);
if (HAS_PENDING_EXCEPTION) {
// Exception is handled in the caller

View File

@ -0,0 +1,43 @@
/*
* Copyright (c) 2019, 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.
*/
super public class RedefineCondy version 55:0 {
public Method "<init>":"(Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/Class;)V"
stack 3 locals 4 {
aload_0;
invokespecial Method java/lang/Object."<init>":"()V";
getstatic Field java/lang/System.out:"Ljava/io/PrintStream;";
ldc String "In RedefineCondy <init> method";
invokevirtual Method java/io/PrintStream.println:"(Ljava/lang/String;)V";
return;
}
public static Method main:"([Ljava/lang/String;)V" stack 3 locals 1 {
new class RedefineCondy;
dup;
ldc Dynamic REF_newInvokeSpecial:RedefineCondy."<init>":"(Ljava/lang/invoke/MethodHandles$Lookup;Ljava/lang/String;Ljava/lang/Class;)V":RedefineCondy:"Ljava/lang/Object;";
return;
}
} // end Class RedefineCondy

View File

@ -0,0 +1,60 @@
/*
* Copyright (c) 2019, 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 8228596
* @summary Test redefining a class with a condy in its constant pool
* @library /test/lib
* @modules java.base/jdk.internal.misc
* @modules java.compiler
* java.instrument
* jdk.jartool/sun.tools.jar
* @compile RedefineCondy.jasm
* @run main RedefineClassHelper
* @run main/othervm -javaagent:redefineagent.jar TestRedefineCondy
*/
import jdk.test.lib.compiler.InMemoryJavaCompiler;
// Test redefining a class that has a constant dynamic in its constant pool
// to a class that does not have a constant dynamic in its constant pool.
public class TestRedefineCondy {
static final String DEST = System.getProperty("test.classes");
static String newClass =
"public class RedefineCondy { " +
"public RedefineCondy(java.lang.invoke.MethodHandles.Lookup l, java.lang.String s, java.lang.Class c) { } " +
"public static void main(String argv[]) { } } ";
public static void main(String[] args) throws Exception {
Class<?> classWithCondy = Class.forName("RedefineCondy");
try {
byte[] classBytes = InMemoryJavaCompiler.compile("RedefineCondy", newClass);
RedefineClassHelper.redefineClass(classWithCondy, classBytes);
} catch (Exception e) {
throw new RuntimeException("Unexpected exception: " + e.getMessage());
}
}
}