1 package compiler.jvmci.compilerToVM;
   2 
   3 import jdk.vm.ci.code.InstalledCode;
   4 import jdk.vm.ci.code.InvalidInstalledCodeException;
   5 import jdk.vm.ci.hotspot.CompilerToVMHelper;
   6 import jdk.test.lib.Asserts;
   7 import jdk.test.lib.Utils;
   8 import jdk.test.lib.Pair;
   9 import sun.hotspot.code.NMethod;
  10 
  11 import java.lang.reflect.Constructor;
  12 import java.lang.reflect.Executable;
  13 import java.lang.reflect.InvocationTargetException;
  14 import java.lang.reflect.Method;
  15 import java.lang.reflect.Modifier;
  16 import java.util.ArrayList;
  17 import java.util.HashMap;
  18 import java.util.List;
  19 import java.util.Map;
  20 
  21 /*
  22  * @test
  23  * @bug 8136421
  24  * @requires (os.simpleArch == "x64" | os.simpleArch == "sparcv9" | os.simpleArch == "aarch64")
  25  * @library /testlibrary /test/lib /
  26  * @library ../common/patches
  27  * @ignore 8139383
  28  * @modules java.base/jdk.internal.misc
  29  * @modules java.base/jdk.internal.org.objectweb.asm
  30  *          java.base/jdk.internal.org.objectweb.asm.tree
  31  *          jdk.vm.ci/jdk.vm.ci.hotspot
  32  *          jdk.vm.ci/jdk.vm.ci.code
  33  * @build jdk.vm.ci/jdk.vm.ci.hotspot.CompilerToVMHelper
  34  * @build compiler.jvmci.compilerToVM.ExecuteInstalledCodeTest
  35  * @build sun.hotspot.WhiteBox
  36  * @run main ClassFileInstaller sun.hotspot.WhiteBox
  37  *                              sun.hotspot.WhiteBox$WhiteBoxPermission
  38  * @run main/othervm -Xbootclasspath/a:.
  39  *                   -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI
  40  *                   -XX:+UnlockExperimentalVMOptions -XX:+EnableJVMCI
  41  *                   compiler.jvmci.compilerToVM.ExecuteInstalledCodeTest
  42  */
  43 
  44 public class ExecuteInstalledCodeTest {
  45 
  46     public static void main(String[] args) {
  47         ExecuteInstalledCodeTest test = new ExecuteInstalledCodeTest();
  48         List<CompileCodeTestCase> testCases = new ArrayList<>();
  49         testCases.addAll(CompileCodeTestCase.generate(/* bci = */ -1));
  50         testCases .stream()
  51                 // ignore <init> of abstract class -- 8138793
  52                 .filter(e -> !(e.executable instanceof Constructor
  53                         && Modifier.isAbstract(
  54                                 e.executable.getDeclaringClass()
  55                                         .getModifiers())))
  56                 .forEach(test::checkSanity);
  57     }
  58 
  59     private void checkSanity(CompileCodeTestCase testCase) {
  60         System.out.println(testCase);
  61         // to have a clean state
  62         testCase.deoptimize();
  63         Pair<Object, ? extends Throwable> reflectionResult;
  64         Object[] args = Utils.getNullValues(
  65                 testCase.executable.getParameterTypes());
  66         reflectionResult = testCase.invoke(args);
  67         NMethod nMethod = testCase.compile();
  68         if (nMethod == null) {
  69             throw new Error(testCase + " : nmethod is null");
  70         }
  71         InstalledCode installedCode = testCase.toInstalledCode();
  72         Object result = null;
  73         Throwable expectedException = reflectionResult.second;
  74         boolean gotException = true;
  75         try {
  76             args = addReceiver(testCase, args);
  77             result = CompilerToVMHelper.executeInstalledCode(
  78                     args, installedCode);
  79             if (testCase.executable instanceof Constructor) {
  80                 // <init> doesn't have return value, it changes receiver
  81                 result = args[0];
  82             }
  83             gotException = false;
  84         } catch (InvalidInstalledCodeException e) {
  85             throw new AssertionError(
  86                     testCase + " : unexpected InvalidInstalledCodeException", e);
  87         } catch (Throwable t) {
  88             if (expectedException == null) {
  89                 throw new AssertionError(testCase
  90                         + " : got unexpected execption : " + t.getMessage(), t);
  91             }
  92 
  93             if (expectedException.getClass() != t.getClass()) {
  94                 System.err.println("exception from CompilerToVM:");
  95                 t.printStackTrace();
  96                 System.err.println("exception from reflection:");
  97                 expectedException.printStackTrace();
  98                 throw new AssertionError(String.format(
  99                         "%s : got unexpected different exceptions : %s != %s",
 100                         testCase, expectedException.getClass(), t.getClass()));
 101             }
 102         }
 103 
 104         Asserts.assertEQ(reflectionResult.first, result, testCase
 105                 + " : different return value");
 106         if (!gotException) {
 107             Asserts.assertNull(expectedException, testCase
 108                     + " : expected exception hasn't been thrown");
 109         }
 110     }
 111 
 112     private Object[] addReceiver(CompileCodeTestCase testCase, Object[] args) {
 113         if (!Modifier.isStatic(testCase.executable.getModifiers())) {
 114             // add instance as 0th arg
 115             Object[] newArgs = new Object[args.length + 1];
 116             newArgs[0] = testCase.receiver;
 117             System.arraycopy(args, 0, newArgs, 1, args.length);
 118             args = newArgs;
 119         }
 120         return args;
 121     }
 122 }