Path: blob/master/test/hotspot/jtreg/compiler/jvmci/compilerToVM/CompileCodeTestCase.java
41153 views
/*1* Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.2* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.3*4* This code is free software; you can redistribute it and/or modify it5* under the terms of the GNU General Public License version 2 only, as6* published by the Free Software Foundation.7*8* This code is distributed in the hope that it will be useful, but WITHOUT9* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or10* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License11* version 2 for more details (a copy is included in the LICENSE file that12* accompanied this code).13*14* You should have received a copy of the GNU General Public License version15* 2 along with this work; if not, write to the Free Software Foundation,16* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.17*18* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA19* or visit www.oracle.com if you need additional information or have any20* questions.21*/2223package compiler.jvmci.compilerToVM;2425import compiler.jvmci.common.CTVMUtilities;26import compiler.testlibrary.CompilerUtils;27import jdk.test.lib.util.Pair;28import jdk.test.lib.Utils;29import jdk.vm.ci.code.InstalledCode;30import jdk.vm.ci.meta.MetaAccessProvider;31import jdk.vm.ci.meta.ResolvedJavaMethod;32import jdk.vm.ci.runtime.JVMCI;33import sun.hotspot.WhiteBox;34import sun.hotspot.code.NMethod;3536import java.lang.reflect.Constructor;37import java.lang.reflect.Executable;38import java.lang.reflect.InvocationTargetException;39import java.lang.reflect.Method;40import java.lang.reflect.Modifier;41import java.util.ArrayList;42import java.util.Arrays;43import java.util.Collections;44import java.util.HashMap;45import java.util.List;46import java.util.Map;4748/**49* A test case for tests which require compiled code.50*/51public class CompileCodeTestCase {52private static final WhiteBox WB = WhiteBox.getWhiteBox();53private static final int COMP_LEVEL;54static {55int[] levels = CompilerUtils.getAvailableCompilationLevels();56if (levels.length == 0) {57throw new Error("TESTBUG: no compilers available");58}59COMP_LEVEL = levels[levels.length - 1];60}61private static final Class<?>[] CLASSES = {62Interface.class,63Dummy.class,64DummyEx.class};65private static final Map<Class<?>, Object> RECEIVERS;6667public final Object receiver;68public final Executable executable;69public final int bci;70private final boolean isOsr;7172public CompileCodeTestCase(Object receiver, Executable executable,73int bci) {74this.receiver = receiver;75this.executable = executable;76this.bci = bci;77isOsr = (bci >= 0);78}7980public NMethod compile() {81return compile(COMP_LEVEL);82}8384public Pair<Object, ? extends Throwable> invoke(Object[] args) {85boolean old = executable.isAccessible();86executable.setAccessible(true);87try {88try {89if (executable instanceof Method) {90Method m = (Method) executable;91return new Pair<>(m.invoke(receiver, args), null);92}9394if (executable instanceof Constructor) {95Constructor c = (Constructor) executable;96return new Pair<>(c.newInstance(args), null);97}98} catch (InvocationTargetException e) {99return new Pair<>(null, e.getCause());100} catch (Throwable e) {101return new Pair<>(null, e);102}103} finally {104executable.setAccessible(old);105}106throw new Error(executable + " has unsupported type "107+ executable.getClass());108}109110public NMethod compile(int level) {111String directive = "[{ match: \"" + executable.getDeclaringClass().getName().replace('.', '/')112+ "." + (executable instanceof Constructor ? "<init>" : executable.getName())113+ "\", " + "BackgroundCompilation: false }]";114if (WB.addCompilerDirective(directive) != 1) {115throw new Error("Failed to add compiler directive: " + directive);116}117boolean enqueued = WB.enqueueMethodForCompilation(executable,118level, bci);119if (!enqueued) {120throw new Error(String.format(121"%s can't be enqueued for %scompilation on level %d",122executable, bci >= 0 ? "osr-" : "", level));123}124Utils.waitForCondition(() -> WB.isMethodCompiled(executable, isOsr));125return NMethod.get(executable, isOsr);126}127128public static List<CompileCodeTestCase> generate(int bci) {129ArrayList<CompileCodeTestCase> result = new ArrayList<>();130for (Class<?> aClass : CLASSES) {131Object receiver = RECEIVERS.get(aClass);132if (receiver == null) {133throw new Error("TESTBUG : no receiver for class " + aClass);134}135for (Executable m : aClass.getDeclaredConstructors()) {136result.add(new CompileCodeTestCase(receiver, m, bci));137}138Arrays.stream(aClass.getDeclaredMethods())139.filter(m -> !Modifier.isAbstract(m.getModifiers()))140.filter(m -> !Modifier.isNative(m.getModifiers()))141.map(m -> new CompileCodeTestCase(receiver, m, bci))142.forEach(result::add);143}144return result;145}146147public NMethod toNMethod() {148return NMethod.get(executable, isOsr);149}150151public InstalledCode toInstalledCode() {152MetaAccessProvider metaAccess = JVMCI.getRuntime().getHostJVMCIBackend().getMetaAccess();153ResolvedJavaMethod resolvedJavaMethod = metaAccess.lookupJavaMethod(executable);154NMethod nmethod = toNMethod();155long address = nmethod == null ? 0L : nmethod.address;156long entryPoint = nmethod == null ? 0L : nmethod.entry_point;157return CTVMUtilities.getInstalledCode(resolvedJavaMethod, executable.getName(), address, entryPoint);158}159160@Override161public String toString() {162return "CompileCodeTestCase{" +163"executable=" + executable +164", bci=" + bci +165'}';166}167168public void deoptimize() {169WB.deoptimizeMethod(executable, isOsr);170}171172public NMethod deoptimizeAndCompile() {173deoptimize();174return compile();175}176177// classes which are used as "input" data in test cases178private static interface Interface {179Interface interfaceMethod();180default Long defaultOverriddenMethod(Interface[] array) {181return array == null ? 0L : array.length;182}183default int defaultMethod(Object o) {184return o != null ? o.hashCode() : 0;185}186}187188private static abstract class Dummy implements Interface {189protected Dummy() {190}191192private static void staticMethod() {193}194195Dummy instanceMethod(int i) {196return null;197}198199abstract Object abstractMethod(double d);200201@Override202public Long defaultOverriddenMethod(Interface[] array) {203return 0L;204}205}206207public static class DummyEx extends Dummy {208@Override209public boolean equals(Object o) {210if (this == o) {211return true;212}213if (o == null || getClass() != o.getClass()) {214return false;215}216return true;217}218219@Override220public int hashCode() {221return 0;222}223224public DummyEx() {225}226227protected Dummy instanceMethod(int i) {228if (i == 0) {229return this;230}231return null;232}233234@Override235Object abstractMethod(double d) {236return this;237}238239@Override240public Interface interfaceMethod() {241return null;242}243}244245static {246Map<Class<?>, Object> map = new HashMap<>();;247map.put(CompileCodeTestCase.DummyEx.class,248new CompileCodeTestCase.DummyEx());249map.put(CompileCodeTestCase.Dummy.class,250new CompileCodeTestCase.Dummy() {251@Override252public CompileCodeTestCase.Interface interfaceMethod() {253throw new AbstractMethodError();254}255256@Override257Object abstractMethod(double d) {258throw new AbstractMethodError();259}260});261map.put(CompileCodeTestCase.Interface.class,262new CompileCodeTestCase.Interface() {263@Override264public CompileCodeTestCase.Interface interfaceMethod() {265throw new AbstractMethodError();266}267});268RECEIVERS = Collections.unmodifiableMap(map);269}270271}272273274