test/hotspot/jtreg/runtime/InvocationTests/shared/ExecutorGenerator.java
changeset 55497 d3a33953b936
equal deleted inserted replaced
55496:8e0ae3830fca 55497:d3a33953b936
       
     1 /*
       
     2  * Copyright (c) 2009, 2019, 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 package shared;
       
    26 
       
    27 import static jdk.internal.org.objectweb.asm.ClassWriter.*;
       
    28 import jdk.internal.org.objectweb.asm.Label;
       
    29 import jdk.internal.org.objectweb.asm.MethodVisitor;
       
    30 import jdk.internal.org.objectweb.asm.Opcodes;
       
    31 import jdk.internal.org.objectweb.asm.ClassWriter;
       
    32 import static jdk.internal.org.objectweb.asm.Opcodes.*;
       
    33 
       
    34 public class ExecutorGenerator {
       
    35     public static final String className = Utils.getInternalName("Test");
       
    36     private String caseDescription;
       
    37     private String staticTargetName;
       
    38     private String dynamicTargetName;
       
    39 
       
    40     private String callerSignature;
       
    41 
       
    42     public ExecutorGenerator(String caseDescription,
       
    43                              String staticTargetName,
       
    44                              String dynamicTargetName) {
       
    45         this.caseDescription = caseDescription;
       
    46         this.staticTargetName = Utils.getInternalName(staticTargetName);
       
    47         this.dynamicTargetName = Utils.getInternalName(dynamicTargetName);
       
    48         callerSignature = String.format("(L%s;)Ljava/lang/String;", this.staticTargetName);
       
    49     }
       
    50 
       
    51     public byte[] generateExecutor(String[] callSites) {
       
    52         ClassWriter cw = new ClassWriter(COMPUTE_MAXS);
       
    53 
       
    54         cw.visit(Utils.version, ACC_PUBLIC | (Utils.isACC_SUPER ? ACC_SUPER : 0), className, null, "java/lang/Object", null);
       
    55 
       
    56         // Generate constructor
       
    57         {
       
    58             MethodVisitor mv = cw.visitMethod(ACC_PUBLIC, "<init>", "()V", null, null);
       
    59             mv.visitCode();
       
    60             mv.visitVarInsn(ALOAD, 0);
       
    61             mv.visitMethodInsn(INVOKESPECIAL, "java/lang/Object", "<init>", "()V");
       
    62             mv.visitInsn(RETURN);
       
    63             mv.visitEnd();
       
    64             mv.visitMaxs(0, 0);
       
    65         }
       
    66 
       
    67         // public static void main(String[] args) {
       
    68         //      new Test().run();
       
    69         // }
       
    70         {
       
    71             MethodVisitor mv = cw.visitMethod(ACC_PUBLIC + ACC_STATIC, "main", "([Ljava/lang/String;)V", null, null);
       
    72             mv.visitCode();
       
    73             mv.visitTypeInsn(NEW, className);
       
    74             mv.visitInsn(DUP);
       
    75             mv.visitMethodInsn(INVOKESPECIAL, className, "<init>", "()V");
       
    76             mv.visitMethodInsn(INVOKEVIRTUAL, className, "run", "()V");
       
    77             mv.visitInsn(RETURN);
       
    78             mv.visitEnd();
       
    79             mv.visitMaxs(0, 0);
       
    80         }
       
    81 
       
    82         //    private String indent(String result) {
       
    83         //        while (result.length() < 8) {
       
    84         //            result = " "+result;
       
    85         //        }
       
    86         //        return result;
       
    87         //    }
       
    88         {
       
    89             MethodVisitor mv = cw.visitMethod(ACC_PRIVATE, "indent", "(Ljava/lang/String;)Ljava/lang/String;", null, null);
       
    90             mv.visitCode();
       
    91             Label l0 = new Label();
       
    92             mv.visitLabel(l0);
       
    93             mv.visitVarInsn(ALOAD, 1);
       
    94             mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/String", "length", "()I");
       
    95             mv.visitIntInsn(BIPUSH, 8);
       
    96             Label l1 = new Label();
       
    97             mv.visitJumpInsn(IF_ICMPGE, l1);
       
    98             mv.visitTypeInsn(NEW, "java/lang/StringBuffer");
       
    99             mv.visitInsn(DUP);
       
   100             mv.visitMethodInsn(INVOKESPECIAL, "java/lang/StringBuffer", "<init>", "()V");
       
   101             mv.visitLdcInsn(" ");
       
   102             mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/StringBuffer", "append", "(Ljava/lang/String;)Ljava/lang/StringBuffer;");
       
   103             mv.visitVarInsn(ALOAD, 1);
       
   104             mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/StringBuffer", "append", "(Ljava/lang/String;)Ljava/lang/StringBuffer;");
       
   105             mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/StringBuffer", "toString", "()Ljava/lang/String;");
       
   106             mv.visitVarInsn(ASTORE, 1);
       
   107             mv.visitJumpInsn(GOTO, l0);
       
   108             mv.visitLabel(l1);
       
   109             mv.visitVarInsn(ALOAD, 1);
       
   110             mv.visitInsn(ARETURN);
       
   111             mv.visitEnd();
       
   112             mv.visitMaxs(0, 0);
       
   113         }
       
   114 
       
   115         //private String abbr(String result) {
       
   116         //      result = result.replaceAll("java.lang.NullPointerException", "NPE");
       
   117         //      result = result.replaceAll("java.lang.IllegalAccessError", "IAE");
       
   118         //      result = result.replaceAll("java.lang.IllegalAccessException", "IAExc");
       
   119         //      result = result.replaceAll("java.lang.NoSuchMethodError", "NSME");
       
   120         //      result = result.replaceAll("java.lang.AbstractMethodError", "AME");
       
   121         //      result = result.replaceAll("java.lang.IncompatibleClassChangeError", "ICCE");
       
   122         //
       
   123         //      return result;
       
   124         //}
       
   125         {
       
   126             MethodVisitor mv = cw.visitMethod(ACC_PRIVATE, "abbr", "(Ljava/lang/String;)Ljava/lang/String;", null, null);
       
   127             mv.visitCode();
       
   128             mv.visitVarInsn(ALOAD, 1);
       
   129             mv.visitLdcInsn("java.lang.NullPointerException");
       
   130             mv.visitLdcInsn("NPE");
       
   131             mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/String", "replaceAll", "(Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String;");
       
   132             mv.visitVarInsn(ASTORE, 1);
       
   133             mv.visitVarInsn(ALOAD, 1);
       
   134             mv.visitLdcInsn("java.lang.IllegalAccessError");
       
   135             mv.visitLdcInsn("IAE");
       
   136             mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/String", "replaceAll", "(Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String;");
       
   137             mv.visitVarInsn(ASTORE, 1);
       
   138             mv.visitVarInsn(ALOAD, 1);
       
   139             mv.visitLdcInsn("java.lang.IllegalAccessException");
       
   140             mv.visitLdcInsn("IAExc");
       
   141             mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/String", "replaceAll", "(Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String;");
       
   142             mv.visitVarInsn(ASTORE, 1);
       
   143             mv.visitVarInsn(ALOAD, 1);
       
   144             mv.visitLdcInsn("java.lang.NoSuchMethodError");
       
   145             mv.visitLdcInsn("NSME");
       
   146             mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/String", "replaceAll", "(Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String;");
       
   147             mv.visitVarInsn(ASTORE, 1);
       
   148             mv.visitVarInsn(ALOAD, 1);
       
   149             mv.visitLdcInsn("java.lang.AbstractMethodError");
       
   150             mv.visitLdcInsn("AME");
       
   151             mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/String", "replaceAll", "(Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String;");
       
   152             mv.visitVarInsn(ASTORE, 1);
       
   153             mv.visitVarInsn(ALOAD, 1);
       
   154             mv.visitLdcInsn("java.lang.IncompatibleClassChangeError");
       
   155             mv.visitLdcInsn("ICCE");
       
   156             mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/String", "replaceAll", "(Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String;");
       
   157             mv.visitVarInsn(ASTORE, 1);
       
   158             mv.visitVarInsn(ALOAD, 1);
       
   159             mv.visitInsn(ARETURN);
       
   160             mv.visitEnd();
       
   161             mv.visitMaxs(0, 0);
       
   162         }
       
   163 
       
   164         // Generate execution method
       
   165         //        public void run() {
       
   166         //            System.out.print("2048| ! a.A PUB    ! b.B PP     a.C PROT    |");
       
   167         //
       
   168         //            C object = new C();
       
   169         //
       
   170         //            try {
       
   171         //              System.out.print(indent(A.call(object)));
       
   172         //            } catch (Throwable e) {
       
   173         //              System.out.print(indent(abbr(e.getClass().getName())));
       
   174         //            }
       
   175         //
       
   176         //            ...
       
   177         //
       
   178         //            System.out.println();
       
   179         //        }
       
   180         {
       
   181             MethodVisitor mv = cw.visitMethod(ACC_PUBLIC, "run", "()V", null, null);
       
   182             mv.visitCode();
       
   183 
       
   184             // Generate try/catch blocks
       
   185             Label[][] tryCatchLabels = new Label[callSites.length][3];
       
   186             for (int I = 0; I < tryCatchLabels.length; I++) {
       
   187                 Label[] labels = tryCatchLabels[I];
       
   188                 for (int K = 0; K < labels.length; K++) {
       
   189                     labels[K] = new Label();
       
   190                 }
       
   191 
       
   192                 mv.visitTryCatchBlock(labels[0], labels[1], labels[2], "java/lang/Throwable");
       
   193             }
       
   194 
       
   195             // System.out.print("2048| ! a.A PUB    ! b.B PP     a.C PROT    |");
       
   196             mv.visitFieldInsn(GETSTATIC, "java/lang/System", "out", "Ljava/io/PrintStream;");
       
   197             mv.visitLdcInsn(caseDescription);
       
   198             mv.visitMethodInsn(INVOKEVIRTUAL, "java/io/PrintStream", "print", "(Ljava/lang/String;)V");
       
   199 
       
   200             // C object = new C();
       
   201             mv.visitTypeInsn(NEW, dynamicTargetName);
       
   202             mv.visitInsn(DUP);
       
   203             mv.visitMethodInsn(INVOKESPECIAL, dynamicTargetName, "<init>", "()V");
       
   204             mv.visitVarInsn(ASTORE, 1);
       
   205 
       
   206 //            for (String site: callSites) {
       
   207             // System.out.print(indent(A.call(object)));
       
   208 //                mv.visitFieldInsn(GETSTATIC, "java/lang/System", "out", "Ljava/io/PrintStream;");
       
   209 //                mv.visitVarInsn(ALOAD, 0);
       
   210 //                mv.visitVarInsn(ALOAD, 1);
       
   211 //                mv.visitMethodInsn(INVOKESTATIC, AbstractGenerator.getInternalName(site), "call", callerSignature);
       
   212 //                mv.visitMethodInsn(INVOKESPECIAL, className, "indent", "(Ljava/lang/String;)Ljava/lang/String;");
       
   213 //                mv.visitMethodInsn(INVOKEVIRTUAL, "java/io/PrintStream", "print", "(Ljava/lang/String;)V");
       
   214 //        }
       
   215 
       
   216             Label returnLabel = new Label();
       
   217             for (int I = 0; I < callSites.length; I++) {
       
   218                 String site = callSites[I];
       
   219                 Label[] l = tryCatchLabels[I];
       
   220 
       
   221                 Label nextBlock = (I+1 < callSites.length ? tryCatchLabels[I+1][0] : returnLabel);
       
   222 
       
   223                 mv.visitLabel(l[0]);
       
   224                 mv.visitFieldInsn(GETSTATIC, "java/lang/System", "out", "Ljava/io/PrintStream;");
       
   225                 mv.visitVarInsn(ALOAD, 0);
       
   226                 mv.visitVarInsn(ALOAD, 1);
       
   227                 mv.visitMethodInsn(INVOKESTATIC, Utils.getInternalName(site), "call", callerSignature);
       
   228                 mv.visitMethodInsn(INVOKESPECIAL, className, "indent", "(Ljava/lang/String;)Ljava/lang/String;");
       
   229                 mv.visitMethodInsn(INVOKEVIRTUAL, "java/io/PrintStream", "print", "(Ljava/lang/String;)V");
       
   230                 mv.visitLabel(l[1]);
       
   231                 mv.visitJumpInsn(GOTO, nextBlock);
       
   232                 mv.visitLabel(l[2]);
       
   233                 mv.visitVarInsn(ASTORE, 2);
       
   234                 mv.visitFieldInsn(GETSTATIC, "java/lang/System", "out", "Ljava/io/PrintStream;");
       
   235                 mv.visitVarInsn(ALOAD, 0);
       
   236                 mv.visitVarInsn(ALOAD, 0);
       
   237                 mv.visitVarInsn(ALOAD, 2);
       
   238                 mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/Object", "getClass", "()Ljava/lang/Class;");
       
   239                 mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/Class", "getName", "()Ljava/lang/String;");
       
   240                 mv.visitMethodInsn(INVOKESPECIAL, className, "abbr", "(Ljava/lang/String;)Ljava/lang/String;");
       
   241                 mv.visitMethodInsn(INVOKESPECIAL, className, "indent", "(Ljava/lang/String;)Ljava/lang/String;");
       
   242                 mv.visitMethodInsn(INVOKEVIRTUAL, "java/io/PrintStream", "print", "(Ljava/lang/String;)V");
       
   243             }
       
   244             mv.visitLabel(returnLabel);
       
   245 
       
   246             // System.out.println();
       
   247             mv.visitFieldInsn(GETSTATIC, "java/lang/System", "out", "Ljava/io/PrintStream;");
       
   248             mv.visitMethodInsn(INVOKEVIRTUAL, "java/io/PrintStream", "println", "()V");
       
   249             mv.visitInsn(RETURN);
       
   250 
       
   251             mv.visitEnd();
       
   252             mv.visitMaxs(0, 0);
       
   253         }
       
   254 
       
   255         cw.visitEnd();
       
   256 
       
   257         return cw.toByteArray();
       
   258     }
       
   259 }