diff test/compiler/testlibrary/rtm/RTMLockingStatistics.java @ 17871:665bbe93823f

8039499: Add all common classes used by tests on RTM support to testlibrary Reviewed-by: kvn, iignatyev Contributed-by: filipp.zhinkin@oracle.com
author iignatyev
date Mon, 14 Apr 2014 19:29:34 +0400
parents
children
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/compiler/testlibrary/rtm/RTMLockingStatistics.java	Mon Apr 14 19:29:34 2014 +0400
@@ -0,0 +1,227 @@
+/*
+ * 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 rtm;
+
+import java.util.EnumMap;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Map;
+import java.util.regex.Pattern;
+import java.util.regex.Matcher;
+
+/**
+ * Wrapper for +UsePreciseRTMLockingStatistics output.
+ *
+ * Example of locking statistics:
+ *
+ * java/lang/ClassLoader.loadClass@7
+ * # rtm locks total (estimated): 0
+ * # rtm lock aborts  : 13
+ * # rtm lock aborts 0: 12
+ * # rtm lock aborts 1: 0
+ * # rtm lock aborts 2: 0
+ * # rtm lock aborts 3: 0
+ * # rtm lock aborts 4: 0
+ * # rtm lock aborts 5: 0
+ */
+public class RTMLockingStatistics {
+    /**
+     * Pattern for aborts per abort type entries.
+     */
+    private static final Pattern ABORT_PATTERN;
+
+    /**
+     * Pattern for whole statistics.
+     */
+    private static final Pattern RTM_LOCKING_STATISTICS_PATTERN;
+
+    static {
+        String abortRe
+                = "# rtm lock aborts\\s+(?<type>[0-9]+):\\s(?<count>[0-9]+)";
+
+        ABORT_PATTERN = Pattern.compile(abortRe);
+        RTM_LOCKING_STATISTICS_PATTERN = Pattern.compile(
+                "(?<className>[^.\n]+)\\." +
+                "(?<methodName>[^@\n]+)@(?<bci>[0-9]+)\n" +
+                "# rtm locks total \\(estimated\\):\\s*" +
+                "(?<totalLocks>[0-9]+)\n" +
+                "# rtm lock aborts\\s+:\\s*(?<totalAborts>[0-9]+)\n" +
+                "(?<abortStats>(" + abortRe + "\n)+)");
+    }
+
+    private final long totalLocks;
+    private final long totalAborts;
+    private final String className;
+    private final String methodName;
+    private final int bci;
+    private final Map<AbortType, Long> aborts = new EnumMap<>(AbortType.class);
+
+    /**
+     * Constructs RTMLockingStatistics from matcher captured statistics entry.
+     * @param matcher Matcher captured statistics entry.
+     */
+    private RTMLockingStatistics(Matcher matcher) {
+        className = matcher.group("className");
+        methodName = matcher.group("methodName");
+        bci = Integer.valueOf(matcher.group("bci"));
+        totalLocks = Long.valueOf(matcher.group("totalLocks"));
+        totalAborts = Long.valueOf(matcher.group("totalAborts"));
+
+        Matcher abortMatcher = ABORT_PATTERN.matcher(matcher.
+                group("abortStats"));
+
+        while (abortMatcher.find()) {
+            int type = Integer.valueOf(abortMatcher.group("type"));
+            long count = Long.valueOf(abortMatcher.group("count"));
+            setAborts(AbortType.lookup(type), count);
+        }
+    }
+
+
+    /**
+     * Parses string and return all founded RTM locking statistics entries.
+     *
+     * @param str the string to be parsed.
+     * @return list with all founded RTM locking statistics entries or
+     *         empty list if nothing was found.
+     */
+    public static List<RTMLockingStatistics> fromString(String str) {
+        List<RTMLockingStatistics> statistics = new LinkedList<>();
+        Matcher matcher = RTM_LOCKING_STATISTICS_PATTERN.matcher(str);
+
+        while (matcher.find()) {
+            RTMLockingStatistics lock = new RTMLockingStatistics(matcher);
+            statistics.add(lock);
+        }
+
+        return statistics;
+    }
+
+    /**
+     * Parses string and return all founded RTM locking statistics entries
+     * for locks in method {@code methodName}.
+     *
+     * @param methodName a name of the method for locks from which statistics
+     *                   should be gathered.
+     * @param str the string to be parsed.
+     * @return list with all founded RTM locking statistics entries or
+     *         empty list if nothing was found.
+     */
+    public static List<RTMLockingStatistics> fromString(String methodName,
+            String str) {
+        String formattedMethodName = formatMethodName(methodName);
+
+        List<RTMLockingStatistics> statisticsForMethod = new LinkedList<>();
+        for (RTMLockingStatistics statistics : fromString(str)) {
+            if (statistics.getLockName().startsWith(formattedMethodName)) {
+                statisticsForMethod.add(statistics);
+            }
+        }
+        return statisticsForMethod;
+    }
+
+    /**
+     * Formats method's name so it will have the same format as
+     * in rtm locking statistics.
+     *
+     * <pre>
+     * Example:
+     * com/example/Klass::method =&gt; com/example/Klass.method
+     * com/example/Klass.method  =&gt; com/example/Klass.method
+     * com.example.Klass::method =&gt; com/example/Klass.method
+     * com.example.Klass.method  =&gt; com/example/Klass.method
+     * </pre>
+     *
+     * @param methodName method's name that should be formatted.
+     * @return formatted method's name.
+     */
+    private static String formatMethodName(String methodName) {
+        String m[];
+        if (methodName.contains("::")) {
+            m = methodName.split("::");
+        } else {
+            int splitAt = methodName.lastIndexOf('.');
+            m = new String[2];
+            m[0] = methodName.substring(0, splitAt);
+            m[1] = methodName.substring(splitAt + 1);
+        }
+        return String.format("%s.%s", m[0].replaceAll("\\.", "/"), m[1]);
+    }
+
+    /**
+     * Returns name of lock for which this statistics was collected.
+     * Lock name has following format:
+     * &lt;class name&gt;.&lt;method name&gt;@&lt;bci&gt;
+     *
+     * @return name of lock.
+     */
+    public String getLockName() {
+        return String.format("%s.%s@%d", className, methodName, bci);
+    }
+
+    /**
+     * Returns aborts count for specified abort type.
+     *
+     * @param type an abort type.
+     * @return count of aborts.
+     */
+    public long getAborts(AbortType type) {
+        return aborts.getOrDefault(type, 0L);
+    }
+
+    /**
+     * Sets aborts count for specified abort type.
+     *
+     * @param type an abort type.
+     * @param count count of aborts.
+     */
+    public void setAborts(AbortType type, long count) {
+        aborts.put(type, count);
+    }
+
+    public long getTotalLocks() {
+        return totalLocks;
+    }
+
+    public long getTotalAborts() {
+        return totalAborts;
+    }
+
+    @Override
+    public String toString() {
+        StringBuilder builder = new StringBuilder();
+        builder.append(getLockName()).append('\n');
+        builder.append(String.format("# rtm locks total (estimated): %d\n",
+                getTotalLocks()));
+        builder.append(String.format("# rtm lock aborts: %d\n",
+                getTotalLocks()));
+
+        for (AbortType type : AbortType.values()) {
+            builder.append(String.format("# rtm lock aborts %s %d\n",
+                    type.toString(), getAborts(type)));
+        }
+        return builder.toString();
+    }
+}