comparison graal/com.oracle.jvmci.debug/src/com/oracle/jvmci/debug/DebugFilter.java @ 21780:3d15183f3c93

Introduce Compiler interface in jvmci. Use it from jvmci.hotspot.CompilationTask
author Gilles Duboscq <gilles.m.duboscq@oracle.com>
date Wed, 03 Jun 2015 15:47:54 +0200
parents graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/DebugFilter.java@b1530a6cce8c
children
comparison
equal deleted inserted replaced
21779:20ace3139510 21780:3d15183f3c93
1 /*
2 * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation.
8 *
9 * This code is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12 * version 2 for more details (a copy is included in the LICENSE file that
13 * accompanied this code).
14 *
15 * You should have received a copy of the GNU General Public License version
16 * 2 along with this work; if not, write to the Free Software Foundation,
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18 *
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20 * or visit www.oracle.com if you need additional information or have any
21 * questions.
22 */
23 package com.oracle.jvmci.debug;
24
25 import java.util.*;
26 import java.util.regex.*;
27
28 import com.oracle.jvmci.debug.internal.*;
29
30 /**
31 * Implements the filter specified by the {@link JVMCIDebugConfig#Dump},
32 * {@link JVMCIDebugConfig#Log}, {@link JVMCIDebugConfig#Meter} and {@link JVMCIDebugConfig#Time}
33 * options.
34 * <p>
35 * These options enable the associated debug facility if their filter matches the
36 * {@linkplain DebugScope#getQualifiedName() name} of the {@linkplain Debug#currentScope() current
37 * scope}. For the {@link JVMCIDebugConfig#Dump} and {@link JVMCIDebugConfig#Log} options, the log
38 * or dump level is set. The {@link JVMCIDebugConfig#Meter} and {@link JVMCIDebugConfig#Time}
39 * options don't have a level, for them {@code level = 0} means disabled and a {@code level > 0}
40 * means enabled.
41 * <p>
42 * A filter is a list of comma-separated terms of the form {@code <pattern>[:<level>]}.
43 * {@code <pattern>} is interpreted as a glob pattern if it contains a "*" or "?" character.
44 * Otherwise, it is interpreted as a substring. If {@code <pattern>} is empty, it matches every
45 * scope. If {@code :<level>} is omitted, it defaults to {@link Debug#DEFAULT_LOG_LEVEL}. The term
46 * {@code ~<pattern>} is a shorthand for {@code <pattern>:0} to disable a debug facility for a
47 * pattern.
48 * <p>
49 * The resulting log level of a scope is determined by the <em>last</em> matching term. If no term
50 * matches, the log level is 0 (disabled). A filter with no terms matches every scope with a log
51 * level of {@link Debug#DEFAULT_LOG_LEVEL}.
52 *
53 * <h2>Examples of filters</h2>
54 *
55 * <ul>
56 * <li>(empty string)<br>
57 * Matches any scope with log level {@link Debug#DEFAULT_LOG_LEVEL}.
58 *
59 * <li> {@code :1}<br>
60 * Matches any scope with log level 1.
61 *
62 * <li> {@code *}<br>
63 * Matches any scope with log level {@link Debug#DEFAULT_LOG_LEVEL}.
64 *
65 * <li> {@code CodeGen,CodeInstall}<br>
66 * Matches scopes containing "CodeGen" or "CodeInstall", both with log level
67 * {@link Debug#DEFAULT_LOG_LEVEL}.
68 *
69 * <li> {@code CodeGen:2,CodeInstall:1}<br>
70 * Matches scopes containing "CodeGen" with log level 2, or "CodeInstall" with log level 1.
71 *
72 * <li> {@code :1,Dead:2}<br>
73 * Matches scopes containing "Dead" with log level 2, and all other scopes with log level 1.
74 *
75 * <li> {@code :1,Dead:0}<br>
76 * Matches all scopes with log level 1, except those containing "Dead".
77 *
78 * <li> {@code Code*}<br>
79 * Matches scopes starting with "Code" with log level {@link Debug#DEFAULT_LOG_LEVEL}.
80 *
81 * <li> {@code Code,~Dead}<br>
82 * Matches scopes containing "Code" but not "Dead", with log level {@link Debug#DEFAULT_LOG_LEVEL}.
83 * </ul>
84 */
85 final class DebugFilter {
86
87 public static DebugFilter parse(String spec) {
88 if (spec == null) {
89 return null;
90 }
91 return new DebugFilter(spec.split(","));
92 }
93
94 private final Term[] terms;
95
96 private DebugFilter(String[] terms) {
97 if (terms.length == 0) {
98 this.terms = null;
99 } else {
100 this.terms = new Term[terms.length];
101 for (int i = 0; i < terms.length; i++) {
102 String t = terms[i];
103 int idx = t.indexOf(':');
104
105 String pattern;
106 int level;
107 if (idx < 0) {
108 if (t.startsWith("~")) {
109 pattern = t.substring(1);
110 level = 0;
111 } else {
112 pattern = t;
113 level = Debug.DEFAULT_LOG_LEVEL;
114 }
115 } else {
116 pattern = t.substring(0, idx);
117 if (idx + 1 < t.length()) {
118 level = Integer.parseInt(t.substring(idx + 1));
119 } else {
120 level = Debug.DEFAULT_LOG_LEVEL;
121 }
122 }
123
124 this.terms[i] = new Term(pattern, level);
125 }
126 }
127 }
128
129 /**
130 * Check whether a given input is matched by this filter, and determine the log level.
131 */
132 public int matchLevel(String input) {
133 if (terms == null) {
134 return Debug.DEFAULT_LOG_LEVEL;
135 } else {
136 int level = 0;
137 for (Term t : terms) {
138 if (t.matches(input)) {
139 level = t.level;
140 }
141 }
142 return level;
143 }
144 }
145
146 @Override
147 public String toString() {
148 StringBuilder buf = new StringBuilder("DebugFilter");
149 if (terms != null) {
150 buf.append(Arrays.toString(terms));
151 } else {
152 buf.append("[]");
153 }
154 return buf.toString();
155 }
156
157 private static class Term {
158
159 private final Pattern pattern;
160 public final int level;
161
162 public Term(String filter, int level) {
163 this.level = level;
164 if (filter.isEmpty()) {
165 this.pattern = null;
166 } else if (filter.contains("*") || filter.contains("?")) {
167 this.pattern = Pattern.compile(MethodFilter.createGlobString(filter));
168 } else {
169 this.pattern = Pattern.compile(".*" + MethodFilter.createGlobString(filter) + ".*");
170 }
171 }
172
173 /**
174 * Determines if a given input is matched by this filter.
175 */
176 public boolean matches(String input) {
177 return pattern == null || pattern.matcher(input).matches();
178 }
179
180 @Override
181 public String toString() {
182 return (pattern == null ? ".*" : pattern.toString()) + ":" + level;
183 }
184 }
185 }