Mercurial > hg > graal-jvmci-8
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; + } + +}