mirror of
https://github.com/openjdk/jdk.git
synced 2026-03-15 18:33:41 +00: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
@ -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…
x
Reference in New Issue
Block a user