mirror of
https://github.com/openjdk/jdk.git
synced 2025-08-27 06:45:07 +02:00
8059625: JEP-JDK-8043304: Test task: DTrace- tests for segmented codecache feature
Reviewed-by: sspitsyn, twisti, fzhinkin, iignatyev
This commit is contained in:
parent
583d750b3d
commit
ea23edb88a
6 changed files with 664 additions and 0 deletions
|
@ -0,0 +1,307 @@
|
||||||
|
/*
|
||||||
|
* 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 com.oracle.java.testlibrary.Asserts;
|
||||||
|
import com.oracle.java.testlibrary.JDKToolFinder;
|
||||||
|
import com.oracle.java.testlibrary.OutputAnalyzer;
|
||||||
|
import com.oracle.java.testlibrary.Utils;
|
||||||
|
import com.oracle.java.testlibrary.dtrace.DtraceResultsAnalyzer;
|
||||||
|
import com.oracle.java.testlibrary.dtrace.DtraceRunner;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.lang.reflect.Executable;
|
||||||
|
import java.nio.file.Files;
|
||||||
|
import java.nio.file.Paths;
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.HashSet;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Random;
|
||||||
|
import java.util.Set;
|
||||||
|
import java.util.regex.Matcher;
|
||||||
|
import java.util.regex.Pattern;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* @test SegmentedCodeCacheDtraceTest
|
||||||
|
* @bug 8015774
|
||||||
|
* @requires os.family=="solaris"
|
||||||
|
* @library /testlibrary /compiler/testlibrary /../../test/lib
|
||||||
|
* @build SegmentedCodeCacheDtraceTestWorker
|
||||||
|
* @run main ClassFileInstaller sun.hotspot.WhiteBox
|
||||||
|
* sun.hotspot.WhiteBox$WhiteBoxPermission
|
||||||
|
* @run main/othervm/timeout=600 -Xbootclasspath/a:. -XX:+TieredCompilation
|
||||||
|
* -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI
|
||||||
|
* SegmentedCodeCacheDtraceTest
|
||||||
|
* @summary testing of dtrace for segmented code cache
|
||||||
|
*/
|
||||||
|
public class SegmentedCodeCacheDtraceTest {
|
||||||
|
|
||||||
|
private static final String WORKER_CLASS_NAME
|
||||||
|
= SegmentedCodeCacheDtraceTestWorker.class.getName();
|
||||||
|
private static final String JAVA_OPTS = " -XX:+DTraceMethodProbes "
|
||||||
|
+ "-Xbootclasspath/a:" + System.getProperty("test.classes") + " "
|
||||||
|
+ "-XX:+UnlockDiagnosticVMOptions "
|
||||||
|
+ "-XX:+WhiteBoxAPI -XX:+SegmentedCodeCache "
|
||||||
|
+ "-XX:CompileCommand=compileonly,"
|
||||||
|
+ WORKER_CLASS_NAME + "::* "
|
||||||
|
+ " -classpath " + System.getProperty("test.class.path") + " "
|
||||||
|
+ String.join(" ", Utils.getTestJavaOpts());
|
||||||
|
private static final String DTRACE_SCRIPT
|
||||||
|
= "SegmentedCodeCacheDtraceTestScript.d";
|
||||||
|
private static final List<Executable> MLIST =
|
||||||
|
SegmentedCodeCacheDtraceTestWorker.TESTED_METHODS_LIST;
|
||||||
|
private static final int WORKER_METHODS_COUNT = MLIST.size();
|
||||||
|
|
||||||
|
private void runTest(TestCombination tc) {
|
||||||
|
String params = MLIST.stream()
|
||||||
|
.map(Executable::getName)
|
||||||
|
.map(x -> tc.data.get(x).compileLevel + " " + tc.data.get(x).isInlined)
|
||||||
|
.collect(Collectors.joining(" "));
|
||||||
|
DtraceRunner runner = new DtraceRunner();
|
||||||
|
runner.runDtrace(JDKToolFinder.getTestJDKTool("java"), JAVA_OPTS,
|
||||||
|
WORKER_CLASS_NAME, params, Paths.get(System.getProperty("test.src"),
|
||||||
|
DTRACE_SCRIPT).toString(),
|
||||||
|
DtraceRunner.PERMIT_DESTRUCTIVE_ACTIONS_DTRACE_OPTION,
|
||||||
|
new SegmentedCodeCacheDtraceResultsAnalyzer());
|
||||||
|
}
|
||||||
|
|
||||||
|
private static TestCombination generateUniqueCombination(
|
||||||
|
int[] availableLevels, Set<TestCombination> combinations) {
|
||||||
|
int len = availableLevels.length;
|
||||||
|
/* first, check if we're out of combinations. */
|
||||||
|
int maxCombinationsCount
|
||||||
|
= (1 << WORKER_METHODS_COUNT)
|
||||||
|
* (int) Math.pow(len, WORKER_METHODS_COUNT);
|
||||||
|
if (combinations.size() == maxCombinationsCount) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
Random r = Utils.getRandomInstance();
|
||||||
|
while (combinations.size() < maxCombinationsCount) {
|
||||||
|
int levels[] = new int[WORKER_METHODS_COUNT];
|
||||||
|
boolean inlines[] = new boolean[WORKER_METHODS_COUNT];
|
||||||
|
for (int i = 0; i < WORKER_METHODS_COUNT; i++) {
|
||||||
|
levels[i] = availableLevels[r.nextInt(len)];
|
||||||
|
inlines[i] = r.nextBoolean();
|
||||||
|
}
|
||||||
|
TestCombination tc = new TestCombination(levels, inlines);
|
||||||
|
if (combinations.add(tc)) {
|
||||||
|
return tc;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void main(String args[]) {
|
||||||
|
int iterations
|
||||||
|
= Integer.getInteger("com.oracle.java.testlibrary.iterations", 1);
|
||||||
|
if (!DtraceRunner.dtraceAvailable()) {
|
||||||
|
System.out.println("INFO: There is no dtrace avaiable. Skipping.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
int[] availableLevels = CompilerUtils.getAvailableCompilationLevels();
|
||||||
|
// adding one more entry(zero) for interpeter
|
||||||
|
availableLevels
|
||||||
|
= Arrays.copyOf(availableLevels, availableLevels.length + 1);
|
||||||
|
Set<TestCombination> combinations = new HashSet<>();
|
||||||
|
for (int i = 0; i < iterations; i++) {
|
||||||
|
TestCombination tc
|
||||||
|
= generateUniqueCombination(availableLevels, combinations);
|
||||||
|
if (tc == null) {
|
||||||
|
System.out.println("INFO: no more combinations available");
|
||||||
|
return;
|
||||||
|
} else {
|
||||||
|
System.out.println("INFO: Running testcase for: " + tc);
|
||||||
|
new SegmentedCodeCacheDtraceTest().runTest(tc);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static class MethodData {
|
||||||
|
|
||||||
|
public final int compileLevel;
|
||||||
|
public final boolean isInlined;
|
||||||
|
public final String name;
|
||||||
|
|
||||||
|
public MethodData(String name, int compileLevel, boolean isInlined) {
|
||||||
|
this.name = name;
|
||||||
|
this.compileLevel = compileLevel;
|
||||||
|
this.isInlined = isInlined;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean equals(Object o) {
|
||||||
|
if (o == null || !(o instanceof MethodData)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
MethodData md = (MethodData) o;
|
||||||
|
return md.compileLevel == compileLevel
|
||||||
|
&& md.isInlined == isInlined
|
||||||
|
&& md.name.equals(name);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int hashCode() {
|
||||||
|
return 100 * name.hashCode() + 10 * compileLevel + (isInlined ? 1 : 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return name + " " + compileLevel + " " + isInlined;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static class TestCombination {
|
||||||
|
|
||||||
|
private final Map<String, MethodData> data;
|
||||||
|
|
||||||
|
public TestCombination(int compLevels[], boolean inlines[]) {
|
||||||
|
Map<String, MethodData> d = new HashMap<>();
|
||||||
|
for (int i = 0; i < MLIST.size(); i++) {
|
||||||
|
d.put(MLIST.get(i).getName(), new MethodData(MLIST.get(i).getName(),
|
||||||
|
compLevels[i], inlines[i]));
|
||||||
|
}
|
||||||
|
data = Collections.unmodifiableMap(d);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean equals(Object o) {
|
||||||
|
if (o == null || !(o instanceof TestCombination)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
TestCombination second = (TestCombination) o;
|
||||||
|
return second.data.equals(data);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int hashCode() {
|
||||||
|
int sum = 0;
|
||||||
|
for (MethodData md : data.values()) {
|
||||||
|
sum += md.hashCode();
|
||||||
|
}
|
||||||
|
return sum;
|
||||||
|
}
|
||||||
|
|
||||||
|
private String getMethodDescString(MethodData md) {
|
||||||
|
return (md == null)
|
||||||
|
? null
|
||||||
|
: String.format("Method %s compilation level %d and %s",
|
||||||
|
md.name, md.compileLevel,
|
||||||
|
md.isInlined ? "inlined" : "not inlined");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return data.values().stream().map(m -> getMethodDescString(m))
|
||||||
|
.collect(Collectors.joining(Utils.NEW_LINE,
|
||||||
|
"Combination: ", ""));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private class SegmentedCodeCacheDtraceResultsAnalyzer
|
||||||
|
implements DtraceResultsAnalyzer {
|
||||||
|
|
||||||
|
private static final int EXPECTED_MATCH_COUNT = 2;
|
||||||
|
|
||||||
|
private final Pattern checkPattern;
|
||||||
|
|
||||||
|
public SegmentedCodeCacheDtraceResultsAnalyzer() {
|
||||||
|
String workerClassRegExp = "\\s*" + WORKER_CLASS_NAME + "\\.";
|
||||||
|
String delimeter = "\\(\\)V\\*?" + workerClassRegExp;
|
||||||
|
String suffix = "test\\(\\)V\\*?" + workerClassRegExp
|
||||||
|
+ "main\\(\\[Ljava\\/lang\\/String;\\)V";
|
||||||
|
StringBuilder sb = new StringBuilder(workerClassRegExp);
|
||||||
|
// method order is important, so, going from list tail to head,
|
||||||
|
// accoring to call order representation in stacktrace
|
||||||
|
for (int i = MLIST.size() - 1; i > -1; i--) {
|
||||||
|
sb.append(MLIST.get(i).getName()).append(delimeter);
|
||||||
|
}
|
||||||
|
sb.append(suffix);
|
||||||
|
checkPattern = Pattern.compile(sb.toString());
|
||||||
|
/* such pattern match should pass on a stacktrace like
|
||||||
|
CPU ID FUNCTION:NAME
|
||||||
|
0 53573 __1cNSharedRuntimeTdtrace_method_entry6FpnKJavaThread_pnGMethod__i_:method-entry ustack:
|
||||||
|
|
||||||
|
libjvm.so`__1cNSharedRuntimeTdtrace_method_entry6FpnKJavaThread_pnGMethod__i_+0x39c
|
||||||
|
SegmentedCodeCacheDtraceTestWorker.baz()V*
|
||||||
|
SegmentedCodeCacheDtraceTestWorker.bar()V
|
||||||
|
SegmentedCodeCacheDtraceTestWorker.foo()V*
|
||||||
|
SegmentedCodeCacheDtraceTestWorker.test()V
|
||||||
|
SegmentedCodeCacheDtraceTestWorker.main([Ljava/lang/String;)V
|
||||||
|
0xffffffff6b0004b8
|
||||||
|
libjvm.so`__1cJJavaCallsLcall_helper6FpnJJavaValue_pnMmethodHandle_pnRJavaCallArguments_pnGThread__v_+0x94c
|
||||||
|
libjvm.so`__1cRjni_invoke_static6FpnHJNIEnv__pnJJavaValue_pnI_jobject_nLJNICallType_pnK_jmethodID_pnSJNI_ArgumentPusher_pnGThread__v_+0xa64
|
||||||
|
libjvm.so`jni_CallStaticVoidMethod+0x508
|
||||||
|
libjli.so`JavaMain+0x584
|
||||||
|
libc.so.1`_lwp_start
|
||||||
|
jstack:
|
||||||
|
|
||||||
|
libjvm.so`__1cNSharedRuntimeTdtrace_method_entry6FpnKJavaThread_pnGMethod__i_+0x39c
|
||||||
|
SegmentedCodeCacheDtraceTestWorker.baz()V*
|
||||||
|
SegmentedCodeCacheDtraceTestWorker.bar()V
|
||||||
|
SegmentedCodeCacheDtraceTestWorker.foo()V*
|
||||||
|
SegmentedCodeCacheDtraceTestWorker.test()V
|
||||||
|
SegmentedCodeCacheDtraceTestWorker.main([Ljava/lang/String;)V
|
||||||
|
0xffffffff6b0004b8
|
||||||
|
libjvm.so`__1cJJavaCallsLcall_helper6FpnJJavaValue_pnMmethodHandle_pnRJavaCallArguments_pnGThread__v_+0x94c
|
||||||
|
libjvm.so`__1cRjni_invoke_static6FpnHJNIEnv__pnJJavaValue_pnI_jobject_nLJNICallType_pnK_jmethodID_pnSJNI_ArgumentPusher_pnGThread__v_+0xa64
|
||||||
|
libjvm.so`jni_CallStaticVoidMethod+0x508
|
||||||
|
libjli.so`JavaMain+0x584
|
||||||
|
libc.so.1`_lwp_start
|
||||||
|
*/
|
||||||
|
}
|
||||||
|
|
||||||
|
protected List<String> loadLog(String dtraceOutFile) throws IOException {
|
||||||
|
return Files.readAllLines(Paths.get(dtraceOutFile));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void analyze(OutputAnalyzer oa, String dtraceOutFilePath) {
|
||||||
|
oa.shouldHaveExitValue(0);
|
||||||
|
List<String> dOut;
|
||||||
|
try {
|
||||||
|
dOut = loadLog(dtraceOutFilePath);
|
||||||
|
} catch (IOException e) {
|
||||||
|
throw new Error("Can't load log", e);
|
||||||
|
}
|
||||||
|
StringBuilder allDtraceOutput = new StringBuilder();
|
||||||
|
for (String entry : dOut) {
|
||||||
|
allDtraceOutput.append(entry);
|
||||||
|
}
|
||||||
|
int matchCount = getMatchCount(allDtraceOutput.toString());
|
||||||
|
Asserts.assertEQ(matchCount, EXPECTED_MATCH_COUNT,
|
||||||
|
"Unexpected output match amount. expected: "
|
||||||
|
+ EXPECTED_MATCH_COUNT + " but found " + matchCount);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected int getMatchCount(String source) {
|
||||||
|
Matcher m = checkPattern.matcher(source);
|
||||||
|
int matchCount = 0;
|
||||||
|
while (m.find()) {
|
||||||
|
matchCount++;
|
||||||
|
}
|
||||||
|
return matchCount;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,33 @@
|
||||||
|
#!/usr/sbin/dtrace -s
|
||||||
|
|
||||||
|
/*
|
||||||
|
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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
hotspot$target:::method-entry
|
||||||
|
/ copyinstr(arg3, arg4) == "baz" /
|
||||||
|
{
|
||||||
|
printf("ustack:\n");
|
||||||
|
ustack(50, 500);
|
||||||
|
printf("jstack:\n");
|
||||||
|
jstack();
|
||||||
|
}
|
|
@ -0,0 +1,113 @@
|
||||||
|
/*
|
||||||
|
* 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 com.oracle.java.testlibrary.Utils;
|
||||||
|
import java.lang.reflect.Executable;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.List;
|
||||||
|
import sun.hotspot.WhiteBox;
|
||||||
|
|
||||||
|
public class SegmentedCodeCacheDtraceTestWorker {
|
||||||
|
|
||||||
|
private static final String METHOD1_NAME = "foo";
|
||||||
|
private static final String METHOD2_NAME = "bar";
|
||||||
|
private static final String METHOD3_NAME = "baz";
|
||||||
|
public static final List<Executable> TESTED_METHODS_LIST;
|
||||||
|
private final WhiteBox wb;
|
||||||
|
private final int compLevels[];
|
||||||
|
|
||||||
|
static {
|
||||||
|
List<Executable> methods = new ArrayList<>();
|
||||||
|
try {
|
||||||
|
// method order is important. Need to place methods in call order,
|
||||||
|
// to be able to verify results later
|
||||||
|
methods.add(SegmentedCodeCacheDtraceTestWorker.class.getMethod(METHOD1_NAME));
|
||||||
|
methods.add(SegmentedCodeCacheDtraceTestWorker.class.getMethod(METHOD2_NAME));
|
||||||
|
methods.add(SegmentedCodeCacheDtraceTestWorker.class.getMethod(METHOD3_NAME));
|
||||||
|
} catch (NoSuchMethodException e) {
|
||||||
|
throw new Error("TESTBUG: no expected method found", e);
|
||||||
|
}
|
||||||
|
TESTED_METHODS_LIST = Collections.unmodifiableList(methods);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected static final boolean BACKGROUND_COMPILATION
|
||||||
|
= WhiteBox.getWhiteBox().getBooleanVMFlag("BackgroundCompilation");
|
||||||
|
|
||||||
|
public static void main(String[] args) {
|
||||||
|
if (args.length != 2 * TESTED_METHODS_LIST.size()) {
|
||||||
|
throw new Error("Usage: java <thisClass> <fooCompLevel> <fooInlined>"
|
||||||
|
+ "<barCompLevel> <barInlined> "
|
||||||
|
+ "<bazCompLevel> <bazInlined>");
|
||||||
|
} else {
|
||||||
|
int compLevels[] = new int[TESTED_METHODS_LIST.size()];
|
||||||
|
boolean inlines[] = new boolean[TESTED_METHODS_LIST.size()];
|
||||||
|
for (int i = 0; i < TESTED_METHODS_LIST.size(); i++) {
|
||||||
|
compLevels[i] = Integer.parseInt(args[2 * i]);
|
||||||
|
inlines[i] = Boolean.parseBoolean(args[2 * i + 1]);
|
||||||
|
}
|
||||||
|
new SegmentedCodeCacheDtraceTestWorker(compLevels, inlines).test();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public SegmentedCodeCacheDtraceTestWorker(int compLevels[], boolean inlines[]) {
|
||||||
|
wb = WhiteBox.getWhiteBox();
|
||||||
|
this.compLevels = Arrays.copyOf(compLevels, compLevels.length);
|
||||||
|
for (int i = 0; i < compLevels.length; i++) {
|
||||||
|
if (inlines[i]) {
|
||||||
|
wb.testSetForceInlineMethod(TESTED_METHODS_LIST.get(i), true);
|
||||||
|
} else {
|
||||||
|
wb.testSetDontInlineMethod(TESTED_METHODS_LIST.get(i), true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void waitForCompilation(Executable executable, int compLevel) {
|
||||||
|
if (compLevel > 0) {
|
||||||
|
Utils.waitForCondition(() -> wb.isMethodCompiled(executable));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void test() {
|
||||||
|
for (int i = 0; i < TESTED_METHODS_LIST.size(); i++) {
|
||||||
|
Executable method = TESTED_METHODS_LIST.get(i);
|
||||||
|
int compLevel = compLevels[i];
|
||||||
|
wb.enqueueMethodForCompilation(method, compLevel);
|
||||||
|
waitForCompilation(method, compLevel);
|
||||||
|
}
|
||||||
|
foo();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void foo() {
|
||||||
|
bar();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void bar() {
|
||||||
|
baz();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void baz() {
|
||||||
|
System.out.println("Reached baz method");
|
||||||
|
}
|
||||||
|
}
|
61
hotspot/test/compiler/testlibrary/CompilerUtils.java
Normal file
61
hotspot/test/compiler/testlibrary/CompilerUtils.java
Normal file
|
@ -0,0 +1,61 @@
|
||||||
|
/*
|
||||||
|
* 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 com.oracle.java.testlibrary.Asserts;
|
||||||
|
import com.oracle.java.testlibrary.Platform;
|
||||||
|
import java.util.stream.IntStream;
|
||||||
|
import sun.hotspot.WhiteBox;
|
||||||
|
|
||||||
|
public class CompilerUtils {
|
||||||
|
|
||||||
|
private CompilerUtils() {
|
||||||
|
// to prevent from instantiation
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns available compilation levels
|
||||||
|
*
|
||||||
|
* @return int array with compilation levels
|
||||||
|
*/
|
||||||
|
public static int[] getAvailableCompilationLevels() {
|
||||||
|
if (!WhiteBox.getWhiteBox().getBooleanVMFlag("UseCompiler")) {
|
||||||
|
return new int[0];
|
||||||
|
}
|
||||||
|
if (WhiteBox.getWhiteBox().getBooleanVMFlag("TieredCompilation")) {
|
||||||
|
Long flagValue = WhiteBox.getWhiteBox()
|
||||||
|
.getIntxVMFlag("TieredStopAtLevel");
|
||||||
|
int maxLevel = flagValue.intValue();
|
||||||
|
Asserts.assertEQ(new Long(maxLevel), flagValue,
|
||||||
|
"TieredStopAtLevel has value out of int capacity");
|
||||||
|
return IntStream.rangeClosed(1, maxLevel).toArray();
|
||||||
|
} else {
|
||||||
|
if (Platform.isServer()) {
|
||||||
|
return new int[]{4};
|
||||||
|
}
|
||||||
|
if (Platform.isClient() || Platform.isMinimal()) {
|
||||||
|
return new int[]{1};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return new int[0];
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,29 @@
|
||||||
|
/*
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
|
package com.oracle.java.testlibrary.dtrace;
|
||||||
|
|
||||||
|
import com.oracle.java.testlibrary.OutputAnalyzer;
|
||||||
|
|
||||||
|
public interface DtraceResultsAnalyzer {
|
||||||
|
public void analyze(OutputAnalyzer oa, String logFilePath);
|
||||||
|
}
|
|
@ -0,0 +1,121 @@
|
||||||
|
/*
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
|
package com.oracle.java.testlibrary.dtrace;
|
||||||
|
|
||||||
|
import com.oracle.java.testlibrary.Asserts;
|
||||||
|
import com.oracle.java.testlibrary.OutputAnalyzer;
|
||||||
|
import java.io.File;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
public class DtraceRunner {
|
||||||
|
|
||||||
|
private static final String DTRACE_DEFAULT_PATH = "/usr/sbin/dtrace";
|
||||||
|
private static final String DTRACE_PATH_PROPERTY
|
||||||
|
= "com.oracle.test.dtrace.path";
|
||||||
|
private static final String OUTPUT_FILE_DTRACE_OPTION = "o";
|
||||||
|
private static final String RUN_COMMAND_DTRACE_OPTION = "c";
|
||||||
|
private static final String RUN_SCRIPT_DTRACE_OPTION = "s";
|
||||||
|
private static final String ALLOW_ZERO_PROBE_DESCRIPTION_DTRACE_OPTION = "Z";
|
||||||
|
private static final String DTRACE_OPTION_PREFIX = "-";
|
||||||
|
public static final String PERMIT_DESTRUCTIVE_ACTIONS_DTRACE_OPTION = "w";
|
||||||
|
public static final String DTRACE_OUT_LOG = "dtrace.out";
|
||||||
|
|
||||||
|
private final String dtraceExecutable;
|
||||||
|
|
||||||
|
public DtraceRunner() {
|
||||||
|
dtraceExecutable = getDtracePath();
|
||||||
|
}
|
||||||
|
|
||||||
|
private List<String> getLaunchCmd(String java, String javaOpts,
|
||||||
|
String execClass, String testArgs, String dtraceScript,
|
||||||
|
String dtraceAddOpts) {
|
||||||
|
Asserts.assertTrue(!java.matches("\\s"), "Current dtrace implementation"
|
||||||
|
+ " can't handle whitespaces in application path");
|
||||||
|
List<String> result = new ArrayList<>();
|
||||||
|
result.add(dtraceExecutable);
|
||||||
|
result.add(DTRACE_OPTION_PREFIX + System.getProperty("sun.arch.data.model"));
|
||||||
|
result.add(DTRACE_OPTION_PREFIX
|
||||||
|
+ ALLOW_ZERO_PROBE_DESCRIPTION_DTRACE_OPTION
|
||||||
|
+ ((dtraceAddOpts == null) ? "" : dtraceAddOpts)
|
||||||
|
+ RUN_SCRIPT_DTRACE_OPTION); // run_script should be last one
|
||||||
|
result.add(dtraceScript);
|
||||||
|
result.add(DTRACE_OPTION_PREFIX + OUTPUT_FILE_DTRACE_OPTION);
|
||||||
|
result.add(DTRACE_OUT_LOG);
|
||||||
|
result.add(DTRACE_OPTION_PREFIX + RUN_COMMAND_DTRACE_OPTION);
|
||||||
|
result.add(java + " " + javaOpts + " " + execClass + " " + testArgs);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void backupLogFile(File file) {
|
||||||
|
if (file.exists()) {
|
||||||
|
file.renameTo(new File(file.getPath() + ".bak"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void runDtrace(String java, String javaOpts, String execClass,
|
||||||
|
String testArgs, String dtraceScript, String dtraceAddOpts,
|
||||||
|
DtraceResultsAnalyzer analyzer) {
|
||||||
|
backupLogFile(new File(DTRACE_OUT_LOG));
|
||||||
|
ProcessBuilder pbuilder = new ProcessBuilder(
|
||||||
|
getLaunchCmd(java, javaOpts, execClass, testArgs,
|
||||||
|
dtraceScript, dtraceAddOpts));
|
||||||
|
OutputAnalyzer oa;
|
||||||
|
try {
|
||||||
|
oa = new OutputAnalyzer(pbuilder.start());
|
||||||
|
} catch (IOException e) {
|
||||||
|
throw new Error("TESTBUG: Can't start process", e);
|
||||||
|
}
|
||||||
|
analyzer.analyze(oa, DTRACE_OUT_LOG);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static boolean dtraceAvailable() {
|
||||||
|
String path = getDtracePath();
|
||||||
|
if (path == null) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
// now we'll launch dtrace to trace itself just to be sure it works
|
||||||
|
// and have all additional previleges set
|
||||||
|
ProcessBuilder pbuilder = new ProcessBuilder(path, path);
|
||||||
|
try {
|
||||||
|
OutputAnalyzer oa = new OutputAnalyzer(pbuilder.start());
|
||||||
|
if (oa.getExitValue() != 0) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
} catch (IOException e) {
|
||||||
|
throw new Error("Couldn't launch dtrace", e);
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static String getDtracePath() {
|
||||||
|
String propPath = System.getProperty(DTRACE_PATH_PROPERTY);
|
||||||
|
if (propPath != null && new File(propPath).exists()) {
|
||||||
|
return propPath;
|
||||||
|
} else if (new File(DTRACE_DEFAULT_PATH).exists()) {
|
||||||
|
return DTRACE_DEFAULT_PATH;
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
Loading…
Add table
Add a link
Reference in a new issue