# HG changeset patch # User Lukas Stadler # Date 1331892234 -3600 # Node ID e2da6471a9a122e661a3096ed727f25b01f37c59 # Parent 0c968a6e0ca0ed53d3a4f2ad0b7126b490edb8c4 better MethodFilter (allows filtering by class, method name and parameter types) diff -r 0c968a6e0ca0 -r e2da6471a9a1 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotDebugConfig.java --- 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 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; } } diff -r 0c968a6e0ca0 -r e2da6471a9a1 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/MethodFilter.java --- /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: + * + *
+ * SourcePattern = [ Class "." ] method [ "(" [ Parameter { ";" Parameter } ] ")" ] .
+ * Parameter = Class | "int" | "long" | "float" | "double" | "short" | "char" | "boolean" .
+ * Class = { package "." } class .
+ * 
+ * + * + * Glob pattern matching (*, ?) is allowed in all parts of the source pattern. Examples for valid filters are: + * + * + * + */ +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; + } + +}