test/hotspot/jtreg/runtime/InvocationTests/invokevirtual/Generator.java
author hseigel
Wed, 26 Jun 2019 09:06:32 -0400
changeset 55497 d3a33953b936
permissions -rw-r--r--
8224137: Analyze and port invocation tests to jtreg and co-locate to jdk repo Summary: Add JTReg compatible main programs to run tests for various invoke* instructions Reviewed-by: lfoltan, coleenp

/*
 * Copyright (c) 2009, 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.
 *
 */

package invokevirtual;

import static jdk.internal.org.objectweb.asm.Opcodes.ACC_ABSTRACT;
import static jdk.internal.org.objectweb.asm.Opcodes.ACC_PUBLIC;
import shared.AbstractGenerator;
import shared.AccessType;

import java.util.HashMap;
import java.util.Map;

public class Generator extends AbstractGenerator {
    public Generator(String[] args) {
        super(args);
    }

    public static void main (String[] args) throws Exception {
        new Generator(args).run();
    }

    protected Checker getChecker(Class paramClass, Class targetClass) {
        return new Checker(paramClass, targetClass);
    }

    private void run() throws Exception {
        // Specify package names
        String pkg1 = "a.";
        String pkg2 = "b.";
        String pkg3 = "c.";
        String[] packages = new String[] { "", pkg1, pkg2, pkg3 };

        boolean isPassed = true;

        // Hierarchy
        // The following triples will be used during further
        // hierarchy construction and will specify packages for A, B and C
        String[][] packageSets = new String[][] {
                {   "",   "",   "" }
                , {   "", pkg1, pkg1 }
                , {   "", pkg1, pkg2 }
                , { pkg1, pkg1, pkg1 }
                , { pkg1, pkg1, pkg2 }
                , { pkg1, pkg2, pkg1 }
                , { pkg1, pkg2, pkg2 }
        };

        String [] header = new String[] {
                String.format("%30s %45s %20s", "Method access modifiers", "Call site location", "Status")
                , String.format("%4s  %-12s %-12s %-12s   %7s %7s %7s %7s %7s %7s"
                        , "  # "
                        , "A.m()"
                        , "B.m()"
                        , "C.m()"
                        , "  A  "
                        , "pkgA "
                        , "  B  "
                        , " pkgB"
                        , "  C  "
                        , "pkgC "
                        )
                , "-------------------------------------------------------------------------------------------------"
        };

        for (String str : header) {
            System.out.println(str);
        }

        for (String[] pkgSet : packageSets) {
            String packageA = pkgSet[0];
            String packageB = pkgSet[1];
            String packageC = pkgSet[2];

            String classNameA = packageA + "A";
            String classNameB = packageB + "B";
            String classNameC = packageC + "C";

            String staticCallerParam = classNameA;

            // For all possible access modifier combinations
            for (AccessType accessA : AccessType.values()) {
                for (AccessType accessB : AccessType.values()) {
                    for (AccessType accessC : AccessType.values()) {

                        if (accessA == AccessType.UNDEF) {
                            continue;
                        }

                        for (int I = 0; I < 4; I++) {
                            boolean isAbstractA = ((I & 1) != 0);
                            boolean isAbstractB = ((I & 2) != 0);

                            Map<String, byte[]> classes = new HashMap<String, byte[]>();

                            // Generate class A
                            classes.put(
                                    classNameA
                                    , new ClassGenerator( classNameA
                                                        , "java.lang.Object"
                                                        , ACC_PUBLIC | (isAbstractA ? ACC_ABSTRACT : 0))
                                        .addTargetMethod( accessA
                                                        , (isAbstractA ? ACC_ABSTRACT : 0))
                                        .addCaller(staticCallerParam)
                                        .getClassFile()
                            );

                            // Generate class B
                            classes.put(
                                    classNameB
                                    , new ClassGenerator( classNameB
                                                        , classNameA
                                                        , ACC_PUBLIC | (isAbstractB ? ACC_ABSTRACT : 0))
                                    .addTargetMethod( accessB
                                                    , (isAbstractB ? ACC_ABSTRACT : 0))
                                    .addCaller(staticCallerParam)
                                    .getClassFile()
                            );

                            // Generate class C
                            classes.put(
                                    classNameC
                                    , new ClassGenerator(classNameC, classNameB)
                                        .addTargetMethod(accessC)
                                        .addCaller(staticCallerParam)
                                        .getClassFile()
                            );

                            // Generate package callers
                            for (String pkg : packages) {
                                classes.put(
                                        pkg+"Caller"
                                        , new ClassGenerator(pkg+"Caller")
                                        .addCaller(staticCallerParam)
                                        .getClassFile()
                                );
                            }

                            String[] callSites = new String[] {
                                    classNameA
                                    , packageA+"Caller"
                                    , classNameB
                                    , packageB+"Caller"
                                    , classNameC
                                    , packageC+"Caller"
                            };


                            String caseDescription =
                                    String.format("%-12s %-12s %-12s| "
                                        , (isAbstractA ? "! " : "  ") + classNameA + " " + accessA
                                        , (isAbstractB ? "! " : "  ") + classNameB + " " + accessB
                                        , classNameC + " " + accessC
                                    );

                            boolean result = exec(classes, caseDescription, staticCallerParam, classNameC, callSites);
                            isPassed = isPassed && result;
                        }
                    }
                }
            }
        }

        // Print footer
        for (int i = header.length-1; i >= 0; i--) {
            System.out.println(header[i]);
        }

        if (executeTests) {
            System.out.printf("\nEXECUTION STATUS: %s\n", (isPassed? "PASSED" : "FAILED"));
        }
    }
}