You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
443 lines
16 KiB
443 lines
16 KiB
1 year ago
|
/*
|
||
|
* Copyright (c) 2014, 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.
|
||
|
*
|
||
|
*/
|
||
|
|
||
|
import java.util.*;
|
||
|
import java.io.IOException;
|
||
|
import java.nio.file.Files;
|
||
|
import java.nio.file.Paths;
|
||
|
import java.nio.charset.StandardCharsets;
|
||
|
|
||
|
import com.oracle.java.testlibrary.*;
|
||
|
|
||
|
/**
|
||
|
* Test runner that invokes all methods implemented by particular Expr
|
||
|
* with random arguments in two different JVM processes and compares output.
|
||
|
* JVMs being started in different modes - one in int and other in comp
|
||
|
* with C2 and disabled tiered compilation.
|
||
|
*/
|
||
|
public class BMITestRunner {
|
||
|
|
||
|
enum VMMode {
|
||
|
COMP, INT;
|
||
|
};
|
||
|
|
||
|
public static int DEFAULT_ITERATIONS_COUNT = 4000;
|
||
|
|
||
|
/**
|
||
|
* Execute all methods implemented by <b>expr</b> in int and comp modes
|
||
|
* and compare output.
|
||
|
* Test pass only of output obtained with different VM modes is equal.
|
||
|
* To control behaviour of test following options could be passed:
|
||
|
* <ul>
|
||
|
* <li>-iterations=<N> each operation implemented by
|
||
|
* <b>expr</b> will be executed <i>N</i> times. Default value
|
||
|
* is 4000.</li>
|
||
|
* <li>-seed=<SEED> arguments for <b>expr</b>'s methods
|
||
|
* obtained via RNG initiated with seed <i>SEED</i>. By default
|
||
|
* some random seed will be used.</li>
|
||
|
* </ul>
|
||
|
*
|
||
|
* @param expr operation that should be tested
|
||
|
* @param testOpts options to control test behaviour
|
||
|
* @param additionalVMOpts additional options for VM
|
||
|
*
|
||
|
* @throws Throwable if test failed.
|
||
|
*/
|
||
|
public static void runTests(Class<? extends Expr> expr,
|
||
|
String testOpts[],
|
||
|
String... additionalVMOpts)
|
||
|
throws Throwable {
|
||
|
|
||
|
int seed = new Random().nextInt();
|
||
|
int iterations = DEFAULT_ITERATIONS_COUNT;
|
||
|
|
||
|
for (String testOption : testOpts) {
|
||
|
if (testOption.startsWith("-iterations=")) {
|
||
|
iterations = Integer.valueOf(testOption.
|
||
|
replace("-iterations=", ""));
|
||
|
} else if (testOption.startsWith("-seed=")) {
|
||
|
seed = Integer.valueOf(testOption.replace("-seed=", ""));
|
||
|
}
|
||
|
}
|
||
|
|
||
|
System.out.println("Running test with seed: " + seed);
|
||
|
|
||
|
OutputAnalyzer intOutput = runTest(expr, VMMode.INT,
|
||
|
additionalVMOpts,
|
||
|
seed, iterations);
|
||
|
OutputAnalyzer compOutput = runTest(expr, VMMode.COMP,
|
||
|
additionalVMOpts,
|
||
|
seed, iterations);
|
||
|
|
||
|
dumpOutput(intOutput, "int");
|
||
|
dumpOutput(compOutput, "comp");
|
||
|
|
||
|
Asserts.assertStringsEqual(intOutput.getStdout(),
|
||
|
compOutput.getStdout(),
|
||
|
"Results obtained in -Xint and " +
|
||
|
"-Xcomp should be the same.");
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Execute tests on methods implemented by <b>expr</b> in new VM
|
||
|
* started in <b>testVMMode</b> mode.
|
||
|
*
|
||
|
* @param expr operation that should be tested
|
||
|
* @param testVMMode VM mode for test
|
||
|
* @param additionalVMOpts additional options for VM
|
||
|
* @param seed for RNG used it tests
|
||
|
* @param iterations that will be used to invoke <b>expr</b>'s methods.
|
||
|
*
|
||
|
* @return OutputAnalyzer for executed test.
|
||
|
* @throws Throwable when something goes wrong.
|
||
|
*/
|
||
|
public static OutputAnalyzer runTest(Class<? extends Expr> expr,
|
||
|
VMMode testVMMode,
|
||
|
String additionalVMOpts[],
|
||
|
int seed, int iterations)
|
||
|
throws Throwable {
|
||
|
|
||
|
List<String> vmOpts = new LinkedList<String>();
|
||
|
|
||
|
Collections.addAll(vmOpts, additionalVMOpts);
|
||
|
|
||
|
//setup mode-specific options
|
||
|
switch (testVMMode) {
|
||
|
case INT:
|
||
|
Collections.addAll(vmOpts, new String[] { "-Xint" });
|
||
|
break;
|
||
|
case COMP:
|
||
|
Collections.addAll(vmOpts, new String[] {
|
||
|
"-Xcomp",
|
||
|
"-XX:-TieredCompilation",
|
||
|
String.format("-XX:CompileCommand=compileonly,%s::*",
|
||
|
expr.getName())
|
||
|
});
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
Collections.addAll(vmOpts, new String[] {
|
||
|
"-XX:+DisplayVMOutputToStderr",
|
||
|
Executor.class.getName(),
|
||
|
expr.getName(),
|
||
|
new Integer(seed).toString(),
|
||
|
new Integer(iterations).toString()
|
||
|
});
|
||
|
|
||
|
OutputAnalyzer outputAnalyzer = ProcessTools.
|
||
|
executeTestJvm(vmOpts.toArray(new String[vmOpts.size()]));
|
||
|
|
||
|
outputAnalyzer.shouldHaveExitValue(0);
|
||
|
|
||
|
return outputAnalyzer;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Dump stdout and stderr of test process to <i>prefix</i>.test.out
|
||
|
* and <i>prefix</i>.test.err respectively.
|
||
|
*
|
||
|
* @param outputAnalyzer OutputAnalyzer whom output should be dumped
|
||
|
* @param prefix Prefix that will be used in file names.
|
||
|
* @throws IOException if unable to dump output to file.
|
||
|
*/
|
||
|
protected static void dumpOutput(OutputAnalyzer outputAnalyzer,
|
||
|
String prefix)
|
||
|
throws IOException {
|
||
|
Files.write(Paths.get(prefix + ".test.out"),
|
||
|
outputAnalyzer.getStdout().getBytes());
|
||
|
|
||
|
Files.write(Paths.get(prefix + ".test.err"),
|
||
|
outputAnalyzer.getStderr().getBytes());
|
||
|
}
|
||
|
|
||
|
|
||
|
/**
|
||
|
* Executor that invoke all methods implemented by particular
|
||
|
* Expr instance.
|
||
|
*/
|
||
|
public static class Executor {
|
||
|
|
||
|
/**
|
||
|
* Usage: BMITestRunner$Executor <ExprClassName> <seed> <iterations>
|
||
|
*/
|
||
|
public static void main(String args[]) throws Exception {
|
||
|
@SuppressWarnings("unchecked")
|
||
|
Class<? extends Expr> exprClass =
|
||
|
(Class<? extends Expr>)Class.forName(args[0]);
|
||
|
Expr expr = exprClass.getConstructor().newInstance();
|
||
|
Random rng = new Random(Integer.valueOf(args[1]));
|
||
|
int iterations = Integer.valueOf(args[2]);
|
||
|
runTests(expr, iterations, rng);
|
||
|
}
|
||
|
|
||
|
|
||
|
public static int[] getIntBitShifts() {
|
||
|
//SIZE+1 shift is for zero.
|
||
|
int data[] = new int[Integer.SIZE+1];
|
||
|
for (int s = 0; s < data.length; s++) {
|
||
|
data[s] = 1<<s;
|
||
|
}
|
||
|
return data;
|
||
|
}
|
||
|
|
||
|
public static long[] getLongBitShifts() {
|
||
|
//SIZE+1 shift is for zero.
|
||
|
long data[] = new long[Long.SIZE+1];
|
||
|
for (int s = 0; s < data.length; s++) {
|
||
|
data[s] = 1L<<s;
|
||
|
}
|
||
|
return data;
|
||
|
}
|
||
|
|
||
|
public static void log(String format, Object... args) {
|
||
|
System.out.println(String.format(format, args));
|
||
|
}
|
||
|
|
||
|
public static void runTests(Expr expr, int iterations, Random rng) {
|
||
|
runUnaryIntRegTest(expr, iterations, rng);
|
||
|
runUnaryIntMemTest(expr, iterations, rng);
|
||
|
runUnaryLongRegTest(expr, iterations, rng);
|
||
|
runUnaryLongMemTest(expr, iterations, rng);
|
||
|
runBinaryRegRegIntTest(expr, iterations, rng);
|
||
|
runBinaryRegMemIntTest(expr, iterations, rng);
|
||
|
runBinaryMemRegIntTest(expr, iterations, rng);
|
||
|
runBinaryMemMemIntTest(expr, iterations, rng);
|
||
|
runBinaryRegRegLongTest(expr, iterations, rng);
|
||
|
runBinaryRegMemLongTest(expr, iterations, rng);
|
||
|
runBinaryMemRegLongTest(expr, iterations, rng);
|
||
|
runBinaryMemMemLongTest(expr, iterations, rng);
|
||
|
}
|
||
|
|
||
|
public static void runUnaryIntRegTest(Expr expr, int iterations,
|
||
|
Random rng) {
|
||
|
if (!(expr.isUnaryArgumentSupported()
|
||
|
&& expr.isIntExprSupported())) {
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
for (int value : getIntBitShifts()) {
|
||
|
log("UnaryIntReg(0X%x) -> 0X%x",
|
||
|
value, expr.intExpr(value));
|
||
|
}
|
||
|
|
||
|
for (int i = 0; i < iterations; i++) {
|
||
|
int value = rng.nextInt();
|
||
|
log("UnaryIntReg(0X%x) -> 0X%x",
|
||
|
value, expr.intExpr(value));
|
||
|
}
|
||
|
}
|
||
|
|
||
|
public static void runUnaryIntMemTest(Expr expr, int iterations,
|
||
|
Random rng) {
|
||
|
if (!(expr.isUnaryArgumentSupported()
|
||
|
&& expr.isIntExprSupported()
|
||
|
&& expr.isMemExprSupported())) {
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
for (int value : getIntBitShifts()) {
|
||
|
log("UnaryIntMem(0X%x) -> 0X%x",
|
||
|
value, expr.intExpr(new Expr.MemI(value)));
|
||
|
}
|
||
|
|
||
|
for (int i = 0; i < iterations; i++) {
|
||
|
int value = rng.nextInt();
|
||
|
log("UnaryIntMem(0X%x) -> 0X%x",
|
||
|
value, expr.intExpr(new Expr.MemI(value)));
|
||
|
}
|
||
|
}
|
||
|
|
||
|
public static void runUnaryLongRegTest(Expr expr, int iterations,
|
||
|
Random rng) {
|
||
|
if (!(expr.isUnaryArgumentSupported()
|
||
|
&& expr.isLongExprSupported())) {
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
for (long value : getLongBitShifts()) {
|
||
|
log("UnaryLongReg(0X%x) -> 0X%x",
|
||
|
value, expr.longExpr(value));
|
||
|
}
|
||
|
|
||
|
for (int i = 0; i < iterations; i++) {
|
||
|
long value = rng.nextLong();
|
||
|
log("UnaryLongReg(0X%x) -> 0X%x",
|
||
|
value, expr.longExpr(value));
|
||
|
}
|
||
|
}
|
||
|
|
||
|
public static void runUnaryLongMemTest(Expr expr, int iterations,
|
||
|
Random rng) {
|
||
|
if (!(expr.isUnaryArgumentSupported()
|
||
|
&& expr.isLongExprSupported()
|
||
|
&& expr.isMemExprSupported())) {
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
for (long value : getLongBitShifts()) {
|
||
|
log("UnaryLongMem(0X%x) -> 0X%x",
|
||
|
value, expr.longExpr(new Expr.MemL(value)));
|
||
|
}
|
||
|
|
||
|
for (int i = 0; i < iterations; i++) {
|
||
|
long value = rng.nextLong();
|
||
|
log("UnaryLongMem(0X%x) -> 0X%x",
|
||
|
value, expr.longExpr(new Expr.MemL(value)));
|
||
|
}
|
||
|
}
|
||
|
|
||
|
public static void runBinaryRegRegIntTest(Expr expr, int iterations,
|
||
|
Random rng) {
|
||
|
if (!(expr.isIntExprSupported()
|
||
|
&& expr.isBinaryArgumentSupported())) {
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
for (int i = 0; i < iterations; i++) {
|
||
|
int aValue = rng.nextInt();
|
||
|
int bValue = rng.nextInt();
|
||
|
log("BinaryIntRegReg(0X%x, 0X%x) -> 0X%x",
|
||
|
aValue, bValue, expr.intExpr(aValue, bValue));
|
||
|
}
|
||
|
}
|
||
|
|
||
|
public static void runBinaryRegMemIntTest(Expr expr, int iterations,
|
||
|
Random rng) {
|
||
|
if (!(expr.isIntExprSupported()
|
||
|
&& expr.isBinaryArgumentSupported()
|
||
|
&& expr.isMemExprSupported())) {
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
for (int i = 0; i < iterations; i++) {
|
||
|
int aValue = rng.nextInt();
|
||
|
int bValue = rng.nextInt();
|
||
|
log("BinaryIntRegMem(0X%x, 0X%x) -> 0X%x", aValue, bValue,
|
||
|
expr.intExpr(aValue, new Expr.MemI(bValue)));
|
||
|
}
|
||
|
}
|
||
|
|
||
|
public static void runBinaryMemRegIntTest(Expr expr, int iterations,
|
||
|
Random rng) {
|
||
|
if (!(expr.isIntExprSupported()
|
||
|
&& expr.isBinaryArgumentSupported()
|
||
|
&& expr.isMemExprSupported())) {
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
for (int i = 0; i < iterations; i++) {
|
||
|
int aValue = rng.nextInt();
|
||
|
int bValue = rng.nextInt();
|
||
|
log("BinaryIntMemReg(0X%x, 0X%x) -> 0X%x", aValue, bValue,
|
||
|
expr.intExpr(new Expr.MemI(aValue), bValue));
|
||
|
}
|
||
|
}
|
||
|
|
||
|
public static void runBinaryMemMemIntTest(Expr expr, int iterations,
|
||
|
Random rng) {
|
||
|
if (!(expr.isIntExprSupported()
|
||
|
&& expr.isBinaryArgumentSupported()
|
||
|
&& expr.isMemExprSupported())) {
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
for (int i = 0; i < iterations; i++) {
|
||
|
int aValue = rng.nextInt();
|
||
|
int bValue = rng.nextInt();
|
||
|
log("BinaryIntMemMem(0X%x, 0X%x) -> 0X%x", aValue, bValue,
|
||
|
expr.intExpr(new Expr.MemI(aValue),
|
||
|
new Expr.MemI(bValue)));
|
||
|
}
|
||
|
}
|
||
|
|
||
|
public static void runBinaryRegRegLongTest(Expr expr,
|
||
|
int iterations,
|
||
|
Random rng) {
|
||
|
if (!(expr.isLongExprSupported()
|
||
|
&& expr.isBinaryArgumentSupported())) {
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
for (int i = 0; i < iterations; i++) {
|
||
|
long aValue = rng.nextLong();
|
||
|
long bValue = rng.nextLong();
|
||
|
log("BinaryLongRegReg(0X%x, 0X%x) -> 0X%x", aValue, bValue,
|
||
|
expr.longExpr(aValue, bValue));
|
||
|
}
|
||
|
}
|
||
|
|
||
|
public static void runBinaryRegMemLongTest(Expr expr,
|
||
|
int iterations,
|
||
|
Random rng) {
|
||
|
if (!(expr.isLongExprSupported()
|
||
|
&& expr.isBinaryArgumentSupported()
|
||
|
&& expr.isMemExprSupported())) {
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
for (int i = 0; i < iterations; i++) {
|
||
|
long aValue = rng.nextLong();
|
||
|
long bValue = rng.nextLong();
|
||
|
log("BinaryLongRegMem(0X%x, 0X%x) -> 0X%x", aValue, bValue,
|
||
|
expr.longExpr(aValue, new Expr.MemL(bValue)));
|
||
|
}
|
||
|
}
|
||
|
|
||
|
public static void runBinaryMemRegLongTest(Expr expr,
|
||
|
int iterations,
|
||
|
Random rng) {
|
||
|
if (!(expr.isLongExprSupported()
|
||
|
&& expr.isBinaryArgumentSupported()
|
||
|
&& expr.isMemExprSupported())) {
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
for (int i = 0; i < iterations; i++) {
|
||
|
long aValue = rng.nextLong();
|
||
|
long bValue = rng.nextLong();
|
||
|
log("BinaryLongMemReg(0X%x, 0X%x) -> 0X%x", aValue, bValue,
|
||
|
expr.longExpr(new Expr.MemL(aValue), bValue));
|
||
|
}
|
||
|
}
|
||
|
|
||
|
public static void runBinaryMemMemLongTest(Expr expr,
|
||
|
int iterations,
|
||
|
Random rng) {
|
||
|
if (!(expr.isLongExprSupported()
|
||
|
&& expr.isBinaryArgumentSupported()
|
||
|
&& expr.isMemExprSupported())) {
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
for (int i = 0; i < iterations; i++) {
|
||
|
long aValue = rng.nextLong();
|
||
|
long bValue = rng.nextLong();
|
||
|
log("BinaryLongMemMem(0X%x, 0X%x) -> 0X%x", aValue, bValue,
|
||
|
expr.longExpr(new Expr.MemL(aValue),
|
||
|
new Expr.MemL(bValue)));
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|