changeset 5280:71e00437d0a8

enhanced debug filter to be a comma-separated list of glob or substring terms
author Doug Simon <doug.simon@oracle.com>
date Tue, 24 Apr 2012 16:04:14 +0200
parents 96e52f0c0785
children d30314b667eb
files graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/DebugFilter.java graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotDebugConfig.java graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/MethodFilter.java
diffstat 3 files changed, 190 insertions(+), 25 deletions(-) [+]
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/DebugFilter.java	Tue Apr 24 16:04:14 2012 +0200
@@ -0,0 +1,161 @@
+/*
+ * 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.hotspot;
+
+import static com.oracle.graal.hotspot.MethodFilter.*;
+
+import java.util.*;
+import java.util.regex.*;
+
+import com.oracle.graal.compiler.*;
+import com.oracle.graal.debug.*;
+import com.oracle.graal.debug.internal.*;
+
+/**
+ * Implements the filter specified by the {@link GraalOptions#Dump},
+ * {@link GraalOptions#Log}, {@link GraalOptions#Meter} and {@link GraalOptions#Time}
+ * options.
+ * <p>
+ * These options enable the associated debug facility if their filter
+ * matches the {@linkplain DebugScope#getQualifiedName() name} of the
+ * {@linkplain Debug#currentScope() current scope}.
+ * <p>
+ * 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).
+ * <p>
+ * Examples of filters include:
+ * <p>
+ * <ul>
+ * <li><pre>""</pre>
+ * Matches any scope.</li>
+ * <li><pre>"*"</pre>
+ * Matches any scope.</li>
+ * <li><pre>"CodeGen,CodeInstall"</pre>
+ * Matches a scope whose name contains "CodeGen" or "CodeInstall".</li>
+ * <li><pre>"Code*"</pre>
+ * Matches a scope whose name starts with "Code".</li>
+ * <li><pre>"Code,~Dead"</pre>
+ * Matches a scope whose name contains "Code" but does not contain "Dead".</li>
+ * </ul>
+ */
+class DebugFilter {
+
+    public static DebugFilter parse(String spec) {
+        if (spec == null) {
+            return null;
+        }
+        return new DebugFilter(spec.split(","));
+    }
+
+    final Term[] positive;
+    final Term[] negative;
+
+    DebugFilter(String[] terms) {
+        List<Term> pos = new ArrayList<>(terms.length);
+        List<Term> 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));
+            }
+        }
+        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.
+     */
+    public boolean matches(String input) {
+        boolean match = true;
+        if (positive != null) {
+            match = false;
+            for (Term t : positive) {
+                if (t.matches(input)) {
+                    match = true;
+                    break;
+                }
+            }
+        }
+        if (match && negative != null) {
+            for (Term t : negative) {
+                if (t.matches(input)) {
+                    match = false;
+                    break;
+                }
+            }
+        }
+//        if (match) {
+//            System.out.println(this + " matches " + input);
+//        }
+        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 = ", ";
+        }
+        if (negative != null) {
+            buf.append(sep).append("neg=").append(Arrays.toString(negative));
+            sep = ", ";
+        }
+        return buf.append("]").toString();
+    }
+
+    static class Term {
+
+        final Pattern pattern;
+
+        public Term(String filter) {
+            if (filter.isEmpty()) {
+                this.pattern = null;
+            } else if (filter.contains("*") || filter.contains("?")) {
+                this.pattern = Pattern.compile(createGlobString(filter));
+            } else {
+                this.pattern = Pattern.compile(".*" + createGlobString(filter) + ".*");
+            }
+        }
+
+        /**
+         * Determines if a given input is matched by this filter.
+         */
+        public boolean matches(String input) {
+            return pattern == null || pattern.matcher(input).matches();
+        }
+
+        @Override
+        public String toString() {
+            return pattern == null ? ".*" : pattern.toString();
+        }
+    }
+}
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotDebugConfig.java	Tue Apr 24 13:13:59 2012 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotDebugConfig.java	Tue Apr 24 16:04:14 2012 +0200
@@ -23,7 +23,6 @@
 package com.oracle.graal.hotspot;
 
 import java.util.*;
-import java.util.regex.*;
 
 import com.oracle.graal.compiler.*;
 import com.oracle.graal.debug.*;
