# HG changeset patch # User Doug Simon # Date 1403169856 -7200 # Node ID af9f3a5f091bec97ab75aeab8667c84ef11b8547 # Parent 4f185700f4b7d0c7807b0570693909d57fd5945e extended Debug API with DebugVerifyHandlers diff -r 4f185700f4b7 -r af9f3a5f091b 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 Jun 19 00:45:04 2014 +0200 +++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/FlowSenReduTest.java Thu Jun 19 11:24:16 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, debugConfig.dumpHandlers(), debugConfig.output()); + DebugConfig fixedConfig = Debug.fixedConfig(false, true, false, false, false, false, debugConfig.dumpHandlers(), debugConfig.verifyHandlers(), debugConfig.output()); try (DebugConfigScope s = Debug.setConfig(fixedConfig)) { Debug.dump(graph, title); diff -r 4f185700f4b7 -r af9f3a5f091b 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 Jun 19 00:45:04 2014 +0200 +++ b/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/GraalDebugConfig.java Thu Jun 19 11:24:16 2014 +0200 @@ -42,6 +42,8 @@ public static final OptionValue Dump = new OptionValue<>(null); @Option(help = "Pattern for scope(s) to in which metering is enabled (see DebugFilter and Debug.metric)") public static final OptionValue Meter = new OptionValue<>(null); + @Option(help = "Pattern for scope(s) to in which verification is enabled (see DebugFilter and Debug.verify)") + public static final OptionValue Verify = new OptionValue<>(null); @Option(help = "Pattern for scope(s) to in which memory use tracking is enabled (see DebugFilter and Debug.metric)") public static final OptionValue TrackMemUse = new OptionValue<>(null); @Option(help = "Pattern for scope(s) to in which timing is enabled (see DebugFilter and Debug.timer)") @@ -89,18 +91,21 @@ private final DebugFilter trackMemUseFilter; private final DebugFilter timerFilter; private final DebugFilter dumpFilter; + private final DebugFilter verifyFilter; private final MethodFilter[] methodFilter; private final List dumpHandlers; + private final List verifyHandlers; private final PrintStream output; private final Set extraFilters = new HashSet<>(); - public GraalDebugConfig(String logFilter, String meterFilter, String trackMemUseFilter, String timerFilter, String dumpFilter, String methodFilter, PrintStream output, - List dumpHandlers) { + public GraalDebugConfig(String logFilter, String meterFilter, String trackMemUseFilter, String timerFilter, String dumpFilter, String verifyFilter, String methodFilter, PrintStream output, + List dumpHandlers, List verifyHandlers) { this.logFilter = DebugFilter.parse(logFilter); this.meterFilter = DebugFilter.parse(meterFilter); this.trackMemUseFilter = DebugFilter.parse(trackMemUseFilter); this.timerFilter = DebugFilter.parse(timerFilter); this.dumpFilter = DebugFilter.parse(dumpFilter); + this.verifyFilter = DebugFilter.parse(verifyFilter); if (methodFilter == null || methodFilter.isEmpty()) { this.methodFilter = null; } else { @@ -112,6 +117,7 @@ // TTY.println(Thread.currentThread().getName() + ": " + toString()); } this.dumpHandlers = dumpHandlers; + this.verifyHandlers = verifyHandlers; this.output = output; } @@ -127,10 +133,6 @@ return isEnabled(meterFilter); } - public boolean isMetderEnabled() { - return isEnabled(meterFilter); - } - public boolean isMemUseTrackingEnabled() { return isEnabled(trackMemUseFilter); } @@ -143,6 +145,14 @@ return isEnabledForMethod(dumpFilter); } + public boolean isVerifyEnabled() { + return isEnabled(verifyFilter); + } + + public boolean isVerifyEnabledForMethod() { + return isEnabledForMethod(verifyFilter); + } + public boolean isTimeEnabled() { return isEnabled(timerFilter); } @@ -231,7 +241,7 @@ if (e instanceof BailoutException) { return null; } - Debug.setConfig(Debug.fixedConfig(true, true, false, false, false, dumpHandlers, output)); + Debug.setConfig(Debug.fixedConfig(true, true, 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) { @@ -269,6 +279,11 @@ } @Override + public Collection verifyHandlers() { + return verifyHandlers; + } + + @Override public void addToContext(Object o) { extraFilters.add(o); } diff -r 4f185700f4b7 -r af9f3a5f091b 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 Jun 19 00:45:04 2014 +0200 +++ b/graal/com.oracle.graal.debug/src/com/oracle/graal/debug/Debug.java Thu Jun 19 11:24:16 2014 +0200 @@ -86,6 +86,33 @@ return ENABLED && DebugScope.getInstance().isDumpEnabled(); } + /** + * Determines if verification is enabled in the current method, regardless of the + * {@linkplain Debug#currentScope() current debug scope}. + * + * @see Debug#verify(Object, String) + */ + public static boolean isVerifyEnabledForMethod() { + if (!ENABLED) { + return false; + } + DebugConfig config = DebugScope.getConfig(); + if (config == null) { + return false; + } + return config.isVerifyEnabledForMethod(); + } + + /** + * Determines if verification is enabled in the {@linkplain Debug#currentScope() current debug + * scope}. + * + * @see Debug#verify(Object, String) + */ + public static boolean isVerifyEnabled() { + return ENABLED && DebugScope.getInstance().isVerifyEnabled(); + } + public static boolean isMeterEnabled() { return ENABLED && DebugScope.getInstance().isMeterEnabled(); } @@ -460,6 +487,65 @@ } /** + * Calls all {@link DebugVerifyHandler}s in the current {@linkplain DebugScope#getConfig() + * config} to perform verification on a given object. + * + * @param object the object to be verified + * @param msg denoting context of verification + */ + public static void verify(Object object, String msg) { + if (ENABLED && DebugScope.getInstance().isVerifyEnabled()) { + DebugScope.getInstance().verify(object, msg); + } + } + + /** + * Calls all {@link DebugVerifyHandler}s in the current {@linkplain DebugScope#getConfig() + * config} to perform verification on a given object. + * + * @param object the object to be verified + * @param format format string for message denoting context of verification + * @param arg argument to format string + */ + public static void verify(Object object, String format, Object arg) { + if (ENABLED && DebugScope.getInstance().isVerifyEnabled()) { + DebugScope.getInstance().verify(object, format, arg); + } + } + + /** + * @see Debug#verify(Object, String, Object) + */ + public static void verify(Object object, String format, Object arg1, Object arg2) { + if (ENABLED && DebugScope.getInstance().isVerifyEnabled()) { + DebugScope.getInstance().verify(object, format, arg1, arg2); + } + } + + /** + * @see Debug#verify(Object, String, Object) + */ + public static void verify(Object object, String format, Object arg1, Object arg2, Object arg3) { + if (ENABLED && DebugScope.getInstance().isVerifyEnabled()) { + DebugScope.getInstance().verify(object, format, arg1, arg2, arg3); + } + } + + /** + * This override exists to catch cases when {@link #verify(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 verify(Object object, String format, Object[] args) { + assert false : "shouldn't use this"; + if (ENABLED && DebugScope.getInstance().isVerifyEnabled()) { + DebugScope.getInstance().verify(object, format, args); + } + } + + /** * Opens a new indentation level (by adding some spaces) based on the current indentation level. * This should be used in a {@linkplain Indent try-with-resources} pattern. * @@ -773,11 +859,11 @@ } public static DebugConfig silentConfig() { - return fixedConfig(false, false, false, false, false, Collections. emptyList(), System.out); + return fixedConfig(false, false, false, false, false, false, Collections. emptyList(), Collections. emptyList(), System.out); } public static DebugConfig fixedConfig(final boolean isLogEnabled, final boolean isDumpEnabled, final boolean isMeterEnabled, final boolean isMemUseTrackingEnabled, final boolean isTimerEnabled, - final Collection dumpHandlers, final PrintStream output) { + final boolean isVerifyEnabled, final Collection dumpHandlers, final Collection verifyHandlers, final PrintStream output) { return new DebugConfig() { @Override @@ -809,6 +895,15 @@ } @Override + public boolean isVerifyEnabled() { + return isVerifyEnabled; + } + + public boolean isVerifyEnabledForMethod() { + return isVerifyEnabled; + } + + @Override public boolean isTimeEnabled() { return isTimerEnabled; } @@ -824,6 +919,11 @@ } @Override + public Collection verifyHandlers() { + return verifyHandlers; + } + + @Override public PrintStream output() { return output; } diff -r 4f185700f4b7 -r af9f3a5f091b 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 Jun 19 00:45:04 2014 +0200 +++ b/graal/com.oracle.graal.debug/src/com/oracle/graal/debug/DebugConfig.java Thu Jun 19 11:24:16 2014 +0200 @@ -69,6 +69,16 @@ boolean isDumpEnabledForMethod(); /** + * @see Debug#isVerifyEnabled() + */ + boolean isVerifyEnabled(); + + /** + * @see Debug#isVerifyEnabledForMethod() + */ + boolean isVerifyEnabledForMethod(); + + /** * Adds an object the context used by this configuration to do filtering. */ void addToContext(Object o); @@ -94,9 +104,14 @@ RuntimeException interceptException(Throwable e); /** - * Gets the modifiable collection dump handlers registered with this configuration. + * Gets the modifiable collection of dump handlers registered with this configuration. */ Collection dumpHandlers(); PrintStream output(); + + /** + * Gets the modifiable collection of verify handlers registered with this configuration. + */ + Collection verifyHandlers(); } diff -r 4f185700f4b7 -r af9f3a5f091b graal/com.oracle.graal.debug/src/com/oracle/graal/debug/DebugVerifyHandler.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.debug/src/com/oracle/graal/debug/DebugVerifyHandler.java Thu Jun 19 11:24:16 2014 +0200 @@ -0,0 +1,34 @@ +/* + * Copyright (c) 2012, 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.graal.debug; + +/** + * Performs some kind of verification on an object. + */ +public interface DebugVerifyHandler { + + /** + * Verifies that a given object satisfies some invariants. + */ + void verify(Object object, String message); +} diff -r 4f185700f4b7 -r af9f3a5f091b 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 Jun 19 00:45:04 2014 +0200 +++ b/graal/com.oracle.graal.debug/src/com/oracle/graal/debug/DelegatingDebugConfig.java Thu Jun 19 11:24:16 2014 +0200 @@ -55,6 +55,14 @@ */ DUMP_METHOD, /** + * @see Debug#isVerifyEnabled() + */ + VERIFY, + /** + * @see Debug#isVerifyEnabledForMethod() + */ + VERIFY_METHOD, + /** * @see Debug#isMeterEnabled() */ METER, @@ -155,6 +163,23 @@ } @Override + public boolean isVerifyEnabled() { + Boolean fs = featureState.get(Feature.VERIFY); + if (fs == null) { + return delegate.isVerifyEnabled(); + } + return fs.booleanValue(); + } + + public boolean isVerifyEnabledForMethod() { + Boolean fs = featureState.get(Feature.VERIFY_METHOD); + if (fs == null) { + return delegate.isVerifyEnabledForMethod(); + } + return fs.booleanValue(); + } + + @Override public boolean isTimeEnabled() { Boolean fs = featureState.get(Feature.TIME); if (fs == null) { @@ -178,6 +203,11 @@ } @Override + public Collection verifyHandlers() { + return delegate.verifyHandlers(); + } + + @Override public PrintStream output() { return delegate.output(); } diff -r 4f185700f4b7 -r af9f3a5f091b 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 Jun 19 00:45:04 2014 +0200 +++ b/graal/com.oracle.graal.debug/src/com/oracle/graal/debug/internal/DebugScope.java Thu Jun 19 11:24:16 2014 +0200 @@ -95,6 +95,7 @@ private boolean timeEnabled; private boolean memUseTrackingEnabled; private boolean dumpEnabled; + private boolean verifyEnabled; private boolean logEnabled; private PrintStream output; @@ -158,6 +159,10 @@ return dumpEnabled; } + public boolean isVerifyEnabled() { + return verifyEnabled; + } + public boolean isLogEnabled() { return logEnabled; } @@ -213,6 +218,21 @@ } /** + * @see Debug#verify(Object, String, Object) + */ + public void verify(Object object, String formatString, Object... args) { + if (isVerifyEnabled()) { + DebugConfig config = getConfig(); + if (config != null) { + String message = String.format(formatString, args); + for (DebugVerifyHandler handler : config.verifyHandlers()) { + handler.verify(object, message); + } + } + } + } + + /** * Creates and enters a new debug scope which is either a child of the current scope or a * disjoint top level scope. * @@ -269,6 +289,7 @@ memUseTrackingEnabled = false; timeEnabled = false; dumpEnabled = false; + verifyEnabled = false; // Be pragmatic: provide a default log stream to prevent a crash if the stream is not // set while logging @@ -278,6 +299,7 @@ memUseTrackingEnabled = config.isMemUseTrackingEnabled(); timeEnabled = config.isTimeEnabled(); dumpEnabled = config.isDumpEnabled(); + verifyEnabled = config.isVerifyEnabled(); logEnabled = config.isLogEnabled(); output = config.output(); } diff -r 4f185700f4b7 -r af9f3a5f091b 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 Jun 19 00:45:04 2014 +0200 +++ b/graal/com.oracle.graal.hotspot.test/src/com/oracle/graal/hotspot/test/WriteBarrierVerificationTest.java Thu Jun 19 11:24:16 2014 +0200 @@ -692,7 +692,7 @@ }; DebugConfig debugConfig = DebugScope.getConfig(); - DebugConfig fixedConfig = Debug.fixedConfig(false, false, false, false, false, debugConfig.dumpHandlers(), debugConfig.output()); + DebugConfig fixedConfig = Debug.fixedConfig(false, false, 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 4f185700f4b7 -r af9f3a5f091b graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotGraalRuntime.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotGraalRuntime.java Thu Jun 19 00:45:04 2014 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotGraalRuntime.java Thu Jun 19 11:24:16 2014 +0200 @@ -123,9 +123,9 @@ TTY.initialize(Options.LogFile.getStream()); - if (Log.getValue() == null && Meter.getValue() == null && Time.getValue() == null && Dump.getValue() == null) { + if (Log.getValue() == null && Meter.getValue() == null && Time.getValue() == null && Dump.getValue() == null && Verify.getValue() == null) { if (MethodFilter.getValue() != null) { - TTY.println("WARNING: Ignoring MethodFilter option since Log, Meter, Time and Dump options are all null"); + TTY.println("WARNING: Ignoring MethodFilter option since Log, Meter, Time, Dump and Verify options are all null"); } } diff -r 4f185700f4b7 -r af9f3a5f091b graal/com.oracle.graal.printer/src/com/oracle/graal/printer/DebugEnvironment.java --- a/graal/com.oracle.graal.printer/src/com/oracle/graal/printer/DebugEnvironment.java Thu Jun 19 00:45:04 2014 +0200 +++ b/graal/com.oracle.graal.printer/src/com/oracle/graal/printer/DebugEnvironment.java Thu Jun 19 11:24:16 2014 +0200 @@ -34,6 +34,13 @@ public class DebugEnvironment { + @SuppressWarnings("all") + private static boolean assertionsEnabled() { + boolean assertionsEnabled = false; + assert assertionsEnabled = true; + return assertionsEnabled; + } + public static GraalDebugConfig initialize(PrintStream log) { // Ensure Graal runtime is initialized prior to Debug being initialized as the former @@ -55,7 +62,13 @@ if (DecompileAfterPhase.getValue() != null) { dumpHandlers.add(new DecompilerDebugDumpHandler()); } - GraalDebugConfig debugConfig = new GraalDebugConfig(Log.getValue(), Meter.getValue(), TrackMemUse.getValue(), Time.getValue(), Dump.getValue(), MethodFilter.getValue(), log, dumpHandlers); + List verifyHandlers = new ArrayList<>(); + String verifyFilter = Verify.getValue(); + if (verifyFilter == null && assertionsEnabled()) { + verifyFilter = ""; + } + GraalDebugConfig debugConfig = new GraalDebugConfig(Log.getValue(), Meter.getValue(), TrackMemUse.getValue(), Time.getValue(), Dump.getValue(), verifyFilter, MethodFilter.getValue(), log, + dumpHandlers, verifyHandlers); Debug.setConfig(debugConfig); return debugConfig; }