changeset 5128:e2da6471a9a1

better MethodFilter (allows filtering by class, method name and parameter types)
author Lukas Stadler <lukas.stadler@jku.at>
date Fri, 16 Mar 2012 11:03:54 +0100
parents 0c968a6e0ca0
children 51111665eda6
files 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 2 files changed, 140 insertions(+), 5 deletions(-) [+]
line wrap: on
line diff
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotDebugConfig.java	Wed Mar 14 18:00:59 2012 +0100
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotDebugConfig.java	Fri Mar 16 11:03:54 2012 +0100
@@ -39,7 +39,7 @@
     private final String meterFilter;
     private final String timerFilter;
     private final String dumpFilter;
-    private final String[] methodFilter;
+    private final MethodFilter[] methodFilter;
     private final List<DebugDumpHandler> dumpHandlers = new ArrayList<>();
 
     public HotSpotDebugConfig(String logFilter, String meterFilter, String timerFilter, String dumpFilter, String methodFilter) {
@@ -47,7 +47,15 @@
         this.meterFilter = meterFilter;
         this.timerFilter = timerFilter;
         this.dumpFilter = dumpFilter;
-        this.methodFilter = methodFilter == null ? null : methodFilter.split(",");
+        if (methodFilter == null || methodFilter.isEmpty()) {
+            this.methodFilter = null;
+        } else {
+            String[] filters = methodFilter.split(",");
+            this.methodFilter = new MethodFilter[filters.length];
+            for (int i = 0; i < filters.length; i++) {
+                this.methodFilter[i] = new MethodFilter(filters[i]);
+            }
+        }
         if (GraalOptions.PrintIdealGraphFile) {
             dumpHandlers.add(new IdealGraphPrinterDumpHandler());
         } else {
@@ -93,9 +101,8 @@
         } else {
             for (Object o : Debug.context()) {
                 if (o instanceof RiMethod) {
-                    String methodName = CiUtil.format("%H.%n", (RiMethod) o);
-                    for (String filter : methodFilter) {
-                        if (methodName.contains(filter)) {
+                    for (MethodFilter filter : methodFilter) {
+                        if (filter.matches((RiMethod) o)) {
                             return true;
                         }
                     }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/MethodFilter.java	Fri Mar 16 11:03:54 2012 +0100
@@ -0,0 +1,128 @@
+/*
+ * 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 java.util.regex.*;
+
+import com.oracle.max.cri.ci.*;
+import com.oracle.max.cri.ri.*;
+
+/**
+ * This class implements a method filter that can filter based on class name, method name and parameters.
+ * The syntax for the source pattern that is passed to the constructor is as follows:
+ *
+ * <pre>
+ * SourcePattern = [ Class "." ] method [ "(" [ Parameter { ";" Parameter } ] ")" ] .
+ * Parameter = Class | "int" | "long" | "float" | "double" | "short" | "char" | "boolean" .
+ * Class = { package "." } class .
+ * </pre>
+ *
+ *
+ * Glob pattern matching (*, ?) is allowed in all parts of the source pattern. Examples for valid filters are:
+ *
+ * <ul>
+ * <li><pre>visit(Argument;BlockScope)</pre>
+ * Matches all methods named "visit", with the first parameter of type "Argument", and the second parameter of type "BlockScope".
+ * The packages of the parameter types are irrelevant.</li>
+ * <li><pre>com.oracle.graal.compiler.graph.PostOrderNodeIterator.*</pre>
+ * Matches all methods in the class "com.oracle.graal.compiler.graph.PostOrderNodeIterator".</li>
+ * <li><pre>*</pre>
+ * Matches all methods in all classes</li>
+ * <li><pre>com.oracle.graal.compiler.graph.*.visit</pre>
+ * Matches all methods named "visit" in classes in the package "com.oracle.graal.compiler.graph".</pre>
+ * </ul>
+ *
+ */
+public class MethodFilter {
+
+    private final Pattern clazz;
+    private final Pattern methodName;
+    private final Pattern[] signature;
+
+    public MethodFilter(String sourcePattern) {
+        String pattern = sourcePattern.trim();
+
+        // extract parameter part
+        int pos = pattern.indexOf('(');
+        if (pos != -1) {
+            if (pattern.charAt(pattern.length() - 1) != ')') {
+                throw new IllegalArgumentException("missing ')' at end of method filter pattern: " + pattern);
+            }
+            String[] signatureClasses = pattern.substring(pos + 1, pattern.length() - 1).split(";");
+            signature = new Pattern[signatureClasses.length];
+            for (int i = 0; i < signatureClasses.length; i++) {
+                signature[i] = createClassGlobPattern(signatureClasses[i].trim());
+            }
+            pattern = pattern.substring(0, pos);
+        } else {
+            signature = null;
+        }
+
+        // If there is at least one "." then everything before the last "." is the class name.
+        // Otherwise, the pattern contains only the method name.
+        pos = pattern.lastIndexOf('.');
+        if (pos != -1) {
+            clazz = createClassGlobPattern(pattern.substring(0, pos));
+            methodName = Pattern.compile(createGlobString(pattern.substring(pos + 1)));
+        } else {
+            clazz = null;
+            methodName = Pattern.compile(createGlobString(pattern));
+        }
+    }
+
+    private static String createGlobString(String pattern) {
+        return pattern.replace("\\", "\\\\").replace(".", "\\.").replace('?', '.').replace("*", ".*").replace("[", "\\[").replace("]", "\\]");
+    }
+
+    private static Pattern createClassGlobPattern(String pattern) {
+        if (pattern.contains(".")) {
+            return Pattern.compile(createGlobString(pattern));
+        } else {
+            return Pattern.compile("([^\\.]\\.])*" + createGlobString(pattern));
+        }
+    }
+
+    public boolean matches(RiMethod o) {
+        // check method name first, since CiUtil.toJavaName is expensive
+        if (methodName != null && !methodName.matcher(o.name()).matches()) {
+            return false;
+        }
+        if (clazz != null && !clazz.matcher(CiUtil.toJavaName(o.holder())).matches()) {
+            return false;
+        }
+        if (signature != null) {
+            RiSignature sig = o.signature();
+            if (sig.argumentCount(false) != signature.length) {
+                return false;
+            }
+            for (int i = 0; i < signature.length; i++) {
+                RiType type = sig.argumentTypeAt(i, null);
+                if (!signature[i].matcher(CiUtil.toJavaName(type)).matches()) {
+                    return false;
+                }
+            }
+        }
+        return true;
+    }
+
+}