1 /* 2 * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. 8 * 9 * This code is distributed in the hope that it will be useful, but WITHOUT 10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 12 * version 2 for more details (a copy is included in the LICENSE file that 13 * accompanied this code). 14 * 15 * You should have received a copy of the GNU General Public License version 16 * 2 along with this work; if not, write to the Free Software Foundation, 17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 18 * 19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 20 * or visit www.oracle.com if you need additional information or have any 21 * questions. 22 */ 23 24 /* 25 * @test 26 * @bug 8072008 27 * @modules java.base/jdk.internal.org.objectweb.asm 28 * java.base/jdk.internal.misc 29 * java.base/jdk.internal.vm.annotation 30 * @library /testlibrary /test/lib / ../patches 31 * @requires vm.flavor != "minimal" 32 * @build sun.hotspot.WhiteBox 33 * @build java.base/java.lang.invoke.MethodHandleHelper 34 * @build compiler.jsr292.NonInlinedCall.RedefineTest 35 * @run main compiler.jsr292.NonInlinedCall.Agent agent.jar compiler.jsr292.NonInlinedCall.RedefineTest 36 * @run main ClassFileInstaller sun.hotspot.WhiteBox 37 * sun.hotspot.WhiteBox$WhiteBoxPermission 38 * compiler.jsr292.NonInlinedCall.RedefineTest 39 * @run main/bootclasspath/othervm -javaagent:agent.jar 40 * -XX:+IgnoreUnrecognizedVMOptions 41 * -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI 42 * -Xbatch -XX:-TieredCompilation -XX:CICompilerCount=1 43 * compiler.jsr292.NonInlinedCall.RedefineTest 44 */ 45 46 package compiler.jsr292.NonInlinedCall; 47 48 import sun.hotspot.WhiteBox; 49 50 import java.lang.instrument.ClassDefinition; 51 import java.lang.instrument.Instrumentation; 52 import java.lang.invoke.MethodHandle; 53 import java.lang.invoke.MethodHandles; 54 import java.lang.invoke.MethodHandleHelper; 55 import java.lang.invoke.MethodType; 56 57 import jdk.internal.misc.Unsafe; 58 import jdk.internal.vm.annotation.DontInline; 59 import jdk.internal.org.objectweb.asm.*; 60 61 import static jdk.internal.org.objectweb.asm.Opcodes.*; 62 63 public class RedefineTest { 64 static final MethodHandles.Lookup LOOKUP = MethodHandleHelper.IMPL_LOOKUP; 65 static final Unsafe UNSAFE = Unsafe.getUnsafe(); 66 67 static final String NAME = "compiler/jsr292/NonInlinedCall/RedefineTest$T"; 68 69 static Class<?> getClass(int r) { 70 byte[] classFile = getClassFile(r); 71 return UNSAFE.defineClass(NAME, classFile, 0, classFile.length, null, null); 72 } 73 74 /** 75 * Generates a class of the following shape: 76 * static class T { 77 * @DontInline public static int f() { return $r; } 78 * } 79 */ 80 static byte[] getClassFile(int r) { 81 ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_FRAMES | ClassWriter.COMPUTE_MAXS); 82 MethodVisitor mv; 83 cw.visit(52, ACC_PUBLIC | ACC_SUPER, NAME, null, "java/lang/Object", null); 84 { 85 mv = cw.visitMethod(ACC_PUBLIC | ACC_STATIC, "f", "()I", null, null); 86 mv.visitAnnotation("Ljdk/internal/vm/annotation/DontInline;", true); 87 mv.visitCode(); 88 mv.visitLdcInsn(r); 89 mv.visitInsn(IRETURN); 90 mv.visitMaxs(0, 0); 91 mv.visitEnd(); 92 } 93 cw.visitEnd(); 94 return cw.toByteArray(); 95 } 96 97 static final MethodHandle mh; 98 static final Class<?> CLS = getClass(0); 99 static { 100 try { 101 mh = LOOKUP.findStatic(CLS, "f", MethodType.methodType(int.class)); 102 } catch (Exception e) { 103 throw new Error(e); 104 } 105 } 106 107 static final WhiteBox WB = WhiteBox.getWhiteBox(); 108 109 @DontInline 110 static int invokeBasic() { 111 try { 112 return (int)mh.invokeExact(); 113 } catch (Throwable e) { 114 throw new Error(e); 115 } 116 } 117 118 static Instrumentation instr; 119 public static void premain(String args, Instrumentation instr) { 120 RedefineTest.instr = instr; 121 } 122 123 124 public static void main(String[] args) throws Exception { 125 for (int i = 0; i < 20_000; i++) { 126 int r = invokeBasic(); 127 if (r != 0) { 128 throw new Error(r + " != 0"); 129 } 130 } 131 // WB.ensureCompiled(); 132 133 redefine(); 134 135 int exp = (instr != null) ? 1 : 0; 136 137 for (int i = 0; i < 20_000; i++) { 138 if (invokeBasic() != exp) { 139 throw new Error(); 140 } 141 } 142 143 WB.clearInlineCaches(); 144 145 for (int i = 0; i < 20_000; i++) { 146 if (invokeBasic() != exp) { 147 throw new Error(); 148 } 149 } 150 151 // WB.ensureCompiled(); 152 } 153 154 static void redefine() { 155 if (instr == null) { 156 System.out.println("NOT REDEFINED"); 157 return; 158 } 159 ClassDefinition cd = new ClassDefinition(CLS, getClassFile(1)); 160 try { 161 instr.redefineClasses(cd); 162 } catch (Exception e) { 163 throw new Error(e); 164 } 165 System.out.println("REDEFINED"); 166 } 167 }