@@ -31,21 +30,24 @@
 import com.oracle.graal.printer.*;
 import com.oracle.max.cri.ci.*;
 import com.oracle.max.cri.ri.*;
+import com.oracle.max.criutils.*;
 
 public class HotSpotDebugConfig implements DebugConfig {
 
-    private final String logFilter;
-    private final String meterFilter;
-    private final String timerFilter;
-    private final String dumpFilter;
+    private final DebugFilter logFilter;
+    private final DebugFilter meterFilter;
+    private final DebugFilter timerFilter;
+    private final DebugFilter dumpFilter;
     private final MethodFilter[] methodFilter;
     private final List<DebugDumpHandler> dumpHandlers = new ArrayList<>();
 
+
+
     public HotSpotDebugConfig(String logFilter, String meterFilter, String timerFilter, String dumpFilter, String methodFilter) {
-        this.logFilter = logFilter;
-        this.meterFilter = meterFilter;
-        this.timerFilter = timerFilter;
-        this.dumpFilter = dumpFilter;
+        this.logFilter = DebugFilter.parse(logFilter);
+        this.meterFilter = DebugFilter.parse(meterFilter);
+        this.timerFilter = DebugFilter.parse(timerFilter);
+        this.dumpFilter = DebugFilter.parse(dumpFilter);
         if (methodFilter == null || methodFilter.isEmpty()) {
             this.methodFilter = null;
         } else {
@@ -53,9 +55,14 @@
             this.methodFilter = new MethodFilter[filters.length];
             for (int i = 0; i < filters.length; i++) {
                 this.methodFilter[i] = new MethodFilter(filters[i]);
-                // com.oracle.max.criutils.TTY.println(this.methodFilter[i].toString());
             }
         }
+
+        // Report the filters that have been configured so the user can verify it's what they expect
+        if (logFilter != null || meterFilter != null || timerFilter != null || dumpFilter != null || methodFilter != null) {
+            TTY.println(this.toString());
+        }
+
         if (GraalOptions.PrintIdealGraphFile) {
             dumpHandlers.add(new IdealGraphPrinterDumpHandler());
         } else {
@@ -80,19 +87,12 @@
         return isEnabled(timerFilter);
     }
 
-    private boolean isEnabled(String filter) {
-        return filter != null && checkContains(Debug.currentScope(), filter) && checkMethodFilter();
+    private boolean isEnabled(DebugFilter filter) {
+        return checkDebugFilter(Debug.currentScope(), filter) && checkMethodFilter();
     }
 
-    private static boolean checkContains(String currentScope, String filter) {
-        if (filter.contains("*")) {
-            /*filter = filter.replace("*", ".*");
-            filter = filter.replace("[", "\\[");
-            filter = filter.replace("]", "\\]");
-            filter = filter.replace(":", "\\:");*/
-            return Pattern.matches(filter, currentScope);
-        }
-        return currentScope.contains(filter);
+    private static boolean checkDebugFilter(String currentScope, DebugFilter filter) {
+        return filter != null && filter.matches(currentScope);
     }
 
     private boolean checkMethodFilter() {
@@ -120,16 +120,20 @@
         add(sb, "Meter", meterFilter);
         add(sb, "Time", timerFilter);
         add(sb, "Dump", dumpFilter);
-        add(sb, "MethodFilter", Arrays.toString(methodFilter));
+        add(sb, "MethodFilter", methodFilter);
         return sb.toString();
     }
 
-    private static void add(StringBuilder sb, String name, String filter) {
+    private static void add(StringBuilder sb, String name, Object filter) {
         if (filter != null) {
             sb.append(' ');
             sb.append(name);
             sb.append('=');
-            sb.append(filter);
+            if (filter instanceof Object[]) {
+                sb.append(Arrays.toString((Object[]) filter));
+            } else {
+                sb.append(String.valueOf(filter));
+            }
         }
     }
 
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/MethodFilter.java	Tue Apr 24 13:13:59 2012 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/MethodFilter.java	Tue Apr 24 16:04:14 2012 +0200
@@ -93,7 +93,7 @@
         }
     }
 
-    private static String createGlobString(String pattern) {
+    static String createGlobString(String pattern) {
         return pattern.replace("\\", "\\\\").replace(".", "\\.").replace('?', '.').replace("*", ".*").replace("[", "\\[").replace("]", "\\]");
     }