--- /dev/null 2015-10-08 07:26:35.000000000 -1000 +++ new/test/compiler/jvmci/compilerToVM/CompileCodeTestCase.java 2015-10-08 07:26:35.000000000 -1000 @@ -0,0 +1,216 @@ +/* + * Copyright (c) 2015, 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 compiler.jvmci.compilerToVM; + +import compiler.testlibrary.CompilerUtils; +import jdk.test.lib.Utils; +import sun.hotspot.WhiteBox; +import sun.hotspot.code.NMethod; + +import java.lang.reflect.Executable; +import java.lang.reflect.Modifier; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +/** + * A test case for tests which require compiled code. + */ +public final class CompileCodeTestCase { + public static final Map, Object> RECEIVERS; + private static final WhiteBox WB = WhiteBox.getWhiteBox(); + private static final int COMP_LEVEL; + static { + int[] levels = CompilerUtils.getAvailableCompilationLevels(); + if (levels.length == 0) { + throw new Error("TESTBUG: no compilers available"); + } + COMP_LEVEL = levels[levels.length - 1]; + } + private static final Class[] CLASSES = { + Interface.class, + Dummy.class, + DummyEx.class}; + + public final Executable executable; + public final int bci; + private final boolean isOsr; + + public CompileCodeTestCase(Executable executable, int bci) { + this.executable = executable; + this.bci = bci; + isOsr = bci >= 0; + } + + public NMethod compile() { + return compile(COMP_LEVEL); + } + + public NMethod compile(int level) { + boolean enqueued = WB.enqueueMethodForCompilation(executable, + level, bci); + if (!enqueued) { + throw new Error(String.format( + "%s can't be enqueued for %scompilation on level %d", + executable, bci >= 0 ? "osr-" : "", level)); + } + Utils.waitForCondition(() -> WB.isMethodCompiled(executable, isOsr)); + return NMethod.get(executable, isOsr); + } + + public static List generate(int bci) { + ArrayList result = new ArrayList<>(); + for (Class aClass : CLASSES) { + for (Executable m : aClass.getDeclaredConstructors()) { + result.add(new CompileCodeTestCase(m, bci)); + } + Arrays.stream(aClass.getDeclaredMethods()) + .filter(m -> !Modifier.isAbstract(m.getModifiers())) + .filter(m -> !Modifier.isNative(m.getModifiers())) + .map(m -> new CompileCodeTestCase(m, bci)) + .forEach(result::add); + } + return result; + } + + public NMethod toNMethod() { + return NMethod.get(executable, isOsr); + } + + @Override + public String toString() { + return "CompileCodeTestCase{" + + "executable=" + executable + + ", bci=" + bci + + '}'; + } + + public void deoptimize() { + WB.deoptimizeMethod(executable, isOsr); + } + + public NMethod deoptimizeAndCompile() { + deoptimize(); + return compile(); + } + + // classes which are used as "input" data in test cases + private static interface Interface { + Interface interfaceMethod(); + default Long defaultOverriddenMethod(Interface[] array) { + return array == null ? 0L : array.length; + } + default int defaultMethod(Object o) { + return o != null ? o.hashCode() : 0; + } + } + + private static abstract class Dummy implements Interface { + protected Dummy() { + } + + private static void staticMethod() { + } + + Dummy instanceMethod(int i) { + return null; + } + + abstract Object abstractMethod(double d); + + @Override + public Long defaultOverriddenMethod(Interface[] array) { + return 0L; + } + } + + public static class DummyEx extends Dummy { + @Override + public boolean equals(Object o) { + if (this == o) { + return true; + } + if (o == null || getClass() != o.getClass()) { + return false; + } + return true; + } + + @Override + public int hashCode() { + return 0; + } + + public DummyEx() { + } + + protected Dummy instanceMethod(int i) { + if (i == 0) { + return this; + } + return null; + } + + @Override + Object abstractMethod(double d) { + return this; + } + + @Override + public Interface interfaceMethod() { + return null; + } + } + + static { + Map, Object> map = new HashMap<>();; + map.put(CompileCodeTestCase.DummyEx.class, + new CompileCodeTestCase.DummyEx()); + map.put(CompileCodeTestCase.Dummy.class, + new CompileCodeTestCase.Dummy() { + @Override + public CompileCodeTestCase.Interface interfaceMethod() { + throw new AbstractMethodError(); + } + + @Override + Object abstractMethod(double d) { + throw new AbstractMethodError(); + } + }); + map.put(CompileCodeTestCase.Interface.class, + new CompileCodeTestCase.Interface() { + @Override + public CompileCodeTestCase.Interface interfaceMethod() { + throw new AbstractMethodError(); + } + }); + RECEIVERS = Collections.unmodifiableMap(map); + } + +}