# HG changeset patch # User Roland Schatz # Date 1405009798 -7200 # Node ID f1d839174e71a157eefa1e81dcbbf670785193a9 # Parent 1a6989c482f6eb91bc2be8553dc953967fa3cc96 Support for specifying log and dump levels. diff -r 1a6989c482f6 -r f1d839174e71 graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/FlowSenReduTest.java --- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/FlowSenReduTest.java Thu Jul 10 17:17:17 2014 +0200 +++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/FlowSenReduTest.java Thu Jul 10 18:29:58 2014 +0200 @@ -384,7 +384,7 @@ public StructuredGraph visualize(StructuredGraph graph, String title) { DebugConfig debugConfig = DebugScope.getConfig(); - DebugConfig fixedConfig = Debug.fixedConfig(false, true, false, false, false, false, debugConfig.dumpHandlers(), debugConfig.verifyHandlers(), debugConfig.output()); + DebugConfig fixedConfig = Debug.fixedConfig(0, Debug.DEFAULT_LOG_LEVEL, false, false, false, false, debugConfig.dumpHandlers(), debugConfig.verifyHandlers(), debugConfig.output()); try (DebugConfigScope s = Debug.setConfig(fixedConfig)) { Debug.dump(graph, title); diff -r 1a6989c482f6 -r f1d839174e71 graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/DebugFilter.java --- a/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/DebugFilter.java Thu Jul 10 17:17:17 2014 +0200 +++ b/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/DebugFilter.java Thu Jul 10 18:29:58 2014 +0200 @@ -35,52 +35,52 @@ *

