8051484: Test compiler/6932496/Test6932496.java failed to compile after JDK-8011044: 1.5 is no longer supported
authoriignatyev
Sun, 03 Aug 2014 12:04:36 +0400
changeset 25925 4d05abb05c1a
parent 25924 4c3dd8541530
child 25926 486f1571b70f
child 25928 8fc19b57296f
8051484: Test compiler/6932496/Test6932496.java failed to compile after JDK-8011044: 1.5 is no longer supported Reviewed-by: kvn, roland
hotspot/test/compiler/6932496/Test6932496.java
--- a/hotspot/test/compiler/6932496/Test6932496.java	Sun Aug 03 12:04:17 2014 +0400
+++ b/hotspot/test/compiler/6932496/Test6932496.java	Sun Aug 03 12:04:36 2014 +0400
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2010, 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
@@ -26,26 +26,162 @@
  * @test
  * @bug 6932496
  * @summary incorrect deopt of jsr subroutine on 64 bit c1
- *
- * @compile -source 1.5 -target 1.5 -XDjsrlimit=0 Test6932496.java
- * @run main/othervm -Xcomp -XX:CompileOnly=Test6932496.m Test6932496
+ * @run main/othervm -Xcomp -XX:CompileOnly=Test.test Test6932496
  */
+import java.lang.reflect.Method;
+import java.nio.file.Files;
+import java.nio.file.Paths;
+import java.io.IOException;
 
