comparison graal/com.oracle.jvmci.debug/src/com/oracle/jvmci/debug/JVMCIDebugConfig.java @ 21780:3d15183f3c93

Introduce Compiler interface in jvmci. Use it from jvmci.hotspot.CompilationTask
author Gilles Duboscq <gilles.m.duboscq@oracle.com>
date Wed, 03 Jun 2015 15:47:54 +0200
parents graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/GraalDebugConfig.java@a9f347ae6f5f
children 5b9adb645217
comparison
equal deleted inserted replaced
21779:20ace3139510 21780:3d15183f3c93
1 /*
2 * Copyright (c) 2012, 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 package com.oracle.jvmci.debug;
24
25 import java.io.*;
26 import java.util.*;
27
28 import com.oracle.jvmci.code.*;
29 import com.oracle.jvmci.meta.*;
30 import com.oracle.jvmci.options.*;
31
32 public class JVMCIDebugConfig implements DebugConfig {
33 @SuppressWarnings("all")
34 private static boolean assertionsEnabled() {
35 boolean assertionsEnabled = false;
36 assert assertionsEnabled = true;
37 return assertionsEnabled;
38 }
39
40 // @formatter:off
41 @Option(help = "Pattern for scope(s) in which dumping is enabled (see DebugFilter and Debug.dump)", type = OptionType.Debug)
42 public static final OptionValue<String> Dump = new OptionValue<>(null);
43 @Option(help = "Pattern for scope(s) in which metering is enabled (see DebugFilter and Debug.metric). " +
44 "An empty value enables all metrics unconditionally.", type = OptionType.Debug)
45 public static final OptionValue<String> Meter = new OptionValue<>(null);
46 @Option(help = "Pattern for scope(s) in which verification is enabled (see DebugFilter and Debug.verify).", type = OptionType.Debug)
47 public static final OptionValue<String> Verify = new OptionValue<String>() {
48 @Override
49 protected String defaultValue() {
50 return assertionsEnabled() ? "" : null;
51 }
52 };
53 @Option(help = "Pattern for scope(s) in which memory use tracking is enabled (see DebugFilter and Debug.metric). " +
54 "An empty value enables all memory use trackers unconditionally.", type = OptionType.Debug)
55 public static final OptionValue<String> TrackMemUse = new OptionValue<>(null);
56 @Option(help = "Pattern for scope(s) in which timing is enabled (see DebugFilter and Debug.timer). " +
57 "An empty value enables all timers unconditionally.", type = OptionType.Debug)
58 public static final OptionValue<String> Time = new OptionValue<>(null);
59 @Option(help = "Pattern for scope(s) in which logging is enabled (see DebugFilter and Debug.log)", type = OptionType.Debug)
60 public static final OptionValue<String> Log = new OptionValue<>(null);
61 @Option(help = "Pattern for filtering debug scope output based on method context (see MethodFilter)", type = OptionType.Debug)
62 public static final OptionValue<String> MethodFilter = new OptionValue<>(null);
63 @Option(help = "Only check MethodFilter against the root method in the context if true, otherwise check all methods", type = OptionType.Debug)
64 public static final OptionValue<Boolean> MethodFilterRootOnly = new OptionValue<>(false);
65
66 @Option(help = "How to print metric and timing values:%n" +
67 "Name - aggregate by unqualified name%n" +
68 "Partial - aggregate by partially qualified name (e.g., A.B.C.D.Counter and X.Y.Z.D.Counter will be merged to D.Counter)%n" +
69 "Complete - aggregate by qualified name%n" +
70 "Thread - aggregate by qualified name and thread", type = OptionType.Debug)
71 public static final OptionValue<String> DebugValueSummary = new OptionValue<>("Name");
72 @Option(help = "Omit reporting 0-value metrics", type = OptionType.Debug)
73 public static final OptionValue<Boolean> SuppressZeroDebugValues = new OptionValue<>(true);
74 @Option(help = "Only report debug values for maps which match the regular expression.", type = OptionType.Debug)
75 public static final OptionValue<String> DebugValueThreadFilter = new OptionValue<>(null);
76 @Option(help = "Send Graal IR to dump handlers on error", type = OptionType.Debug)
77 public static final OptionValue<Boolean> DumpOnError = new OptionValue<>(false);
78 @Option(help = "Intercept also bailout exceptions", type = OptionType.Debug)
79 public static final OptionValue<Boolean> InterceptBailout = new OptionValue<>(false);
80 @Option(help = "Enable more verbose log output when available", type = OptionType.Debug)
81 public static final OptionValue<Boolean> LogVerbose = new OptionValue<>(false);
82 // @formatter:on
83
84 static boolean isNotEmpty(OptionValue<String> option) {
85 return option.getValue() != null && !option.getValue().isEmpty();
86 }
87
88 public static boolean areDebugScopePatternsEnabled() {
89 return DumpOnError.getValue() || Dump.getValue() != null || Log.getValue() != null || areScopedMetricsOrTimersEnabled();
90 }
91
92 /**
93 * Determines if any of {@link #Meter}, {@link #Time} or {@link #TrackMemUse} has a non-null,
94 * non-empty value.
95 */
96 public static boolean areScopedMetricsOrTimersEnabled() {
97 return isNotEmpty(Meter) || isNotEmpty(Time) || isNotEmpty(TrackMemUse);
98 }
99
100 private final DebugFilter logFilter;
101 private final DebugFilter meterFilter;
102 private final DebugFilter trackMemUseFilter;
103 private final DebugFilter timerFilter;
104 private final DebugFilter dumpFilter;
105 private final DebugFilter verifyFilter;
106 private final MethodFilter[] methodFilter;
107 private final List<DebugDumpHandler> dumpHandlers;
108 private final List<DebugVerifyHandler> verifyHandlers;
109 private final PrintStream output;
110 private final Set<Object> extraFilters = new HashSet<>();
111
112 public JVMCIDebugConfig(String logFilter, String meterFilter, String trackMemUseFilter, String timerFilter, String dumpFilter, String verifyFilter, String methodFilter, PrintStream output,
113 List<DebugDumpHandler> dumpHandlers, List<DebugVerifyHandler> verifyHandlers) {
114 this.logFilter = DebugFilter.parse(logFilter);
115 this.meterFilter = DebugFilter.parse(meterFilter);
116 this.trackMemUseFilter = DebugFilter.parse(trackMemUseFilter);
117 this.timerFilter = DebugFilter.parse(timerFilter);
118 this.dumpFilter = DebugFilter.parse(dumpFilter);
119 this.verifyFilter = DebugFilter.parse(verifyFilter);
120 if (methodFilter == null || methodFilter.isEmpty()) {
121 this.methodFilter = null;
122 } else {
123 this.methodFilter = com.oracle.jvmci.debug.MethodFilter.parse(methodFilter);
124 }
125
126 // Report the filters that have been configured so the user can verify it's what they expect
127 if (logFilter != null || meterFilter != null || timerFilter != null || dumpFilter != null || methodFilter != null) {
128 // TTY.println(Thread.currentThread().getName() + ": " + toString());
129 }
130 this.dumpHandlers = dumpHandlers;
131 this.verifyHandlers = verifyHandlers;
132 this.output = output;
133 }
134
135 public int getLogLevel() {
136 return getLevel(logFilter);
137 }
138
139 public boolean isLogEnabledForMethod() {
140 return isEnabledForMethod(logFilter);
141 }
142
143 public boolean isMeterEnabled() {
144 return isEnabled(meterFilter);
145 }
146
147 public boolean isMemUseTrackingEnabled() {
148 return isEnabled(trackMemUseFilter);
149 }
150
151 public int getDumpLevel() {
152 return getLevel(dumpFilter);
153 }
154
155 public boolean isDumpEnabledForMethod() {
156 return isEnabledForMethod(dumpFilter);
157 }
158
159 public boolean isVerifyEnabled() {
160 return isEnabled(verifyFilter);
161 }
162
163 public boolean isVerifyEnabledForMethod() {
164 return isEnabledForMethod(verifyFilter);
165 }
166
167 public boolean isTimeEnabled() {
168 return isEnabled(timerFilter);
169 }
170
171 public PrintStream output() {
172 return output;
173 }
174
175 private boolean isEnabled(DebugFilter filter) {
176 return getLevel(filter) > 0;
177 }
178
179 private int getLevel(DebugFilter filter) {
180 int level;
181 if (filter == null) {
182 level = 0;
183 } else {
184 level = filter.matchLevel(Debug.currentScope());
185 }
186 if (level > 0 && !checkMethodFilter()) {
187 level = 0;
188 }
189 return level;
190 }
191
192 private boolean isEnabledForMethod(DebugFilter filter) {
193 return filter != null && checkMethodFilter();
194 }
195
196 /**
197 * Extracts a {@link JavaMethod} from an opaque debug context.
198 *
199 * @return the {@link JavaMethod} represented by {@code context} or null
200 */
201 public static JavaMethod asJavaMethod(Object context) {
202 if (context instanceof JavaMethodContex) {
203 return ((JavaMethodContex) context).asJavaMethod();
204 }
205 return null;
206 }
207
208 private boolean checkMethodFilter() {
209 if (methodFilter == null && extraFilters.isEmpty()) {
210 return true;
211 } else {
212 JavaMethod lastMethod = null;
213 for (Object o : Debug.context()) {
214 if (extraFilters.contains(o)) {
215 return true;
216 } else if (methodFilter != null) {
217 JavaMethod method = asJavaMethod(o);
218 if (method != null) {
219 if (!MethodFilterRootOnly.getValue()) {
220 if (com.oracle.jvmci.debug.MethodFilter.matches(methodFilter, method)) {
221 return true;
222 }
223 } else {
224 /*
225 * The context values operate as a stack so if we want MethodFilter to
226 * only apply to the root method we have to check only the last method
227 * seen.
228 */
229 lastMethod = method;
230 }
231 }
232 }
233 }
234 if (lastMethod != null && com.oracle.jvmci.debug.MethodFilter.matches(methodFilter, lastMethod)) {
235 return true;
236 }
237 return false;
238 }
239 }
240
241 @Override
242 public String toString() {
243 StringBuilder sb = new StringBuilder();
244 sb.append("Debug config:");
245 add(sb, "Log", logFilter);
246 add(sb, "Meter", meterFilter);
247 add(sb, "Time", timerFilter);
248 add(sb, "Dump", dumpFilter);
249 add(sb, "MethodFilter", methodFilter);
250 return sb.toString();
251 }
252
253 private static void add(StringBuilder sb, String name, Object filter) {
254 if (filter != null) {
255 sb.append(' ');
256 sb.append(name);
257 sb.append('=');
258 if (filter instanceof Object[]) {
259 sb.append(Arrays.toString((Object[]) filter));
260 } else {
261 sb.append(String.valueOf(filter));
262 }
263 }
264 }
265
266 @Override
267 public RuntimeException interceptException(Throwable e) {
268 if (e instanceof BailoutException && !InterceptBailout.getValue()) {
269 return null;
270 }
271 Debug.setConfig(Debug.fixedConfig(Debug.DEFAULT_LOG_LEVEL, Debug.DEFAULT_LOG_LEVEL, false, false, false, false, dumpHandlers, verifyHandlers, output));
272 Debug.log(String.format("Exception occurred in scope: %s", Debug.currentScope()));
273 for (Object o : Debug.context()) {
274 if (DumpOnError.getValue()) {
275 Debug.dump(o, "Exception");
276 } else {
277 Debug.log("Context obj %s", o);
278 }
279
280 }
281 return null;
282 }
283
284 @Override
285 public Collection<DebugDumpHandler> dumpHandlers() {
286 return dumpHandlers;
287 }
288
289 @Override
290 public Collection<DebugVerifyHandler> verifyHandlers() {
291 return verifyHandlers;
292 }
293
294 @Override
295 public void addToContext(Object o) {
296 extraFilters.add(o);
297 }
298
299 @Override
300 public void removeFromContext(Object o) {
301 extraFilters.remove(o);
302 }
303 }