comparison 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
comparison
equal deleted inserted replaced
17870:a0eb3f61d34a 17871:665bbe93823f
1 /*
2 * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation.
8 *
9 * This code is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12 * version 2 for more details (a copy is included in the LICENSE file that
13 * accompanied this code).
14 *
15 * You should have received a copy of the GNU General Public License version
16 * 2 along with this work; if not, write to the Free Software Foundation,
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18 *
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20 * or visit www.oracle.com if you need additional information or have any
21 * questions.
22 *
23 */
24
25 package rtm;
26
27 import java.util.EnumMap;
28 import java.util.LinkedList;
29 import java.util.List;
30 import java.util.Map;
31 import java.util.regex.Pattern;
32 import java.util.regex.Matcher;
33
34 /**
35 * Wrapper for +UsePreciseRTMLockingStatistics output.
36 *
37 * Example of locking statistics:
38 *
39 * java/lang/ClassLoader.loadClass@7
40 * # rtm locks total (estimated): 0
41 * # rtm lock aborts : 13
42 * # rtm lock aborts 0: 12
43 * # rtm lock aborts 1: 0
44 * # rtm lock aborts 2: 0
45 * # rtm lock aborts 3: 0
46 * # rtm lock aborts 4: 0
47 * # rtm lock aborts 5: 0
48 */
49 public class RTMLockingStatistics {
50 /**
51 * Pattern for aborts per abort type entries.
52 */
53 private static final Pattern ABORT_PATTERN;
54
55 /**
56 * Pattern for whole statistics.
57 */
58 private static final Pattern RTM_LOCKING_STATISTICS_PATTERN;
59
60 static {
61 String abortRe
62 = "# rtm lock aborts\\s+(?<type>[0-9]+):\\s(?<count>[0-9]+)";
63
64 ABORT_PATTERN = Pattern.compile(abortRe);
65 RTM_LOCKING_STATISTICS_PATTERN = Pattern.compile(
66 "(?<className>[^.\n]+)\\." +
67 "(?<methodName>[^@\n]+)@(?<bci>[0-9]+)\n" +
68 "# rtm locks total \\(estimated\\):\\s*" +
69 "(?<totalLocks>[0-9]+)\n" +
70 "# rtm lock aborts\\s+:\\s*(?<totalAborts>[0-9]+)\n" +
71 "(?<abortStats>(" + abortRe + "\n)+)");
72 }
73
74 private final long totalLocks;
75 private final long totalAborts;
76 private final String className;
77 private final String methodName;
78 private final int bci;
79 private final Map<AbortType, Long> aborts = new EnumMap<>(AbortType.class);
80
81 /**
82 * Constructs RTMLockingStatistics from matcher captured statistics entry.
83 * @param matcher Matcher captured statistics entry.
84 */
85 private RTMLockingStatistics(Matcher matcher) {
86 className = matcher.group("className");
87 methodName = matcher.group("methodName");
88 bci = Integer.valueOf(matcher.group("bci"));
89 totalLocks = Long.valueOf(matcher.group("totalLocks"));
90 totalAborts = Long.valueOf(matcher.group("totalAborts"));
91
92 Matcher abortMatcher = ABORT_PATTERN.matcher(matcher.
93 group("abortStats"));
94
95 while (abortMatcher.find()) {
96 int type = Integer.valueOf(abortMatcher.group("type"));
97 long count = Long.valueOf(abortMatcher.group("count"));
98 setAborts(AbortType.lookup(type), count);
99 }
100 }
101
102
103 /**
104 * Parses string and return all founded RTM locking statistics entries.
105 *
106 * @param str the string to be parsed.
107 * @return list with all founded RTM locking statistics entries or
108 * empty list if nothing was found.
109 */
110 public static List<RTMLockingStatistics> fromString(String str) {
111 List<RTMLockingStatistics> statistics = new LinkedList<>();
112 Matcher matcher = RTM_LOCKING_STATISTICS_PATTERN.matcher(str);
113
114 while (matcher.find()) {
115 RTMLockingStatistics lock = new RTMLockingStatistics(matcher);
116 statistics.add(lock);
117 }
118
119 return statistics;
120 }
121
122 /**
123 * Parses string and return all founded RTM locking statistics entries
124 * for locks in method {@code methodName}.
125 *
126 * @param methodName a name of the method for locks from which statistics
127 * should be gathered.
128 * @param str the string to be parsed.
129 * @return list with all founded RTM locking statistics entries or
130 * empty list if nothing was found.
131 */
132 public static List<RTMLockingStatistics> fromString(String methodName,
133 String str) {
134 String formattedMethodName = formatMethodName(methodName);
135
136 List<RTMLockingStatistics> statisticsForMethod = new LinkedList<>();
137 for (RTMLockingStatistics statistics : fromString(str)) {
138 if (statistics.getLockName().startsWith(formattedMethodName)) {
139 statisticsForMethod.add(statistics);
140 }
141 }
142 return statisticsForMethod;
143 }
144
145 /**
146 * Formats method's name so it will have the same format as
147 * in rtm locking statistics.
148 *
149 * <pre>
150 * Example:
151 * com/example/Klass::method =&gt; com/example/Klass.method
152 * com/example/Klass.method =&gt; com/example/Klass.method
153 * com.example.Klass::method =&gt; com/example/Klass.method
154 * com.example.Klass.method =&gt; com/example/Klass.method
155 * </pre>
156 *
157 * @param methodName method's name that should be formatted.
158 * @return formatted method's name.
159 */
160 private static String formatMethodName(String methodName) {
161 String m[];
162 if (methodName.contains("::")) {
163 m = methodName.split("::");
164 } else {
165 int splitAt = methodName.lastIndexOf('.');
166 m = new String[2];
167 m[0] = methodName.substring(0, splitAt);
168 m[1] = methodName.substring(splitAt + 1);
169 }
170 return String.format("%s.%s", m[0].replaceAll("\\.", "/"), m[1]);
171 }
172
173 /**
174 * Returns name of lock for which this statistics was collected.
175 * Lock name has following format:
176 * &lt;class name&gt;.&lt;method name&gt;@&lt;bci&gt;
177 *
178 * @return name of lock.
179 */
180 public String getLockName() {
181 return String.format("%s.%s@%d", className, methodName, bci);
182 }
183
184 /**
185 * Returns aborts count for specified abort type.
186 *
187 * @param type an abort type.
188 * @return count of aborts.
189 */
190 public long getAborts(AbortType type) {
191 return aborts.getOrDefault(type, 0L);
192 }
193
194 /**
195 * Sets aborts count for specified abort type.
196 *
197 * @param type an abort type.
198 * @param count count of aborts.
199 */
200 public void setAborts(AbortType type, long count) {
201 aborts.put(type, count);
202 }
203
204 public long getTotalLocks() {
205 return totalLocks;
206 }
207
208 public long getTotalAborts() {
209 return totalAborts;
210 }
211
212 @Override
213 public String toString() {
214 StringBuilder builder = new StringBuilder();
215 builder.append(getLockName()).append('\n');
216 builder.append(String.format("# rtm locks total (estimated): %d\n",
217 getTotalLocks()));
218 builder.append(String.format("# rtm lock aborts: %d\n",
219 getTotalLocks()));
220
221 for (AbortType type : AbortType.values()) {
222 builder.append(String.format("# rtm lock aborts %s %d\n",
223 type.toString(), getAborts(type)));
224 }
225 return builder.toString();
226 }
227 }