-public class Test6932496 {
-    static class A {
-        volatile boolean flag = false;
+import jdk.internal.org.objectweb.asm.ClassWriter;
+import jdk.internal.org.objectweb.asm.MethodVisitor;
+import jdk.internal.org.objectweb.asm.FieldVisitor;
+import jdk.internal.org.objectweb.asm.Opcodes;
+import jdk.internal.org.objectweb.asm.Type;
+import jdk.internal.org.objectweb.asm.Label;
+
+public class Test6932496 extends ClassLoader {
+    private static final int CLASS_FILE_VERSION = 49;
+    private static final String CLASS_TEST = "Test";
+    private static final String CLASS_OBJECT = "java/lang/Object";
+    private static final String METHOD_INIT = "<init>";
+    private static final String METHOD_TEST = "test";
+    private static final String DESC_VOID_METHOD = "()V";
+    private static final String FIELD_FLAG = "flag";
+
+    public static void main(String[] args) {
+        Test6932496 test = new Test6932496();
+        test.execute();
     }
 
-    static void m() {
+    private void execute() {
+        byte[] bytecode = Test6932496.generateTestClass();
+
         try {
-        } finally {
-            A a = new A();
-            a.flag = true;
+            Files.write(Paths.get("Test.class.dump"), bytecode);
+        } catch (IOException e) {
+            System.err.println("classfile dump failed : " + e.getMessage());
+            e.printStackTrace();
+        }
+        try {
+            Class aClass = defineClass(CLASS_TEST, bytecode, 0, bytecode.length);
+            Method test = aClass.getDeclaredMethod(METHOD_TEST);
+            test.invoke(null);
+        } catch (ClassFormatError | IllegalArgumentException
+                    | ReflectiveOperationException e) {
+            throw new RuntimeException("TESTBUG : generated class is invalid", e);
         }
     }
 
+    /*
+        public class Test {
+            volatile boolean flag = false;
+            public static void m() {
+                try {
+                } finally {
+                    Test test = new Test();
+                    test.flag = true;
+                }
+            }
+        }
+    */
+    private static byte[] generateTestClass() {
+        ClassWriter cw = new ClassWriter(0);
+        cw.visit(CLASS_FILE_VERSION, Opcodes.ACC_PUBLIC + Opcodes.ACC_SUPER,
+                CLASS_TEST, null, CLASS_OBJECT, null);
+        // volatile boolean flag;
+        {
+            FieldVisitor fv = cw.visitField(Opcodes.ACC_VOLATILE, FIELD_FLAG,
+                    Type.BOOLEAN_TYPE.getDescriptor(),
+                    /* signature = */ null, /* value = */ null);
+        }
 
-    static public void main(String[] args) {
-        m();
+        /*
+            public Test() {
+                flag = false;
+            }
+        */
+        {
+            MethodVisitor mv = cw.visitMethod(Opcodes.ACC_PUBLIC,
+                    METHOD_INIT, DESC_VOID_METHOD,
+                    /* signature = */ null, /* exceptions = */ null);
+
+            mv.visitCode();
+            mv.visitVarInsn(Opcodes.ALOAD, 0);
+            mv.visitMethodInsn(Opcodes.INVOKESPECIAL, CLASS_OBJECT, METHOD_INIT,
+                    DESC_VOID_METHOD, false);
+
+            mv.visitVarInsn(Opcodes.ALOAD, 0);
+            mv.visitInsn(Opcodes.ICONST_0);
+            mv.visitFieldInsn(Opcodes.PUTFIELD, CLASS_TEST, FIELD_FLAG,
+                    Type.BOOLEAN_TYPE.getDescriptor());
+
+            mv.visitInsn(Opcodes.RETURN);
+            mv.visitMaxs(/* stack = */ 2, /* locals = */ 1);
+            mv.visitEnd();
+        }
+
+        /*
+            public static void m() {
+                try {
+                } finally {
+                    Test test = new Test();
+                    test.flag = true;
+                }
+            }
+        */
+        {
+            MethodVisitor mv = cw.visitMethod(
+                    Opcodes.ACC_STATIC + Opcodes.ACC_PUBLIC,
+                    METHOD_TEST, DESC_VOID_METHOD,
+                    /* signature = */ null, /* exceptions = */ null);
+            Label beginLabel = new Label();
+            Label block1EndLabel = new Label();
+            Label handlerLabel = new Label();
+            Label block2EndLabel = new Label();
+            Label label = new Label();
+            Label endLabel = new Label();
+
+            mv.visitCode();
+            mv.visitTryCatchBlock(beginLabel, block1EndLabel, handlerLabel,
+                    /* type = <any> */ null);
+            mv.visitTryCatchBlock(handlerLabel, block2EndLabel, handlerLabel,
+                    /* type = <any> */ null);
+
+            mv.visitLabel(beginLabel);
+            mv.visitJumpInsn(Opcodes.JSR, label);
+            mv.visitLabel(block1EndLabel);
+            mv.visitJumpInsn(Opcodes.GOTO, endLabel);
+
+            mv.visitLabel(handlerLabel);
+            mv.visitVarInsn(Opcodes.ASTORE, 0);
+            mv.visitJumpInsn(Opcodes.JSR, label);
+            mv.visitLabel(block2EndLabel);
+            mv.visitVarInsn(Opcodes.ALOAD, 0);
+            mv.visitInsn(Opcodes.ATHROW);
+
+            mv.visitLabel(label);
+            mv.visitVarInsn(Opcodes.ASTORE, 1);
+            mv.visitTypeInsn(Opcodes.NEW, CLASS_TEST);
+            mv.visitInsn(Opcodes.DUP);
+            mv.visitMethodInsn(Opcodes.INVOKESPECIAL, CLASS_TEST, METHOD_INIT,
+                    DESC_VOID_METHOD);
+            mv.visitVarInsn(Opcodes.ASTORE, 2);
+
+            mv.visitVarInsn(Opcodes.ALOAD, 2);
+            mv.visitInsn(Opcodes.ICONST_1);
+            mv.visitFieldInsn(Opcodes.PUTFIELD, CLASS_TEST, FIELD_FLAG,
+                    Type.BOOLEAN_TYPE.getDescriptor());
+
+            mv.visitVarInsn(Opcodes.RET, 1);
+
+            mv.visitLabel(endLabel);
+            mv.visitInsn(Opcodes.RETURN);
+            mv.visitMaxs(/* stack = */ 2, /* locals = */ 3);
+            mv.visitEnd();
+        }
+
+        cw.visitEnd();
+        return cw.toByteArray();
     }
 }