1 /* 2 * Copyright (c) 2010, 2015, 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 /** 26 * @test 27 * @bug 6932496 28 * @summary incorrect deopt of jsr subroutine on 64 bit c1 29 * @modules java.base/jdk.internal.org.objectweb.asm 30 * 31 * @run main/othervm -Xcomp 32 * -XX:CompileCommand=compileonly,compiler.c1.Test6932496::test 33 * compiler.c1.Test6932496 34 */ 35 36 package compiler.c1; 37 38 import jdk.internal.org.objectweb.asm.ClassWriter; 39 import jdk.internal.org.objectweb.asm.FieldVisitor; 40 import jdk.internal.org.objectweb.asm.Label; 41 import jdk.internal.org.objectweb.asm.MethodVisitor; 42 import jdk.internal.org.objectweb.asm.Opcodes; 43 import jdk.internal.org.objectweb.asm.Type; 44 45 import java.io.IOException; 46 import java.lang.reflect.Method; 47 import java.nio.file.Files; 48 import java.nio.file.Paths; 49 50 public class Test6932496 extends ClassLoader { 51 private static final int CLASS_FILE_VERSION = 49; 52 private static final String CLASS_TEST = "Test"; 53 private static final String CLASS_OBJECT = "java/lang/Object"; 54 private static final String METHOD_INIT = "<init>"; 55 private static final String METHOD_TEST = "test"; 56 private static final String DESC_VOID_METHOD = "()V"; 57 private static final String FIELD_FLAG = "flag"; 58 59 public static void main(String[] args) { 60 Test6932496 test = new Test6932496(); 61 test.execute(); 62 } 63 64 private void execute() { 65 byte[] bytecode = Test6932496.generateTestClass(); 66 67 try { 68 Files.write(Paths.get("Test.class.dump"), bytecode); 69 } catch (IOException e) { 70 System.err.println("classfile dump failed : " + e.getMessage()); 71 e.printStackTrace(); 72 } 73 try { 74 Class aClass = defineClass(CLASS_TEST, bytecode, 0, bytecode.length); 75 Method test = aClass.getDeclaredMethod(METHOD_TEST); 76 test.invoke(null); 77 } catch (ClassFormatError | IllegalArgumentException 78 | ReflectiveOperationException e) { 79 throw new RuntimeException("TESTBUG : generated class is invalid", e); 80 } 81 } 82 83 /* 84 public class Test { 85 volatile boolean flag = false; 86 public static void m() { 87 try { 88 } finally { 89 Test test = new Test(); 90 test.flag = true; 91 } 92 } 93 } 94 */ 95 private static byte[] generateTestClass() { 96 ClassWriter cw = new ClassWriter(0); 97 cw.visit(CLASS_FILE_VERSION, Opcodes.ACC_PUBLIC + Opcodes.ACC_SUPER, 98 CLASS_TEST, null, CLASS_OBJECT, null); 99 // volatile boolean flag; 100 { 101 FieldVisitor fv = cw.visitField(Opcodes.ACC_VOLATILE, FIELD_FLAG, 102 Type.BOOLEAN_TYPE.getDescriptor(), 103 /* signature = */ null, /* value = */ null); 104 } 105 106 /* 107 public Test() { 108 flag = false; 109 } 110 */ 111 { 112 MethodVisitor mv = cw.visitMethod(Opcodes.ACC_PUBLIC, 113 METHOD_INIT, DESC_VOID_METHOD, 114 /* signature = */ null, /* exceptions = */ null); 115 116 mv.visitCode(); 117 mv.visitVarInsn(Opcodes.ALOAD, 0); 118 mv.visitMethodInsn(Opcodes.INVOKESPECIAL, CLASS_OBJECT, METHOD_INIT, 119 DESC_VOID_METHOD, false); 120 121 mv.visitVarInsn(Opcodes.ALOAD, 0); 122 mv.visitInsn(Opcodes.ICONST_0); 123 mv.visitFieldInsn(Opcodes.PUTFIELD, CLASS_TEST, FIELD_FLAG, 124 Type.BOOLEAN_TYPE.getDescriptor()); 125 126 mv.visitInsn(Opcodes.RETURN); 127 mv.visitMaxs(/* stack = */ 2, /* locals = */ 1); 128 mv.visitEnd(); 129 } 130 131 /* 132 public static void m() { 133 try { 134 } finally { 135 Test test = new Test(); 136 test.flag = true; 137 } 138 } 139 */ 140 { 141 MethodVisitor mv = cw.visitMethod( 142 Opcodes.ACC_STATIC + Opcodes.ACC_PUBLIC, 143 METHOD_TEST, DESC_VOID_METHOD, 144 /* signature = */ null, /* exceptions = */ null); 145 Label beginLabel = new Label(); 146 Label block1EndLabel = new Label(); 147 Label handlerLabel = new Label(); 148 Label block2EndLabel = new Label(); 149 Label label = new Label(); 150 Label endLabel = new Label(); 151 152 mv.visitCode(); 153 mv.visitTryCatchBlock(beginLabel, block1EndLabel, handlerLabel, 154 /* type = <any> */ null); 155 mv.visitTryCatchBlock(handlerLabel, block2EndLabel, handlerLabel, 156 /* type = <any> */ null); 157 158 mv.visitLabel(beginLabel); 159 mv.visitJumpInsn(Opcodes.JSR, label); 160 mv.visitLabel(block1EndLabel); 161 mv.visitJumpInsn(Opcodes.GOTO, endLabel); 162 163 mv.visitLabel(handlerLabel); 164 mv.visitVarInsn(Opcodes.ASTORE, 0); 165 mv.visitJumpInsn(Opcodes.JSR, label); 166 mv.visitLabel(block2EndLabel); 167 mv.visitVarInsn(Opcodes.ALOAD, 0); 168 mv.visitInsn(Opcodes.ATHROW); 169 170 mv.visitLabel(label); 171 mv.visitVarInsn(Opcodes.ASTORE, 1); 172 mv.visitTypeInsn(Opcodes.NEW, CLASS_TEST); 173 mv.visitInsn(Opcodes.DUP); 174 mv.visitMethodInsn(Opcodes.INVOKESPECIAL, CLASS_TEST, METHOD_INIT, 175 DESC_VOID_METHOD); 176 mv.visitVarInsn(Opcodes.ASTORE, 2); 177 178 mv.visitVarInsn(Opcodes.ALOAD, 2); 179 mv.visitInsn(Opcodes.ICONST_1); 180 mv.visitFieldInsn(Opcodes.PUTFIELD, CLASS_TEST, FIELD_FLAG, 181 Type.BOOLEAN_TYPE.getDescriptor()); 182 183 mv.visitVarInsn(Opcodes.RET, 1); 184 185 mv.visitLabel(endLabel); 186 mv.visitInsn(Opcodes.RETURN); 187 mv.visitMaxs(/* stack = */ 2, /* locals = */ 3); 188 mv.visitEnd(); 189 } 190 191 cw.visitEnd(); 192 return cw.toByteArray(); 193 } 194 }