RFR: 8059625 - JEP-JDK-8043304: Test task: DTrace- tests for segmented codecache feature
Dmitrij Pochepko
dmitrij.pochepko at oracle.com
Thu Dec 25 12:06:49 UTC 2014
v.$next
> I'd prefer to check privileges by running dtrace against dtrace;
> and do it in DtraceRunner::dtraceAvailable, smth like
>
>> result = false;
>> dtrace = getDtracePath();
>> if ($dtrace) {
>> $dtrace $dtrace
>> result = $? == 0;
>> }
>> return $result;
>
>
> Igor
>
> On 12/24/2014 11:09 PM, Dmitrij Pochepko wrote:
>> Hi,
>>
>> i've placed a guard which skips test in case dtrace exits with non-zero
>> code.
>>
>> http://cr.openjdk.java.net/~iignatyev/dpochepk/8059625/webrev.02/
>>
>> Thanks,
>> Dmitrij
>>> Hi,
>>>
>>> There is one more issues related to these tests(not directly).
>>> Currently, dtrace tests can't be run in jprt, because dtrace require
>>> additional previleges for launching user.
>>> Perhaps it's just user to be granted previleges in jprt solaris
>>> hosts...
>>> Not sure about some guard in tests... the only way i know so far is to
>>> just try launching dtrace and parse output
>>> saying about missing previleges, but it doesn't seem to be good
>>> solution.
>>> I think test should assume to be launched in correct environment and
>>> in case it's failed because of previleges, evaluating engineer
>>> starting to work on respective env. issue...
>>> Does anybody have some additional concerns?
>>>
>>> Thanks,
>>> Dmitrij
>>>
>>>> Hi Dmitrij,
>>>>
>>>>
>>>> There is still a typo in spelling (DESCTRUCTIVE => DESTRUCTIVE):
>>>>
>>>> test/testlibrary/com/oracle/java/testlibrary/dtrace/DtraceRunner.java
>>>> 42 public static final String
>>>> PERMIT_DESCTRUCTIVE_ACTIONS_DTRACE_OPTION = "w";
>>>>
>>>> test/compiler/codecache/dtrace/SegmentedCodeCacheDtraceTest.java
>>>> 85
>>>> DtraceRunner.PERMIT_DESCTRUCTIVE_ACTIONS_DTRACE_OPTION,
>>>>
>>>>
>>>> Otherwise, looks good.
>>>> Please, consider it reviewed (no need to re-review).
>>>>
>>>> Thanks,
>>>> Serguei
>>>>
>>>>
>>>> On 12/23/14 3:36 AM, Dmitrij Pochepko wrote:
>>>>> Hi,
>>>>> please review updated webrev
>>>>>
>>>>> http://cr.openjdk.java.net/~iignatyev/dpochepk/8059625/webrev.01/
>>>>>
>>>>> Thanks,
>>>>> Dmitrij
>>>>>> On 12/23/14 12:37 AM, Dmitrij Pochepko wrote:
>>>>>>> Hi,
>>>>>>>
>>>>>>> Thank you for catching these issues.
>>>>>>> I have a question regarding last comment: does it make any
>>>>>>> difference to change "reading of static member 3 times" to
>>>>>>> "copying into static member of another class and then read it 3
>>>>>>> times"?
>>>>>>
>>>>>> Yes, it does (it is a minor issue though).
>>>>>> It is because the class names are pretty big.
>>>>>> It would simplify the code and improve readability, right?
>>>>>>
>>>>>> You already do it two times:
>>>>>> 179 List<Executable> tml
>>>>>> 180 =
>>>>>> SegmentedCodeCacheDtraceTestWorker.TESTED_METHODS_LIST;
>>>>>> ...
>>>>>> 235 List<Executable> mlist
>>>>>> 236 =
>>>>>> SegmentedCodeCacheDtraceTestWorker.TESTED_METHODS_LIST;
>>>>>>
>>>>>> My suggestion is to do it once somewhere before the line 74:
>>>>>> static final List<Executable> MLIST =
>>>>>> SegmentedCodeCacheDtraceTestWorker.TESTED_METHODS_LIST;
>>>>>> and then use the mlist in other places where it is needed:
>>>>>>
>>>>>> 75 String params = MLIST.stream()
>>>>>> ...
>>>>>> 182 d.put(MLIST.get(i).getName(), new
>>>>>> MethodData(MLIST.get(i).getName(),
>>>>>> ...
>>>>>> 239 for (int i = MLIST.size() - 1; i > -1; i--) {
>>>>>> 240
>>>>>> sb.append(MLIST.get(i).getName()).append(delimeter);
>>>>>> These lines will go away:
>>>>>> 179 List<Executable> tml
>>>>>> 180 =
>>>>>> SegmentedCodeCacheDtraceTestWorker.TESTED_METHODS_LIST;
>>>>>> ...
>>>>>> 235 List<Executable> mlist
>>>>>> 236 =
>>>>>> SegmentedCodeCacheDtraceTestWorker.TESTED_METHODS_LIST;
>>>>>>
>>>>>>
>>>>>> Both private static classes are inner classes of the public one.
>>>>>> The MLIST will be in a context for the inner classes, and so, needs
>>>>>> no prefixing.
>>>>>>
>>>>>>
>>>>>> Thanks,
>>>>>> Serguei
>>>>>>
>>>>>>>
>>>>>>> Thanks,
>>>>>>> Dmitrij
>>>>>>>> Hi Dmitry,
>>>>>>>>
>>>>>>>>
>>>>>>>> It looks good in general.
>>>>>>>> Some minor comments are below.
>>>>>>>>
>>>>>>>> test/testlibrary/com/oracle/java/testlibrary/dtrace/DtraceRunner.java
>>>>>>>>
>>>>>>>>
>>>>>>>> 42 public static final String
>>>>>>>> PERMIT_DESCTUCTIVE_ACTIONS_DTRACE_OPTION = "w";
>>>>>>>> A typo in the constant name: DESCTUCTIVE => DESTRUCTIVE
>>>>>>>>
>>>>>>>>
>>>>>>>> test/compiler/codecache/dtrace/SegmentedCodeCacheDtraceTest.java
>>>>>>>>
>>>>>>>> 84
>>>>>>>> DtraceRunner.PERMIT_DESCTUCTIVE_ACTIONS_DTRACE_OPTION,
>>>>>>>> A typo in the constant name: DESCTUCTIVE => DESTRUCTIVE
>>>>>>>>
>>>>>>>>
>>>>>>>> 60 private static final String WORKER_CLASS_NAME
>>>>>>>> 61 =
>>>>>>>> SegmentedCodeCacheDtraceTestWorker.class.getName();
>>>>>>>> ...
>>>>>>>> 80
>>>>>>>> runner.runDtrace(JDKToolFinder.getTestJDKTool("java"), JAVA_OPTS,
>>>>>>>> 81
>>>>>>>> SegmentedCodeCacheDtraceTestWorker.class.getName(), params,
>>>>>>>> The WORKER_CLASS_NAME can be used at 81.
>>>>>>>>
>>>>>>>> 75 String params =
>>>>>>>> SegmentedCodeCacheDtraceTestWorker.TESTED_METHODS_LIST.stream()
>>>>>>>> ...
>>>>>>>> 179 List<Executable> tml
>>>>>>>> 180 =
>>>>>>>> SegmentedCodeCacheDtraceTestWorker.TESTED_METHODS_LIST;
>>>>>>>> ...
>>>>>>>> 235 List<Executable> mlist
>>>>>>>> 236 =
>>>>>>>> SegmentedCodeCacheDtraceTestWorker.TESTED_METHODS_LIST;
>>>>>>>> The TESTED_METHODS_LIST is used three times.
>>>>>>>> It can be cached at the top and re-used.
>>>>>>>>
>>>>>>>> Thanks,
>>>>>>>> Serguei
>>>>>>>>
>>>>>>>>
>>>>>>>>
>>>>>>>> On 12/19/14 11:03 AM, Dmitrij Pochepko wrote:
>>>>>>>>> Hi all,
>>>>>>>>>
>>>>>>>>> Please review changes for
>>>>>>>>> https://bugs.openjdk.java.net/browse/JDK-8059625 -
>>>>>>>>> JEP-JDK-8043304: Test task: DTrace- tests for segmented
>>>>>>>>> codecache feature
>>>>>>>>>
>>>>>>>>> Description: this fix introduce dtrace test, which verify that
>>>>>>>>> different combinations of available compile levels(and, in case
>>>>>>>>> compile levels allows it, different code heaps as result)
>>>>>>>>> doesn't affect callstack shown by dtrace. There is a control
>>>>>>>>> class SegmentedCodeCacheDtraceTest.java and class for running
>>>>>>>>> via dtrace SegmentedCodeCacheDtraceTestWorker.java. A dtrace d
>>>>>>>>> script is also present (SegmentedCodeCacheDtraceTestScript.d). A
>>>>>>>>> control class is using DtraceRunner.java to run dtrace and then
>>>>>>>>> analyzing results using class
>>>>>>>>> SegmentedCodeCacheDtraceResultsAnalyzer with
>>>>>>>>> DtraceResultsAnalyzer interface.
>>>>>>>>> There is also a small class CompilerUtils.java created for
>>>>>>>>> usefull common code.
>>>>>>>>>
>>>>>>>>> webrev:
>>>>>>>>> http://cr.openjdk.java.net/~iignatyev/dpochepk/8059625/webrev.00/
>>>>>>>>>
>>>>>>>>> Additional note: Please note that this path assumes that fix for
>>>>>>>>> JDK-8066440 - Various changes in testlibrary for JDK-8059613 is
>>>>>>>>> also applied.
>>>>>>>>>
>>>>>>>>> Thanks,
>>>>>>>>> Dmitrij
>>>>>>>>
>>>>>>>
>>>>>>
>>>>>
>>>>
>>>
>>
-------------- next part --------------
diff -r 89977bee2ddd test/compiler/codecache/dtrace/SegmentedCodeCacheDtraceTest.java
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/compiler/codecache/dtrace/SegmentedCodeCacheDtraceTest.java Thu Dec 25 15:06:23 2014 +0300
@@ -0,0 +1,305 @@
+/*
+ * 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
+ * @requires os.family=="solaris"
+ * @library /testlibrary /compiler/testlibrary
+ * @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) {
+ 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;
+ }
+ }
+}
diff -r 89977bee2ddd test/compiler/codecache/dtrace/SegmentedCodeCacheDtraceTestScript.d
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/compiler/codecache/dtrace/SegmentedCodeCacheDtraceTestScript.d Thu Dec 25 15:06:23 2014 +0300
@@ -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();
+}
diff -r 89977bee2ddd test/compiler/codecache/dtrace/SegmentedCodeCacheDtraceTestWorker.java
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/compiler/codecache/dtrace/SegmentedCodeCacheDtraceTestWorker.java Thu Dec 25 15:06:23 2014 +0300
@@ -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");
+ }
+}
diff -r 89977bee2ddd test/compiler/testlibrary/CompilerUtils.java
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/compiler/testlibrary/CompilerUtils.java Thu Dec 25 15:06:23 2014 +0300
@@ -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];
+ }
+}
diff -r 89977bee2ddd test/testlibrary/com/oracle/java/testlibrary/dtrace/DtraceResultsAnalyzer.java
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/testlibrary/com/oracle/java/testlibrary/dtrace/DtraceResultsAnalyzer.java Thu Dec 25 15:06:23 2014 +0300
@@ -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);
+}
diff -r 89977bee2ddd test/testlibrary/com/oracle/java/testlibrary/dtrace/DtraceRunner.java
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/test/testlibrary/com/oracle/java/testlibrary/dtrace/DtraceRunner.java Thu Dec 25 15:06:23 2014 +0300
@@ -0,0 +1,122 @@
+/*
+ * 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 {
+ Process proc = pbuilder.start();
+ proc.waitFor();
+ if (proc.exitValue() != 0) {
+ return false;
+ }
+ } catch (IOException | InterruptedException e) {
+ return false;
+ }
+ 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;
+ }
+}
More information about the serviceability-dev
mailing list