mirror of
https://github.com/openjdk/jdk.git
synced 2025-08-26 22:34:27 +02:00
8140240: Missing test files in CompilerControl tests
Add missing files Reviewed-by: kvn, neliasso
This commit is contained in:
parent
b7f5ea4aee
commit
3ee545ab1d
4 changed files with 485 additions and 1 deletions
371
hotspot/test/compiler/compilercontrol/share/scenario/State.java
Normal file
371
hotspot/test/compiler/compilercontrol/share/scenario/State.java
Normal file
|
@ -0,0 +1,371 @@
|
|||
/*
|
||||
* 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.compilercontrol.share.scenario;
|
||||
|
||||
import jdk.test.lib.Asserts;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Optional;
|
||||
|
||||
/**
|
||||
* Represents method compilation state
|
||||
*/
|
||||
public class State {
|
||||
// Each of the two-elements array contains a state for each compiler
|
||||
private Optional<Boolean>[] compile =
|
||||
(Optional<Boolean>[]) new Optional[Scenario.Compiler.values().length];
|
||||
private Optional<Boolean>[] forceInline =
|
||||
(Optional<Boolean>[]) new Optional[Scenario.Compiler.values().length];
|
||||
private Optional<Boolean>[] dontInline =
|
||||
(Optional<Boolean>[]) new Optional[Scenario.Compiler.values().length];
|
||||
private Optional<Boolean> printAssembly = Optional.empty();
|
||||
private Optional<Boolean> printInline = Optional.empty();
|
||||
private Optional<Boolean> log = Optional.empty();
|
||||
|
||||
public State() {
|
||||
Arrays.fill(compile, Optional.empty());
|
||||
Arrays.fill(forceInline, Optional.empty());
|
||||
Arrays.fill(dontInline, Optional.empty());
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates state from the string
|
||||
*
|
||||
* @param strings array of strings that represent the state
|
||||
* @return State instance
|
||||
* @see #toString()
|
||||
*/
|
||||
public static State fromString(String[] strings) {
|
||||
Asserts.assertNotNull(strings, "Non null array is required");
|
||||
Asserts.assertNE(strings.length, 0, "Non empty array is required");
|
||||
State st = new State();
|
||||
for (String string : strings) {
|
||||
int i = string.indexOf(' ');
|
||||
String command = string.substring(0, i);
|
||||
String values = string.substring(i + 1); // skip space symbol
|
||||
switch (command) {
|
||||
case "compile" :
|
||||
parseArray(st.compile, values);
|
||||
break;
|
||||
case "force_inline" :
|
||||
parseArray(st.forceInline, values);
|
||||
break;
|
||||
case "dont_inline" :
|
||||
parseArray(st.dontInline, values);
|
||||
break;
|
||||
case "log" :
|
||||
st.log = parseElement(values);
|
||||
break;
|
||||
case "print_assembly" :
|
||||
st.printAssembly = parseElement(values);
|
||||
break;
|
||||
case "print_inline" :
|
||||
st.printInline = parseElement(values);
|
||||
break;
|
||||
default:
|
||||
throw new Error("TESTBUG: ");
|
||||
}
|
||||
}
|
||||
return st;
|
||||
}
|
||||
|
||||
private static void parseArray(Optional<Boolean>[] array, String str) {
|
||||
Asserts.assertNotNull(str);
|
||||
int beginBrace = 0;
|
||||
int endBrace = str.length() - 1;
|
||||
if (str.charAt(beginBrace) != '[' || str.charAt(endBrace) != ']') {
|
||||
throw new Error("TESTBUG: not an array type: " + str);
|
||||
}
|
||||
// Get all elements divided with comma as an array
|
||||
String[] strValues = str.substring(beginBrace + 1, endBrace)
|
||||
.split(", ");
|
||||
Asserts.assertEQ(strValues.length, array.length, "Different amount of "
|
||||
+ "elements in the string");
|
||||
for (int i = 0; i < strValues.length; i++) {
|
||||
array[i] = parseElement(strValues[i]);
|
||||
}
|
||||
}
|
||||
|
||||
private static Optional<Boolean> parseElement(String str) {
|
||||
Asserts.assertNotNull(str);
|
||||
Asserts.assertTrue(str.startsWith(Optional.class.getSimpleName()),
|
||||
"String is not of type Optional: " + str);
|
||||
if ("Optional.empty".equals(str)) {
|
||||
return Optional.empty();
|
||||
}
|
||||
int begin = str.indexOf('[');
|
||||
Asserts.assertNE(begin, -1, "TEST BUG: Wrong Optional string");
|
||||
int end = str.indexOf(']');
|
||||
Asserts.assertEQ(end, str.length() - 1);
|
||||
boolean b = Boolean.parseBoolean(str.substring(begin + 1, end));
|
||||
return Optional.of(b);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets string representation of this state
|
||||
*/
|
||||
@Override
|
||||
public String toString() {
|
||||
return "compile " + Arrays.toString(compile)
|
||||
+ "\nforce_inline " + Arrays.toString(forceInline)
|
||||
+ "\ndont_inline " + Arrays.toString(dontInline)
|
||||
+ "\nlog " + log
|
||||
+ "\nprint_assembly " + printAssembly
|
||||
+ "\nprint_inline " + printInline;
|
||||
}
|
||||
|
||||
public boolean isC1Compilable() {
|
||||
return compile[Scenario.Compiler.C1.ordinal()].orElse(true);
|
||||
}
|
||||
|
||||
public boolean isC2Compilable() {
|
||||
return compile[Scenario.Compiler.C2.ordinal()].orElse(true);
|
||||
}
|
||||
|
||||
public boolean isCompilable() {
|
||||
return isC1Compilable() && isC2Compilable();
|
||||
}
|
||||
|
||||
public void setC1Compilable(boolean value) {
|
||||
setCompilable(Scenario.Compiler.C1.ordinal(), value);
|
||||
}
|
||||
|
||||
public void setC2Compilable(boolean value) {
|
||||
setCompilable(Scenario.Compiler.C2.ordinal(), value);
|
||||
}
|
||||
|
||||
public void setCompilable(Scenario.Compiler compiler, boolean value) {
|
||||
if (compiler == null) {
|
||||
setC1Compilable(value);
|
||||
setC2Compilable(value);
|
||||
return;
|
||||
}
|
||||
switch (compiler) {
|
||||
case C1:
|
||||
setC1Compilable(value);
|
||||
break;
|
||||
case C2:
|
||||
setC2Compilable(value);
|
||||
break;
|
||||
default:
|
||||
throw new Error("Unknown compiler");
|
||||
}
|
||||
}
|
||||
|
||||
private void setCompilable(int level, boolean value) {
|
||||
check(level);
|
||||
compile[level] = Optional.of(value);
|
||||
if (!value) {
|
||||
setDontInline(level);
|
||||
}
|
||||
}
|
||||
|
||||
public boolean isC1Inlinable() {
|
||||
return ! dontInline[Scenario.Compiler.C1.ordinal()].orElse(false);
|
||||
}
|
||||
|
||||
public boolean isC2Inlinable() {
|
||||
return ! dontInline[Scenario.Compiler.C2.ordinal()].orElse(false);
|
||||
}
|
||||
|
||||
public boolean isInlinable() {
|
||||
return isC1Inlinable() && isC2Inlinable();
|
||||
}
|
||||
|
||||
private void setDontInline(int level) {
|
||||
check(level);
|
||||
dontInline[level] = Optional.of(true);
|
||||
forceInline[level] = Optional.of(false);
|
||||
}
|
||||
|
||||
private void setForceInline(int level) {
|
||||
check(level);
|
||||
dontInline[level] = Optional.of(false);
|
||||
forceInline[level] = Optional.of(true);
|
||||
}
|
||||
|
||||
public boolean isC1ForceInline() {
|
||||
return forceInline[Scenario.Compiler.C1.ordinal()].orElse(false);
|
||||
}
|
||||
|
||||
public boolean isC2ForceInline() {
|
||||
return forceInline[Scenario.Compiler.C2.ordinal()].orElse(false);
|
||||
}
|
||||
|
||||
public boolean isForceInline() {
|
||||
return isC1ForceInline() && isC2ForceInline();
|
||||
}
|
||||
|
||||
public void setC1Inline(boolean value) {
|
||||
if (value && isC1Compilable()) {
|
||||
setForceInline(Scenario.Compiler.C1.ordinal());
|
||||
} else {
|
||||
setDontInline(Scenario.Compiler.C1.ordinal());
|
||||
}
|
||||
}
|
||||
|
||||
public void setC2Inline(boolean value) {
|
||||
if (value && isC2Compilable()) {
|
||||
setForceInline(Scenario.Compiler.C2.ordinal());
|
||||
} else {
|
||||
setDontInline(Scenario.Compiler.C1.ordinal());
|
||||
}
|
||||
}
|
||||
|
||||
public void setInline(Scenario.Compiler compiler, boolean value) {
|
||||
if (compiler == null) {
|
||||
setC1Inline(value);
|
||||
setC2Inline(value);
|
||||
return;
|
||||
}
|
||||
switch (compiler) {
|
||||
case C1:
|
||||
setC1Inline(value);
|
||||
break;
|
||||
case C2:
|
||||
setC2Inline(value);
|
||||
break;
|
||||
default:
|
||||
throw new Error("Unknown compiler");
|
||||
}
|
||||
}
|
||||
|
||||
public boolean isPrintAssembly() {
|
||||
return printAssembly.orElse(false);
|
||||
}
|
||||
|
||||
public void setPrintAssembly(boolean value) {
|
||||
printAssembly = Optional.of(value);
|
||||
}
|
||||
|
||||
public boolean isPrintInline() {
|
||||
return printInline.orElse(false);
|
||||
}
|
||||
|
||||
public void setPrintInline(boolean value) {
|
||||
printInline = Optional.of(value);
|
||||
}
|
||||
|
||||
public boolean isLog() {
|
||||
return log.orElse(false);
|
||||
}
|
||||
|
||||
public void setLog(boolean log) {
|
||||
this.log = Optional.of(log);
|
||||
}
|
||||
|
||||
private void check(int level) {
|
||||
if (level < 0 || level > compile.length) {
|
||||
throw new IllegalArgumentException("TESTBUG: Wrong level " + level);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Applies given command to the state.
|
||||
*
|
||||
* @param compileCommand command to be applied
|
||||
*/
|
||||
public void apply(CompileCommand compileCommand) {
|
||||
switch (compileCommand.command) {
|
||||
case COMPILEONLY:
|
||||
setCompilable(compileCommand.compiler, true);
|
||||
break;
|
||||
case EXCLUDE:
|
||||
setCompilable(compileCommand.compiler, false);
|
||||
break;
|
||||
case INLINE:
|
||||
setInline(compileCommand.compiler, true);
|
||||
break;
|
||||
case DONTINLINE:
|
||||
setInline(compileCommand.compiler, false);
|
||||
break;
|
||||
case LOG:
|
||||
setLog(true);
|
||||
break;
|
||||
case PRINT:
|
||||
setPrintAssembly(true);
|
||||
break;
|
||||
case QUIET:
|
||||
case NONEXISTENT:
|
||||
// doesn't apply the state
|
||||
break;
|
||||
default:
|
||||
throw new Error("Wrong command: " + compileCommand.command);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Merges two given states with different priority
|
||||
*
|
||||
* @param low state with lower merge priority
|
||||
* @param high state with higher merge priority
|
||||
*/
|
||||
public static State merge(State low, State high) {
|
||||
if (high == null) {
|
||||
if (low == null) {
|
||||
return new State();
|
||||
}
|
||||
return low;
|
||||
}
|
||||
if (low == null) {
|
||||
return high;
|
||||
}
|
||||
State result = new State();
|
||||
// Compilable
|
||||
result.compile[Scenario.Compiler.C1.ordinal()] = mergeOptional(
|
||||
high.compile[Scenario.Compiler.C1.ordinal()],
|
||||
low.compile[Scenario.Compiler.C1.ordinal()]);
|
||||
result.compile[Scenario.Compiler.C2.ordinal()] = mergeOptional(
|
||||
high.compile[Scenario.Compiler.C2.ordinal()],
|
||||
low.compile[Scenario.Compiler.C2.ordinal()]);
|
||||
// Force inline
|
||||
result.forceInline[Scenario.Compiler.C1.ordinal()] = mergeOptional(
|
||||
high.forceInline[Scenario.Compiler.C1.ordinal()],
|
||||
low.forceInline[Scenario.Compiler.C1.ordinal()]);
|
||||
result.forceInline[Scenario.Compiler.C2.ordinal()] = mergeOptional(
|
||||
high.forceInline[Scenario.Compiler.C2.ordinal()],
|
||||
low.forceInline[Scenario.Compiler.C2.ordinal()]);
|
||||
// Don't inline
|
||||
result.dontInline[Scenario.Compiler.C1.ordinal()] = mergeOptional(
|
||||
high.dontInline[Scenario.Compiler.C1.ordinal()],
|
||||
low.dontInline[Scenario.Compiler.C1.ordinal()]);
|
||||
result.dontInline[Scenario.Compiler.C2.ordinal()] = mergeOptional(
|
||||
high.dontInline[Scenario.Compiler.C2.ordinal()],
|
||||
low.dontInline[Scenario.Compiler.C2.ordinal()]);
|
||||
// set PrintAssembly
|
||||
result.printAssembly = mergeOptional(high.printAssembly,
|
||||
low.printAssembly);
|
||||
// set PrintInline
|
||||
result.printInline = mergeOptional(high.printInline, low.printInline);
|
||||
// set LogCompilation
|
||||
result.log = mergeOptional(high.log, low.log);
|
||||
return result;
|
||||
}
|
||||
|
||||
private static <T> Optional<T> mergeOptional(Optional<T> high,
|
||||
Optional<T> low) {
|
||||
T val = high.orElse(low.orElse(null));
|
||||
return Optional.ofNullable(val);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,65 @@
|
|||
/*
|
||||
* 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.compilercontrol.share.scenario;
|
||||
|
||||
import java.lang.reflect.Executable;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
public interface StateBuilder<T extends CompileCommand> {
|
||||
/**
|
||||
* Adds CompileCommand to builder
|
||||
*
|
||||
* @param command command used to build states
|
||||
*/
|
||||
void add(T command);
|
||||
|
||||
/**
|
||||
* Gets final states of methods
|
||||
*
|
||||
* @return a map with pairs of executables and their states
|
||||
*/
|
||||
Map<Executable, State> getStates();
|
||||
|
||||
/**
|
||||
* Gets list of VM options that will change states of methods
|
||||
*
|
||||
* @return a list of VM options
|
||||
*/
|
||||
List<String> getOptions();
|
||||
|
||||
/**
|
||||
* Gets list of passed commands {@link CompileCommand}
|
||||
*
|
||||
* @return a list of compile commands
|
||||
*/
|
||||
List<T> getCompileCommands();
|
||||
|
||||
/**
|
||||
* Shows that this state builder created a valid input for the test vm
|
||||
*
|
||||
* @return true if this is a valid input
|
||||
*/
|
||||
boolean isValid();
|
||||
}
|
|
@ -39,7 +39,7 @@ public final class ProcessTools {
|
|||
/**
|
||||
* Pumps stdout and stderr from running the process into a String.
|
||||
*
|
||||
* @param processHandler ProcessHandler to run.
|
||||
* @param processBuilder ProcessBuilder to run.
|
||||
* @return Output from process.
|
||||
* @throws IOException If an I/O error occurs.
|
||||
*/
|
||||
|
@ -108,6 +108,17 @@ public final class ProcessTools {
|
|||
return result.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the array of strings containing input arguments passed to the VM
|
||||
*
|
||||
* @return arguments
|
||||
*/
|
||||
public static String[] getVmInputArgs() {
|
||||
RuntimeMXBean runtime = ManagementFactory.getRuntimeMXBean();
|
||||
List<String> args = runtime.getInputArguments();
|
||||
return args.toArray(new String[args.size()]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get platform specific VM arguments (e.g. -d64 on 64bit Solaris)
|
||||
*
|
||||
|
@ -172,6 +183,26 @@ public final class ProcessTools {
|
|||
return executeProcess(pb);
|
||||
}
|
||||
|
||||
/**
|
||||
* Executes a test jvm process, waits for it to finish and returns the process output.
|
||||
* The default jvm options from the test's run command, jtreg, test.vm.opts and test.java.opts, are added.
|
||||
* The java from the test.jdk is used to execute the command.
|
||||
*
|
||||
* The command line will be like:
|
||||
* {test.jdk}/bin/java {test.fromRun.opts} {test.vm.opts} {test.java.opts} cmds
|
||||
*
|
||||
* @param cmds User specifed arguments.
|
||||
* @return The output from the process.
|
||||
*/
|
||||
public static OutputAnalyzer executeTestJvmAllArgs(String... cmds) throws Throwable {
|
||||
List<String> argsList = new ArrayList<>();
|
||||
String[] testArgs = getVmInputArgs();
|
||||
Collections.addAll(argsList, testArgs);
|
||||
Collections.addAll(argsList, Utils.addTestJavaOpts(cmds));
|
||||
ProcessBuilder pb = createJavaProcessBuilder(argsList.toArray(new String[argsList.size()]));
|
||||
return executeProcess(pb);
|
||||
}
|
||||
|
||||
/**
|
||||
* Executes a process, waits for it to finish and returns the process output.
|
||||
* The process will have exited before this method returns.
|
||||
|
|
|
@ -411,6 +411,23 @@ public final class Utils {
|
|||
return iterator.next();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns random element of non empty array
|
||||
*
|
||||
* @param <T> a type of array element
|
||||
* @param array array of elements
|
||||
* @return random element of array
|
||||
* @throws IllegalArgumentException if array is empty
|
||||
*/
|
||||
public static <T> T getRandomElement(T[] array)
|
||||
throws IllegalArgumentException {
|
||||
if (array == null || array.length == 0) {
|
||||
throw new IllegalArgumentException("Empty or null array");
|
||||
}
|
||||
Random random = getRandomInstance();
|
||||
return array[random.nextInt(array.length)];
|
||||
}
|
||||
|
||||
/**
|
||||
* Wait for condition to be true
|
||||
*
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue