Mercurial > hg > truffle
changeset 7318:323ece2b012b
Refactor debug environment creation.
author | Thomas Wuerthinger <thomas.wuerthinger@oracle.com> |
---|---|
date | Wed, 09 Jan 2013 23:18:18 +0100 |
parents | 40be0ff5a3ce |
children | 1c77cca1ee76 |
files | graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/GraalCompilerTest.java graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/DebugFilter.java graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/GraalDebugConfig.java graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/MethodFilter.java graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/CompilerThread.java graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/bridge/VMToCompilerImpl.java graal/com.oracle.graal.phases/src/com/oracle/graal/phases/GraalOptions.java graal/com.oracle.graal.printer/src/com/oracle/graal/printer/DebugEnvironment.java mx/projects |
diffstat | 9 files changed, 557 insertions(+), 10 deletions(-) [+] |
line wrap: on
line diff
--- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/GraalCompilerTest.java Wed Jan 09 21:41:37 2013 +0100 +++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/GraalCompilerTest.java Wed Jan 09 23:18:18 2013 +0100 @@ -42,6 +42,7 @@ import com.oracle.graal.phases.*; import com.oracle.graal.phases.PhasePlan.PhasePosition; import com.oracle.graal.phases.schedule.*; +import com.oracle.graal.printer.*; /** * Base class for Graal compiler unit tests. @@ -68,7 +69,9 @@ protected final GraalCompiler graalCompiler; public GraalCompilerTest() { - Debug.enable(); + GraalOptions.Dump = ""; + DebugEnvironment.initialize(System.out); + System.out.println("initialized debug environment " + GraalOptions.Dump); this.runtime = Graal.getRequiredCapability(GraalCodeCacheProvider.class); this.graalCompiler = Graal.getRequiredCapability(GraalCompiler.class); }
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/DebugFilter.java Wed Jan 09 23:18:18 2013 +0100 @@ -0,0 +1,159 @@ +/* + * 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.compiler; + +import java.util.*; +import java.util.regex.*; + +import com.oracle.graal.debug.*; +import com.oracle.graal.debug.internal.*; +import com.oracle.graal.phases.*; + +/** + * 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(MethodFilter.createGlobString(filter)); + } else { + this.pattern = Pattern.compile(".*" + MethodFilter.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(); + } + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/GraalDebugConfig.java Wed Jan 09 23:18:18 2013 +0100 @@ -0,0 +1,186 @@ +/* + * 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.compiler; + +import java.io.*; +import java.util.*; + +import com.oracle.graal.api.code.*; +import com.oracle.graal.api.meta.*; +import com.oracle.graal.debug.*; +import com.oracle.graal.graph.*; +import com.oracle.graal.nodes.util.*; +import com.oracle.graal.phases.*; + +public class GraalDebugConfig implements DebugConfig { + + 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; + private final PrintStream output; + private final Set<Object> extraFilters = new HashSet<>(); + + public GraalDebugConfig(String logFilter, String meterFilter, String timerFilter, String dumpFilter, String methodFilter, PrintStream output, List<DebugDumpHandler> dumpHandlers) { + 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 { + 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]); + } + } + + // 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(Thread.currentThread().getName() + ": " + toString()); + } + this.dumpHandlers = dumpHandlers; + this.output = output; + } + + public boolean isLogEnabled() { + return isEnabled(logFilter); + } + + public boolean isMeterEnabled() { + return isEnabled(meterFilter); + } + + public boolean isDumpEnabled() { + return isEnabled(dumpFilter); + } + + public boolean isTimeEnabled() { + return isEnabled(timerFilter); + } + + public PrintStream output() { + return output; + } + + private boolean isEnabled(DebugFilter filter) { + return checkDebugFilter(Debug.currentScope(), filter) && checkMethodFilter(); + } + + private static boolean checkDebugFilter(String currentScope, DebugFilter filter) { + return filter != null && filter.matches(currentScope); + } + + private boolean checkMethodFilter() { + if (methodFilter == null && extraFilters.isEmpty()) { + return true; + } else { + for (Object o : Debug.context()) { + if (extraFilters.contains(o)) { + return true; + } else if (methodFilter != null) { + if (o instanceof JavaMethod) { + for (MethodFilter filter : methodFilter) { + if (filter.matches((JavaMethod) o)) { + return true; + } + } + } + } + } + return false; + } + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder(); + sb.append("Debug config:"); + add(sb, "Log", logFilter); + add(sb, "Meter", meterFilter); + add(sb, "Time", timerFilter); + add(sb, "Dump", dumpFilter); + add(sb, "MethodFilter", methodFilter); + return sb.toString(); + } + + private static void add(StringBuilder sb, String name, Object filter) { + if (filter != null) { + sb.append(' '); + sb.append(name); + sb.append('='); + if (filter instanceof Object[]) { + sb.append(Arrays.toString((Object[]) filter)); + } else { + sb.append(String.valueOf(filter)); + } + } + } + + @Override + public RuntimeException interceptException(Throwable e) { + if (e instanceof BailoutException) { + return null; + } + Debug.setConfig(Debug.fixedConfig(true, true, false, false, dumpHandlers, output)); + Debug.log(String.format("Exception occurred in scope: %s", Debug.currentScope())); + for (Object o : Debug.context()) { + if (o instanceof Graph) { + Debug.log("Context obj %s", o); + if (GraalOptions.DumpOnError) { + Debug.dump(o, "Exception graph"); + } else { + Debug.log("Use -G:+DumpOnError to enable dumping of graphs on this error"); + } + } else if (o instanceof Node) { + String location = GraphUtil.approxSourceLocation((Node) o); + if (location != null) { + Debug.log("Context obj %s (approx. location: %s)", o, location); + } else { + Debug.log("Context obj %s", o); + } + } else { + Debug.log("Context obj %s", o); + } + } + return null; + } + + @Override + public Collection<DebugDumpHandler> dumpHandlers() { + return dumpHandlers; + } + + @Override + public void addToContext(Object o) { + extraFilters.add(o); + } + + @Override + public void removeFromContext(Object o) { + extraFilters.remove(o); + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/MethodFilter.java Wed Jan 09 23:18:18 2013 +0100 @@ -0,0 +1,151 @@ +/* + * 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.compiler; + +import java.util.*; +import java.util.regex.*; + +import com.oracle.graal.api.meta.*; + +/** + * 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>arraycopy(Object;;;;)</pre> + * Matches all methods named "arraycopy", with the first parameter of type "Object", and four more parameters of any type. + * 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(";", -1); + 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)); + } + } + + static String createGlobString(String pattern) { + return Pattern.quote(pattern).replace("?", "\\E.\\Q").replace("*", "\\E.*\\Q"); + } + + private static Pattern createClassGlobPattern(String pattern) { + if (pattern.length() == 0) { + return null; + } else if (pattern.contains(".")) { + return Pattern.compile(createGlobString(pattern)); + } else { + return Pattern.compile("([^\\.]*\\.)*" + createGlobString(pattern)); + } + } + + public boolean matches(JavaMethod o) { + // check method name first, since MetaUtil.toJavaName is expensive + if (methodName != null && !methodName.matcher(o.getName()).matches()) { + return false; + } + if (clazz != null && !clazz.matcher(MetaUtil.toJavaName(o.getDeclaringClass())).matches()) { + return false; + } + if (signature != null) { + Signature sig = o.getSignature(); + if (sig.getParameterCount(false) != signature.length) { + return false; + } + for (int i = 0; i < signature.length; i++) { + JavaType type = sig.getParameterType(i, null); + String javaName = MetaUtil.toJavaName(type); + if (signature[i] != null && !signature[i].matcher(javaName).matches()) { + return false; + } + } + } + return true; + } + + @Override + public String toString() { + StringBuilder buf = new StringBuilder("MethodFilter["); + String sep = ""; + if (clazz != null) { + buf.append(sep).append("clazz=").append(clazz); + sep = ", "; + } + if (methodName != null) { + buf.append(sep).append("methodName=").append(methodName); + sep = ", "; + } + if (signature != null) { + buf.append(sep).append("signature=").append(Arrays.toString(signature)); + sep = ", "; + } + return buf.append("]").toString(); + } +}
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/CompilerThread.java Wed Jan 09 21:41:37 2013 +0100 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/CompilerThread.java Wed Jan 09 23:18:18 2013 +0100 @@ -25,8 +25,10 @@ import java.io.*; import java.util.concurrent.*; +import com.oracle.graal.compiler.*; import com.oracle.graal.debug.*; import com.oracle.graal.phases.*; +import com.oracle.graal.printer.*; public final class CompilerThread extends Thread { @@ -56,12 +58,10 @@ @Override public void run() { - HotSpotDebugConfig hotspotDebugConfig = null; + GraalDebugConfig hotspotDebugConfig = null; if (GraalOptions.Debug) { - Debug.enable(); PrintStream log = HotSpotGraalRuntime.getInstance().getVMToCompiler().log(); - hotspotDebugConfig = new HotSpotDebugConfig(GraalOptions.Log, GraalOptions.Meter, GraalOptions.Time, GraalOptions.Dump, GraalOptions.MethodFilter, log); - Debug.setConfig(hotspotDebugConfig); + DebugEnvironment.initialize(log); } try { super.run();
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/bridge/VMToCompilerImpl.java Wed Jan 09 21:41:37 2013 +0100 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/bridge/VMToCompilerImpl.java Wed Jan 09 23:18:18 2013 +0100 @@ -44,6 +44,7 @@ import com.oracle.graal.nodes.*; import com.oracle.graal.phases.*; import com.oracle.graal.phases.PhasePlan.PhasePosition; +import com.oracle.graal.printer.*; import com.oracle.graal.snippets.*; /** @@ -123,10 +124,8 @@ } } - if (GraalOptions.Debug) { - Debug.enable(); - HotSpotDebugConfig hotspotDebugConfig = new HotSpotDebugConfig(GraalOptions.Log, GraalOptions.Meter, GraalOptions.Time, GraalOptions.Dump, GraalOptions.MethodFilter, log); - Debug.setConfig(hotspotDebugConfig); + if (GraalOptions.Debug && GraalOptions.DebugSnippets) { + DebugEnvironment.initialize(log); } // Install intrinsics. GraalCompiler compiler = graalRuntime.getCompiler();
--- a/graal/com.oracle.graal.phases/src/com/oracle/graal/phases/GraalOptions.java Wed Jan 09 21:41:37 2013 +0100 +++ b/graal/com.oracle.graal.phases/src/com/oracle/graal/phases/GraalOptions.java Wed Jan 09 23:18:18 2013 +0100 @@ -121,6 +121,7 @@ // Debug settings: public static boolean Debug = true; + public static boolean DebugSnippets = false; public static boolean PerThreadDebugValues = ____; public static boolean SummarizeDebugValues = ____; public static boolean SummarizePerPhase = ____;
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.printer/src/com/oracle/graal/printer/DebugEnvironment.java Wed Jan 09 23:18:18 2013 +0100 @@ -0,0 +1,48 @@ +/* + * Copyright (c) 2013, 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.printer; + +import java.io.*; +import java.util.*; + +import com.oracle.graal.compiler.*; +import com.oracle.graal.debug.*; +import com.oracle.graal.phases.*; + + +public class DebugEnvironment { + + public static void initialize(PrintStream log) { + Debug.enable(); + List<DebugDumpHandler> dumpHandlers = new ArrayList<>(); + dumpHandlers.add(new GraphPrinterDumpHandler()); + if (GraalOptions.PrintCFG) { + if (GraalOptions.PrintBinaryGraphs) { + TTY.println("CFG dumping slows down PrintBinaryGraphs: use -G:-PrintCFG to disable it"); + } + dumpHandlers.add(new CFGPrinterObserver()); + } + GraalDebugConfig hotspotDebugConfig = new GraalDebugConfig(GraalOptions.Log, GraalOptions.Meter, GraalOptions.Time, GraalOptions.Dump, GraalOptions.MethodFilter, log, dumpHandlers); + Debug.setConfig(hotspotDebugConfig); + } +}
--- a/mx/projects Wed Jan 09 21:41:37 2013 +0100 +++ b/mx/projects Wed Jan 09 23:18:18 2013 +0100 @@ -237,7 +237,7 @@ # graal.compiler.test project@com.oracle.graal.compiler.test@subDir=graal project@com.oracle.graal.compiler.test@sourceDirs=src -project@com.oracle.graal.compiler.test@dependencies=JUNIT,com.oracle.graal.compiler,com.oracle.graal.java,com.oracle.graal.api.runtime +project@com.oracle.graal.compiler.test@dependencies=JUNIT,com.oracle.graal.compiler,com.oracle.graal.printer,com.oracle.graal.java,com.oracle.graal.api.runtime project@com.oracle.graal.compiler.test@checkstyle=com.oracle.graal.graph project@com.oracle.graal.compiler.test@javaCompliance=1.7