* These options enable the associated debug facility if their filter matches the * {@linkplain DebugScope#getQualifiedName() name} of the {@linkplain Debug#currentScope() current - * scope}. + * scope}. For the {@link GraalDebugConfig#Dump} and {@link GraalDebugConfig#Log} options, the log + * or dump level is set. The {@link GraalDebugConfig#Meter} and {@link GraalDebugConfig#Time} + * options don't have a level, for them {@code level = 0} means disabled and a {@code level > 0} + * means enabled. *

- * A filter is a list of comma-separated terms. Each term is interpreted as a glob pattern if it - * contains a "*" or "?" character. Otherwise, it is interpreted as a substring. If a term starts - * with "~", then it is an positive term. An input is matched by a filter if any of its positive - * terms match the input (or it has no positive terms) AND none of its negative terms match the - * input (or it has no negative terms). + * A filter is a list of comma-separated terms of the form {@code [:]}. + * {@code } is interpreted as a glob pattern if it contains a "*" or "?" character. + * Otherwise, it is interpreted as a substring. If {@code } is empty, it matches every + * scope. If {@code :} is omitted, it defaults to {@link Debug#DEFAULT_LOG_LEVEL}. The term + * {@code ~} is a shorthand for {@code :0} to disable a debug facility for a + * pattern. *

- * Examples of filters include: - *

+ * The resulting log level of a scope is determined by the last matching term. If no term + * matches, the log level is 0 (disabled). A filter with no terms matches every scope with a log + * level of {@link Debug#DEFAULT_LOG_LEVEL}. + * + *

Examples of filters

+ * * */ class DebugFilter { @@ -92,69 +92,76 @@ return new DebugFilter(spec.split(",")); } - final Term[] positive; - final Term[] negative; + private final Term[] terms; + + private DebugFilter(String[] terms) { + if (terms.length == 0) { + this.terms = null; + } else { + this.terms = new Term[terms.length]; + for (int i = 0; i < terms.length; i++) { + String t = terms[i]; + int idx = t.indexOf(':'); - DebugFilter(String[] terms) { - List pos = new ArrayList<>(terms.length); - List neg = new ArrayList<>(terms.length); - for (int i = 0; i < terms.length; i++) { - String t = terms[i]; - if (t.startsWith("~")) { - neg.add(new Term(t.substring(1))); - } else { - pos.add(new Term(t)); + String pattern; + int level; + if (idx < 0) { + if (t.startsWith("~")) { + pattern = t.substring(1); + level = 0; + } else { + pattern = t; + level = Debug.DEFAULT_LOG_LEVEL; + } + } else { + pattern = t.substring(0, idx); + if (idx + 1 < t.length()) { + level = Integer.parseInt(t.substring(idx + 1)); + } else { + level = Debug.DEFAULT_LOG_LEVEL; + } + } + + this.terms[i] = new Term(pattern, level); } } - this.positive = pos.isEmpty() ? null : pos.toArray(new Term[pos.size()]); - this.negative = neg.isEmpty() ? null : neg.toArray(new Term[neg.size()]); } /** - * Determines if a given input is matched by this filter. + * Check whether a given input is matched by this filter, and determine the log level. */ - public boolean matches(String input) { - boolean match = true; - if (positive != null) { - match = false; - for (Term t : positive) { + public int matchLevel(String input) { + if (terms == null) { + return Debug.DEFAULT_LOG_LEVEL; + } else { + int level = 0; + for (Term t : terms) { if (t.matches(input)) { - match = true; - break; + level = t.level; } } + return level; } - if (match && negative != null) { - for (Term t : negative) { - if (t.matches(input)) { - match = false; - break; - } - } - } - return match; } @Override public String toString() { - StringBuilder buf = new StringBuilder("DebugFilter["); - String sep = ""; - if (positive != null) { - buf.append(sep).append("pos=").append(Arrays.toString(positive)); - sep = ", "; + StringBuilder buf = new StringBuilder("DebugFilter"); + if (terms != null) { + buf.append(Arrays.toString(terms)); + } else { + buf.append("[]"); } - if (negative != null) { - buf.append(sep).append("neg=").append(Arrays.toString(negative)); - sep = ", "; - } - return buf.append("]").toString(); + return buf.toString(); } - static class Term { + private static class Term { - final Pattern pattern; + private final Pattern pattern; + public final int level; - public Term(String filter) { + public Term(String filter, int level) { + this.level = level; if (filter.isEmpty()) { this.pattern = null; } else if (filter.contains("*") || filter.contains("?")) { @@ -173,7 +180,7 @@ @Override public String toString() { - return pattern == null ? ".*" : pattern.toString(); + return (pattern == null ? ".*" : pattern.toString()) + ":" + level; } } } diff -r 1a6989c482f6 -r f1d839174e71 graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/GraalDebugConfig.java --- a/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/GraalDebugConfig.java Thu Jul 10 17:17:17 2014 +0200 +++ b/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/GraalDebugConfig.java Thu Jul 10 18:29:58 2014 +0200 @@ -121,8 +121,8 @@ this.output = output; } - public boolean isLogEnabled() { - return isEnabled(logFilter); + public int getLogLevel() { + return getLevel(logFilter); } public boolean isLogEnabledForMethod() { @@ -137,8 +137,8 @@ return isEnabled(trackMemUseFilter); } - public boolean isDumpEnabled() { - return isEnabled(dumpFilter); + public int getDumpLevel() { + return getLevel(dumpFilter); } public boolean isDumpEnabledForMethod() { @@ -162,15 +162,27 @@ } private boolean isEnabled(DebugFilter filter) { - return checkDebugFilter(Debug.currentScope(), filter) && checkMethodFilter(); + return getLevel(filter) > 0; + } + + private int getLevel(DebugFilter filter) { + int level = checkDebugFilter(Debug.currentScope(), filter); + if (level > 0 && !checkMethodFilter()) { + level = 0; + } + return level; } private boolean isEnabledForMethod(DebugFilter filter) { return filter != null && checkMethodFilter(); } - private static boolean checkDebugFilter(String currentScope, DebugFilter filter) { - return filter != null && filter.matches(currentScope); + private static int checkDebugFilter(String currentScope, DebugFilter filter) { + if (filter == null) { + return 0; + } else { + return filter.matchLevel(currentScope); + } } /** @@ -241,7 +253,7 @@ if (e instanceof BailoutException) { return null; } - Debug.setConfig(Debug.fixedConfig(true, true, false, false, false, false, dumpHandlers, verifyHandlers, output)); + Debug.setConfig(Debug.fixedConfig(Debug.DEFAULT_LOG_LEVEL, Debug.DEFAULT_LOG_LEVEL, false, false, false, false, dumpHandlers, verifyHandlers, output)); Debug.log(String.format("Exception occurred in scope: %s", Debug.currentScope())); for (Object o : Debug.context()) { if (o instanceof Graph) { diff -r 1a6989c482f6 -r f1d839174e71 graal/com.oracle.graal.debug/src/com/oracle/graal/debug/Debug.java --- a/graal/com.oracle.graal.debug/src/com/oracle/graal/debug/Debug.java Thu Jul 10 17:17:17 2014 +0200 +++ b/graal/com.oracle.graal.debug/src/com/oracle/graal/debug/Debug.java Thu Jul 10 18:29:58 2014 +0200 @@ -82,8 +82,14 @@ return config.isDumpEnabledForMethod(); } + public static final int DEFAULT_LOG_LEVEL = 2; + public static boolean isDumpEnabled() { - return ENABLED && DebugScope.getInstance().isDumpEnabled(); + return isDumpEnabled(DEFAULT_LOG_LEVEL); + } + + public static boolean isDumpEnabled(int dumpLevel) { + return ENABLED && DebugScope.getInstance().isDumpEnabled(dumpLevel); } /** @@ -137,7 +143,11 @@ } public static boolean isLogEnabled() { - return ENABLED && DebugScope.getInstance().isLogEnabled(); + return isLogEnabled(DEFAULT_LOG_LEVEL); + } + + public static boolean isLogEnabled(int logLevel) { + return ENABLED && DebugScope.getInstance().isLogEnabled(logLevel); } @SuppressWarnings("unused") @@ -352,74 +362,106 @@ } } + public static void log(String msg) { + log(DEFAULT_LOG_LEVEL, msg); + } + /** * Prints a message to the current debug scope's logging stream if logging is enabled. * * @param msg the message to log */ - public static void log(String msg) { + public static void log(int logLevel, String msg) { if (ENABLED) { - DebugScope.getInstance().log(msg); + DebugScope.getInstance().log(logLevel, msg); } } + public static void log(String format, Object arg) { + log(DEFAULT_LOG_LEVEL, format, arg); + } + /** * Prints a message to the current debug scope's logging stream if logging is enabled. * * @param format a format string * @param arg the argument referenced by the format specifiers in {@code format} */ - public static void log(String format, Object arg) { + public static void log(int logLevel, String format, Object arg) { if (ENABLED) { - DebugScope.getInstance().log(format, arg); + DebugScope.getInstance().log(logLevel, format, arg); } } + public static void log(String format, Object arg1, Object arg2) { + log(DEFAULT_LOG_LEVEL, format, arg1, arg2); + } + /** - * @see #log(String, Object) + * @see #log(int, String, Object) */ - public static void log(String format, Object arg1, Object arg2) { + public static void log(int logLevel, String format, Object arg1, Object arg2) { if (ENABLED) { - DebugScope.getInstance().log(format, arg1, arg2); + DebugScope.getInstance().log(logLevel, format, arg1, arg2); } } + public static void log(String format, Object arg1, Object arg2, Object arg3) { + log(DEFAULT_LOG_LEVEL, format, arg1, arg2, arg3); + } + /** - * @see #log(String, Object) + * @see #log(int, String, Object) */ - public static void log(String format, Object arg1, Object arg2, Object arg3) { + public static void log(int logLevel, String format, Object arg1, Object arg2, Object arg3) { if (ENABLED) { - DebugScope.getInstance().log(format, arg1, arg2, arg3); + DebugScope.getInstance().log(logLevel, format, arg1, arg2, arg3); } } + public static void log(String format, Object arg1, Object arg2, Object arg3, Object arg4) { + log(DEFAULT_LOG_LEVEL, format, arg1, arg2, arg3, arg4); + } + /** - * @see #log(String, Object) + * @see #log(int, String, Object) */ - public static void log(String format, Object arg1, Object arg2, Object arg3, Object arg4) { + public static void log(int logLevel, String format, Object arg1, Object arg2, Object arg3, Object arg4) { if (ENABLED) { - DebugScope.getInstance().log(format, arg1, arg2, arg3, arg4); + DebugScope.getInstance().log(logLevel, format, arg1, arg2, arg3, arg4); } } + public static void log(String format, Object arg1, Object arg2, Object arg3, Object arg4, Object arg5) { + log(DEFAULT_LOG_LEVEL, format, arg1, arg2, arg3, arg4, arg5); + } + /** - * @see #log(String, Object) + * @see #log(int, String, Object) */ - public static void log(String format, Object arg1, Object arg2, Object arg3, Object arg4, Object arg5) { + public static void log(int logLevel, String format, Object arg1, Object arg2, Object arg3, Object arg4, Object arg5) { if (ENABLED) { - DebugScope.getInstance().log(format, arg1, arg2, arg3, arg4, arg5); + DebugScope.getInstance().log(logLevel, format, arg1, arg2, arg3, arg4, arg5); } } + public static void log(String format, Object arg1, Object arg2, Object arg3, Object arg4, Object arg5, Object arg6) { + log(DEFAULT_LOG_LEVEL, format, arg1, arg2, arg3, arg4, arg5, arg6); + } + /** - * @see #log(String, Object) + * @see #log(int, String, Object) */ - public static void log(String format, Object arg1, Object arg2, Object arg3, Object arg4, Object arg5, Object arg6) { + public static void log(int logLevel, String format, Object arg1, Object arg2, Object arg3, Object arg4, Object arg5, Object arg6) { if (ENABLED) { - DebugScope.getInstance().log(format, arg1, arg2, arg3, arg4, arg5, arg6); + DebugScope.getInstance().log(logLevel, format, arg1, arg2, arg3, arg4, arg5, arg6); } } + public static void logv(String format, Object... args) { + logv(DEFAULT_LOG_LEVEL, format, args); + } + /** * Prints a message to the current debug scope's logging stream. This method must only be called * if debugging is {@linkplain Debug#isEnabled() enabled} as it incurs allocation at the call @@ -429,11 +471,11 @@ * @param format a format string * @param args the arguments referenced by the format specifiers in {@code format} */ - public static void logv(String format, Object... args) { + public static void logv(int logLevel, String format, Object... args) { if (!ENABLED) { throw new InternalError("Use of Debug.logv() must be guarded by a test of Debug.isEnabled()"); } - DebugScope.getInstance().log(format, args); + DebugScope.getInstance().log(logLevel, format, args); } /** @@ -445,30 +487,58 @@ @Deprecated public static void log(String format, Object[] args) { assert false : "shouldn't use this"; - logv(format, args); + log(DEFAULT_LOG_LEVEL, format, args); + } + + /** + * This override exists to catch cases when {@link #log(int, String, Object)} is called with one + * argument bound to a varargs method parameter. It will bind to this method instead of the + * single arg variant and produce a deprecation warning instead of silently wrapping the + * Object[] inside of another Object[]. + */ + @Deprecated + public static void log(int logLevel, String format, Object[] args) { + assert false : "shouldn't use this"; + logv(logLevel, format, args); } public static void dump(Object object, String msg) { - if (ENABLED && DebugScope.getInstance().isDumpEnabled()) { - DebugScope.getInstance().dump(object, msg); + dump(DEFAULT_LOG_LEVEL, object, msg); + } + + public static void dump(int dumpLevel, Object object, String msg) { + if (ENABLED && DebugScope.getInstance().isDumpEnabled(dumpLevel)) { + DebugScope.getInstance().dump(dumpLevel, object, msg); } } public static void dump(Object object, String format, Object arg) { - if (ENABLED && DebugScope.getInstance().isDumpEnabled()) { - DebugScope.getInstance().dump(object, format, arg); + dump(DEFAULT_LOG_LEVEL, object, format, arg); + } + + public static void dump(int dumpLevel, Object object, String format, Object arg) { + if (ENABLED && DebugScope.getInstance().isDumpEnabled(dumpLevel)) { + DebugScope.getInstance().dump(dumpLevel, object, format, arg); } } public static void dump(Object object, String format, Object arg1, Object arg2) { - if (ENABLED && DebugScope.getInstance().isDumpEnabled()) { - DebugScope.getInstance().dump(object, format, arg1, arg2); + dump(DEFAULT_LOG_LEVEL, object, format, arg1, arg2); + } + + public static void dump(int dumpLevel, Object object, String format, Object arg1, Object arg2) { + if (ENABLED && DebugScope.getInstance().isDumpEnabled(dumpLevel)) { + DebugScope.getInstance().dump(dumpLevel, object, format, arg1, arg2); } } public static void dump(Object object, String format, Object arg1, Object arg2, Object arg3) { - if (ENABLED && DebugScope.getInstance().isDumpEnabled()) { - DebugScope.getInstance().dump(object, format, arg1, arg2, arg3); + dump(DEFAULT_LOG_LEVEL, object, format, arg1, arg2, arg3); + } + + public static void dump(int dumpLevel, Object object, String format, Object arg1, Object arg2, Object arg3) { + if (ENABLED && DebugScope.getInstance().isDumpEnabled(dumpLevel)) { + DebugScope.getInstance().dump(dumpLevel, object, format, arg1, arg2, arg3); } } @@ -481,8 +551,20 @@ @Deprecated public static void dump(Object object, String format, Object[] args) { assert false : "shouldn't use this"; - if (ENABLED && DebugScope.getInstance().isDumpEnabled()) { - DebugScope.getInstance().dump(object, format, args); + dump(DEFAULT_LOG_LEVEL, object, format, args); + } + + /** + * This override exists to catch cases when {@link #dump(int, Object, String, Object)} is called + * with one argument bound to a varargs method parameter. It will bind to this method instead of + * the single arg variant and produce a deprecation warning instead of silently wrapping the + * Object[] inside of another Object[]. + */ + @Deprecated + public static void dump(int dumpLevel, Object object, String format, Object[] args) { + assert false : "shouldn't use this"; + if (ENABLED && DebugScope.getInstance().isDumpEnabled(dumpLevel)) { + DebugScope.getInstance().dump(dumpLevel, object, format, args); } } @@ -537,8 +619,8 @@ * * @return an object that reverts to the current indentation level when * {@linkplain Indent#close() closed} or null if debugging is disabled - * @see #logAndIndent(String) - * @see #logAndIndent(String, Object) + * @see #logAndIndent(int, String) + * @see #logAndIndent(int, String, Object) */ public static Indent indent() { if (ENABLED) { @@ -548,6 +630,10 @@ return null; } + public static Indent logAndIndent(String msg) { + return logAndIndent(DEFAULT_LOG_LEVEL, msg); + } + /** * A convenience function which combines {@link #log(String)} and {@link #indent()}. * @@ -555,13 +641,17 @@ * @return an object that reverts to the current indentation level when * {@linkplain Indent#close() closed} or null if debugging is disabled */ - public static Indent logAndIndent(String msg) { + public static Indent logAndIndent(int logLevel, String msg) { if (ENABLED) { - return logvAndIndent(msg); + return logvAndIndent(logLevel, msg); } return null; } + public static Indent logAndIndent(String format, Object arg) { + return logAndIndent(DEFAULT_LOG_LEVEL, format, arg); + } + /** * A convenience function which combines {@link #log(String, Object)} and {@link #indent()}. * @@ -570,45 +660,54 @@ * @return an object that reverts to the current indentation level when * {@linkplain Indent#close() closed} or null if debugging is disabled */ - public static Indent logAndIndent(String format, Object arg) { + public static Indent logAndIndent(int logLevel, String format, Object arg) { + if (ENABLED) { + return logvAndIndent(logLevel, format, arg); + } + return null; + } + + public static Indent logAndIndent(String format, Object arg1, Object arg2) { + return logAndIndent(DEFAULT_LOG_LEVEL, format, arg1, arg2); + } + + /** + * @see #logAndIndent(int, String, Object) + */ + public static Indent logAndIndent(int logLevel, String format, Object arg1, Object arg2) { if (ENABLED) { - return logvAndIndent(format, arg); + return logvAndIndent(logLevel, format, arg1, arg2); + } + return null; + } + + public static Indent logAndIndent(String format, Object arg1, Object arg2, Object arg3) { + return logAndIndent(DEFAULT_LOG_LEVEL, format, arg1, arg2, arg3); + } + + /** + * @see #logAndIndent(int, String, Object) + */ + public static Indent logAndIndent(int logLevel, String format, Object arg1, Object arg2, Object arg3) { + if (ENABLED) { + return logvAndIndent(logLevel, format, arg1, arg2, arg3); } return null; } /** - * @see #logAndIndent(String, Object) - */ - public static Indent logAndIndent(String format, Object arg1, Object arg2) { - if (ENABLED) { - return logvAndIndent(format, arg1, arg2); - } - return null; - } - - /** - * @see #logAndIndent(String, Object) - */ - public static Indent logAndIndent(String format, Object arg1, Object arg2, Object arg3) { - if (ENABLED) { - return logvAndIndent(format, arg1, arg2, arg3); - } - return null; - } - - /** - * A convenience function which combines {@link #logv(String, Object...)} and {@link #indent()}. + * A convenience function which combines {@link #logv(int, String, Object...)} and + * {@link #indent()}. * * @param format a format string * @param args the arguments referenced by the format specifiers in {@code format} * @return an object that reverts to the current indentation level when * {@linkplain Indent#close() closed} or null if debugging is disabled */ - public static Indent logvAndIndent(String format, Object... args) { + public static Indent logvAndIndent(int logLevel, String format, Object... args) { if (ENABLED) { DebugScope scope = DebugScope.getInstance(); - scope.log(format, args); + scope.log(logLevel, format, args); return scope.pushIndentLogger(); } throw new InternalError("Use of Debug.logvAndIndent() must be guarded by a test of Debug.isEnabled()"); @@ -623,7 +722,19 @@ @Deprecated public static void logAndIndent(String format, Object[] args) { assert false : "shouldn't use this"; - logvAndIndent(format, args); + logAndIndent(DEFAULT_LOG_LEVEL, format, args); + } + + /** + * This override exists to catch cases when {@link #logAndIndent(int, String, Object)} is called + * with one argument bound to a varargs method parameter. It will bind to this method instead of + * the single arg variant and produce a deprecation warning instead of silently wrapping the + * Object[] inside of another Object[]. + */ + @Deprecated + public static void logAndIndent(int logLevel, String format, Object[] args) { + assert false : "shouldn't use this"; + logvAndIndent(logLevel, format, args); } public static Iterable context() { @@ -845,20 +956,20 @@ } public static DebugConfig silentConfig() { - return fixedConfig(false, false, false, false, false, false, Collections. emptyList(), Collections. emptyList(), null); + return fixedConfig(0, 0, false, false, false, false, Collections. emptyList(), Collections. emptyList(), null); } - public static DebugConfig fixedConfig(final boolean isLogEnabled, final boolean isDumpEnabled, final boolean isMeterEnabled, final boolean isMemUseTrackingEnabled, final boolean isTimerEnabled, + public static DebugConfig fixedConfig(final int logLevel, final int dumpLevel, final boolean isMeterEnabled, final boolean isMemUseTrackingEnabled, final boolean isTimerEnabled, final boolean isVerifyEnabled, final Collection dumpHandlers, final Collection verifyHandlers, final PrintStream output) { return new DebugConfig() { @Override - public boolean isLogEnabled() { - return isLogEnabled; + public int getLogLevel() { + return logLevel; } public boolean isLogEnabledForMethod() { - return isLogEnabled; + return logLevel > 0; } @Override @@ -872,12 +983,12 @@ } @Override - public boolean isDumpEnabled() { - return isDumpEnabled; + public int getDumpLevel() { + return dumpLevel; } public boolean isDumpEnabledForMethod() { - return isDumpEnabled; + return dumpLevel > 0; } @Override diff -r 1a6989c482f6 -r f1d839174e71 graal/com.oracle.graal.debug/src/com/oracle/graal/debug/DebugConfig.java --- a/graal/com.oracle.graal.debug/src/com/oracle/graal/debug/DebugConfig.java Thu Jul 10 17:17:17 2014 +0200 +++ b/graal/com.oracle.graal.debug/src/com/oracle/graal/debug/DebugConfig.java Thu Jul 10 18:29:58 2014 +0200 @@ -28,9 +28,16 @@ public interface DebugConfig { /** - * Determines if logging is on in the {@linkplain Debug#currentScope() current debug scope} . + * Determines the current log level in the {@linkplain Debug#currentScope() current debug scope} + * . */ - boolean isLogEnabled(); + int getLogLevel(); + + /** + * Determines the current dump level in the {@linkplain Debug#currentScope() current debug + * scope}. + */ + int getDumpLevel(); /** * Determines if logging can be enabled in the current method, regardless of the @@ -55,14 +62,6 @@ boolean isMemUseTrackingEnabled(); /** - * Determines if dumping is enabled in the {@linkplain Debug#currentScope() current debug scope} - * . - * - * @see Debug#dump(Object, String) - */ - boolean isDumpEnabled(); - - /** * Determines if dumping can be enabled in the current method, regardless of the * {@linkplain Debug#currentScope() current debug scope}. */ diff -r 1a6989c482f6 -r f1d839174e71 graal/com.oracle.graal.debug/src/com/oracle/graal/debug/DelegatingDebugConfig.java --- a/graal/com.oracle.graal.debug/src/com/oracle/graal/debug/DelegatingDebugConfig.java Thu Jul 10 17:17:17 2014 +0200 +++ b/graal/com.oracle.graal.debug/src/com/oracle/graal/debug/DelegatingDebugConfig.java Thu Jul 10 18:29:58 2014 +0200 @@ -83,6 +83,18 @@ private final Map featureState = new EnumMap<>(Feature.class); /** + * The debug levels of a {@link DelegatingDebugConfig} than can be + * {@linkplain DelegatingDebugConfig#override(Level, int) overridden} or + * {@linkplain DelegatingDebugConfig#delegate(Level) delegated}. + */ + public enum Level { + LOG, + DUMP + } + + private final Map levelState = new EnumMap<>(Level.class); + + /** * Creates a config that delegates to the {@link DebugScope#getConfig() current config}. */ public DelegatingDebugConfig() { @@ -106,18 +118,28 @@ return this; } + public DelegatingDebugConfig override(Level level, int newLevel) { + levelState.put(level, newLevel); + return this; + } + public DelegatingDebugConfig delegate(Feature feature) { featureState.put(feature, null); return this; } + public DelegatingDebugConfig delegate(Level level) { + levelState.put(level, null); + return this; + } + @Override - public boolean isLogEnabled() { - Boolean fs = featureState.get(Feature.LOG); - if (fs == null) { - return delegate.isLogEnabled(); + public int getLogLevel() { + Integer ls = levelState.get(Level.LOG); + if (ls == null) { + return delegate.getLogLevel(); } - return fs.booleanValue(); + return ls.intValue(); } public boolean isLogEnabledForMethod() { @@ -146,12 +168,12 @@ } @Override - public boolean isDumpEnabled() { - Boolean fs = featureState.get(Feature.DUMP); - if (fs == null) { - return delegate.isDumpEnabled(); + public int getDumpLevel() { + Integer ls = levelState.get(Level.DUMP); + if (ls == null) { + return delegate.getDumpLevel(); } - return fs.booleanValue(); + return ls.intValue(); } public boolean isDumpEnabledForMethod() { diff -r 1a6989c482f6 -r f1d839174e71 graal/com.oracle.graal.debug/src/com/oracle/graal/debug/internal/DebugScope.java --- a/graal/com.oracle.graal.debug/src/com/oracle/graal/debug/internal/DebugScope.java Thu Jul 10 17:17:17 2014 +0200 +++ b/graal/com.oracle.graal.debug/src/com/oracle/graal/debug/internal/DebugScope.java Thu Jul 10 18:29:58 2014 +0200 @@ -52,8 +52,8 @@ } } - public void log(String msg, Object... args) { - if (isLogEnabled()) { + public void log(int logLevel, String msg, Object... args) { + if (isLogEnabled(logLevel)) { StringBuilder str = new StringBuilder(); printScopeName(str); str.append(indent); @@ -102,9 +102,10 @@ private boolean meterEnabled; private boolean timeEnabled; private boolean memUseTrackingEnabled; - private boolean dumpEnabled; private boolean verifyEnabled; - private boolean logEnabled; + + private int currentDumpLevel; + private int currentLogLevel; private PrintStream output; @@ -163,16 +164,18 @@ lastClosedTL.set(this); } - public boolean isDumpEnabled() { - return dumpEnabled; + public boolean isDumpEnabled(int dumpLevel) { + assert dumpLevel > 0; + return currentDumpLevel >= dumpLevel; } public boolean isVerifyEnabled() { return verifyEnabled; } - public boolean isLogEnabled() { - return logEnabled; + public boolean isLogEnabled(int logLevel) { + assert logLevel > 0; + return currentLogLevel >= logLevel; } public boolean isMeterEnabled() { @@ -187,12 +190,12 @@ return memUseTrackingEnabled; } - public void log(String msg, Object... args) { - lastUsedIndent.log(msg, args); + public void log(int logLevel, String msg, Object... args) { + lastUsedIndent.log(logLevel, msg, args); } - public void dump(Object object, String formatString, Object... args) { - if (isDumpEnabled()) { + public void dump(int dumpLevel, Object object, String formatString, Object... args) { + if (isDumpEnabled(dumpLevel)) { DebugConfig config = getConfig(); if (config != null) { String message = String.format(formatString, args); @@ -289,9 +292,10 @@ meterEnabled = false; memUseTrackingEnabled = false; timeEnabled = false; - dumpEnabled = false; verifyEnabled = false; + currentDumpLevel = 0; + // Be pragmatic: provide a default log stream to prevent a crash if the stream is not // set while logging output = TTY.cachedOut; @@ -299,10 +303,10 @@ meterEnabled = config.isMeterEnabled(); memUseTrackingEnabled = config.isMemUseTrackingEnabled(); timeEnabled = config.isTimeEnabled(); - dumpEnabled = config.isDumpEnabled(); verifyEnabled = config.isVerifyEnabled(); - logEnabled = config.isLogEnabled(); output = config.output(); + currentDumpLevel = config.getDumpLevel(); + currentLogLevel = config.getLogLevel(); } } diff -r 1a6989c482f6 -r f1d839174e71 graal/com.oracle.graal.hotspot.test/src/com/oracle/graal/hotspot/test/WriteBarrierVerificationTest.java --- a/graal/com.oracle.graal.hotspot.test/src/com/oracle/graal/hotspot/test/WriteBarrierVerificationTest.java Thu Jul 10 17:17:17 2014 +0200 +++ b/graal/com.oracle.graal.hotspot.test/src/com/oracle/graal/hotspot/test/WriteBarrierVerificationTest.java Thu Jul 10 18:29:58 2014 +0200 @@ -692,7 +692,7 @@ }; DebugConfig debugConfig = DebugScope.getConfig(); - DebugConfig fixedConfig = Debug.fixedConfig(false, false, false, false, false, false, debugConfig.dumpHandlers(), debugConfig.verifyHandlers(), debugConfig.output()); + DebugConfig fixedConfig = Debug.fixedConfig(0, 0, false, false, false, false, debugConfig.dumpHandlers(), debugConfig.verifyHandlers(), debugConfig.output()); try (DebugConfigScope s = Debug.setConfig(fixedConfig)) { ReentrantNodeIterator.apply(closure, graph.start(), false); new WriteBarrierVerificationPhase().apply(graph); diff -r 1a6989c482f6 -r f1d839174e71 graal/com.oracle.graal.phases/src/com/oracle/graal/phases/BasePhase.java --- a/graal/com.oracle.graal.phases/src/com/oracle/graal/phases/BasePhase.java Thu Jul 10 17:17:17 2014 +0200 +++ b/graal/com.oracle.graal.phases/src/com/oracle/graal/phases/BasePhase.java Thu Jul 10 18:29:58 2014 +0200 @@ -38,6 +38,8 @@ */ public abstract class BasePhase { + public static final int PHASE_DUMP_LEVEL = 1; + private CharSequence name; /** @@ -97,8 +99,8 @@ this.run(graph, context); executionCount.increment(); inputNodesCount.add(graph.getNodeCount()); - if (dumpGraph && Debug.isDumpEnabled()) { - Debug.dump(graph, "After phase %s", getName()); + if (dumpGraph && Debug.isDumpEnabled(PHASE_DUMP_LEVEL)) { + Debug.dump(PHASE_DUMP_LEVEL, graph, "After phase %s", getName()); } if (Debug.isVerifyEnabled()) { Debug.verify(graph, "After phase %s", getName());