e7795851d2
Reviewed-by: lmesnik, dholmes
286 lines
10 KiB
Java
286 lines
10 KiB
Java
/*
|
|
* Copyright (c) 2015, 2022, 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.whitebox;
|
|
|
|
import jdk.test.whitebox.WhiteBox;
|
|
|
|
import java.lang.reflect.Constructor;
|
|
import java.lang.reflect.Executable;
|
|
import java.lang.reflect.Method;
|
|
import java.util.concurrent.Callable;
|
|
|
|
public enum SimpleTestCase implements CompilerWhiteBoxTest.TestCase {
|
|
/** constructor test case */
|
|
CONSTRUCTOR_TEST(SimpleTestCaseHelper.CONSTRUCTOR, SimpleTestCaseHelper.CONSTRUCTOR_CALLABLE, false),
|
|
/** method test case */
|
|
METHOD_TEST(SimpleTestCaseHelper.METHOD, SimpleTestCaseHelper.METHOD_CALLABLE, false),
|
|
/** static method test case */
|
|
STATIC_TEST(SimpleTestCaseHelper.STATIC, SimpleTestCaseHelper.STATIC_CALLABLE, false),
|
|
/** OSR constructor test case */
|
|
OSR_CONSTRUCTOR_TEST(SimpleTestCaseHelper.OSR_CONSTRUCTOR, SimpleTestCaseHelper.OSR_CONSTRUCTOR_CALLABLE, true),
|
|
/** OSR method test case */
|
|
OSR_METHOD_TEST(SimpleTestCaseHelper.OSR_METHOD, SimpleTestCaseHelper.OSR_METHOD_CALLABLE, true),
|
|
/** OSR static method test case */
|
|
OSR_STATIC_TEST(SimpleTestCaseHelper.OSR_STATIC, SimpleTestCaseHelper.OSR_STATIC_CALLABLE, true);
|
|
|
|
private final Executable executable;
|
|
private final Callable<Integer> callable;
|
|
private final boolean isOsr;
|
|
|
|
private SimpleTestCase(Executable executable, Callable<Integer> callable,
|
|
boolean isOsr) {
|
|
this.executable = executable;
|
|
this.callable = callable;
|
|
this.isOsr = isOsr;
|
|
}
|
|
|
|
@Override
|
|
public Executable getExecutable() {
|
|
return executable;
|
|
}
|
|
|
|
@Override
|
|
public Callable<Integer> getCallable() {
|
|
return callable;
|
|
}
|
|
|
|
@Override
|
|
public boolean isOsr() {
|
|
return isOsr;
|
|
}
|
|
}
|
|
|
|
class SimpleTestCaseHelper {
|
|
|
|
public static final Callable<Integer> CONSTRUCTOR_CALLABLE
|
|
= new Callable<Integer>() {
|
|
@Override
|
|
public Integer call() throws Exception {
|
|
return new SimpleTestCaseHelper(1337).hashCode();
|
|
}
|
|
};
|
|
|
|
public static final Callable<Integer> METHOD_CALLABLE
|
|
= new Callable<Integer>() {
|
|
private final SimpleTestCaseHelper helper = new SimpleTestCaseHelper();
|
|
|
|
@Override
|
|
public Integer call() throws Exception {
|
|
return helper.method();
|
|
}
|
|
};
|
|
|
|
public static final Callable<Integer> STATIC_CALLABLE
|
|
= new Callable<Integer>() {
|
|
@Override
|
|
public Integer call() throws Exception {
|
|
return staticMethod();
|
|
}
|
|
};
|
|
|
|
public static final Callable<Integer> OSR_CONSTRUCTOR_CALLABLE
|
|
= new Callable<Integer>() {
|
|
@Override
|
|
public Integer call() throws Exception {
|
|
return new SimpleTestCaseHelper(null, CompilerWhiteBoxTest.BACKEDGE_THRESHOLD).hashCode();
|
|
}
|
|
};
|
|
|
|
public static final Callable<Integer> OSR_METHOD_CALLABLE
|
|
= new Callable<Integer>() {
|
|
private final SimpleTestCaseHelper helper = new SimpleTestCaseHelper();
|
|
|
|
@Override
|
|
public Integer call() throws Exception {
|
|
return helper.osrMethod(CompilerWhiteBoxTest.BACKEDGE_THRESHOLD);
|
|
}
|
|
};
|
|
|
|
public static final Callable<Integer> OSR_STATIC_CALLABLE
|
|
= new Callable<Integer>() {
|
|
@Override
|
|
public Integer call() throws Exception {
|
|
return osrStaticMethod(CompilerWhiteBoxTest.BACKEDGE_THRESHOLD);
|
|
}
|
|
};
|
|
|
|
public static final Constructor CONSTRUCTOR;
|
|
public static final Constructor OSR_CONSTRUCTOR;
|
|
public static final Method METHOD;
|
|
public static final Method STATIC;
|
|
public static final Method OSR_METHOD;
|
|
public static final Method OSR_STATIC;
|
|
|
|
static {
|
|
try {
|
|
CONSTRUCTOR = SimpleTestCaseHelper.class.getDeclaredConstructor(int.class);
|
|
} catch (NoSuchMethodException | SecurityException e) {
|
|
throw new RuntimeException(
|
|
"exception on getting method Helper.<init>(int)", e);
|
|
}
|
|
try {
|
|
OSR_CONSTRUCTOR = SimpleTestCaseHelper.class.getDeclaredConstructor(
|
|
Object.class, long.class);
|
|
} catch (NoSuchMethodException | SecurityException e) {
|
|
throw new RuntimeException(
|
|
"exception on getting method Helper.<init>(Object, long)", e);
|
|
}
|
|
METHOD = getMethod("method");
|
|
STATIC = getMethod("staticMethod");
|
|
OSR_METHOD = getMethod("osrMethod", long.class);
|
|
OSR_STATIC = getMethod("osrStaticMethod", long.class);
|
|
}
|
|
|
|
private static Method getMethod(String name, Class<?>... parameterTypes) {
|
|
try {
|
|
return SimpleTestCaseHelper.class.getDeclaredMethod(name, parameterTypes);
|
|
} catch (NoSuchMethodException | SecurityException e) {
|
|
throw new RuntimeException(
|
|
"exception on getting method Helper." + name, e);
|
|
}
|
|
}
|
|
|
|
private static int staticMethod() {
|
|
return 1138;
|
|
}
|
|
|
|
private int method() {
|
|
return 42;
|
|
}
|
|
|
|
/**
|
|
* Deoptimizes all non-osr versions of the given executable after
|
|
* compilation finished.
|
|
*
|
|
* @param e Executable
|
|
* @throws Exception
|
|
*/
|
|
private static void waitAndDeoptimize(Executable e) {
|
|
CompilerWhiteBoxTest.waitBackgroundCompilation(e);
|
|
if (WhiteBox.getWhiteBox().isMethodQueuedForCompilation(e)) {
|
|
throw new RuntimeException(e + " must not be in queue");
|
|
}
|
|
// Deoptimize non-osr versions of executable
|
|
WhiteBox.getWhiteBox().deoptimizeMethod(e, false);
|
|
}
|
|
|
|
/**
|
|
* Executes the method multiple times to make sure we have
|
|
* enough profiling information before triggering an OSR
|
|
* compilation. Otherwise the C2 compiler may add uncommon traps.
|
|
*
|
|
* @param m Method to be executed
|
|
* @return Number of times the method was executed
|
|
* @throws Exception
|
|
*/
|
|
private static int warmup(Method m) throws Exception {
|
|
waitAndDeoptimize(m);
|
|
SimpleTestCaseHelper helper = new SimpleTestCaseHelper();
|
|
int result = 0;
|
|
for (long i = 0; i < CompilerWhiteBoxTest.THRESHOLD; ++i) {
|
|
result += (int)m.invoke(helper, 1);
|
|
}
|
|
// Wait to make sure OSR compilation is not blocked by
|
|
// non-OSR compilation in the compile queue
|
|
CompilerWhiteBoxTest.waitBackgroundCompilation(m);
|
|
return result;
|
|
}
|
|
|
|
/**
|
|
* Executes the constructor multiple times to make sure we
|
|
* have enough profiling information before triggering an OSR
|
|
* compilation. Otherwise the C2 compiler may add uncommon traps.
|
|
*
|
|
* @param c Constructor to be executed
|
|
* @return Number of times the constructor was executed
|
|
* @throws Exception
|
|
*/
|
|
private static int warmup(Constructor c) throws Exception {
|
|
waitAndDeoptimize(c);
|
|
int result = 0;
|
|
for (long i = 0; i < CompilerWhiteBoxTest.THRESHOLD; ++i) {
|
|
result += c.newInstance(null, 1).hashCode();
|
|
}
|
|
// Wait to make sure OSR compilation is not blocked by
|
|
// non-OSR compilation in the compile queue
|
|
CompilerWhiteBoxTest.waitBackgroundCompilation(c);
|
|
return result;
|
|
}
|
|
|
|
private static int osrStaticMethod(long limit) throws Exception {
|
|
int result = 0;
|
|
if (limit != 1) {
|
|
result = warmup(OSR_STATIC);
|
|
}
|
|
// Trigger osr compilation
|
|
for (long i = 0; i < limit; ++i) {
|
|
result += staticMethod();
|
|
}
|
|
return result;
|
|
}
|
|
|
|
private int osrMethod(long limit) throws Exception {
|
|
int result = 0;
|
|
if (limit != 1) {
|
|
result = warmup(OSR_METHOD);
|
|
}
|
|
// Trigger osr compilation
|
|
for (long i = 0; i < limit; ++i) {
|
|
result += method();
|
|
}
|
|
return result;
|
|
}
|
|
|
|
private final int x;
|
|
|
|
// for method and OSR method test case
|
|
public SimpleTestCaseHelper() {
|
|
x = 0;
|
|
}
|
|
|
|
// for OSR constructor test case
|
|
private SimpleTestCaseHelper(Object o, long limit) throws Exception {
|
|
int result = 0;
|
|
if (limit != 1) {
|
|
result = warmup(OSR_CONSTRUCTOR);
|
|
}
|
|
// Trigger osr compilation
|
|
for (long i = 0; i < limit; ++i) {
|
|
result += method();
|
|
}
|
|
x = result;
|
|
}
|
|
|
|
// for constructor test case
|
|
private SimpleTestCaseHelper(int x) {
|
|
this.x = x;
|
|
}
|
|
|
|
@Override
|
|
public int hashCode() {
|
|
return x;
|
|
}
|
|
}
|
|
|