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








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;
+    }
+}

Reply via email to