# HG changeset patch # User Gilles Duboscq # Date 1433339274 -7200 # Node ID 3d15183f3c939546bd5967c053f12f80f8f09801 # Parent 20ace3139510adc697af187ff25996050af44578 Introduce Compiler interface in jvmci. Use it from jvmci.hotspot.CompilationTask diff -r 20ace3139510 -r 3d15183f3c93 graal/com.oracle.graal.compiler.common/src/com/oracle/graal/compiler/common/GraalOptions.java --- a/graal/com.oracle.graal.compiler.common/src/com/oracle/graal/compiler/common/GraalOptions.java Mon Jun 08 13:20:02 2015 +0200 +++ b/graal/com.oracle.graal.compiler.common/src/com/oracle/graal/compiler/common/GraalOptions.java Wed Jun 03 15:47:54 2015 +0200 @@ -128,9 +128,6 @@ @Option(help = "", type = OptionType.Debug) public static final OptionValue VerifyPhases = new OptionValue<>(false); - @Option(help = "", type = OptionType.Debug) - public static final OptionValue PrintFilter = new OptionValue<>(null); - // Debug settings: @Option(help = "", type = OptionType.Debug) public static final OptionValue BootstrapReplacements = new OptionValue<>(false); @@ -173,33 +170,16 @@ public static final OptionValue PrintIdealGraphSchedule = new OptionValue<>(false); // Other printing settings - @Option(help = "", type = OptionType.Debug) - public static final OptionValue PrintCompilation = new OptionValue<>(false); - - @Option(help = "", type = OptionType.Debug) - public static final OptionValue PrintAfterCompilation = new OptionValue<>(false); - @Option(help = "Print profiling information when parsing a method's bytecode", type = OptionType.Debug) public static final OptionValue PrintProfilingInformation = new OptionValue<>(false); @Option(help = "", type = OptionType.Debug) public static final OptionValue PrintCodeBytes = new OptionValue<>(false); - @Option(help = "", type = OptionType.Debug) - public static final OptionValue PrintBailout = new OptionValue<>(false); @Option(help = "", type = OptionType.Debug) public static final StableOptionValue TraceEscapeAnalysis = new StableOptionValue<>(false); - @Option(help = "", type = OptionType.Debug) - public static final OptionValue ExitVMOnBailout = new OptionValue<>(false); - - @Option(help = "", type = OptionType.Debug) - public static final OptionValue ExitVMOnException = new OptionValue<>(true); - - @Option(help = "", type = OptionType.Debug) - public static final OptionValue PrintStackTraceOnException = new OptionValue<>(false); - // HotSpot command line options @Option(help = "Print inlining optimizations", type = OptionType.Debug) public static final OptionValue HotSpotPrintInlining = new OptionValue<>(false); diff -r 20ace3139510 -r 3d15183f3c93 graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/CheckGraalInvariants.java --- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/CheckGraalInvariants.java Mon Jun 08 13:20:02 2015 +0200 +++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/CheckGraalInvariants.java Wed Jun 03 15:47:54 2015 +0200 @@ -33,8 +33,6 @@ import org.junit.*; import com.oracle.graal.api.runtime.*; -import com.oracle.graal.compiler.*; -import com.oracle.graal.compiler.CompilerThreadFactory.DebugConfigAccess; import com.oracle.graal.compiler.common.type.*; import com.oracle.graal.graph.*; import com.oracle.graal.graphbuilderconf.*; @@ -48,11 +46,12 @@ import com.oracle.graal.phases.tiers.*; import com.oracle.graal.phases.util.*; import com.oracle.graal.phases.verify.*; -import com.oracle.graal.printer.*; import com.oracle.graal.runtime.*; import com.oracle.graal.test.*; import com.oracle.jvmci.code.*; import com.oracle.jvmci.code.Register.RegisterCategory; +import com.oracle.jvmci.compiler.*; +import com.oracle.jvmci.compiler.CompilerThreadFactory.DebugConfigAccess; import com.oracle.jvmci.debug.*; import com.oracle.jvmci.meta.*; @@ -125,7 +124,7 @@ String[] filters = property == null ? null : property.split(","); CompilerThreadFactory factory = new CompilerThreadFactory("CheckInvariantsThread", new DebugConfigAccess() { - public GraalDebugConfig getDebugConfig() { + public JVMCIDebugConfig getDebugConfig() { return DebugEnvironment.initialize(System.out); } }); diff -r 20ace3139510 -r 3d15183f3c93 graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/GraalCompilerTest.java --- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/GraalCompilerTest.java Mon Jun 08 13:20:02 2015 +0200 +++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/GraalCompilerTest.java Wed Jun 03 15:47:54 2015 +0200 @@ -23,9 +23,9 @@ package com.oracle.graal.compiler.test; import static com.oracle.graal.compiler.GraalCompiler.*; -import static com.oracle.graal.compiler.common.GraalOptions.*; import static com.oracle.graal.nodes.ConstantNode.*; import static com.oracle.jvmci.code.CodeUtil.*; +import static com.oracle.jvmci.compiler.Compiler.*; import java.lang.reflect.*; import java.util.*; @@ -33,7 +33,7 @@ import java.util.function.*; import org.junit.*; -import org.junit.internal.*; +import org.junit.internal.AssumptionViolatedException; import com.oracle.graal.api.directives.*; import com.oracle.graal.api.replacements.*; @@ -59,7 +59,6 @@ import com.oracle.graal.phases.schedule.SchedulePhase.SchedulingStrategy; import com.oracle.graal.phases.tiers.*; import com.oracle.graal.phases.util.*; -import com.oracle.graal.printer.*; import com.oracle.graal.runtime.*; import com.oracle.graal.test.*; import com.oracle.jvmci.code.*; diff -r 20ace3139510 -r 3d15183f3c93 graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/CompilerThread.java --- a/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/CompilerThread.java Mon Jun 08 13:20:02 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,61 +0,0 @@ -/* - * Copyright (c) 2012, 2014, 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 com.oracle.graal.compiler.CompilerThreadFactory.DebugConfigAccess; -import com.oracle.jvmci.debug.*; - -/** - * A compiler thread is a daemon thread that runs at {@link Thread#MAX_PRIORITY} and executes in the - * context of a thread-local {@linkplain GraalDebugConfig debug configuration}. - */ -public class CompilerThread extends Thread { - - private final DebugConfigAccess debugConfigAccess; - - public CompilerThread(Runnable r, String namePrefix, DebugConfigAccess debugConfigAccess) { - super(r); - this.setName(namePrefix + "-" + this.getId()); - this.setPriority(Thread.MAX_PRIORITY); - this.setDaemon(true); - this.debugConfigAccess = debugConfigAccess; - } - - @Override - public void run() { - GraalDebugConfig debugConfig = debugConfigAccess.getDebugConfig(); - setContextClassLoader(getClass().getClassLoader()); - try { - super.run(); - } finally { - if (debugConfig != null) { - for (DebugDumpHandler dumpHandler : debugConfig.dumpHandlers()) { - try { - dumpHandler.close(); - } catch (Throwable t) { - } - } - } - } - } -} diff -r 20ace3139510 -r 3d15183f3c93 graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/CompilerThreadFactory.java --- a/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/CompilerThreadFactory.java Mon Jun 08 13:20:02 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,56 +0,0 @@ -/* - * 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.concurrent.*; - -import com.oracle.jvmci.debug.*; - -/** - * Facility for creating {@linkplain CompilerThread compiler threads}. - */ -public class CompilerThreadFactory implements ThreadFactory { - - /** - * Capability to get a thread-local debug configuration for the current thread. - */ - public interface DebugConfigAccess { - /** - * Get a thread-local debug configuration for the current thread. This will be null if - * debugging is {@linkplain Debug#isEnabled() disabled}. - */ - GraalDebugConfig getDebugConfig(); - } - - protected final String threadNamePrefix; - protected final DebugConfigAccess debugConfigAccess; - - public CompilerThreadFactory(String threadNamePrefix, DebugConfigAccess debugConfigAccess) { - this.threadNamePrefix = threadNamePrefix; - this.debugConfigAccess = debugConfigAccess; - } - - public Thread newThread(Runnable r) { - return new CompilerThread(r, threadNamePrefix, debugConfigAccess); - } -} diff -r 20ace3139510 -r 3d15183f3c93 graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/DebugFilter.java --- a/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/DebugFilter.java Mon Jun 08 13:20:02 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,186 +0,0 @@ -/* - * 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.jvmci.debug.*; -import com.oracle.jvmci.debug.internal.*; - -/** - * Implements the filter specified by the {@link GraalDebugConfig#Dump}, - * {@link GraalDebugConfig#Log}, {@link GraalDebugConfig#Meter} and {@link GraalDebugConfig#Time} - * options. - *

- * These options enable the associated debug facility if their filter matches the - * {@linkplain DebugScope#getQualifiedName() name} of the {@linkplain Debug#currentScope() current - * scope}. For the {@link GraalDebugConfig#Dump} and {@link GraalDebugConfig#Log} options, the log - * or dump level is set. The {@link GraalDebugConfig#Meter} and {@link GraalDebugConfig#Time} - * options don't have a level, for them {@code level = 0} means disabled and a {@code level > 0} - * means enabled. - *

- * A filter is a list of comma-separated terms of the form {@code [:]}. - * {@code } is interpreted as a glob pattern if it contains a "*" or "?" character. - * Otherwise, it is interpreted as a substring. If {@code } is empty, it matches every - * scope. If {@code :} is omitted, it defaults to {@link Debug#DEFAULT_LOG_LEVEL}. The term - * {@code ~} is a shorthand for {@code :0} to disable a debug facility for a - * pattern. - *

- * The resulting log level of a scope is determined by the last matching term. If no term - * matches, the log level is 0 (disabled). A filter with no terms matches every scope with a log - * level of {@link Debug#DEFAULT_LOG_LEVEL}. - * - *

Examples of filters

- * - *
    - *
  • (empty string)
    - * Matches any scope with log level {@link Debug#DEFAULT_LOG_LEVEL}. - * - *
  • {@code :1}
    - * Matches any scope with log level 1. - * - *
  • {@code *}
    - * Matches any scope with log level {@link Debug#DEFAULT_LOG_LEVEL}. - * - *
  • {@code CodeGen,CodeInstall}
    - * Matches scopes containing "CodeGen" or "CodeInstall", both with log level - * {@link Debug#DEFAULT_LOG_LEVEL}. - * - *
  • {@code CodeGen:2,CodeInstall:1}
    - * Matches scopes containing "CodeGen" with log level 2, or "CodeInstall" with log level 1. - * - *
  • {@code :1,Dead:2}
    - * Matches scopes containing "Dead" with log level 2, and all other scopes with log level 1. - * - *
  • {@code :1,Dead:0}
    - * Matches all scopes with log level 1, except those containing "Dead". - * - *
  • {@code Code*}
    - * Matches scopes starting with "Code" with log level {@link Debug#DEFAULT_LOG_LEVEL}. - * - *
  • {@code Code,~Dead}
    - * Matches scopes containing "Code" but not "Dead", with log level {@link Debug#DEFAULT_LOG_LEVEL}. - *
- */ -final class DebugFilter { - - public static DebugFilter parse(String spec) { - if (spec == null) { - return null; - } - return new DebugFilter(spec.split(",")); - } - - private final Term[] terms; - - private DebugFilter(String[] terms) { - if (terms.length == 0) { - this.terms = null; - } else { - this.terms = new Term[terms.length]; - for (int i = 0; i < terms.length; i++) { - String t = terms[i]; - int idx = t.indexOf(':'); - - String pattern; - int level; - if (idx < 0) { - if (t.startsWith("~")) { - pattern = t.substring(1); - level = 0; - } else { - pattern = t; - level = Debug.DEFAULT_LOG_LEVEL; - } - } else { - pattern = t.substring(0, idx); - if (idx + 1 < t.length()) { - level = Integer.parseInt(t.substring(idx + 1)); - } else { - level = Debug.DEFAULT_LOG_LEVEL; - } - } - - this.terms[i] = new Term(pattern, level); - } - } - } - - /** - * Check whether a given input is matched by this filter, and determine the log level. - */ - public int matchLevel(String input) { - if (terms == null) { - return Debug.DEFAULT_LOG_LEVEL; - } else { - int level = 0; - for (Term t : terms) { - if (t.matches(input)) { - level = t.level; - } - } - return level; - } - } - - @Override - public String toString() { - StringBuilder buf = new StringBuilder("DebugFilter"); - if (terms != null) { - buf.append(Arrays.toString(terms)); - } else { - buf.append("[]"); - } - return buf.toString(); - } - - private static class Term { - - private final Pattern pattern; - public final int level; - - public Term(String filter, int level) { - this.level = level; - 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()) + ":" + level; - } - } -} diff -r 20ace3139510 -r 3d15183f3c93 graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/GraalCompiler.java --- a/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/GraalCompiler.java Mon Jun 08 13:20:02 2015 +0200 +++ b/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/GraalCompiler.java Wed Jun 03 15:47:54 2015 +0200 @@ -238,7 +238,8 @@ LIRGenerationResult lirGen = null; lirGen = emitLIR(backend, target, schedule, graph, stub, cc, registerConfig, lirSuites); try (Scope s2 = Debug.scope("CodeGen", lirGen, lirGen.getLIR())) { - emitCode(backend, graph.getAssumptions(), graph.method(), graph.getInlinedMethods(), lirGen, compilationResult, installedCodeOwner, factory); + int bytecodeSize = graph.method() == null ? 0 : graph.getBytecodeSize(); + emitCode(backend, graph.getAssumptions(), graph.method(), graph.getInlinedMethods(), bytecodeSize, lirGen, compilationResult, installedCodeOwner, factory); } catch (Throwable e) { throw Debug.handle(e); } @@ -327,7 +328,7 @@ return lirGenRes; } - public static void emitCode(Backend backend, Assumptions assumptions, ResolvedJavaMethod rootMethod, Set inlinedMethods, LIRGenerationResult lirGenRes, + public static void emitCode(Backend backend, Assumptions assumptions, ResolvedJavaMethod rootMethod, Set inlinedMethods, int bytecodeSize, LIRGenerationResult lirGenRes, CompilationResult compilationResult, ResolvedJavaMethod installedCodeOwner, CompilationResultBuilderFactory factory) { try (DebugCloseable a = EmitCode.start()) { FrameMap frameMap = lirGenRes.getFrameMap(); @@ -339,6 +340,7 @@ } if (inlinedMethods != null) { compilationResult.setMethods(rootMethod, inlinedMethods); + compilationResult.setBytecodeSize(bytecodeSize); } if (Debug.isMeterEnabled()) { diff -r 20ace3139510 -r 3d15183f3c93 graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/GraalDebugConfig.java --- a/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/GraalDebugConfig.java Mon Jun 08 13:20:02 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,342 +0,0 @@ -/* - * 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.graph.*; -import com.oracle.graal.lir.*; -import com.oracle.graal.lir.alloc.lsra.*; -import com.oracle.graal.nodeinfo.*; -import com.oracle.graal.nodes.*; -import com.oracle.graal.nodes.util.*; -import com.oracle.jvmci.code.*; -import com.oracle.jvmci.debug.*; -import com.oracle.jvmci.meta.*; -import com.oracle.jvmci.options.*; - -public class GraalDebugConfig implements DebugConfig { - - // @formatter:off - @Option(help = "Pattern for scope(s) in which dumping is enabled (see DebugFilter and Debug.dump)", type = OptionType.Debug) - public static final OptionValue Dump = new OptionValue<>(null); - @Option(help = "Pattern for scope(s) in which metering is enabled (see DebugFilter and Debug.metric). " + - "An empty value enables all metrics unconditionally.", type = OptionType.Debug) - public static final OptionValue Meter = new OptionValue<>(null); - @Option(help = "Pattern for scope(s) in which verification is enabled (see DebugFilter and Debug.verify).", type = OptionType.Debug) - public static final OptionValue Verify = new OptionValue<>(null); - @Option(help = "Pattern for scope(s) in which memory use tracking is enabled (see DebugFilter and Debug.metric). " + - "An empty value enables all memory use trackers unconditionally.", type = OptionType.Debug) - public static final OptionValue TrackMemUse = new OptionValue<>(null); - @Option(help = "Pattern for scope(s) in which timing is enabled (see DebugFilter and Debug.timer). " + - "An empty value enables all timers unconditionally.", type = OptionType.Debug) - public static final OptionValue Time = new OptionValue<>(null); - @Option(help = "Pattern for scope(s) in which logging is enabled (see DebugFilter and Debug.log)", type = OptionType.Debug) - public static final OptionValue Log = new OptionValue<>(null); - @Option(help = "Pattern for filtering debug scope output based on method context (see MethodFilter)", type = OptionType.Debug) - public static final OptionValue MethodFilter = new OptionValue<>(null); - @Option(help = "Only check MethodFilter against the root method in the context if true, otherwise check all methods", type = OptionType.Debug) - public static final OptionValue MethodFilterRootOnly = new OptionValue<>(false); - - @Option(help = "How to print metric and timing values:%n" + - "Name - aggregate by unqualified name%n" + - "Partial - aggregate by partially qualified name (e.g., A.B.C.D.Counter and X.Y.Z.D.Counter will be merged to D.Counter)%n" + - "Complete - aggregate by qualified name%n" + - "Thread - aggregate by qualified name and thread", type = OptionType.Debug) - public static final OptionValue DebugValueSummary = new OptionValue<>("Name"); - @Option(help = "Omit reporting 0-value metrics", type = OptionType.Debug) - public static final OptionValue SuppressZeroDebugValues = new OptionValue<>(true); - @Option(help = "Only report debug values for maps which match the regular expression.", type = OptionType.Debug) - public static final OptionValue DebugValueThreadFilter = new OptionValue<>(null); - @Option(help = "Send Graal IR to dump handlers on error", type = OptionType.Debug) - public static final OptionValue DumpOnError = new OptionValue<>(false); - @Option(help = "Intercept also bailout exceptions", type = OptionType.Debug) - public static final OptionValue InterceptBailout = new OptionValue<>(false); - @Option(help = "Enable more verbose log output when available", type = OptionType.Debug) - public static final OptionValue LogVerbose = new OptionValue<>(false); - // @formatter:on - - static boolean isNotEmpty(OptionValue option) { - return option.getValue() != null && !option.getValue().isEmpty(); - } - - static boolean areDebugScopePatternsEnabled() { - return DumpOnError.getValue() || Dump.getValue() != null || Log.getValue() != null || areScopedMetricsOrTimersEnabled(); - } - - /** - * Determines if any of {@link #Meter}, {@link #Time} or {@link #TrackMemUse} has a non-null, - * non-empty value. - */ - public static boolean areScopedMetricsOrTimersEnabled() { - return isNotEmpty(Meter) || isNotEmpty(Time) || isNotEmpty(TrackMemUse); - } - - private final DebugFilter logFilter; - private final DebugFilter meterFilter; - private final DebugFilter trackMemUseFilter; - private final DebugFilter timerFilter; - private final DebugFilter dumpFilter; - private final DebugFilter verifyFilter; - private final MethodFilter[] methodFilter; - private final List dumpHandlers; - private final List verifyHandlers; - private final PrintStream output; - private final Set extraFilters = new HashSet<>(); - - public GraalDebugConfig(String logFilter, String meterFilter, String trackMemUseFilter, String timerFilter, String dumpFilter, String verifyFilter, String methodFilter, PrintStream output, - List dumpHandlers, List verifyHandlers) { - this.logFilter = DebugFilter.parse(logFilter); - this.meterFilter = DebugFilter.parse(meterFilter); - this.trackMemUseFilter = DebugFilter.parse(trackMemUseFilter); - this.timerFilter = DebugFilter.parse(timerFilter); - this.dumpFilter = DebugFilter.parse(dumpFilter); - this.verifyFilter = DebugFilter.parse(verifyFilter); - if (methodFilter == null || methodFilter.isEmpty()) { - this.methodFilter = null; - } else { - this.methodFilter = com.oracle.graal.compiler.MethodFilter.parse(methodFilter); - } - - // 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.verifyHandlers = verifyHandlers; - this.output = output; - } - - public int getLogLevel() { - return getLevel(logFilter); - } - - public boolean isLogEnabledForMethod() { - return isEnabledForMethod(logFilter); - } - - public boolean isMeterEnabled() { - return isEnabled(meterFilter); - } - - public boolean isMemUseTrackingEnabled() { - return isEnabled(trackMemUseFilter); - } - - public int getDumpLevel() { - return getLevel(dumpFilter); - } - - public boolean isDumpEnabledForMethod() { - return isEnabledForMethod(dumpFilter); - } - - public boolean isVerifyEnabled() { - return isEnabled(verifyFilter); - } - - public boolean isVerifyEnabledForMethod() { - return isEnabledForMethod(verifyFilter); - } - - public boolean isTimeEnabled() { - return isEnabled(timerFilter); - } - - public PrintStream output() { - return output; - } - - private boolean isEnabled(DebugFilter filter) { - return getLevel(filter) > 0; - } - - private int getLevel(DebugFilter filter) { - int level; - if (filter == null) { - level = 0; - } else { - level = filter.matchLevel(Debug.currentScope()); - } - if (level > 0 && !checkMethodFilter()) { - level = 0; - } - return level; - } - - private boolean isEnabledForMethod(DebugFilter filter) { - return filter != null && checkMethodFilter(); - } - - /** - * Extracts a {@link JavaMethod} from an opaque debug context. - * - * @return the {@link JavaMethod} represented by {@code context} or null - */ - public static JavaMethod asJavaMethod(Object context) { - if (context instanceof JavaMethod) { - return (JavaMethod) context; - } - if (context instanceof StructuredGraph) { - ResolvedJavaMethod method = ((StructuredGraph) context).method(); - if (method != null) { - return method; - } - } - return null; - } - - private boolean checkMethodFilter() { - if (methodFilter == null && extraFilters.isEmpty()) { - return true; - } else { - JavaMethod lastMethod = null; - for (Object o : Debug.context()) { - if (extraFilters.contains(o)) { - return true; - } else if (methodFilter != null) { - JavaMethod method = asJavaMethod(o); - if (method != null) { - if (!MethodFilterRootOnly.getValue()) { - if (com.oracle.graal.compiler.MethodFilter.matches(methodFilter, method)) { - return true; - } - } else { - /* - * The context values operate as a stack so if we want MethodFilter to - * only apply to the root method we have to check only the last method - * seen. - */ - lastMethod = method; - } - } - } - } - if (lastMethod != null && com.oracle.graal.compiler.MethodFilter.matches(methodFilter, lastMethod)) { - 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 && !InterceptBailout.getValue()) { - return null; - } - Debug.setConfig(Debug.fixedConfig(Debug.DEFAULT_LOG_LEVEL, Debug.DEFAULT_LOG_LEVEL, false, false, false, false, dumpHandlers, verifyHandlers, output)); - Debug.log(String.format("Exception occurred in scope: %s", Debug.currentScope())); - boolean dumpedLIR = false; - Interval[] intervals = null; - for (Object o : Debug.context()) { - if (o instanceof Graph) { - Debug.log("Context obj %s", o); - if (DumpOnError.getValue()) { - Debug.dump(o, "Exception graph: " + e); - } else { - Debug.log("Use -G:+DumpOnError to enable dumping of graphs on this error"); - } - } else if (o instanceof LIR) { - Debug.log("Context obj %s", o); - if (DumpOnError.getValue()) { - Debug.dump(o, "Exception LIR: " + e); - dumpedLIR = true; - if (intervals != null) { - Debug.dump(intervals, "Exception Intervals: " + e); - intervals = null; - } - } else { - Debug.log("Use -G:+DumpOnError to enable dumping of graphs on this error"); - } - } else if (o instanceof Interval[]) { - if (DumpOnError.getValue()) { - if (dumpedLIR) { - // Can only dump intervals if LIR has been dumped. - Debug.dump(o, "Exception Intervals: " + e); - } else { - intervals = (Interval[]) o; - } - } else { - Debug.log("Use -G:+DumpOnError to enable dumping of intervals on this error"); - } - } else if (o instanceof Node) { - String location = GraphUtil.approxSourceLocation((Node) o); - String node = ((Node) o).toString(Verbosity.Debugger); - if (location != null) { - Debug.log("Context obj %s (approx. location: %s)", node, location); - } else { - Debug.log("Context obj %s", node); - } - } else { - Debug.log("Context obj %s", o); - } - } - return null; - } - - @Override - public Collection dumpHandlers() { - return dumpHandlers; - } - - @Override - public Collection verifyHandlers() { - return verifyHandlers; - } - - @Override - public void addToContext(Object o) { - extraFilters.add(o); - } - - @Override - public void removeFromContext(Object o) { - extraFilters.remove(o); - } -} diff -r 20ace3139510 -r 3d15183f3c93 graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/GraalDebugInitializationPropertyProvider.java --- a/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/GraalDebugInitializationPropertyProvider.java Mon Jun 08 13:20:02 2015 +0200 +++ b/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/GraalDebugInitializationPropertyProvider.java Wed Jun 03 15:47:54 2015 +0200 @@ -27,23 +27,23 @@ /** * Sets system properties used in the initialization of {@link Debug} based on the values specified - * for various {@link GraalDebugConfig} options. + * for various {@link JVMCIDebugConfig} options. */ @ServiceProvider(DebugInitializationPropertyProvider.class) class GraalDebugInitializationPropertyProvider implements DebugInitializationPropertyProvider { @Override public void apply() { - if (GraalDebugConfig.areDebugScopePatternsEnabled()) { + if (JVMCIDebugConfig.areDebugScopePatternsEnabled()) { System.setProperty(Debug.Initialization.INITIALIZER_PROPERTY_NAME, "true"); } - if ("".equals(GraalDebugConfig.Meter.getValue())) { + if ("".equals(JVMCIDebugConfig.Meter.getValue())) { System.setProperty(Debug.ENABLE_UNSCOPED_METRICS_PROPERTY_NAME, "true"); } - if ("".equals(GraalDebugConfig.Time.getValue())) { + if ("".equals(JVMCIDebugConfig.Time.getValue())) { System.setProperty(Debug.ENABLE_UNSCOPED_TIMERS_PROPERTY_NAME, "true"); } - if ("".equals(GraalDebugConfig.TrackMemUse.getValue())) { + if ("".equals(JVMCIDebugConfig.TrackMemUse.getValue())) { System.setProperty(Debug.ENABLE_UNSCOPED_MEM_USE_TRACKERS_PROPERTY_NAME, "true"); } } diff -r 20ace3139510 -r 3d15183f3c93 graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/MethodFilter.java --- a/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/MethodFilter.java Mon Jun 08 13:20:02 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,231 +0,0 @@ -/* - * 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 com.oracle.jvmci.meta.JavaType; -import com.oracle.jvmci.meta.JavaMethod; -import com.oracle.jvmci.meta.Signature; -import java.util.*; -import java.util.regex.*; - -/** - * 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: - * - *
- * SourcePatterns = SourcePattern ["," SourcePatterns] .
- * 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: - * - *
    - *
  • - * - *
    - * visit(Argument;BlockScope)
    - * 
    - * - * 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.
  • - *
  • - * - *
    - * arraycopy(Object;;;;)
    - * 
    - * - * 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.
  • - *
  • - * - *
    - * com.oracle.graal.compiler.graph.PostOrderNodeIterator.*
    - * 
    - * - * Matches all methods in the class "com.oracle.graal.compiler.graph.PostOrderNodeIterator".
  • - *
  • - * - *
    - * *
    - * 
    - * - * Matches all methods in all classes
  • - *
  • - * - *
    - * com.oracle.graal.compiler.graph.*.visit
    - * 
    - * - * Matches all methods named "visit" in classes in the package "com.oracle.graal.compiler.graph". - *
  • - * - *
    - * arraycopy,toString
    - * 
    - * - * Matches all methods named "arraycopy" or "toString", meaning that ',' acts as an or - * operator.
  • - *
- */ -public class MethodFilter { - - private final Pattern clazz; - private final Pattern methodName; - private final Pattern[] signature; - - /** - * Parses a string containing list of comma separated filter patterns into an array of - * {@link MethodFilter}s. - */ - public static MethodFilter[] parse(String commaSeparatedPatterns) { - String[] filters = commaSeparatedPatterns.split(","); - MethodFilter[] methodFilters = new MethodFilter[filters.length]; - for (int i = 0; i < filters.length; i++) { - methodFilters[i] = new MethodFilter(filters[i]); - } - return methodFilters; - } - - /** - * Determines if a given method is matched by a given array of filters. - */ - public static boolean matches(MethodFilter[] filters, JavaMethod method) { - for (MethodFilter filter : filters) { - if (filter.matches(method)) { - return true; - } - } - return false; - } - - /** - * Determines if a given class name is matched by a given array of filters. - */ - public static boolean matchesClassName(MethodFilter[] filters, String className) { - for (MethodFilter filter : filters) { - if (filter.matchesClassName(className)) { - return true; - } - } - return false; - } - - 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)); - } - } - - /** - * Determines if the class part of this filter matches a given class name. - */ - public boolean matchesClassName(String className) { - return clazz == null || clazz.matcher(className).matches(); - } - - 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(o.getDeclaringClass().toJavaName()).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 = type.toJavaName(); - 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(); - } -} diff -r 20ace3139510 -r 3d15183f3c93 graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/gen/NodeLIRBuilder.java --- a/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/gen/NodeLIRBuilder.java Mon Jun 08 13:20:02 2015 +0200 +++ b/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/gen/NodeLIRBuilder.java Wed Jun 03 15:47:54 2015 +0200 @@ -31,8 +31,9 @@ import com.oracle.jvmci.meta.AllocatableValue; import com.oracle.jvmci.meta.PlatformKind; import com.oracle.jvmci.meta.JavaConstant; + import static com.oracle.jvmci.code.ValueUtil.*; -import static com.oracle.graal.compiler.GraalDebugConfig.*; +import static com.oracle.jvmci.debug.JVMCIDebugConfig.*; import static com.oracle.graal.compiler.common.GraalOptions.*; import static com.oracle.graal.lir.LIR.*; diff -r 20ace3139510 -r 3d15183f3c93 graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/match/MatchContext.java --- a/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/match/MatchContext.java Mon Jun 08 13:20:02 2015 +0200 +++ b/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/match/MatchContext.java Wed Jun 03 15:47:54 2015 +0200 @@ -22,7 +22,7 @@ */ package com.oracle.graal.compiler.match; -import static com.oracle.graal.compiler.GraalDebugConfig.*; +import static com.oracle.jvmci.debug.JVMCIDebugConfig.*; import java.util.*; diff -r 20ace3139510 -r 3d15183f3c93 graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/match/MatchRuleRegistry.java --- a/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/match/MatchRuleRegistry.java Mon Jun 08 13:20:02 2015 +0200 +++ b/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/match/MatchRuleRegistry.java Wed Jun 03 15:47:54 2015 +0200 @@ -22,7 +22,7 @@ */ package com.oracle.graal.compiler.match; -import static com.oracle.graal.compiler.GraalDebugConfig.*; +import static com.oracle.jvmci.debug.JVMCIDebugConfig.*; import java.util.*; import java.util.Map.Entry; diff -r 20ace3139510 -r 3d15183f3c93 graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/match/MatchStatement.java --- a/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/match/MatchStatement.java Mon Jun 08 13:20:02 2015 +0200 +++ b/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/match/MatchStatement.java Wed Jun 03 15:47:54 2015 +0200 @@ -22,7 +22,7 @@ */ package com.oracle.graal.compiler.match; -import static com.oracle.graal.compiler.GraalDebugConfig.*; +import static com.oracle.jvmci.debug.JVMCIDebugConfig.*; import java.util.*; diff -r 20ace3139510 -r 3d15183f3c93 graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotBackend.java --- a/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotBackend.java Mon Jun 08 13:20:02 2015 +0200 +++ b/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotBackend.java Wed Jun 03 15:47:54 2015 +0200 @@ -22,21 +22,13 @@ */ package com.oracle.graal.hotspot.sparc; -import com.oracle.jvmci.code.CompilationResult; -import com.oracle.jvmci.code.CallingConvention; -import com.oracle.jvmci.code.StackSlot; -import com.oracle.jvmci.code.RegisterConfig; -import com.oracle.jvmci.code.Register; -import com.oracle.jvmci.meta.ResolvedJavaMethod; -import com.oracle.jvmci.meta.JavaType; - -import static com.oracle.jvmci.code.CallingConvention.Type.*; -import static com.oracle.jvmci.code.ValueUtil.*; import static com.oracle.graal.asm.sparc.SPARCAssembler.Annul.*; import static com.oracle.graal.asm.sparc.SPARCAssembler.BranchPredict.*; import static com.oracle.graal.asm.sparc.SPARCAssembler.CC.*; import static com.oracle.graal.asm.sparc.SPARCAssembler.ConditionFlag.*; import static com.oracle.graal.compiler.common.GraalOptions.*; +import static com.oracle.jvmci.code.CallingConvention.Type.*; +import static com.oracle.jvmci.code.ValueUtil.*; import static com.oracle.jvmci.common.UnsafeAccess.*; import static com.oracle.jvmci.sparc.SPARC.*; @@ -58,7 +50,9 @@ import com.oracle.graal.lir.sparc.*; import com.oracle.graal.nodes.*; import com.oracle.graal.nodes.spi.*; +import com.oracle.jvmci.code.*; import com.oracle.jvmci.hotspot.*; +import com.oracle.jvmci.meta.*; /** * HotSpot SPARC specific backend. diff -r 20ace3139510 -r 3d15183f3c93 graal/com.oracle.graal.hotspot.test/src/com/oracle/graal/hotspot/test/CompileTheWorldTest.java --- a/graal/com.oracle.graal.hotspot.test/src/com/oracle/graal/hotspot/test/CompileTheWorldTest.java Mon Jun 08 13:20:02 2015 +0200 +++ b/graal/com.oracle.graal.hotspot.test/src/com/oracle/graal/hotspot/test/CompileTheWorldTest.java Wed Jun 03 15:47:54 2015 +0200 @@ -22,13 +22,13 @@ */ package com.oracle.graal.hotspot.test; -import static com.oracle.graal.compiler.common.GraalOptions.*; +import static com.oracle.jvmci.compiler.Compiler.*; import org.junit.*; import com.oracle.graal.compiler.test.*; -import com.oracle.graal.hotspot.*; -import com.oracle.graal.hotspot.CompileTheWorld.Config; +import com.oracle.jvmci.hotspot.*; +import com.oracle.jvmci.hotspot.CompileTheWorld.Config; /** * Tests {@link CompileTheWorld} functionality. @@ -41,7 +41,7 @@ // Compile a couple classes in rt.jar String file = System.getProperty("java.home") + "/lib/rt.jar"; new CompileTheWorld(file, new Config(null), 1, 5, null, null, false).compile(); - ExitVMOnException.setValue(originalSetting); + assert ExitVMOnException.getValue() == originalSetting; } } diff -r 20ace3139510 -r 3d15183f3c93 graal/com.oracle.graal.hotspot.test/src/com/oracle/graal/hotspot/test/MemoryUsageBenchmark.java --- a/graal/com.oracle.graal.hotspot.test/src/com/oracle/graal/hotspot/test/MemoryUsageBenchmark.java Mon Jun 08 13:20:02 2015 +0200 +++ b/graal/com.oracle.graal.hotspot.test/src/com/oracle/graal/hotspot/test/MemoryUsageBenchmark.java Wed Jun 03 15:47:54 2015 +0200 @@ -22,20 +22,17 @@ */ package com.oracle.graal.hotspot.test; -import static com.oracle.graal.hotspot.CompileTheWorld.*; -import static com.oracle.graal.hotspot.CompileTheWorld.Options.*; -import static com.oracle.graal.nodes.StructuredGraph.*; import static com.oracle.jvmci.debug.internal.MemUseTrackerImpl.*; +import static com.oracle.jvmci.hotspot.CompileTheWorld.*; +import static com.oracle.jvmci.hotspot.CompileTheWorld.Options.*; import com.oracle.graal.api.runtime.*; import com.oracle.graal.compiler.test.*; -import com.oracle.graal.hotspot.*; -import com.oracle.graal.hotspot.CompileTheWorld.Config; import com.oracle.graal.nodes.StructuredGraph.AllowAssumptions; -import com.oracle.graal.printer.*; import com.oracle.jvmci.debug.*; import com.oracle.jvmci.debug.internal.*; import com.oracle.jvmci.hotspot.*; +import com.oracle.jvmci.hotspot.CompileTheWorld.Config; /** * Used to benchmark memory usage during Graal compilation. @@ -129,16 +126,15 @@ private void doCompilation(String methodName, String label) { HotSpotResolvedJavaMethod method = (HotSpotResolvedJavaMethod) getResolvedJavaMethod(methodName); - HotSpotBackend backend = runtime().getHostBackend(); // invalidate any existing compiled code method.reprofile(); - int id = method.allocateCompileId(INVOCATION_ENTRY_BCI); + int id = method.allocateCompileId(com.oracle.jvmci.compiler.Compiler.INVOCATION_ENTRY_BCI); long graalEnv = 0L; try (MemoryUsageCloseable c = label == null ? null : new MemoryUsageCloseable(label)) { - CompilationTask task = new CompilationTask(backend, method, INVOCATION_ENTRY_BCI, graalEnv, id, false); + CompilationTask task = new CompilationTask(method, com.oracle.jvmci.compiler.Compiler.INVOCATION_ENTRY_BCI, graalEnv, id, false); task.runCompilation(); } } @@ -146,15 +142,14 @@ private void allocSpyCompilation(String methodName) { if (AllocSpy.isEnabled()) { HotSpotResolvedJavaMethod method = (HotSpotResolvedJavaMethod) getResolvedJavaMethod(methodName); - HotSpotBackend backend = runtime().getHostBackend(); // invalidate any existing compiled code method.reprofile(); - int id = method.allocateCompileId(INVOCATION_ENTRY_BCI); + int id = method.allocateCompileId(com.oracle.jvmci.compiler.Compiler.INVOCATION_ENTRY_BCI); long graalEnv = 0L; try (AllocSpy as = AllocSpy.open(methodName)) { - CompilationTask task = new CompilationTask(backend, method, INVOCATION_ENTRY_BCI, graalEnv, id, false); + CompilationTask task = new CompilationTask(method, com.oracle.jvmci.compiler.Compiler.INVOCATION_ENTRY_BCI, graalEnv, id, false); task.runCompilation(); } } diff -r 20ace3139510 -r 3d15183f3c93 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/CompilationStatistics.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/CompilationStatistics.java Mon Jun 08 13:20:02 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,213 +0,0 @@ -/* - * 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 static java.lang.Thread.*; - -import java.io.*; -import java.lang.annotation.*; -import java.lang.management.*; -import java.lang.reflect.*; -import java.util.*; -import java.util.concurrent.*; - -import com.oracle.jvmci.hotspot.*; -import com.sun.management.ThreadMXBean; - -@SuppressWarnings("unused") -public final class CompilationStatistics { - - private static final long RESOLUTION = 100000000; - private static final boolean ENABLED = Boolean.getBoolean("graal.comp.stats"); - - private static final CompilationStatistics DUMMY = new CompilationStatistics(null, false); - - private static ConcurrentLinkedDeque list = new ConcurrentLinkedDeque<>(); - - private static final ThreadLocal> current = new ThreadLocal>() { - - @Override - protected Deque initialValue() { - return new ArrayDeque<>(); - } - }; - - @Retention(RetentionPolicy.RUNTIME) - @Target(ElementType.FIELD) - private static @interface NotReported { - } - - @Retention(RetentionPolicy.RUNTIME) - @Target(ElementType.FIELD) - private static @interface TimeValue { - } - - private static long zeroTime = System.nanoTime(); - - private static long getThreadAllocatedBytes() { - ThreadMXBean thread = (ThreadMXBean) ManagementFactory.getThreadMXBean(); - return thread.getThreadAllocatedBytes(currentThread().getId()); - } - - @NotReported private final long startTime; - @NotReported private long threadAllocatedBytesStart; - - private int bytecodeCount; - private int codeSize; - @TimeValue private long duration; - private long memoryUsed; - private final boolean osr; - private final String holder; - private final String name; - private final String signature; - - private CompilationStatistics(HotSpotResolvedJavaMethod method, boolean osr) { - this.osr = osr; - if (method != null) { - holder = method.getDeclaringClass().getName(); - name = method.getName(); - signature = method.getSignature().toMethodDescriptor(); - startTime = System.nanoTime(); - bytecodeCount = method.getCodeSize(); - threadAllocatedBytesStart = getThreadAllocatedBytes(); - } else { - holder = ""; - name = ""; - signature = ""; - startTime = 0; - } - } - - public void finish(HotSpotResolvedJavaMethod method, HotSpotInstalledCode code) { - if (ENABLED) { - duration = System.nanoTime() - startTime; - codeSize = (int) code.getCodeSize(); - memoryUsed = getThreadAllocatedBytes() - threadAllocatedBytesStart; - if (current.get().getLast() != this) { - throw new RuntimeException("mismatch in finish()"); - } - current.get().removeLast(); - } - } - - public static CompilationStatistics current() { - return current.get().isEmpty() ? null : current.get().getLast(); - } - - public static CompilationStatistics create(HotSpotResolvedJavaMethod method, boolean isOSR) { - if (ENABLED) { - CompilationStatistics stats = new CompilationStatistics(method, isOSR); - list.add(stats); - current.get().addLast(stats); - return stats; - } else { - return DUMMY; - } - } - - @SuppressWarnings("deprecation") - public static void clear(String dumpName) { - if (!ENABLED) { - return; - } - try { - ConcurrentLinkedDeque snapshot = list; - long snapshotZeroTime = zeroTime; - - list = new ConcurrentLinkedDeque<>(); - zeroTime = System.nanoTime(); - - Date now = new Date(); - String dateString = (now.getYear() + 1900) + "-" + (now.getMonth() + 1) + "-" + now.getDate() + "-" + now.getHours() + "" + now.getMinutes(); - - dumpCompilations(snapshot, dumpName, dateString); - - try (FileOutputStream fos = new FileOutputStream("timeline_" + dateString + "_" + dumpName + ".csv", true); PrintStream out = new PrintStream(fos)) { - - long[] timeSpent = new long[10000]; - int maxTick = 0; - for (CompilationStatistics stats : snapshot) { - long start = stats.startTime - snapshotZeroTime; - long duration = stats.duration; - if (start < 0) { - duration -= -start; - start = 0; - } - - int tick = (int) (start / RESOLUTION); - long timeLeft = RESOLUTION - (start % RESOLUTION); - - while (tick < timeSpent.length && duration > 0) { - if (tick > maxTick) { - maxTick = tick; - } - timeSpent[tick] += Math.min(timeLeft, duration); - duration -= timeLeft; - tick++; - timeLeft = RESOLUTION; - } - } - String timelineName = System.getProperty("stats.timeline.name"); - if (timelineName != null && !timelineName.isEmpty()) { - out.print(timelineName + "\t"); - } - for (int i = 0; i <= maxTick; i++) { - out.print((timeSpent[i] * 100 / RESOLUTION) + "\t"); - } - out.println(); - } - } catch (Exception e) { - throw new RuntimeException(e); - } - } - - protected static void dumpCompilations(ConcurrentLinkedDeque snapshot, String dumpName, String dateString) throws IllegalAccessException, FileNotFoundException { - String fileName = "compilations_" + dateString + "_" + dumpName + ".csv"; - try (PrintStream out = new PrintStream(fileName)) { - // output the list of all compilations - - Field[] declaredFields = CompilationStatistics.class.getDeclaredFields(); - ArrayList fields = new ArrayList<>(); - for (Field field : declaredFields) { - if (!Modifier.isStatic(field.getModifiers()) && !field.isAnnotationPresent(NotReported.class)) { - fields.add(field); - } - } - for (Field field : fields) { - out.print(field.getName() + "\t"); - } - out.println(); - for (CompilationStatistics stats : snapshot) { - for (Field field : fields) { - if (field.isAnnotationPresent(TimeValue.class)) { - double value = field.getLong(stats) / 1000000d; - out.print(String.format(Locale.ENGLISH, "%.3f", value) + "\t"); - } else { - out.print(field.get(stats) + "\t"); - } - } - out.println(); - } - } - } -} diff -r 20ace3139510 -r 3d15183f3c93 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/CompilationTask.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/CompilationTask.java Mon Jun 08 13:20:02 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,383 +0,0 @@ -/* - * Copyright (c) 2012, 2015, 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 static com.oracle.graal.compiler.GraalCompiler.*; -import static com.oracle.graal.compiler.common.GraalOptions.*; -import static com.oracle.graal.hotspot.HotSpotGraalRuntime.*; -import static com.oracle.graal.hotspot.meta.HotSpotSuitesProvider.*; -import static com.oracle.graal.nodes.StructuredGraph.*; -import static com.oracle.jvmci.code.CallingConvention.Type.*; -import static com.oracle.jvmci.code.CodeUtil.*; -import static com.oracle.jvmci.common.UnsafeAccess.*; -import static com.oracle.jvmci.debug.Debug.*; - -import java.lang.management.*; -import java.util.concurrent.*; - -import com.oracle.graal.api.runtime.*; -import com.oracle.graal.hotspot.meta.*; -import com.oracle.graal.hotspot.phases.*; -import com.oracle.graal.lir.asm.*; -import com.oracle.graal.lir.phases.*; -import com.oracle.graal.nodes.*; -import com.oracle.graal.nodes.StructuredGraph.AllowAssumptions; -import com.oracle.graal.phases.*; -import com.oracle.graal.phases.OptimisticOptimizations.Optimization; -import com.oracle.graal.phases.tiers.*; -import com.oracle.graal.printer.*; -import com.oracle.jvmci.code.*; -import com.oracle.jvmci.code.CallingConvention.Type; -import com.oracle.jvmci.debug.*; -import com.oracle.jvmci.debug.Debug.Scope; -import com.oracle.jvmci.debug.internal.*; -import com.oracle.jvmci.hotspot.*; -import com.oracle.jvmci.hotspot.events.*; -import com.oracle.jvmci.hotspot.events.EventProvider.*; -import com.oracle.jvmci.meta.*; -import com.oracle.jvmci.service.*; - -//JaCoCo Exclude - -public class CompilationTask { - private static final DebugMetric BAILOUTS = Debug.metric("Bailouts"); - - private static final EventProvider eventProvider; - static { - EventProvider provider = Services.loadSingle(EventProvider.class, false); - if (provider == null) { - eventProvider = new EmptyEventProvider(); - } else { - eventProvider = provider; - } - } - - private final HotSpotBackend backend; - private final HotSpotResolvedJavaMethod method; - private final int entryBCI; - private final int id; - - /** - * Specifies whether the compilation result is installed as the - * {@linkplain HotSpotNmethod#isDefault() default} nmethod for the compiled method. - */ - private final boolean installAsDefault; - - private StructuredGraph graph; - - /** - * A {@link com.sun.management.ThreadMXBean} to be able to query some information about the - * current compiler thread, e.g. total allocated bytes. - */ - private static final com.sun.management.ThreadMXBean threadMXBean = (com.sun.management.ThreadMXBean) ManagementFactory.getThreadMXBean(); - - /** - * The address of the GraalEnv associated with this compilation or 0L if no such object exists. - */ - private final long graalEnv; - - public CompilationTask(HotSpotBackend backend, HotSpotResolvedJavaMethod method, int entryBCI, long graalEnv, int id, boolean installAsDefault) { - this.backend = backend; - this.method = method; - this.entryBCI = entryBCI; - this.id = id; - this.graalEnv = graalEnv; - this.installAsDefault = installAsDefault; - } - - public ResolvedJavaMethod getMethod() { - return method; - } - - /** - * Returns the compilation id of this task. - * - * @return compile id - */ - public int getId() { - return id; - } - - public int getEntryBCI() { - return entryBCI; - } - - /** - * Time spent in compilation. - */ - private static final DebugTimer CompilationTime = Debug.timer("CompilationTime"); - - /** - * Meters the {@linkplain StructuredGraph#getBytecodeSize() bytecodes} compiled. - */ - private static final DebugMetric CompiledBytecodes = Debug.metric("CompiledBytecodes"); - - public static final DebugTimer CodeInstallationTime = Debug.timer("CodeInstallation"); - - protected Suites getSuites(HotSpotProviders providers) { - return providers.getSuites().getDefaultSuites(); - } - - protected LIRSuites getLIRSuites(HotSpotProviders providers) { - return providers.getSuites().getDefaultLIRSuites(); - } - - protected PhaseSuite getGraphBuilderSuite(HotSpotProviders providers) { - PhaseSuite suite = withSimpleDebugInfoIfRequested(providers.getSuites().getDefaultGraphBuilderSuite()); - - boolean osrCompilation = entryBCI != StructuredGraph.INVOCATION_ENTRY_BCI; - if (osrCompilation) { - suite = suite.copy(); - suite.appendPhase(new OnStackReplacementPhase()); - } - return suite; - } - - protected OptimisticOptimizations getOptimisticOpts(ProfilingInfo profilingInfo) { - return new OptimisticOptimizations(profilingInfo); - } - - protected ProfilingInfo getProfilingInfo() { - boolean osrCompilation = entryBCI != StructuredGraph.INVOCATION_ENTRY_BCI; - return method.getProfilingInfo(!osrCompilation, osrCompilation); - } - - public void runCompilation() { - HotSpotVMConfig config = backend.getRuntime().getConfig(); - final long threadId = Thread.currentThread().getId(); - long startCompilationTime = System.nanoTime(); - HotSpotInstalledCode installedCode = null; - final boolean isOSR = entryBCI != StructuredGraph.INVOCATION_ENTRY_BCI; - - // Log a compilation event. - CompilationEvent compilationEvent = eventProvider.newCompilationEvent(); - - // If there is already compiled code for this method on our level we simply return. - // Graal compiles are always at the highest compile level, even in non-tiered mode so we - // only need to check for that value. - if (method.hasCodeAtLevel(entryBCI, config.compilationLevelFullOptimization)) { - return; - } - - try (DebugCloseable a = CompilationTime.start()) { - CompilationStatistics stats = CompilationStatistics.create(method, isOSR); - final boolean printCompilation = PrintCompilation.getValue() && !TTY.isSuppressed(); - if (printCompilation) { - TTY.println(getMethodDescription() + "..."); - } - - CompilationResult result = null; - TTY.Filter filter = new TTY.Filter(PrintFilter.getValue(), method); - final long start = System.currentTimeMillis(); - final long allocatedBytesBefore = threadMXBean.getThreadAllocatedBytes(threadId); - - try (Scope s = Debug.scope("Compiling", new DebugDumpScope(String.valueOf(id), true))) { - // Begin the compilation event. - compilationEvent.begin(); - - HotSpotProviders providers = backend.getProviders(); - graph = new StructuredGraph(method, entryBCI, AllowAssumptions.from(OptAssumptions.getValue())); - if (shouldDisableMethodInliningRecording(config)) { - graph.disableInlinedMethodRecording(); - } - CallingConvention cc = getCallingConvention(providers.getCodeCache(), Type.JavaCallee, graph.method(), false); - if (graph.getEntryBCI() != StructuredGraph.INVOCATION_ENTRY_BCI) { - // for OSR, only a pointer is passed to the method. - JavaType[] parameterTypes = new JavaType[]{providers.getMetaAccess().lookupJavaType(long.class)}; - CallingConvention tmp = providers.getCodeCache().getRegisterConfig().getCallingConvention(JavaCallee, providers.getMetaAccess().lookupJavaType(void.class), parameterTypes, - backend.getTarget(), false); - cc = new CallingConvention(cc.getStackSize(), cc.getReturn(), tmp.getArgument(0)); - } - Suites suites = getSuites(providers); - LIRSuites lirSuites = getLIRSuites(providers); - ProfilingInfo profilingInfo = getProfilingInfo(); - OptimisticOptimizations optimisticOpts = getOptimisticOpts(profilingInfo); - if (isOSR) { - // In OSR compiles, we cannot rely on never executed code profiles, because - // all code after the OSR loop is never executed. - optimisticOpts.remove(Optimization.RemoveNeverExecutedCode); - } - result = compileGraph(graph, cc, method, providers, backend, backend.getTarget(), getGraphBuilderSuite(providers), optimisticOpts, profilingInfo, method.getSpeculationLog(), suites, - lirSuites, new CompilationResult(), CompilationResultBuilderFactory.Default); - result.setId(getId()); - result.setEntryBCI(entryBCI); - } catch (Throwable e) { - throw Debug.handle(e); - } finally { - // End the compilation event. - compilationEvent.end(); - - filter.remove(); - final boolean printAfterCompilation = PrintAfterCompilation.getValue() && !TTY.isSuppressed(); - - if (printAfterCompilation || printCompilation) { - final long stop = System.currentTimeMillis(); - final int targetCodeSize = result != null ? result.getTargetCodeSize() : -1; - final long allocatedBytesAfter = threadMXBean.getThreadAllocatedBytes(threadId); - final long allocatedBytes = (allocatedBytesAfter - allocatedBytesBefore) / 1024; - - if (printAfterCompilation) { - TTY.println(getMethodDescription() + String.format(" | %4dms %5dB %5dkB", stop - start, targetCodeSize, allocatedBytes)); - } else if (printCompilation) { - TTY.println(String.format("%-6d Graal %-70s %-45s %-50s | %4dms %5dB %5dkB", id, "", "", "", stop - start, targetCodeSize, allocatedBytes)); - } - } - } - - try (DebugCloseable b = CodeInstallationTime.start()) { - installedCode = (HotSpotInstalledCode) installMethod(result); - if (!isOSR) { - ProfilingInfo profile = method.getProfilingInfo(); - profile.setCompilerIRSize(StructuredGraph.class, graph.getNodeCount()); - } - } - stats.finish(method, installedCode); - } catch (BailoutException bailout) { - BAILOUTS.increment(); - if (ExitVMOnBailout.getValue()) { - TTY.cachedOut.println(method.format("Bailout in %H.%n(%p)")); - bailout.printStackTrace(TTY.cachedOut); - System.exit(-1); - } else if (PrintBailout.getValue()) { - TTY.cachedOut.println(method.format("Bailout in %H.%n(%p)")); - bailout.printStackTrace(TTY.cachedOut); - } - } catch (Throwable t) { - if (PrintStackTraceOnException.getValue() || ExitVMOnException.getValue()) { - t.printStackTrace(TTY.cachedOut); - } - - // Log a failure event. - CompilerFailureEvent event = eventProvider.newCompilerFailureEvent(); - if (event.shouldWrite()) { - event.setCompileId(getId()); - event.setMessage(t.getMessage()); - event.commit(); - } - - if (ExitVMOnException.getValue()) { - System.exit(-1); - } - } finally { - final int compiledBytecodes = graph.getBytecodeSize(); - CompiledBytecodes.add(compiledBytecodes); - - // Log a compilation event. - if (compilationEvent.shouldWrite() && installedCode != null) { - compilationEvent.setMethod(method.format("%H.%n(%p)")); - compilationEvent.setCompileId(getId()); - compilationEvent.setCompileLevel(config.compilationLevelFullOptimization); - compilationEvent.setSucceeded(true); - compilationEvent.setIsOsr(isOSR); - compilationEvent.setCodeSize(installedCode.getSize()); - compilationEvent.setInlinedBytes(compiledBytecodes); - compilationEvent.commit(); - } - - if (graalEnv != 0) { - long ctask = unsafe.getAddress(graalEnv + config.jvmciEnvTaskOffset); - assert ctask != 0L; - unsafe.putInt(ctask + config.compileTaskNumInlinedBytecodesOffset, compiledBytecodes); - } - long compilationTime = System.nanoTime() - startCompilationTime; - if ((config.ciTime || config.ciTimeEach) && installedCode != null) { - long timeUnitsPerSecond = TimeUnit.NANOSECONDS.convert(1, TimeUnit.SECONDS); - CompilerToVM c2vm = backend.getRuntime().getCompilerToVM(); - c2vm.notifyCompilationStatistics(id, method, entryBCI != INVOCATION_ENTRY_BCI, compiledBytecodes, compilationTime, timeUnitsPerSecond, installedCode); - } - } - } - - /** - * Determines whether to {@linkplain StructuredGraph#disableInlinedMethodRecording() disable} - * method inlining recording for the method being compiled. - * - * @see StructuredGraph#getBytecodeSize() - */ - private boolean shouldDisableMethodInliningRecording(HotSpotVMConfig config) { - if (config.ciTime || config.ciTimeEach || CompiledBytecodes.isEnabled()) { - return false; - } - if (graalEnv == 0 || unsafe.getByte(graalEnv + config.jvmciEnvJvmtiCanHotswapOrPostBreakpointOffset) != 0) { - return false; - } - return true; - } - - private String getMethodDescription() { - return String.format("%-6d Graal %-70s %-45s %-50s %s", id, method.getDeclaringClass().getName(), method.getName(), method.getSignature().toMethodDescriptor(), - entryBCI == StructuredGraph.INVOCATION_ENTRY_BCI ? "" : "(OSR@" + entryBCI + ") "); - } - - private InstalledCode installMethod(final CompilationResult compResult) { - final HotSpotCodeCacheProvider codeCache = backend.getProviders().getCodeCache(); - InstalledCode installedCode = null; - try (Scope s = Debug.scope("CodeInstall", new DebugDumpScope(String.valueOf(id), true), codeCache, method)) { - installedCode = codeCache.installMethod(method, compResult, graalEnv, installAsDefault); - } catch (Throwable e) { - throw Debug.handle(e); - } - return installedCode; - } - - @Override - public String toString() { - return "Compilation[id=" + id + ", " + method.format("%H.%n(%p)") + (entryBCI == StructuredGraph.INVOCATION_ENTRY_BCI ? "" : "@" + entryBCI) + "]"; - } - - /** - * Schedules compilation of a metaspace Method. - * - * Called from the VM. - * - * @param metaspaceMethod - * @param entryBCI - * @param jvmciEnv address of native GraalEnv object - * @param id CompileTask::_compile_id - */ - static void compileMetaspaceMethod(long metaspaceMethod, int entryBCI, long jvmciEnv, int id) { - // Ensure a Graal runtime is initialized prior to Debug being initialized as the former - // may include processing command line options used by the latter. - Graal.getRuntime(); - - // Ensure a debug configuration for this thread is initialized - if (Debug.isEnabled() && DebugScope.getConfig() == null) { - DebugEnvironment.initialize(TTY.cachedOut); - } - - HotSpotResolvedJavaMethod method = HotSpotResolvedJavaMethodImpl.fromMetaspace(metaspaceMethod); - compileMethod(method, entryBCI, jvmciEnv, id); - } - - /** - * Compiles a method to machine code. - */ - static void compileMethod(HotSpotResolvedJavaMethod method, int entryBCI, long graalEnv, int id) { - HotSpotBackend backend = runtime().getHostBackend(); - CompilationTask task = new CompilationTask(backend, method, entryBCI, graalEnv, id, true); - try (DebugConfigScope dcs = setConfig(new TopLevelDebugConfig())) { - task.runCompilation(); - } - return; - } -} diff -r 20ace3139510 -r 3d15183f3c93 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/CompileTheWorld.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/CompileTheWorld.java Mon Jun 08 13:20:02 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,509 +0,0 @@ -/* - * 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.hotspot; - -import static com.oracle.graal.compiler.common.GraalOptions.*; -import static com.oracle.graal.hotspot.HotSpotGraalRuntime.*; -import static com.oracle.graal.nodes.StructuredGraph.*; -import static com.oracle.jvmci.debug.internal.MemUseTrackerImpl.*; - -import java.io.*; -import java.lang.reflect.*; -import java.net.*; -import java.util.*; -import java.util.concurrent.*; -import java.util.concurrent.atomic.*; -import java.util.jar.*; -import java.util.stream.*; - -import com.oracle.graal.bytecode.*; -import com.oracle.graal.compiler.*; -import com.oracle.graal.compiler.CompilerThreadFactory.DebugConfigAccess; -import com.oracle.graal.printer.*; -import com.oracle.graal.replacements.*; -import com.oracle.jvmci.debug.*; -import com.oracle.jvmci.debug.internal.*; -import com.oracle.jvmci.hotspot.*; -import com.oracle.jvmci.meta.*; -import com.oracle.jvmci.options.*; -import com.oracle.jvmci.options.OptionUtils.OptionConsumer; -import com.oracle.jvmci.options.OptionValue.OverrideScope; - -/** - * This class implements compile-the-world functionality in Graal. - */ -public final class CompileTheWorld { - - /** - * Magic token to trigger reading files from the boot class path. - */ - public static final String SUN_BOOT_CLASS_PATH = "sun.boot.class.path"; - - public static class Options { - // @formatter:off - @Option(help = "Compile all methods in all classes on given class path", type = OptionType.Debug) - public static final OptionValue CompileTheWorldClasspath = new OptionValue<>(SUN_BOOT_CLASS_PATH); - @Option(help = "Verbose CompileTheWorld operation", type = OptionType.Debug) - public static final OptionValue CompileTheWorldVerbose = new OptionValue<>(true); - @Option(help = "The number of CompileTheWorld iterations to perform", type = OptionType.Debug) - public static final OptionValue CompileTheWorldIterations = new OptionValue<>(1); - @Option(help = "Only compile methods matching this filter", type = OptionType.Debug) - public static final OptionValue CompileTheWorldMethodFilter = new OptionValue<>(null); - @Option(help = "Exclude methods matching this filter from compilation", type = OptionType.Debug) - public static final OptionValue CompileTheWorldExcludeMethodFilter = new OptionValue<>(null); - @Option(help = "First class to consider when using -XX:+CompileTheWorld", type = OptionType.Debug) - public static final OptionValue CompileTheWorldStartAt = new OptionValue<>(1); - @Option(help = "Last class to consider when using -XX:+CompileTheWorld", type = OptionType.Debug) - public static final OptionValue CompileTheWorldStopAt = new OptionValue<>(Integer.MAX_VALUE); - @Option(help = "Option value overrides to use during compile the world. For example, " + - "to disable inlining and partial escape analysis specify '-PartialEscapeAnalysis -Inline'. " + - "The format for each option is the same as on the command line just without the '-G:' prefix.", type = OptionType.Debug) - public static final OptionValue CompileTheWorldConfig = new OptionValue<>(null); - - @Option(help = "Run CTW using as many threads as there are processors on the system", type = OptionType.Debug) - public static final OptionValue CompileTheWorldMultiThreaded = new OptionValue<>(false); - @Option(help = "Number of threads to use for multithreaded CTW. Defaults to Runtime.getRuntime().availableProcessors()", type = OptionType.Debug) - public static final OptionValue CompileTheWorldThreads = new OptionValue<>(0); - // @formatter:on - - /** - * Overrides {@link #CompileTheWorldStartAt} and {@link #CompileTheWorldStopAt} from - * {@code -XX} HotSpot options of the same name if the latter have non-default values. - */ - static void overrideWithNativeOptions(HotSpotVMConfig c) { - if (c.compileTheWorldStartAt != 1) { - CompileTheWorldStartAt.setValue(c.compileTheWorldStartAt); - } - if (c.compileTheWorldStopAt != Integer.MAX_VALUE) { - CompileTheWorldStopAt.setValue(c.compileTheWorldStopAt); - } - } - } - - /** - * A mechanism for overriding Graal options that affect compilation. A {@link Config} object - * should be used in a try-with-resources statement to ensure overriding of options is scoped - * properly. For example: - * - *
-     *     Config config = ...;
-     *     try (AutoCloseable s = config == null ? null : config.apply()) {
-     *         // perform a Graal compilation
-     *     }
-     * 
- */ - @SuppressWarnings("serial") - public static class Config extends HashMap, Object> implements OptionConsumer { - /** - * Creates a {@link Config} object by parsing a set of space separated override options. - * - * @param options a space separated set of option value settings with each option setting in - * a format compatible with - * {@link OptionUtils#parseOption(String, OptionConsumer)}. Ignored if null. - */ - public Config(String options) { - if (options != null) { - for (String option : options.split("\\s+")) { - OptionUtils.parseOption(option, this); - } - } - } - - /** - * Applies the overrides represented by this object. The overrides are in effect until - * {@link OverrideScope#close()} is called on the returned object. - */ - OverrideScope apply() { - return OptionValue.override(this); - } - - public void set(OptionDescriptor desc, Object value) { - put(desc.getOptionValue(), value); - } - } - - // Some runtime instances we need. - private final HotSpotGraalRuntimeProvider runtime = runtime(); - - /** List of Zip/Jar files to compile (see {@link Options#CompileTheWorldClasspath}). */ - private final String files; - - /** Class index to start compilation at (see {@link Options#CompileTheWorldStartAt}). */ - private final int startAt; - - /** Class index to stop compilation at (see {@link Options#CompileTheWorldStopAt}). */ - private final int stopAt; - - /** Only compile methods matching one of the filters in this array if the array is non-null. */ - private final MethodFilter[] methodFilters; - - /** Exclude methods matching one of the filters in this array if the array is non-null. */ - private final MethodFilter[] excludeMethodFilters; - - // Counters - private int classFileCounter = 0; - private AtomicLong compiledMethodsCounter = new AtomicLong(); - private AtomicLong compileTime = new AtomicLong(); - private AtomicLong memoryUsed = new AtomicLong(); - - private boolean verbose; - private final Config config; - - /** - * Signal that the threads should start compiling in multithreaded mode. - */ - private boolean running; - - private ThreadPoolExecutor threadPool; - - /** - * Creates a compile-the-world instance. - * - * @param files {@link File#pathSeparator} separated list of Zip/Jar files to compile - * @param startAt index of the class file to start compilation at - * @param stopAt index of the class file to stop compilation at - * @param methodFilters - * @param excludeMethodFilters - */ - public CompileTheWorld(String files, Config config, int startAt, int stopAt, String methodFilters, String excludeMethodFilters, boolean verbose) { - this.files = files; - this.startAt = startAt; - this.stopAt = stopAt; - this.methodFilters = methodFilters == null || methodFilters.isEmpty() ? null : MethodFilter.parse(methodFilters); - this.excludeMethodFilters = excludeMethodFilters == null || excludeMethodFilters.isEmpty() ? null : MethodFilter.parse(excludeMethodFilters); - this.verbose = verbose; - this.config = config; - - // We don't want the VM to exit when a method fails to compile... - config.putIfAbsent(ExitVMOnException, false); - - // ...but we want to see exceptions. - config.putIfAbsent(PrintBailout, true); - config.putIfAbsent(PrintStackTraceOnException, true); - } - - /** - * Compiles all methods in all classes in the Zip/Jar archive files in - * {@link Options#CompileTheWorldClasspath}. If {@link Options#CompileTheWorldClasspath} - * contains the magic token {@link #SUN_BOOT_CLASS_PATH} passed up from HotSpot we take the - * files from the boot class path. - */ - public void compile() throws Throwable { - // By default only report statistics for the CTW threads themselves - if (GraalDebugConfig.DebugValueThreadFilter.hasDefaultValue()) { - GraalDebugConfig.DebugValueThreadFilter.setValue("^CompileTheWorld"); - } - - if (SUN_BOOT_CLASS_PATH.equals(files)) { - final String[] entries = System.getProperty(SUN_BOOT_CLASS_PATH).split(File.pathSeparator); - String bcpFiles = ""; - for (int i = 0; i < entries.length; i++) { - final String entry = entries[i]; - - // We stop at rt.jar, unless it is the first boot class path entry. - if (entry.endsWith("rt.jar") && (i > 0)) { - break; - } - if (i > 0) { - bcpFiles += File.pathSeparator; - } - bcpFiles += entry; - } - compile(bcpFiles); - } else { - compile(files); - } - } - - public void println() { - println(""); - } - - public void println(String format, Object... args) { - println(String.format(format, args)); - } - - public void println(String s) { - if (verbose) { - TTY.println(s); - } - } - - /** - * Compiles all methods in all classes in the Zip/Jar files passed. - * - * @param fileList {@link File#pathSeparator} separated list of Zip/Jar files to compile - * @throws IOException - */ - private void compile(String fileList) throws IOException { - final String[] entries = fileList.split(File.pathSeparator); - long start = System.currentTimeMillis(); - - CompilerThreadFactory factory = new CompilerThreadFactory("CompileTheWorld", new DebugConfigAccess() { - public GraalDebugConfig getDebugConfig() { - if (Debug.isEnabled() && DebugScope.getConfig() == null) { - return DebugEnvironment.initialize(System.out); - } - return null; - } - }); - - /* - * Always use a thread pool, even for single threaded mode since it simplifies the use of - * DebugValueThreadFilter to filter on the thread names. - */ - int threadCount = 1; - if (Options.CompileTheWorldMultiThreaded.getValue()) { - threadCount = Options.CompileTheWorldThreads.getValue(); - if (threadCount == 0) { - threadCount = Runtime.getRuntime().availableProcessors(); - } - } else { - running = true; - } - threadPool = new ThreadPoolExecutor(threadCount, threadCount, 0L, TimeUnit.MILLISECONDS, new LinkedBlockingQueue(), factory); - - try (OverrideScope s = config.apply()) { - for (int i = 0; i < entries.length; i++) { - final String entry = entries[i]; - - // For now we only compile all methods in all classes in zip/jar files. - if (!entry.endsWith(".zip") && !entry.endsWith(".jar")) { - println("CompileTheWorld : Skipped classes in " + entry); - println(); - continue; - } - - if (methodFilters == null || methodFilters.length == 0) { - println("CompileTheWorld : Compiling all classes in " + entry); - } else { - String include = Arrays.asList(methodFilters).stream().map(MethodFilter::toString).collect(Collectors.joining(", ")); - println("CompileTheWorld : Compiling all methods in " + entry + " matching one of the following filters: " + include); - } - if (excludeMethodFilters != null && excludeMethodFilters.length > 0) { - String exclude = Arrays.asList(excludeMethodFilters).stream().map(MethodFilter::toString).collect(Collectors.joining(", ")); - println("CompileTheWorld : Excluding all methods matching one of the following filters: " + exclude); - } - println(); - - URL url = new URL("jar", "", "file:" + entry + "!/"); - ClassLoader loader = new URLClassLoader(new URL[]{url}); - - JarFile jarFile = new JarFile(entry); - Enumeration e = jarFile.entries(); - - while (e.hasMoreElements()) { - JarEntry je = e.nextElement(); - if (je.isDirectory() || !je.getName().endsWith(".class")) { - continue; - } - - // Are we done? - if (classFileCounter >= stopAt) { - break; - } - - String className = je.getName().substring(0, je.getName().length() - ".class".length()); - String dottedClassName = className.replace('/', '.'); - classFileCounter++; - - if (methodFilters != null && !MethodFilter.matchesClassName(methodFilters, dottedClassName)) { - continue; - } - if (excludeMethodFilters != null && MethodFilter.matchesClassName(excludeMethodFilters, dottedClassName)) { - continue; - } - - if (dottedClassName.startsWith("jdk.management.") || dottedClassName.startsWith("jdk.internal.cmm.*")) { - continue; - } - - try { - // Load and initialize class - Class javaClass = Class.forName(dottedClassName, true, loader); - - // Pre-load all classes in the constant pool. - try { - HotSpotResolvedObjectType objectType = HotSpotResolvedObjectTypeImpl.fromObjectClass(javaClass); - ConstantPool constantPool = objectType.constantPool(); - for (int cpi = 1; cpi < constantPool.length(); cpi++) { - constantPool.loadReferencedType(cpi, Bytecodes.LDC); - } - } catch (Throwable t) { - // If something went wrong during pre-loading we just ignore it. - println("Preloading failed for (%d) %s: %s", classFileCounter, className, t); - } - - // Are we compiling this class? - MetaAccessProvider metaAccess = runtime.getHostProviders().getMetaAccess(); - if (classFileCounter >= startAt) { - println("CompileTheWorld (%d) : %s", classFileCounter, className); - - // Compile each constructor/method in the class. - for (Constructor constructor : javaClass.getDeclaredConstructors()) { - HotSpotResolvedJavaMethod javaMethod = (HotSpotResolvedJavaMethod) metaAccess.lookupJavaMethod(constructor); - if (canBeCompiled(javaMethod, constructor.getModifiers())) { - compileMethod(javaMethod); - } - } - for (Method method : javaClass.getDeclaredMethods()) { - HotSpotResolvedJavaMethod javaMethod = (HotSpotResolvedJavaMethod) metaAccess.lookupJavaMethod(method); - if (canBeCompiled(javaMethod, method.getModifiers())) { - compileMethod(javaMethod); - } - } - } - } catch (Throwable t) { - println("CompileTheWorld (%d) : Skipping %s %s", classFileCounter, className, t.toString()); - t.printStackTrace(); - } - } - jarFile.close(); - } - } - - if (!running) { - startThreads(); - } - int wakeups = 0; - while (threadPool.getCompletedTaskCount() != threadPool.getTaskCount()) { - if (wakeups % 15 == 0) { - TTY.println("CompileTheWorld : Waiting for " + (threadPool.getTaskCount() - threadPool.getCompletedTaskCount()) + " compiles"); - } - try { - threadPool.awaitTermination(1, TimeUnit.SECONDS); - wakeups++; - } catch (InterruptedException e) { - } - } - threadPool = null; - - long elapsedTime = System.currentTimeMillis() - start; - - println(); - if (Options.CompileTheWorldMultiThreaded.getValue()) { - TTY.println("CompileTheWorld : Done (%d classes, %d methods, %d ms elapsed, %d ms compile time, %d bytes of memory used)", classFileCounter, compiledMethodsCounter.get(), elapsedTime, - compileTime.get(), memoryUsed.get()); - } else { - TTY.println("CompileTheWorld : Done (%d classes, %d methods, %d ms, %d bytes of memory used)", classFileCounter, compiledMethodsCounter.get(), compileTime.get(), memoryUsed.get()); - } - } - - private synchronized void startThreads() { - running = true; - // Wake up any waiting threads - notifyAll(); - } - - private synchronized void waitToRun() { - while (!running) { - try { - wait(); - } catch (InterruptedException e) { - } - } - } - - class CTWCompilationTask extends CompilationTask { - - CTWCompilationTask(HotSpotBackend backend, HotSpotResolvedJavaMethod method) { - super(backend, method, INVOCATION_ENTRY_BCI, 0L, method.allocateCompileId(INVOCATION_ENTRY_BCI), false); - } - - /** - * Returns empty profiling info to be as close to the CTW behavior of C1 and C2 as possible. - */ - @Override - protected ProfilingInfo getProfilingInfo() { - // Be optimistic and return false for exceptionSeen. - return DefaultProfilingInfo.get(TriState.FALSE); - } - } - - private void compileMethod(HotSpotResolvedJavaMethod method) throws InterruptedException, ExecutionException { - if (methodFilters != null && !MethodFilter.matches(methodFilters, method)) { - return; - } - if (excludeMethodFilters != null && MethodFilter.matches(excludeMethodFilters, method)) { - return; - } - Future task = threadPool.submit(new Runnable() { - public void run() { - waitToRun(); - try (OverrideScope s = config.apply()) { - compileMethod(method, classFileCounter); - } - } - }); - if (threadPool.getCorePoolSize() == 1) { - task.get(); - } - } - - /** - * Compiles a method and gathers some statistics. - */ - private void compileMethod(HotSpotResolvedJavaMethod method, int counter) { - try { - long start = System.currentTimeMillis(); - long allocatedAtStart = getCurrentThreadAllocatedBytes(); - - HotSpotBackend backend = runtime.getHostBackend(); - CompilationTask task = new CTWCompilationTask(backend, method); - task.runCompilation(); - - memoryUsed.getAndAdd(getCurrentThreadAllocatedBytes() - allocatedAtStart); - compileTime.getAndAdd(System.currentTimeMillis() - start); - compiledMethodsCounter.incrementAndGet(); - } catch (Throwable t) { - // Catch everything and print a message - println("CompileTheWorld (%d) : Error compiling method: %s", counter, method.format("%H.%n(%p):%r")); - t.printStackTrace(TTY.cachedOut); - } - } - - /** - * Determines if a method should be compiled (Cf. CompilationPolicy::can_be_compiled). - * - * @return true if it can be compiled, false otherwise - */ - private boolean canBeCompiled(HotSpotResolvedJavaMethod javaMethod, int modifiers) { - if (Modifier.isAbstract(modifiers) || Modifier.isNative(modifiers)) { - return false; - } - HotSpotVMConfig c = runtime.getConfig(); - if (c.dontCompileHugeMethods && javaMethod.getCodeSize() > c.hugeMethodLimit) { - return false; - } - // Allow use of -XX:CompileCommand=dontinline to exclude problematic methods - if (!javaMethod.canBeInlined()) { - return false; - } - // Skip @Snippets for now - if (javaMethod.getAnnotation(Snippet.class) != null) { - return false; - } - return true; - } - -} diff -r 20ace3139510 -r 3d15183f3c93 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/DebugValuesPrinter.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/DebugValuesPrinter.java Mon Jun 08 13:20:02 2015 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/DebugValuesPrinter.java Wed Jun 03 15:47:54 2015 +0200 @@ -22,7 +22,7 @@ */ package com.oracle.graal.hotspot; -import static com.oracle.graal.compiler.GraalDebugConfig.*; +import static com.oracle.jvmci.debug.JVMCIDebugConfig.*; import java.io.*; import java.util.*; diff -r 20ace3139510 -r 3d15183f3c93 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotGraalCompiler.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotGraalCompiler.java Wed Jun 03 15:47:54 2015 +0200 @@ -0,0 +1,108 @@ +/* + * Copyright (c) 2015, 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 static com.oracle.graal.compiler.common.GraalOptions.*; +import static com.oracle.jvmci.code.CallingConvention.Type.*; +import static com.oracle.jvmci.code.CodeUtil.*; + +import com.oracle.graal.compiler.*; +import com.oracle.graal.hotspot.meta.*; +import com.oracle.graal.hotspot.phases.*; +import com.oracle.graal.lir.asm.*; +import com.oracle.graal.lir.phases.*; +import com.oracle.graal.nodes.*; +import com.oracle.graal.nodes.StructuredGraph.AllowAssumptions; +import com.oracle.graal.phases.*; +import com.oracle.graal.phases.OptimisticOptimizations.Optimization; +import com.oracle.graal.phases.tiers.*; +import com.oracle.jvmci.code.*; +import com.oracle.jvmci.code.CallingConvention.Type; +import com.oracle.jvmci.compiler.Compiler; +import com.oracle.jvmci.meta.*; +import com.oracle.jvmci.service.*; + +@ServiceProvider(Compiler.class) +public class HotSpotGraalCompiler implements Compiler { + + public CompilationResult compile(ResolvedJavaMethod method, int entryBCI, boolean mustRecordMethodInlining) { + HotSpotBackend backend = HotSpotGraalRuntime.runtime().getHostBackend(); + HotSpotProviders providers = HotSpotGraalRuntime.runtime().getHostProviders(); + final boolean isOSR = entryBCI != INVOCATION_ENTRY_BCI; + + StructuredGraph graph = new StructuredGraph(method, entryBCI, AllowAssumptions.from(OptAssumptions.getValue())); + if (!mustRecordMethodInlining) { + graph.disableInlinedMethodRecording(); + } + + CallingConvention cc = getCallingConvention(providers.getCodeCache(), Type.JavaCallee, graph.method(), false); + if (isOSR) { + // for OSR, only a pointer is passed to the method. + JavaType[] parameterTypes = new JavaType[]{providers.getMetaAccess().lookupJavaType(long.class)}; + CallingConvention tmp = providers.getCodeCache().getRegisterConfig().getCallingConvention(JavaCallee, providers.getMetaAccess().lookupJavaType(void.class), parameterTypes, + backend.getTarget(), false); + cc = new CallingConvention(cc.getStackSize(), cc.getReturn(), tmp.getArgument(0)); + } + Suites suites = getSuites(providers); + LIRSuites lirSuites = getLIRSuites(providers); + ProfilingInfo profilingInfo = method.getProfilingInfo(!isOSR, isOSR); + OptimisticOptimizations optimisticOpts = getOptimisticOpts(profilingInfo); + if (isOSR) { + // In OSR compiles, we cannot rely on never executed code profiles, because + // all code after the OSR loop is never executed. + optimisticOpts.remove(Optimization.RemoveNeverExecutedCode); + } + CompilationResult result = GraalCompiler.compileGraph(graph, cc, method, providers, backend, backend.getTarget(), getGraphBuilderSuite(providers, isOSR), optimisticOpts, profilingInfo, + method.getSpeculationLog(), suites, lirSuites, new CompilationResult(), CompilationResultBuilderFactory.Default); + + result.setEntryBCI(entryBCI); + + if (!isOSR) { + ProfilingInfo profile = method.getProfilingInfo(); + profile.setCompilerIRSize(StructuredGraph.class, graph.getNodeCount()); + } + + return result; + } + + protected OptimisticOptimizations getOptimisticOpts(ProfilingInfo profilingInfo) { + return new OptimisticOptimizations(profilingInfo); + } + + protected Suites getSuites(HotSpotProviders providers) { + return providers.getSuites().getDefaultSuites(); + } + + protected LIRSuites getLIRSuites(HotSpotProviders providers) { + return providers.getSuites().getDefaultLIRSuites(); + } + + protected PhaseSuite getGraphBuilderSuite(HotSpotProviders providers, boolean isOSR) { + PhaseSuite suite = HotSpotSuitesProvider.withSimpleDebugInfoIfRequested(providers.getSuites().getDefaultGraphBuilderSuite()); + if (isOSR) { + suite = suite.copy(); + suite.appendPhase(new OnStackReplacementPhase()); + } + return suite; + } +} diff -r 20ace3139510 -r 3d15183f3c93 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotGraalRuntime.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotGraalRuntime.java Mon Jun 08 13:20:02 2015 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotGraalRuntime.java Wed Jun 03 15:47:54 2015 +0200 @@ -22,10 +22,10 @@ */ package com.oracle.graal.hotspot; -import static com.oracle.graal.compiler.GraalDebugConfig.*; import static com.oracle.graal.compiler.common.GraalOptions.*; import static com.oracle.graal.hotspot.HotSpotGraalRuntime.Options.*; import static com.oracle.jvmci.common.UnsafeAccess.*; +import static com.oracle.jvmci.debug.JVMCIDebugConfig.*; import static com.oracle.jvmci.hotspot.InitTimer.*; import java.lang.reflect.*; @@ -38,7 +38,6 @@ import com.oracle.graal.graph.*; import com.oracle.graal.hotspot.debug.*; import com.oracle.graal.hotspot.meta.*; -import com.oracle.graal.printer.*; import com.oracle.graal.replacements.*; import com.oracle.graal.runtime.*; import com.oracle.jvmci.code.*; diff -r 20ace3139510 -r 3d15183f3c93 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotGraalVMEventListener.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotGraalVMEventListener.java Mon Jun 08 13:20:02 2015 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotGraalVMEventListener.java Wed Jun 03 15:47:54 2015 +0200 @@ -22,10 +22,6 @@ */ package com.oracle.graal.hotspot; -import static com.oracle.graal.hotspot.CompileTheWorld.Options.*; - -import com.oracle.graal.hotspot.CompileTheWorld.Config; -import com.oracle.jvmci.debug.*; import com.oracle.jvmci.hotspot.*; import com.oracle.jvmci.service.*; @@ -34,16 +30,7 @@ @Override public void notifyCompileTheWorld() throws Throwable { - CompilerToVM compilerToVM = HotSpotGraalRuntime.runtime().getJVMCIRuntime().getCompilerToVM(); - int iterations = CompileTheWorld.Options.CompileTheWorldIterations.getValue(); - for (int i = 0; i < iterations; i++) { - compilerToVM.resetCompilationStatistics(); - TTY.println("CompileTheWorld : iteration " + i); - CompileTheWorld ctw = new CompileTheWorld(CompileTheWorldClasspath.getValue(), new Config(CompileTheWorldConfig.getValue()), CompileTheWorldStartAt.getValue(), - CompileTheWorldStopAt.getValue(), CompileTheWorldMethodFilter.getValue(), CompileTheWorldExcludeMethodFilter.getValue(), CompileTheWorldVerbose.getValue()); - ctw.compile(); - } - System.exit(0); + } @Override @@ -53,6 +40,6 @@ @Override public void compileMetaspaceMethod(long metaspaceMethod, int entryBCI, long jvmciEnv, int id) { - CompilationTask.compileMetaspaceMethod(metaspaceMethod, entryBCI, jvmciEnv, id); + } } diff -r 20ace3139510 -r 3d15183f3c93 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/phases/OnStackReplacementPhase.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/phases/OnStackReplacementPhase.java Mon Jun 08 13:20:02 2015 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/phases/OnStackReplacementPhase.java Wed Jun 03 15:47:54 2015 +0200 @@ -22,7 +22,6 @@ */ package com.oracle.graal.hotspot.phases; -import com.oracle.jvmci.code.BailoutException; import static com.oracle.graal.phases.common.DeadCodeEliminationPhase.Optionality.*; import com.oracle.graal.graph.*; @@ -34,14 +33,16 @@ import com.oracle.graal.nodes.util.*; import com.oracle.graal.phases.*; import com.oracle.graal.phases.common.*; +import com.oracle.jvmci.code.*; import com.oracle.jvmci.common.*; +import com.oracle.jvmci.compiler.Compiler; import com.oracle.jvmci.debug.*; public class OnStackReplacementPhase extends Phase { @Override protected void run(StructuredGraph graph) { - if (graph.getEntryBCI() == StructuredGraph.INVOCATION_ENTRY_BCI) { + if (graph.getEntryBCI() == Compiler.INVOCATION_ENTRY_BCI) { // This happens during inlining in a OSR method, because the same phase plan will be // used. return; diff -r 20ace3139510 -r 3d15183f3c93 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/stubs/ForeignCallStub.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/stubs/ForeignCallStub.java Mon Jun 08 13:20:02 2015 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/stubs/ForeignCallStub.java Wed Jun 03 15:47:54 2015 +0200 @@ -31,6 +31,7 @@ import com.oracle.jvmci.meta.Signature; import com.oracle.jvmci.meta.ForeignCallDescriptor; import com.oracle.jvmci.meta.Kind; + import static com.oracle.jvmci.code.CallingConvention.Type.*; import static com.oracle.graal.hotspot.HotSpotForeignCallLinkage.RegisterEffect.*; @@ -119,33 +120,40 @@ return null; } + private class DebugScopeContext implements JavaMethod, JavaMethodContex { + public JavaMethod asJavaMethod() { + return this; + } + + public Signature getSignature() { + ForeignCallDescriptor d = linkage.getDescriptor(); + MetaAccessProvider metaAccess = providers.getMetaAccess(); + Class[] arguments = d.getArgumentTypes(); + ResolvedJavaType[] parameters = new ResolvedJavaType[arguments.length]; + for (int i = 0; i < arguments.length; i++) { + parameters[i] = metaAccess.lookupJavaType(arguments[i]); + } + return new HotSpotSignature(runtime.getJVMCIRuntime(), metaAccess.lookupJavaType(d.getResultType()), parameters); + } + + public String getName() { + return linkage.getDescriptor().getName(); + } + + public JavaType getDeclaringClass() { + return providers.getMetaAccess().lookupJavaType(ForeignCallStub.class); + } + + @Override + public String toString() { + return format("ForeignCallStub<%n(%p)>"); + } + } + @Override protected Object debugScopeContext() { - return new JavaMethod() { - - public Signature getSignature() { - ForeignCallDescriptor d = linkage.getDescriptor(); - MetaAccessProvider metaAccess = providers.getMetaAccess(); - Class[] arguments = d.getArgumentTypes(); - ResolvedJavaType[] parameters = new ResolvedJavaType[arguments.length]; - for (int i = 0; i < arguments.length; i++) { - parameters[i] = metaAccess.lookupJavaType(arguments[i]); - } - return new HotSpotSignature(runtime.getJVMCIRuntime(), metaAccess.lookupJavaType(d.getResultType()), parameters); - } + return new DebugScopeContext() { - public String getName() { - return linkage.getDescriptor().getName(); - } - - public JavaType getDeclaringClass() { - return providers.getMetaAccess().lookupJavaType(ForeignCallStub.class); - } - - @Override - public String toString() { - return format("ForeignCallStub<%n(%p)>"); - } }; } diff -r 20ace3139510 -r 3d15183f3c93 graal/com.oracle.graal.java/src/com/oracle/graal/java/BytecodeParser.java --- a/graal/com.oracle.graal.java/src/com/oracle/graal/java/BytecodeParser.java Mon Jun 08 13:20:02 2015 +0200 +++ b/graal/com.oracle.graal.java/src/com/oracle/graal/java/BytecodeParser.java Wed Jun 03 15:47:54 2015 +0200 @@ -27,7 +27,6 @@ import static com.oracle.graal.compiler.common.type.StampFactory.*; import static com.oracle.graal.graphbuilderconf.IntrinsicContext.CompilationContext.*; import static com.oracle.graal.java.BytecodeParser.Options.*; -import static com.oracle.graal.nodes.StructuredGraph.*; import static com.oracle.graal.nodes.type.StampTool.*; import static com.oracle.jvmci.code.TypeCheckHints.*; import static com.oracle.jvmci.common.JVMCIError.*; @@ -62,6 +61,7 @@ import com.oracle.graal.phases.*; import com.oracle.jvmci.code.*; import com.oracle.jvmci.common.*; +import com.oracle.jvmci.compiler.Compiler; import com.oracle.jvmci.debug.*; import com.oracle.jvmci.debug.Debug.Scope; import com.oracle.jvmci.meta.*; @@ -1524,7 +1524,7 @@ private void parseAndInlineCallee(ResolvedJavaMethod targetMethod, ValueNode[] args, IntrinsicContext calleeIntrinsicContext) { try (IntrinsicScope s = calleeIntrinsicContext != null && !parsingIntrinsic() ? new IntrinsicScope(this, targetMethod.getSignature().toParameterKinds(!targetMethod.isStatic()), args) : null) { - BytecodeParser parser = graphBuilderInstance.createBytecodeParser(graph, this, targetMethod, INVOCATION_ENTRY_BCI, calleeIntrinsicContext); + BytecodeParser parser = graphBuilderInstance.createBytecodeParser(graph, this, targetMethod, Compiler.INVOCATION_ENTRY_BCI, calleeIntrinsicContext); FrameStateBuilder startFrameState = new FrameStateBuilder(parser, targetMethod, graph); if (!targetMethod.isStatic()) { args[0] = nullCheckedValue(args[0]); diff -r 20ace3139510 -r 3d15183f3c93 graal/com.oracle.graal.java/src/com/oracle/graal/java/GraphBuilderPhase.java --- a/graal/com.oracle.graal.java/src/com/oracle/graal/java/GraphBuilderPhase.java Mon Jun 08 13:20:02 2015 +0200 +++ b/graal/com.oracle.graal.java/src/com/oracle/graal/java/GraphBuilderPhase.java Wed Jun 03 15:47:54 2015 +0200 @@ -22,14 +22,11 @@ */ package com.oracle.graal.java; -import static com.oracle.graal.compiler.common.GraalOptions.*; - import com.oracle.graal.graphbuilderconf.*; import com.oracle.graal.nodes.*; import com.oracle.graal.nodes.spi.*; import com.oracle.graal.phases.*; import com.oracle.graal.phases.tiers.*; -import com.oracle.jvmci.debug.*; import com.oracle.jvmci.meta.*; /** @@ -74,12 +71,7 @@ @Override protected void run(StructuredGraph graph) { - TTY.Filter filter = new TTY.Filter(PrintFilter.getValue(), graph.method()); - try { - createBytecodeParser(graph, null, graph.method(), graph.getEntryBCI(), initialIntrinsicContext).buildRootMethod(); - } finally { - filter.remove(); - } + createBytecodeParser(graph, null, graph.method(), graph.getEntryBCI(), initialIntrinsicContext).buildRootMethod(); } /* Hook for subclasses of Instance to provide a subclass of BytecodeParser. */ diff -r 20ace3139510 -r 3d15183f3c93 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/StructuredGraph.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/StructuredGraph.java Mon Jun 08 13:20:02 2015 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/StructuredGraph.java Wed Jun 03 15:47:54 2015 +0200 @@ -32,6 +32,8 @@ import com.oracle.graal.nodes.calc.*; import com.oracle.graal.nodes.java.*; import com.oracle.graal.nodes.util.*; +import com.oracle.jvmci.compiler.Compiler; +import com.oracle.jvmci.debug.*; import com.oracle.jvmci.meta.*; import com.oracle.jvmci.meta.Assumptions.Assumption; @@ -39,7 +41,7 @@ * A graph that contains at least one distinguished node : the {@link #start() start} node. This * node is the start of the control flow of the graph. */ -public class StructuredGraph extends Graph { +public class StructuredGraph extends Graph implements JavaMethodContex { /** * The different stages of the compilation of a {@link Graph} regarding the status of @@ -97,7 +99,6 @@ } } - public static final int INVOCATION_ENTRY_BCI = -1; public static final long INVALID_GRAPH_ID = -1; private static final AtomicLong uniqueGraphIds = new AtomicLong(); @@ -134,11 +135,11 @@ * start} node. */ public StructuredGraph(String name, ResolvedJavaMethod method, AllowAssumptions allowAssumptions) { - this(name, method, uniqueGraphIds.incrementAndGet(), INVOCATION_ENTRY_BCI, allowAssumptions); + this(name, method, uniqueGraphIds.incrementAndGet(), Compiler.INVOCATION_ENTRY_BCI, allowAssumptions); } public StructuredGraph(ResolvedJavaMethod method, AllowAssumptions allowAssumptions) { - this(null, method, uniqueGraphIds.incrementAndGet(), INVOCATION_ENTRY_BCI, allowAssumptions); + this(null, method, uniqueGraphIds.incrementAndGet(), Compiler.INVOCATION_ENTRY_BCI, allowAssumptions); } public StructuredGraph(ResolvedJavaMethod method, int entryBCI, AllowAssumptions allowAssumptions) { @@ -208,7 +209,7 @@ } public boolean isOSR() { - return entryBCI != INVOCATION_ENTRY_BCI; + return entryBCI != Compiler.INVOCATION_ENTRY_BCI; } public long graphId() { @@ -604,4 +605,8 @@ public boolean isTrivial() { return !(start.next() instanceof ReturnNode); } + + public JavaMethod asJavaMethod() { + return method(); + } } diff -r 20ace3139510 -r 3d15183f3c93 graal/com.oracle.graal.printer/src/com/oracle/graal/printer/CFGPrinterObserver.java --- a/graal/com.oracle.graal.printer/src/com/oracle/graal/printer/CFGPrinterObserver.java Mon Jun 08 13:20:02 2015 +0200 +++ b/graal/com.oracle.graal.printer/src/com/oracle/graal/printer/CFGPrinterObserver.java Wed Jun 03 15:47:54 2015 +0200 @@ -114,6 +114,9 @@ return object instanceof Graph || object instanceof BciBlockMapping; } + private LIR lastLIR = null; + private Interval[] delayedIntervals = null; + public void dumpSandboxed(Object object, String message) { if (!dumpFrontend && isFrontendObject(object)) { @@ -166,7 +169,11 @@ } else if (object instanceof LIR) { // Currently no node printing for lir cfgPrinter.printCFG(message, cfgPrinter.lir.codeEmittingOrder(), false); - + lastLIR = (LIR) object; + if (delayedIntervals != null) { + cfgPrinter.printIntervals(message, delayedIntervals); + delayedIntervals = null; + } } else if (object instanceof SchedulePhase) { cfgPrinter.printSchedule(message, (SchedulePhase) object); } else if (object instanceof StructuredGraph) { @@ -183,7 +190,14 @@ Object[] tuple = (Object[]) object; cfgPrinter.printMachineCode(disassemble(codeCache, (CompilationResult) tuple[0], (InstalledCode) tuple[1]), message); } else if (object instanceof Interval[]) { - cfgPrinter.printIntervals(message, (Interval[]) object); + if (lastLIR == cfgPrinter.lir) { + cfgPrinter.printIntervals(message, (Interval[]) object); + } else { + if (delayedIntervals != null) { + Debug.log("Some delayed intervals were dropped (%s)", (Object) delayedIntervals); + } + delayedIntervals = (Interval[]) object; + } } else if (object instanceof StackInterval[]) { cfgPrinter.printStackIntervals(message, (StackInterval[]) object); } diff -r 20ace3139510 -r 3d15183f3c93 graal/com.oracle.graal.printer/src/com/oracle/graal/printer/DebugEnvironment.java --- a/graal/com.oracle.graal.printer/src/com/oracle/graal/printer/DebugEnvironment.java Mon Jun 08 13:20:02 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,75 +0,0 @@ -/* - * 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 static com.oracle.graal.compiler.GraalDebugConfig.*; -import static com.oracle.graal.compiler.common.GraalOptions.*; - -import java.io.*; -import java.util.*; - -import com.oracle.graal.api.runtime.*; -import com.oracle.graal.compiler.*; -import com.oracle.jvmci.debug.*; - -public class DebugEnvironment { - - @SuppressWarnings("all") - private static boolean assertionsEnabled() { - boolean assertionsEnabled = false; - assert assertionsEnabled = true; - return assertionsEnabled; - } - - public static GraalDebugConfig initialize(PrintStream log) { - - // Ensure Graal runtime is initialized prior to Debug being initialized as the former - // may include processing command line options used by the latter. - Graal.getRuntime(); - - if (!Debug.isEnabled()) { - log.println("WARNING: Scope debugging needs to be enabled with -esa or -D" + Debug.Initialization.INITIALIZER_PROPERTY_NAME + "=true"); - return null; - } - List dumpHandlers = new ArrayList<>(); - dumpHandlers.add(new GraphPrinterDumpHandler()); - if (PrintCFG.getValue() || PrintBackendCFG.getValue()) { - if (PrintBinaryGraphs.getValue() && PrintCFG.getValue()) { - TTY.println("Complete C1Visualizer dumping slows down PrintBinaryGraphs: use -G:-PrintCFG to disable it"); - } - dumpHandlers.add(new CFGPrinterObserver(PrintCFG.getValue())); - } - List verifyHandlers = new ArrayList<>(); - String verifyFilter = Verify.getValue(); - if (verifyFilter == null && assertionsEnabled()) { - verifyFilter = ""; - } - if (verifyFilter != null) { - verifyHandlers.add(new NoDeadCodeVerifyHandler()); - } - GraalDebugConfig debugConfig = new GraalDebugConfig(Log.getValue(), Meter.getValue(), TrackMemUse.getValue(), Time.getValue(), Dump.getValue(), verifyFilter, MethodFilter.getValue(), log, - dumpHandlers, verifyHandlers); - Debug.setConfig(debugConfig); - return debugConfig; - } -} diff -r 20ace3139510 -r 3d15183f3c93 graal/com.oracle.graal.printer/src/com/oracle/graal/printer/GraalDebugConfigCustomizer.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.printer/src/com/oracle/graal/printer/GraalDebugConfigCustomizer.java Wed Jun 03 15:47:54 2015 +0200 @@ -0,0 +1,64 @@ +/* + * Copyright (c) 2015, 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 static com.oracle.graal.compiler.common.GraalOptions.*; + +import com.oracle.graal.graph.*; +import com.oracle.graal.nodeinfo.*; +import com.oracle.graal.nodes.util.*; +import com.oracle.jvmci.debug.*; +import com.oracle.jvmci.service.*; + +@ServiceProvider(DebugConfigCustomizer.class) +public class GraalDebugConfigCustomizer implements DebugConfigCustomizer { + public void customize(DebugConfig config) { + config.dumpHandlers().add(new GraphPrinterDumpHandler()); + config.dumpHandlers().add(new NodeDumper()); + if (PrintCFG.getValue() || PrintBackendCFG.getValue()) { + if (PrintBinaryGraphs.getValue() && PrintCFG.getValue()) { + TTY.cachedOut.println("Complete C1Visualizer dumping slows down PrintBinaryGraphs: use -G:-PrintCFG to disable it"); + } + config.dumpHandlers().add(new CFGPrinterObserver(PrintCFG.getValue())); + } + config.verifyHandlers().add(new NoDeadCodeVerifyHandler()); + } + + private static class NodeDumper implements DebugDumpHandler { + + public void dump(Object object, String message) { + if (object instanceof Node) { + String location = GraphUtil.approxSourceLocation((Node) object); + String node = ((Node) object).toString(Verbosity.Debugger); + if (location != null) { + Debug.log("Context obj %s (approx. location: %s)", node, location); + } else { + Debug.log("Context obj %s", node); + } + } + } + + public void close() { + } + } +} diff -r 20ace3139510 -r 3d15183f3c93 graal/com.oracle.graal.printer/src/com/oracle/graal/printer/GraphPrinterDumpHandler.java --- a/graal/com.oracle.graal.printer/src/com/oracle/graal/printer/GraphPrinterDumpHandler.java Mon Jun 08 13:20:02 2015 +0200 +++ b/graal/com.oracle.graal.printer/src/com/oracle/graal/printer/GraphPrinterDumpHandler.java Wed Jun 03 15:47:54 2015 +0200 @@ -24,8 +24,9 @@ import com.oracle.jvmci.meta.ResolvedJavaMethod; import com.oracle.jvmci.meta.JavaMethod; -import static com.oracle.graal.compiler.GraalDebugConfig.*; + import static com.oracle.graal.compiler.common.GraalOptions.*; +import static com.oracle.jvmci.debug.JVMCIDebugConfig.*; import java.io.*; import java.net.*; diff -r 20ace3139510 -r 3d15183f3c93 graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/NodeIntrinsificationPlugin.java --- a/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/NodeIntrinsificationPlugin.java Mon Jun 08 13:20:02 2015 +0200 +++ b/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/NodeIntrinsificationPlugin.java Wed Jun 03 15:47:54 2015 +0200 @@ -28,7 +28,6 @@ import java.util.*; import com.oracle.graal.api.replacements.*; -import com.oracle.graal.compiler.*; import com.oracle.graal.compiler.common.type.*; import com.oracle.graal.graph.Node.NodeIntrinsic; import com.oracle.graal.graphbuilderconf.*; @@ -38,6 +37,7 @@ import com.oracle.graal.nodes.extended.*; import com.oracle.graal.word.*; import com.oracle.jvmci.common.*; +import com.oracle.jvmci.debug.*; import com.oracle.jvmci.meta.*; /** diff -r 20ace3139510 -r 3d15183f3c93 graal/com.oracle.graal.truffle.hotspot/src/com/oracle/graal/truffle/hotspot/HotSpotTruffleRuntime.java --- a/graal/com.oracle.graal.truffle.hotspot/src/com/oracle/graal/truffle/hotspot/HotSpotTruffleRuntime.java Mon Jun 08 13:20:02 2015 +0200 +++ b/graal/com.oracle.graal.truffle.hotspot/src/com/oracle/graal/truffle/hotspot/HotSpotTruffleRuntime.java Wed Jun 03 15:47:54 2015 +0200 @@ -22,27 +22,17 @@ */ package com.oracle.graal.truffle.hotspot; -import com.oracle.jvmci.code.CodeCacheProvider; -import com.oracle.jvmci.code.CompilationResult; -import com.oracle.jvmci.code.CallingConvention; -import com.oracle.jvmci.code.BailoutException; -import com.oracle.jvmci.meta.ResolvedJavaType; -import com.oracle.jvmci.meta.ResolvedJavaMethod; -import com.oracle.jvmci.meta.MetaAccessProvider; - -import static com.oracle.jvmci.code.CodeUtil.*; import static com.oracle.graal.compiler.GraalCompiler.*; import static com.oracle.graal.graph.util.CollectionsAccess.*; import static com.oracle.graal.hotspot.meta.HotSpotSuitesProvider.*; import static com.oracle.graal.truffle.TruffleCompilerOptions.*; +import static com.oracle.jvmci.code.CodeUtil.*; import java.util.*; import java.util.concurrent.*; import java.util.stream.*; -import com.oracle.jvmci.code.CallingConvention.Type; import com.oracle.graal.api.runtime.*; -import com.oracle.graal.compiler.*; import com.oracle.graal.compiler.target.*; import com.oracle.graal.graphbuilderconf.*; import com.oracle.graal.graphbuilderconf.GraphBuilderConfiguration.Plugins; @@ -57,14 +47,17 @@ import com.oracle.graal.phases.common.inlining.*; import com.oracle.graal.phases.tiers.*; import com.oracle.graal.phases.util.*; -import com.oracle.graal.printer.*; import com.oracle.graal.runtime.*; import com.oracle.graal.truffle.*; import com.oracle.graal.truffle.hotspot.nfi.*; +import com.oracle.jvmci.code.*; +import com.oracle.jvmci.code.CallingConvention.Type; import com.oracle.jvmci.common.*; +import com.oracle.jvmci.compiler.*; import com.oracle.jvmci.debug.*; import com.oracle.jvmci.debug.Debug.Scope; import com.oracle.jvmci.hotspot.*; +import com.oracle.jvmci.meta.*; import com.oracle.jvmci.service.*; import com.oracle.nfi.api.*; import com.oracle.truffle.api.*; @@ -96,9 +89,9 @@ // Create compilation queue. CompilerThreadFactory factory = new CompilerThreadFactory("TruffleCompilerThread", new CompilerThreadFactory.DebugConfigAccess() { - public GraalDebugConfig getDebugConfig() { + public JVMCIDebugConfig getDebugConfig() { if (Debug.isEnabled()) { - GraalDebugConfig debugConfig = DebugEnvironment.initialize(TTY.out().out()); + JVMCIDebugConfig debugConfig = DebugEnvironment.initialize(TTY.out().out()); debugConfig.dumpHandlers().add(new TruffleTreeDumpHandler()); return debugConfig; } else { diff -r 20ace3139510 -r 3d15183f3c93 graal/com.oracle.graal.truffle.test/src/com/oracle/graal/truffle/test/PartialEvaluationTest.java --- a/graal/com.oracle.graal.truffle.test/src/com/oracle/graal/truffle/test/PartialEvaluationTest.java Mon Jun 08 13:20:02 2015 +0200 +++ b/graal/com.oracle.graal.truffle.test/src/com/oracle/graal/truffle/test/PartialEvaluationTest.java Wed Jun 03 15:47:54 2015 +0200 @@ -30,7 +30,6 @@ import com.oracle.graal.nodes.java.*; import com.oracle.graal.phases.common.*; import com.oracle.graal.phases.tiers.*; -import com.oracle.graal.printer.*; import com.oracle.graal.truffle.*; import com.oracle.jvmci.debug.*; import com.oracle.jvmci.debug.Debug.Scope; diff -r 20ace3139510 -r 3d15183f3c93 graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/TruffleCompiler.java --- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/TruffleCompiler.java Mon Jun 08 13:20:02 2015 +0200 +++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/TruffleCompiler.java Wed Jun 03 15:47:54 2015 +0200 @@ -22,19 +22,11 @@ */ package com.oracle.graal.truffle; -import com.oracle.jvmci.code.CallingConvention; -import com.oracle.jvmci.code.CodeCacheProvider; -import com.oracle.jvmci.code.InstalledCode; -import com.oracle.jvmci.code.CompilationResult; -import com.oracle.jvmci.meta.*; - +import static com.oracle.graal.compiler.GraalCompiler.*; import static com.oracle.jvmci.code.CodeUtil.*; -import static com.oracle.graal.compiler.GraalCompiler.*; import java.util.*; -import com.oracle.jvmci.code.CallingConvention.Type; -import com.oracle.jvmci.meta.Assumptions.Assumption; import com.oracle.graal.compiler.target.*; import com.oracle.graal.graphbuilderconf.*; import com.oracle.graal.graphbuilderconf.GraphBuilderConfiguration.Plugins; @@ -45,10 +37,13 @@ import com.oracle.graal.phases.*; import com.oracle.graal.phases.tiers.*; import com.oracle.graal.phases.util.*; -import com.oracle.graal.printer.*; import com.oracle.graal.truffle.nodes.*; +import com.oracle.jvmci.code.*; +import com.oracle.jvmci.code.CallingConvention.Type; import com.oracle.jvmci.debug.*; import com.oracle.jvmci.debug.Debug.Scope; +import com.oracle.jvmci.meta.Assumptions.Assumption; +import com.oracle.jvmci.meta.*; import com.oracle.truffle.api.*; import com.oracle.truffle.api.nodes.*; @@ -169,6 +164,7 @@ if (graph.isInlinedMethodRecordingEnabled()) { result.setMethods(graph.method(), graph.getInlinedMethods()); + result.setBytecodeSize(graph.getBytecodeSize()); } else { assert result.getMethods() == null; } diff -r 20ace3139510 -r 3d15183f3c93 graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/TruffleDebugJavaMethod.java --- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/TruffleDebugJavaMethod.java Mon Jun 08 13:20:02 2015 +0200 +++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/TruffleDebugJavaMethod.java Wed Jun 03 15:47:54 2015 +0200 @@ -34,7 +34,7 @@ * Enables a Truffle compilable to masquerade as a {@link JavaMethod} for use as a context value in * {@linkplain Debug#scope(Object) debug scopes}. */ -public class TruffleDebugJavaMethod implements JavaMethod { +public class TruffleDebugJavaMethod implements JavaMethod, JavaMethodContex { private final RootCallTarget compilable; private static final JavaType declaringClass = new JavaType() { @@ -122,4 +122,8 @@ public String toString() { return format("Truffle<%n(%p)>"); } + + public JavaMethod asJavaMethod() { + return this; + } } diff -r 20ace3139510 -r 3d15183f3c93 graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/debug/TraceCompilationFailureListener.java --- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/debug/TraceCompilationFailureListener.java Mon Jun 08 13:20:02 2015 +0200 +++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/debug/TraceCompilationFailureListener.java Wed Jun 03 15:47:54 2015 +0200 @@ -22,12 +22,13 @@ */ package com.oracle.graal.truffle.debug; -import com.oracle.jvmci.code.BailoutException; +import static com.oracle.jvmci.compiler.Compiler.*; + import java.util.*; -import com.oracle.graal.compiler.common.*; import com.oracle.graal.nodes.*; import com.oracle.graal.truffle.*; +import com.oracle.jvmci.code.*; public final class TraceCompilationFailureListener extends AbstractDebugCompilationListener { @@ -40,7 +41,7 @@ @Override public void notifyCompilationFailed(OptimizedCallTarget target, StructuredGraph graph, Throwable t) { - if (isPermanentBailout(t) || GraalOptions.PrintBailout.getValue()) { + if (isPermanentBailout(t) || PrintBailout.getValue()) { Map properties = new LinkedHashMap<>(); properties.put("Reason", t.toString()); log(0, "opt fail", target.toString(), properties); diff -r 20ace3139510 -r 3d15183f3c93 graal/com.oracle.jvmci.code/src/com/oracle/jvmci/code/CompilationResult.java --- a/graal/com.oracle.jvmci.code/src/com/oracle/jvmci/code/CompilationResult.java Mon Jun 08 13:20:02 2015 +0200 +++ b/graal/com.oracle.jvmci.code/src/com/oracle/jvmci/code/CompilationResult.java Wed Jun 03 15:47:54 2015 +0200 @@ -514,6 +514,8 @@ */ private ResolvedJavaMethod[] methods; + private int bytecodeSize; + public CompilationResult() { this(null); } @@ -649,6 +651,14 @@ return methods; } + public void setBytecodeSize(int bytecodeSize) { + this.bytecodeSize = bytecodeSize; + } + + public int getBytecodeSize() { + return bytecodeSize; + } + public DataSection getDataSection() { return dataSection; } diff -r 20ace3139510 -r 3d15183f3c93 graal/com.oracle.jvmci.compiler/src/com/oracle/jvmci/compiler/Compiler.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.jvmci.compiler/src/com/oracle/jvmci/compiler/Compiler.java Wed Jun 03 15:47:54 2015 +0200 @@ -0,0 +1,42 @@ +/* + * Copyright (c) 2015, 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.jvmci.compiler; + +import com.oracle.jvmci.code.*; +import com.oracle.jvmci.meta.*; +import com.oracle.jvmci.options.*; +import com.oracle.jvmci.service.*; + +public interface Compiler extends Service { + int INVOCATION_ENTRY_BCI = -1; + + @Option(help = "", type = OptionType.Debug) OptionValue PrintFilter = new OptionValue<>(null); + @Option(help = "", type = OptionType.Debug) OptionValue PrintCompilation = new OptionValue<>(false); + @Option(help = "", type = OptionType.Debug) OptionValue PrintAfterCompilation = new OptionValue<>(false); + @Option(help = "", type = OptionType.Debug) OptionValue PrintBailout = new OptionValue<>(false); + @Option(help = "", type = OptionType.Debug) OptionValue ExitVMOnBailout = new OptionValue<>(false); + @Option(help = "", type = OptionType.Debug) OptionValue ExitVMOnException = new OptionValue<>(true); + @Option(help = "", type = OptionType.Debug) OptionValue PrintStackTraceOnException = new OptionValue<>(false); + + CompilationResult compile(ResolvedJavaMethod method, int entryBCI, boolean mustRecordMethodInlining); +} diff -r 20ace3139510 -r 3d15183f3c93 graal/com.oracle.jvmci.compiler/src/com/oracle/jvmci/compiler/CompilerThread.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.jvmci.compiler/src/com/oracle/jvmci/compiler/CompilerThread.java Wed Jun 03 15:47:54 2015 +0200 @@ -0,0 +1,61 @@ +/* + * Copyright (c) 2012, 2014, 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.jvmci.compiler; + +import com.oracle.jvmci.compiler.CompilerThreadFactory.*; +import com.oracle.jvmci.debug.*; + +/** + * A compiler thread is a daemon thread that runs at {@link Thread#MAX_PRIORITY} and executes in the + * context of a thread-local {@linkplain JVMCIDebugConfig debug configuration}. + */ +public class CompilerThread extends Thread { + + private final DebugConfigAccess debugConfigAccess; + + public CompilerThread(Runnable r, String namePrefix, DebugConfigAccess debugConfigAccess) { + super(r); + this.setName(namePrefix + "-" + this.getId()); + this.setPriority(Thread.MAX_PRIORITY); + this.setDaemon(true); + this.debugConfigAccess = debugConfigAccess; + } + + @Override + public void run() { + JVMCIDebugConfig debugConfig = debugConfigAccess.getDebugConfig(); + setContextClassLoader(getClass().getClassLoader()); + try { + super.run(); + } finally { + if (debugConfig != null) { + for (DebugDumpHandler dumpHandler : debugConfig.dumpHandlers()) { + try { + dumpHandler.close(); + } catch (Throwable t) { + } + } + } + } + } +} diff -r 20ace3139510 -r 3d15183f3c93 graal/com.oracle.jvmci.compiler/src/com/oracle/jvmci/compiler/CompilerThreadFactory.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.jvmci.compiler/src/com/oracle/jvmci/compiler/CompilerThreadFactory.java Wed Jun 03 15:47:54 2015 +0200 @@ -0,0 +1,56 @@ +/* + * 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.jvmci.compiler; + +import java.util.concurrent.*; + +import com.oracle.jvmci.debug.*; + +/** + * Facility for creating {@linkplain CompilerThread compiler threads}. + */ +public class CompilerThreadFactory implements ThreadFactory { + + /** + * Capability to get a thread-local debug configuration for the current thread. + */ + public interface DebugConfigAccess { + /** + * Get a thread-local debug configuration for the current thread. This will be null if + * debugging is {@linkplain Debug#isEnabled() disabled}. + */ + JVMCIDebugConfig getDebugConfig(); + } + + protected final String threadNamePrefix; + protected final DebugConfigAccess debugConfigAccess; + + public CompilerThreadFactory(String threadNamePrefix, DebugConfigAccess debugConfigAccess) { + this.threadNamePrefix = threadNamePrefix; + this.debugConfigAccess = debugConfigAccess; + } + + public Thread newThread(Runnable r) { + return new CompilerThread(r, threadNamePrefix, debugConfigAccess); + } +} diff -r 20ace3139510 -r 3d15183f3c93 graal/com.oracle.jvmci.debug/src/com/oracle/jvmci/debug/DebugConfigCustomizer.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.jvmci.debug/src/com/oracle/jvmci/debug/DebugConfigCustomizer.java Wed Jun 03 15:47:54 2015 +0200 @@ -0,0 +1,29 @@ +/* + * Copyright (c) 2015, 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.jvmci.debug; + +import com.oracle.jvmci.service.*; + +public interface DebugConfigCustomizer extends Service { + void customize(DebugConfig config); +} diff -r 20ace3139510 -r 3d15183f3c93 graal/com.oracle.jvmci.debug/src/com/oracle/jvmci/debug/DebugEnvironment.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.jvmci.debug/src/com/oracle/jvmci/debug/DebugEnvironment.java Wed Jun 03 15:47:54 2015 +0200 @@ -0,0 +1,56 @@ +/* + * 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.jvmci.debug; + +import static com.oracle.jvmci.debug.JVMCIDebugConfig.*; + +import java.io.*; +import java.util.*; + +import com.oracle.jvmci.service.*; + +public class DebugEnvironment { + + public static JVMCIDebugConfig initialize(PrintStream log) { + + // Ensure Graal runtime is initialized prior to Debug being initialized as the former + // may include processing command line options used by the latter. + // Graal.getRuntime(); + + if (!Debug.isEnabled()) { + log.println("WARNING: Scope debugging needs to be enabled with -esa or -D" + Debug.Initialization.INITIALIZER_PROPERTY_NAME + "=true"); + return null; + } + List dumpHandlers = new ArrayList<>(); + List verifyHandlers = new ArrayList<>(); + JVMCIDebugConfig debugConfig = new JVMCIDebugConfig(Log.getValue(), Meter.getValue(), TrackMemUse.getValue(), Time.getValue(), Dump.getValue(), Verify.getValue(), MethodFilter.getValue(), + log, dumpHandlers, verifyHandlers); + + for (DebugConfigCustomizer customizer : Services.load(DebugConfigCustomizer.class)) { + customizer.customize(debugConfig); + } + + Debug.setConfig(debugConfig); + return debugConfig; + } +} diff -r 20ace3139510 -r 3d15183f3c93 graal/com.oracle.jvmci.debug/src/com/oracle/jvmci/debug/DebugFilter.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.jvmci.debug/src/com/oracle/jvmci/debug/DebugFilter.java Wed Jun 03 15:47:54 2015 +0200 @@ -0,0 +1,185 @@ +/* + * 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.jvmci.debug; + +import java.util.*; +import java.util.regex.*; + +import com.oracle.jvmci.debug.internal.*; + +/** + * Implements the filter specified by the {@link JVMCIDebugConfig#Dump}, + * {@link JVMCIDebugConfig#Log}, {@link JVMCIDebugConfig#Meter} and {@link JVMCIDebugConfig#Time} + * options. + *

+ * These options enable the associated debug facility if their filter matches the + * {@linkplain DebugScope#getQualifiedName() name} of the {@linkplain Debug#currentScope() current + * scope}. For the {@link JVMCIDebugConfig#Dump} and {@link JVMCIDebugConfig#Log} options, the log + * or dump level is set. The {@link JVMCIDebugConfig#Meter} and {@link JVMCIDebugConfig#Time} + * options don't have a level, for them {@code level = 0} means disabled and a {@code level > 0} + * means enabled. + *

+ * A filter is a list of comma-separated terms of the form {@code [:]}. + * {@code } is interpreted as a glob pattern if it contains a "*" or "?" character. + * Otherwise, it is interpreted as a substring. If {@code } is empty, it matches every + * scope. If {@code :} is omitted, it defaults to {@link Debug#DEFAULT_LOG_LEVEL}. The term + * {@code ~} is a shorthand for {@code :0} to disable a debug facility for a + * pattern. + *

+ * The resulting log level of a scope is determined by the last matching term. If no term + * matches, the log level is 0 (disabled). A filter with no terms matches every scope with a log + * level of {@link Debug#DEFAULT_LOG_LEVEL}. + * + *

Examples of filters

+ * + *
    + *
  • (empty string)
    + * Matches any scope with log level {@link Debug#DEFAULT_LOG_LEVEL}. + * + *
  • {@code :1}
    + * Matches any scope with log level 1. + * + *
  • {@code *}
    + * Matches any scope with log level {@link Debug#DEFAULT_LOG_LEVEL}. + * + *
  • {@code CodeGen,CodeInstall}
    + * Matches scopes containing "CodeGen" or "CodeInstall", both with log level + * {@link Debug#DEFAULT_LOG_LEVEL}. + * + *
  • {@code CodeGen:2,CodeInstall:1}
    + * Matches scopes containing "CodeGen" with log level 2, or "CodeInstall" with log level 1. + * + *
  • {@code :1,Dead:2}
    + * Matches scopes containing "Dead" with log level 2, and all other scopes with log level 1. + * + *
  • {@code :1,Dead:0}
    + * Matches all scopes with log level 1, except those containing "Dead". + * + *
  • {@code Code*}
    + * Matches scopes starting with "Code" with log level {@link Debug#DEFAULT_LOG_LEVEL}. + * + *
  • {@code Code,~Dead}
    + * Matches scopes containing "Code" but not "Dead", with log level {@link Debug#DEFAULT_LOG_LEVEL}. + *
+ */ +final class DebugFilter { + + public static DebugFilter parse(String spec) { + if (spec == null) { + return null; + } + return new DebugFilter(spec.split(",")); + } + + private final Term[] terms; + + private DebugFilter(String[] terms) { + if (terms.length == 0) { + this.terms = null; + } else { + this.terms = new Term[terms.length]; + for (int i = 0; i < terms.length; i++) { + String t = terms[i]; + int idx = t.indexOf(':'); + + String pattern; + int level; + if (idx < 0) { + if (t.startsWith("~")) { + pattern = t.substring(1); + level = 0; + } else { + pattern = t; + level = Debug.DEFAULT_LOG_LEVEL; + } + } else { + pattern = t.substring(0, idx); + if (idx + 1 < t.length()) { + level = Integer.parseInt(t.substring(idx + 1)); + } else { + level = Debug.DEFAULT_LOG_LEVEL; + } + } + + this.terms[i] = new Term(pattern, level); + } + } + } + + /** + * Check whether a given input is matched by this filter, and determine the log level. + */ + public int matchLevel(String input) { + if (terms == null) { + return Debug.DEFAULT_LOG_LEVEL; + } else { + int level = 0; + for (Term t : terms) { + if (t.matches(input)) { + level = t.level; + } + } + return level; + } + } + + @Override + public String toString() { + StringBuilder buf = new StringBuilder("DebugFilter"); + if (terms != null) { + buf.append(Arrays.toString(terms)); + } else { + buf.append("[]"); + } + return buf.toString(); + } + + private static class Term { + + private final Pattern pattern; + public final int level; + + public Term(String filter, int level) { + this.level = level; + 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()) + ":" + level; + } + } +} diff -r 20ace3139510 -r 3d15183f3c93 graal/com.oracle.jvmci.debug/src/com/oracle/jvmci/debug/JVMCIDebugConfig.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.jvmci.debug/src/com/oracle/jvmci/debug/JVMCIDebugConfig.java Wed Jun 03 15:47:54 2015 +0200 @@ -0,0 +1,303 @@ +/* + * 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.jvmci.debug; + +import java.io.*; +import java.util.*; + +import com.oracle.jvmci.code.*; +import com.oracle.jvmci.meta.*; +import com.oracle.jvmci.options.*; + +public class JVMCIDebugConfig implements DebugConfig { + @SuppressWarnings("all") + private static boolean assertionsEnabled() { + boolean assertionsEnabled = false; + assert assertionsEnabled = true; + return assertionsEnabled; + } + + // @formatter:off + @Option(help = "Pattern for scope(s) in which dumping is enabled (see DebugFilter and Debug.dump)", type = OptionType.Debug) + public static final OptionValue Dump = new OptionValue<>(null); + @Option(help = "Pattern for scope(s) in which metering is enabled (see DebugFilter and Debug.metric). " + + "An empty value enables all metrics unconditionally.", type = OptionType.Debug) + public static final OptionValue Meter = new OptionValue<>(null); + @Option(help = "Pattern for scope(s) in which verification is enabled (see DebugFilter and Debug.verify).", type = OptionType.Debug) + public static final OptionValue Verify = new OptionValue() { + @Override + protected String defaultValue() { + return assertionsEnabled() ? "" : null; + } + }; + @Option(help = "Pattern for scope(s) in which memory use tracking is enabled (see DebugFilter and Debug.metric). " + + "An empty value enables all memory use trackers unconditionally.", type = OptionType.Debug) + public static final OptionValue TrackMemUse = new OptionValue<>(null); + @Option(help = "Pattern for scope(s) in which timing is enabled (see DebugFilter and Debug.timer). " + + "An empty value enables all timers unconditionally.", type = OptionType.Debug) + public static final OptionValue Time = new OptionValue<>(null); + @Option(help = "Pattern for scope(s) in which logging is enabled (see DebugFilter and Debug.log)", type = OptionType.Debug) + public static final OptionValue Log = new OptionValue<>(null); + @Option(help = "Pattern for filtering debug scope output based on method context (see MethodFilter)", type = OptionType.Debug) + public static final OptionValue MethodFilter = new OptionValue<>(null); + @Option(help = "Only check MethodFilter against the root method in the context if true, otherwise check all methods", type = OptionType.Debug) + public static final OptionValue MethodFilterRootOnly = new OptionValue<>(false); + + @Option(help = "How to print metric and timing values:%n" + + "Name - aggregate by unqualified name%n" + + "Partial - aggregate by partially qualified name (e.g., A.B.C.D.Counter and X.Y.Z.D.Counter will be merged to D.Counter)%n" + + "Complete - aggregate by qualified name%n" + + "Thread - aggregate by qualified name and thread", type = OptionType.Debug) + public static final OptionValue DebugValueSummary = new OptionValue<>("Name"); + @Option(help = "Omit reporting 0-value metrics", type = OptionType.Debug) + public static final OptionValue SuppressZeroDebugValues = new OptionValue<>(true); + @Option(help = "Only report debug values for maps which match the regular expression.", type = OptionType.Debug) + public static final OptionValue DebugValueThreadFilter = new OptionValue<>(null); + @Option(help = "Send Graal IR to dump handlers on error", type = OptionType.Debug) + public static final OptionValue DumpOnError = new OptionValue<>(false); + @Option(help = "Intercept also bailout exceptions", type = OptionType.Debug) + public static final OptionValue InterceptBailout = new OptionValue<>(false); + @Option(help = "Enable more verbose log output when available", type = OptionType.Debug) + public static final OptionValue LogVerbose = new OptionValue<>(false); + // @formatter:on + + static boolean isNotEmpty(OptionValue option) { + return option.getValue() != null && !option.getValue().isEmpty(); + } + + public static boolean areDebugScopePatternsEnabled() { + return DumpOnError.getValue() || Dump.getValue() != null || Log.getValue() != null || areScopedMetricsOrTimersEnabled(); + } + + /** + * Determines if any of {@link #Meter}, {@link #Time} or {@link #TrackMemUse} has a non-null, + * non-empty value. + */ + public static boolean areScopedMetricsOrTimersEnabled() { + return isNotEmpty(Meter) || isNotEmpty(Time) || isNotEmpty(TrackMemUse); + } + + private final DebugFilter logFilter; + private final DebugFilter meterFilter; + private final DebugFilter trackMemUseFilter; + private final DebugFilter timerFilter; + private final DebugFilter dumpFilter; + private final DebugFilter verifyFilter; + private final MethodFilter[] methodFilter; + private final List dumpHandlers; + private final List verifyHandlers; + private final PrintStream output; + private final Set extraFilters = new HashSet<>(); + + public JVMCIDebugConfig(String logFilter, String meterFilter, String trackMemUseFilter, String timerFilter, String dumpFilter, String verifyFilter, String methodFilter, PrintStream output, + List dumpHandlers, List verifyHandlers) { + this.logFilter = DebugFilter.parse(logFilter); + this.meterFilter = DebugFilter.parse(meterFilter); + this.trackMemUseFilter = DebugFilter.parse(trackMemUseFilter); + this.timerFilter = DebugFilter.parse(timerFilter); + this.dumpFilter = DebugFilter.parse(dumpFilter); + this.verifyFilter = DebugFilter.parse(verifyFilter); + if (methodFilter == null || methodFilter.isEmpty()) { + this.methodFilter = null; + } else { + this.methodFilter = com.oracle.jvmci.debug.MethodFilter.parse(methodFilter); + } + + // 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.verifyHandlers = verifyHandlers; + this.output = output; + } + + public int getLogLevel() { + return getLevel(logFilter); + } + + public boolean isLogEnabledForMethod() { + return isEnabledForMethod(logFilter); + } + + public boolean isMeterEnabled() { + return isEnabled(meterFilter); + } + + public boolean isMemUseTrackingEnabled() { + return isEnabled(trackMemUseFilter); + } + + public int getDumpLevel() { + return getLevel(dumpFilter); + } + + public boolean isDumpEnabledForMethod() { + return isEnabledForMethod(dumpFilter); + } + + public boolean isVerifyEnabled() { + return isEnabled(verifyFilter); + } + + public boolean isVerifyEnabledForMethod() { + return isEnabledForMethod(verifyFilter); + } + + public boolean isTimeEnabled() { + return isEnabled(timerFilter); + } + + public PrintStream output() { + return output; + } + + private boolean isEnabled(DebugFilter filter) { + return getLevel(filter) > 0; + } + + private int getLevel(DebugFilter filter) { + int level; + if (filter == null) { + level = 0; + } else { + level = filter.matchLevel(Debug.currentScope()); + } + if (level > 0 && !checkMethodFilter()) { + level = 0; + } + return level; + } + + private boolean isEnabledForMethod(DebugFilter filter) { + return filter != null && checkMethodFilter(); + } + + /** + * Extracts a {@link JavaMethod} from an opaque debug context. + * + * @return the {@link JavaMethod} represented by {@code context} or null + */ + public static JavaMethod asJavaMethod(Object context) { + if (context instanceof JavaMethodContex) { + return ((JavaMethodContex) context).asJavaMethod(); + } + return null; + } + + private boolean checkMethodFilter() { + if (methodFilter == null && extraFilters.isEmpty()) { + return true; + } else { + JavaMethod lastMethod = null; + for (Object o : Debug.context()) { + if (extraFilters.contains(o)) { + return true; + } else if (methodFilter != null) { + JavaMethod method = asJavaMethod(o); + if (method != null) { + if (!MethodFilterRootOnly.getValue()) { + if (com.oracle.jvmci.debug.MethodFilter.matches(methodFilter, method)) { + return true; + } + } else { + /* + * The context values operate as a stack so if we want MethodFilter to + * only apply to the root method we have to check only the last method + * seen. + */ + lastMethod = method; + } + } + } + } + if (lastMethod != null && com.oracle.jvmci.debug.MethodFilter.matches(methodFilter, lastMethod)) { + 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 && !InterceptBailout.getValue()) { + return null; + } + Debug.setConfig(Debug.fixedConfig(Debug.DEFAULT_LOG_LEVEL, Debug.DEFAULT_LOG_LEVEL, false, false, false, false, dumpHandlers, verifyHandlers, output)); + Debug.log(String.format("Exception occurred in scope: %s", Debug.currentScope())); + for (Object o : Debug.context()) { + if (DumpOnError.getValue()) { + Debug.dump(o, "Exception"); + } else { + Debug.log("Context obj %s", o); + } + + } + return null; + } + + @Override + public Collection dumpHandlers() { + return dumpHandlers; + } + + @Override + public Collection verifyHandlers() { + return verifyHandlers; + } + + @Override + public void addToContext(Object o) { + extraFilters.add(o); + } + + @Override + public void removeFromContext(Object o) { + extraFilters.remove(o); + } +} diff -r 20ace3139510 -r 3d15183f3c93 graal/com.oracle.jvmci.debug/src/com/oracle/jvmci/debug/JavaMethodContex.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.jvmci.debug/src/com/oracle/jvmci/debug/JavaMethodContex.java Wed Jun 03 15:47:54 2015 +0200 @@ -0,0 +1,33 @@ +/* + * Copyright (c) 2015, 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.jvmci.debug; + +import com.oracle.jvmci.meta.*; + +/** + * Interface for objects used in Debug {@linkplain Debug#context() context} that can provide a + * {@link JavaMethod}. + */ +public interface JavaMethodContex { + JavaMethod asJavaMethod(); +} diff -r 20ace3139510 -r 3d15183f3c93 graal/com.oracle.jvmci.debug/src/com/oracle/jvmci/debug/MethodFilter.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.jvmci.debug/src/com/oracle/jvmci/debug/MethodFilter.java Wed Jun 03 15:47:54 2015 +0200 @@ -0,0 +1,231 @@ +/* + * 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.jvmci.debug; + +import com.oracle.jvmci.meta.JavaType; +import com.oracle.jvmci.meta.JavaMethod; +import com.oracle.jvmci.meta.Signature; +import java.util.*; +import java.util.regex.*; + +/** + * 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: + * + *
+ * SourcePatterns = SourcePattern ["," SourcePatterns] .
+ * 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: + * + *
    + *
  • + * + *
    + * visit(Argument;BlockScope)
    + * 
    + * + * 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.
  • + *
  • + * + *
    + * arraycopy(Object;;;;)
    + * 
    + * + * 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.
  • + *
  • + * + *
    + * com.oracle.graal.compiler.graph.PostOrderNodeIterator.*
    + * 
    + * + * Matches all methods in the class "com.oracle.graal.compiler.graph.PostOrderNodeIterator".
  • + *
  • + * + *
    + * *
    + * 
    + * + * Matches all methods in all classes
  • + *
  • + * + *
    + * com.oracle.graal.compiler.graph.*.visit
    + * 
    + * + * Matches all methods named "visit" in classes in the package "com.oracle.graal.compiler.graph". + *
  • + * + *
    + * arraycopy,toString
    + * 
    + * + * Matches all methods named "arraycopy" or "toString", meaning that ',' acts as an or + * operator.
  • + *
+ */ +public class MethodFilter { + + private final Pattern clazz; + private final Pattern methodName; + private final Pattern[] signature; + + /** + * Parses a string containing list of comma separated filter patterns into an array of + * {@link MethodFilter}s. + */ + public static MethodFilter[] parse(String commaSeparatedPatterns) { + String[] filters = commaSeparatedPatterns.split(","); + MethodFilter[] methodFilters = new MethodFilter[filters.length]; + for (int i = 0; i < filters.length; i++) { + methodFilters[i] = new MethodFilter(filters[i]); + } + return methodFilters; + } + + /** + * Determines if a given method is matched by a given array of filters. + */ + public static boolean matches(MethodFilter[] filters, JavaMethod method) { + for (MethodFilter filter : filters) { + if (filter.matches(method)) { + return true; + } + } + return false; + } + + /** + * Determines if a given class name is matched by a given array of filters. + */ + public static boolean matchesClassName(MethodFilter[] filters, String className) { + for (MethodFilter filter : filters) { + if (filter.matchesClassName(className)) { + return true; + } + } + return false; + } + + 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)); + } + } + + /** + * Determines if the class part of this filter matches a given class name. + */ + public boolean matchesClassName(String className) { + return clazz == null || clazz.matcher(className).matches(); + } + + 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(o.getDeclaringClass().toJavaName()).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 = type.toJavaName(); + 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(); + } +} diff -r 20ace3139510 -r 3d15183f3c93 graal/com.oracle.jvmci.hotspot/src/com/oracle/jvmci/hotspot/CompilationStatistics.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.jvmci.hotspot/src/com/oracle/jvmci/hotspot/CompilationStatistics.java Wed Jun 03 15:47:54 2015 +0200 @@ -0,0 +1,212 @@ +/* + * 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.jvmci.hotspot; + +import static java.lang.Thread.*; + +import java.io.*; +import java.lang.annotation.*; +import java.lang.management.*; +import java.lang.reflect.*; +import java.util.*; +import java.util.concurrent.*; + +import com.sun.management.ThreadMXBean; + +@SuppressWarnings("unused") +public final class CompilationStatistics { + + private static final long RESOLUTION = 100000000; + private static final boolean ENABLED = Boolean.getBoolean("graal.comp.stats"); + + private static final CompilationStatistics DUMMY = new CompilationStatistics(null, false); + + private static ConcurrentLinkedDeque list = new ConcurrentLinkedDeque<>(); + + private static final ThreadLocal> current = new ThreadLocal>() { + + @Override + protected Deque initialValue() { + return new ArrayDeque<>(); + } + }; + + @Retention(RetentionPolicy.RUNTIME) + @Target(ElementType.FIELD) + private static @interface NotReported { + } + + @Retention(RetentionPolicy.RUNTIME) + @Target(ElementType.FIELD) + private static @interface TimeValue { + } + + private static long zeroTime = System.nanoTime(); + + private static long getThreadAllocatedBytes() { + ThreadMXBean thread = (ThreadMXBean) ManagementFactory.getThreadMXBean(); + return thread.getThreadAllocatedBytes(currentThread().getId()); + } + + @NotReported private final long startTime; + @NotReported private long threadAllocatedBytesStart; + + private int bytecodeCount; + private int codeSize; + @TimeValue private long duration; + private long memoryUsed; + private final boolean osr; + private final String holder; + private final String name; + private final String signature; + + private CompilationStatistics(HotSpotResolvedJavaMethod method, boolean osr) { + this.osr = osr; + if (method != null) { + holder = method.getDeclaringClass().getName(); + name = method.getName(); + signature = method.getSignature().toMethodDescriptor(); + startTime = System.nanoTime(); + bytecodeCount = method.getCodeSize(); + threadAllocatedBytesStart = getThreadAllocatedBytes(); + } else { + holder = ""; + name = ""; + signature = ""; + startTime = 0; + } + } + + public void finish(HotSpotResolvedJavaMethod method, HotSpotInstalledCode code) { + if (ENABLED) { + duration = System.nanoTime() - startTime; + codeSize = (int) code.getCodeSize(); + memoryUsed = getThreadAllocatedBytes() - threadAllocatedBytesStart; + if (current.get().getLast() != this) { + throw new RuntimeException("mismatch in finish()"); + } + current.get().removeLast(); + } + } + + public static CompilationStatistics current() { + return current.get().isEmpty() ? null : current.get().getLast(); + } + + public static CompilationStatistics create(HotSpotResolvedJavaMethod method, boolean isOSR) { + if (ENABLED) { + CompilationStatistics stats = new CompilationStatistics(method, isOSR); + list.add(stats); + current.get().addLast(stats); + return stats; + } else { + return DUMMY; + } + } + + @SuppressWarnings("deprecation") + public static void clear(String dumpName) { + if (!ENABLED) { + return; + } + try { + ConcurrentLinkedDeque snapshot = list; + long snapshotZeroTime = zeroTime; + + list = new ConcurrentLinkedDeque<>(); + zeroTime = System.nanoTime(); + + Date now = new Date(); + String dateString = (now.getYear() + 1900) + "-" + (now.getMonth() + 1) + "-" + now.getDate() + "-" + now.getHours() + "" + now.getMinutes(); + + dumpCompilations(snapshot, dumpName, dateString); + + try (FileOutputStream fos = new FileOutputStream("timeline_" + dateString + "_" + dumpName + ".csv", true); PrintStream out = new PrintStream(fos)) { + + long[] timeSpent = new long[10000]; + int maxTick = 0; + for (CompilationStatistics stats : snapshot) { + long start = stats.startTime - snapshotZeroTime; + long duration = stats.duration; + if (start < 0) { + duration -= -start; + start = 0; + } + + int tick = (int) (start / RESOLUTION); + long timeLeft = RESOLUTION - (start % RESOLUTION); + + while (tick < timeSpent.length && duration > 0) { + if (tick > maxTick) { + maxTick = tick; + } + timeSpent[tick] += Math.min(timeLeft, duration); + duration -= timeLeft; + tick++; + timeLeft = RESOLUTION; + } + } + String timelineName = System.getProperty("stats.timeline.name"); + if (timelineName != null && !timelineName.isEmpty()) { + out.print(timelineName + "\t"); + } + for (int i = 0; i <= maxTick; i++) { + out.print((timeSpent[i] * 100 / RESOLUTION) + "\t"); + } + out.println(); + } + } catch (Exception e) { + throw new RuntimeException(e); + } + } + + protected static void dumpCompilations(ConcurrentLinkedDeque snapshot, String dumpName, String dateString) throws IllegalAccessException, FileNotFoundException { + String fileName = "compilations_" + dateString + "_" + dumpName + ".csv"; + try (PrintStream out = new PrintStream(fileName)) { + // output the list of all compilations + + Field[] declaredFields = CompilationStatistics.class.getDeclaredFields(); + ArrayList fields = new ArrayList<>(); + for (Field field : declaredFields) { + if (!Modifier.isStatic(field.getModifiers()) && !field.isAnnotationPresent(NotReported.class)) { + fields.add(field); + } + } + for (Field field : fields) { + out.print(field.getName() + "\t"); + } + out.println(); + for (CompilationStatistics stats : snapshot) { + for (Field field : fields) { + if (field.isAnnotationPresent(TimeValue.class)) { + double value = field.getLong(stats) / 1000000d; + out.print(String.format(Locale.ENGLISH, "%.3f", value) + "\t"); + } else { + out.print(field.get(stats) + "\t"); + } + } + out.println(); + } + } + } +} diff -r 20ace3139510 -r 3d15183f3c93 graal/com.oracle.jvmci.hotspot/src/com/oracle/jvmci/hotspot/CompilationTask.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.jvmci.hotspot/src/com/oracle/jvmci/hotspot/CompilationTask.java Wed Jun 03 15:47:54 2015 +0200 @@ -0,0 +1,293 @@ +/* + * Copyright (c) 2012, 2015, 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.jvmci.hotspot; + +import static com.oracle.jvmci.common.UnsafeAccess.*; +import static com.oracle.jvmci.debug.Debug.*; +import static com.oracle.jvmci.compiler.Compiler.*; + +import java.lang.management.*; +import java.util.concurrent.*; + +import com.oracle.jvmci.code.*; +import com.oracle.jvmci.compiler.Compiler; +import com.oracle.jvmci.debug.*; +import com.oracle.jvmci.debug.Debug.Scope; +import com.oracle.jvmci.debug.internal.*; +import com.oracle.jvmci.hotspot.events.*; +import com.oracle.jvmci.hotspot.events.EventProvider.CompilationEvent; +import com.oracle.jvmci.hotspot.events.EventProvider.CompilerFailureEvent; +import com.oracle.jvmci.meta.*; +import com.oracle.jvmci.service.*; + +//JaCoCo Exclude + +public class CompilationTask { + + private static final DebugMetric BAILOUTS = Debug.metric("Bailouts"); + + private static final EventProvider eventProvider; + static { + EventProvider provider = Services.loadSingle(EventProvider.class, false); + if (provider == null) { + eventProvider = new EmptyEventProvider(); + } else { + eventProvider = provider; + } + } + private static final Compiler compiler = Services.loadSingle(Compiler.class, true); + + private final HotSpotResolvedJavaMethod method; + private final int entryBCI; + private final int id; + + /** + * Specifies whether the compilation result is installed as the + * {@linkplain HotSpotNmethod#isDefault() default} nmethod for the compiled method. + */ + private final boolean installAsDefault; + + /** + * A {@link com.sun.management.ThreadMXBean} to be able to query some information about the + * current compiler thread, e.g. total allocated bytes. + */ + private static final com.sun.management.ThreadMXBean threadMXBean = (com.sun.management.ThreadMXBean) ManagementFactory.getThreadMXBean(); + + /** + * The address of the GraalEnv associated with this compilation or 0L if no such object exists. + */ + private final long graalEnv; + + public CompilationTask(HotSpotResolvedJavaMethod method, int entryBCI, long graalEnv, int id, boolean installAsDefault) { + this.method = method; + this.entryBCI = entryBCI; + this.id = id; + this.graalEnv = graalEnv; + this.installAsDefault = installAsDefault; + } + + public ResolvedJavaMethod getMethod() { + return method; + } + + /** + * Returns the compilation id of this task. + * + * @return compile id + */ + public int getId() { + return id; + } + + public int getEntryBCI() { + return entryBCI; + } + + /** + * Time spent in compilation. + */ + private static final DebugTimer CompilationTime = Debug.timer("CompilationTime"); + + /** + * Meters the {@linkplain CompilationResult#getBytecodeSize() bytecodes} compiled. + */ + private static final DebugMetric CompiledBytecodes = Debug.metric("CompiledBytecodes"); + + public static final DebugTimer CodeInstallationTime = Debug.timer("CodeInstallation"); + + public void runCompilation() { + HotSpotVMConfig config = HotSpotJVMCIRuntime.runtime().getConfig(); + final long threadId = Thread.currentThread().getId(); + long startCompilationTime = System.nanoTime(); + HotSpotInstalledCode installedCode = null; + final boolean isOSR = entryBCI != Compiler.INVOCATION_ENTRY_BCI; + + // Log a compilation event. + CompilationEvent compilationEvent = eventProvider.newCompilationEvent(); + + // If there is already compiled code for this method on our level we simply return. + // Graal compiles are always at the highest compile level, even in non-tiered mode so we + // only need to check for that value. + if (method.hasCodeAtLevel(entryBCI, config.compilationLevelFullOptimization)) { + return; + } + + CompilationResult result = null; + try (DebugCloseable a = CompilationTime.start()) { + CompilationStatistics stats = CompilationStatistics.create(method, isOSR); + final boolean printCompilation = PrintCompilation.getValue() && !TTY.isSuppressed(); + if (printCompilation) { + TTY.println(getMethodDescription() + "..."); + } + + TTY.Filter filter = new TTY.Filter(PrintFilter.getValue(), method); + final long start = System.currentTimeMillis(); + final long allocatedBytesBefore = threadMXBean.getThreadAllocatedBytes(threadId); + + try (Scope s = Debug.scope("Compiling", new DebugDumpScope(String.valueOf(id), true))) { + // Begin the compilation event. + compilationEvent.begin(); + + result = compiler.compile(method, entryBCI, mustRecordMethodInlining(config)); + + result.setId(getId()); + } catch (Throwable e) { + throw Debug.handle(e); + } finally { + // End the compilation event. + compilationEvent.end(); + + filter.remove(); + final boolean printAfterCompilation = PrintAfterCompilation.getValue() && !TTY.isSuppressed(); + + if (printAfterCompilation || printCompilation) { + final long stop = System.currentTimeMillis(); + final int targetCodeSize = result != null ? result.getTargetCodeSize() : -1; + final long allocatedBytesAfter = threadMXBean.getThreadAllocatedBytes(threadId); + final long allocatedBytes = (allocatedBytesAfter - allocatedBytesBefore) / 1024; + + if (printAfterCompilation) { + TTY.println(getMethodDescription() + String.format(" | %4dms %5dB %5dkB", stop - start, targetCodeSize, allocatedBytes)); + } else if (printCompilation) { + TTY.println(String.format("%-6d Graal %-70s %-45s %-50s | %4dms %5dB %5dkB", id, "", "", "", stop - start, targetCodeSize, allocatedBytes)); + } + } + } + + try (DebugCloseable b = CodeInstallationTime.start()) { + installedCode = (HotSpotInstalledCode) installMethod(result); + } + stats.finish(method, installedCode); + } catch (BailoutException bailout) { + BAILOUTS.increment(); + if (ExitVMOnBailout.getValue()) { + TTY.cachedOut.println(method.format("Bailout in %H.%n(%p)")); + bailout.printStackTrace(TTY.cachedOut); + System.exit(-1); + } else if (PrintBailout.getValue()) { + TTY.cachedOut.println(method.format("Bailout in %H.%n(%p)")); + bailout.printStackTrace(TTY.cachedOut); + } + } catch (Throwable t) { + if (PrintStackTraceOnException.getValue() || ExitVMOnException.getValue()) { + t.printStackTrace(TTY.cachedOut); + } + + // Log a failure event. + CompilerFailureEvent event = eventProvider.newCompilerFailureEvent(); + if (event.shouldWrite()) { + event.setCompileId(getId()); + event.setMessage(t.getMessage()); + event.commit(); + } + + if (ExitVMOnException.getValue()) { + System.exit(-1); + } + } finally { + int compiledBytecodes = 0; + int codeSize = 0; + if (result != null) { + compiledBytecodes = result.getBytecodeSize(); + } + if (installedCode != null) { + codeSize = installedCode.getSize(); + } + CompiledBytecodes.add(compiledBytecodes); + + // Log a compilation event. + if (compilationEvent.shouldWrite()) { + compilationEvent.setMethod(method.format("%H.%n(%p)")); + compilationEvent.setCompileId(getId()); + compilationEvent.setCompileLevel(config.compilationLevelFullOptimization); + compilationEvent.setSucceeded(result != null && installedCode != null); + compilationEvent.setIsOsr(isOSR); + compilationEvent.setCodeSize(codeSize); + compilationEvent.setInlinedBytes(compiledBytecodes); + compilationEvent.commit(); + } + + if (graalEnv != 0) { + long ctask = unsafe.getAddress(graalEnv + config.jvmciEnvTaskOffset); + assert ctask != 0L; + unsafe.putInt(ctask + config.compileTaskNumInlinedBytecodesOffset, compiledBytecodes); + } + long compilationTime = System.nanoTime() - startCompilationTime; + if ((config.ciTime || config.ciTimeEach) && installedCode != null) { + long timeUnitsPerSecond = TimeUnit.NANOSECONDS.convert(1, TimeUnit.SECONDS); + CompilerToVM c2vm = HotSpotJVMCIRuntime.runtime().getCompilerToVM(); + c2vm.notifyCompilationStatistics(id, method, entryBCI != Compiler.INVOCATION_ENTRY_BCI, compiledBytecodes, compilationTime, timeUnitsPerSecond, installedCode); + } + } + } + + /** + * Determines whether to disable method inlining recording for the method being compiled. + */ + private boolean mustRecordMethodInlining(HotSpotVMConfig config) { + if (config.ciTime || config.ciTimeEach || CompiledBytecodes.isEnabled()) { + return true; + } + if (graalEnv == 0 || unsafe.getByte(graalEnv + config.jvmciEnvJvmtiCanHotswapOrPostBreakpointOffset) != 0) { + return true; + } + return false; + } + + private String getMethodDescription() { + return String.format("%-6d Graal %-70s %-45s %-50s %s", id, method.getDeclaringClass().getName(), method.getName(), method.getSignature().toMethodDescriptor(), + entryBCI == Compiler.INVOCATION_ENTRY_BCI ? "" : "(OSR@" + entryBCI + ") "); + } + + private InstalledCode installMethod(final CompilationResult compResult) { + final HotSpotCodeCacheProvider codeCache = (HotSpotCodeCacheProvider) HotSpotJVMCIRuntime.runtime().getHostJVMCIBackend().getCodeCache(); + InstalledCode installedCode = null; + try (Scope s = Debug.scope("CodeInstall", new DebugDumpScope(String.valueOf(id), true), codeCache, method)) { + installedCode = codeCache.installMethod(method, compResult, graalEnv, installAsDefault); + } catch (Throwable e) { + throw Debug.handle(e); + } + return installedCode; + } + + @Override + public String toString() { + return "Compilation[id=" + id + ", " + method.format("%H.%n(%p)") + (entryBCI == Compiler.INVOCATION_ENTRY_BCI ? "" : "@" + entryBCI) + "]"; + } + + /** + * Compiles a method to machine code. + */ + public static void compileMethod(HotSpotResolvedJavaMethod method, int entryBCI, long graalEnv, int id) { + // Ensure a debug configuration for this thread is initialized + if (Debug.isEnabled() && DebugScope.getConfig() == null) { + DebugEnvironment.initialize(TTY.cachedOut); + } + + CompilationTask task = new CompilationTask(method, entryBCI, graalEnv, id, true); + try (DebugConfigScope dcs = setConfig(new TopLevelDebugConfig())) { + task.runCompilation(); + } + return; + } +} diff -r 20ace3139510 -r 3d15183f3c93 graal/com.oracle.jvmci.hotspot/src/com/oracle/jvmci/hotspot/CompileTheWorld.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.jvmci.hotspot/src/com/oracle/jvmci/hotspot/CompileTheWorld.java Wed Jun 03 15:47:54 2015 +0200 @@ -0,0 +1,492 @@ +/* + * 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.jvmci.hotspot; + +//import static com.oracle.graal.compiler.common.GraalOptions.*; +//import static com.oracle.graal.hotspot.HotSpotGraalRuntime.*; +//import static com.oracle.graal.nodes.StructuredGraph.*; +import static com.oracle.jvmci.compiler.Compiler.*; +import static com.oracle.jvmci.debug.internal.MemUseTrackerImpl.*; + +import java.io.*; +import java.lang.annotation.*; +import java.lang.reflect.*; +import java.net.*; +import java.util.*; +import java.util.concurrent.*; +import java.util.concurrent.atomic.*; +import java.util.jar.*; +import java.util.stream.*; + +import com.oracle.jvmci.compiler.*; +import com.oracle.jvmci.compiler.CompilerThreadFactory.DebugConfigAccess; +import com.oracle.jvmci.compiler.Compiler; +import com.oracle.jvmci.debug.*; +import com.oracle.jvmci.debug.internal.*; +import com.oracle.jvmci.meta.*; +import com.oracle.jvmci.options.*; +import com.oracle.jvmci.options.OptionUtils.OptionConsumer; +import com.oracle.jvmci.options.OptionValue.OverrideScope; +import com.oracle.jvmci.runtime.*; + +/** + * This class implements compile-the-world functionality in Graal. + */ +public final class CompileTheWorld { + + /** + * Magic token to trigger reading files from the boot class path. + */ + public static final String SUN_BOOT_CLASS_PATH = "sun.boot.class.path"; + + public static class Options { + // @formatter:off + @Option(help = "Compile all methods in all classes on given class path", type = OptionType.Debug) + public static final OptionValue CompileTheWorldClasspath = new OptionValue<>(SUN_BOOT_CLASS_PATH); + @Option(help = "Verbose CompileTheWorld operation", type = OptionType.Debug) + public static final OptionValue CompileTheWorldVerbose = new OptionValue<>(true); + @Option(help = "The number of CompileTheWorld iterations to perform", type = OptionType.Debug) + public static final OptionValue CompileTheWorldIterations = new OptionValue<>(1); + @Option(help = "Only compile methods matching this filter", type = OptionType.Debug) + public static final OptionValue CompileTheWorldMethodFilter = new OptionValue<>(null); + @Option(help = "Exclude methods matching this filter from compilation", type = OptionType.Debug) + public static final OptionValue CompileTheWorldExcludeMethodFilter = new OptionValue<>(null); + @Option(help = "First class to consider when using -XX:+CompileTheWorld", type = OptionType.Debug) + public static final OptionValue CompileTheWorldStartAt = new OptionValue<>(1); + @Option(help = "Last class to consider when using -XX:+CompileTheWorld", type = OptionType.Debug) + public static final OptionValue CompileTheWorldStopAt = new OptionValue<>(Integer.MAX_VALUE); + @Option(help = "Option value overrides to use during compile the world. For example, " + + "to disable inlining and partial escape analysis specify '-PartialEscapeAnalysis -Inline'. " + + "The format for each option is the same as on the command line just without the '-G:' prefix.", type = OptionType.Debug) + public static final OptionValue CompileTheWorldConfig = new OptionValue<>(null); + + @Option(help = "Run CTW using as many threads as there are processors on the system", type = OptionType.Debug) + public static final OptionValue CompileTheWorldMultiThreaded = new OptionValue<>(false); + @Option(help = "Number of threads to use for multithreaded CTW. Defaults to Runtime.getRuntime().availableProcessors()", type = OptionType.Debug) + public static final OptionValue CompileTheWorldThreads = new OptionValue<>(0); + // @formatter:on + + /** + * Overrides {@link #CompileTheWorldStartAt} and {@link #CompileTheWorldStopAt} from + * {@code -XX} HotSpot options of the same name if the latter have non-default values. + */ + public static void overrideWithNativeOptions(HotSpotVMConfig c) { + if (c.compileTheWorldStartAt != 1) { + CompileTheWorldStartAt.setValue(c.compileTheWorldStartAt); + } + if (c.compileTheWorldStopAt != Integer.MAX_VALUE) { + CompileTheWorldStopAt.setValue(c.compileTheWorldStopAt); + } + } + } + + /** + * A mechanism for overriding Graal options that affect compilation. A {@link Config} object + * should be used in a try-with-resources statement to ensure overriding of options is scoped + * properly. For example: + * + *
+     *     Config config = ...;
+     *     try (AutoCloseable s = config == null ? null : config.apply()) {
+     *         // perform a Graal compilation
+     *     }
+     * 
+ */ + @SuppressWarnings("serial") + public static class Config extends HashMap, Object> implements OptionConsumer { + /** + * Creates a {@link Config} object by parsing a set of space separated override options. + * + * @param options a space separated set of option value settings with each option setting in + * a format compatible with + * {@link OptionUtils#parseOption(String, OptionConsumer)}. Ignored if null. + */ + public Config(String options) { + if (options != null) { + for (String option : options.split("\\s+")) { + OptionUtils.parseOption(option, this); + } + } + } + + /** + * Applies the overrides represented by this object. The overrides are in effect until + * {@link OverrideScope#close()} is called on the returned object. + */ + OverrideScope apply() { + return OptionValue.override(this); + } + + public void set(OptionDescriptor desc, Object value) { + put(desc.getOptionValue(), value); + } + } + + /** List of Zip/Jar files to compile (see {@link Options#CompileTheWorldClasspath}). */ + private final String files; + + /** Class index to start compilation at (see {@link Options#CompileTheWorldStartAt}). */ + private final int startAt; + + /** Class index to stop compilation at (see {@link Options#CompileTheWorldStopAt}). */ + private final int stopAt; + + /** Only compile methods matching one of the filters in this array if the array is non-null. */ + private final MethodFilter[] methodFilters; + + /** Exclude methods matching one of the filters in this array if the array is non-null. */ + private final MethodFilter[] excludeMethodFilters; + + // Counters + private int classFileCounter = 0; + private AtomicLong compiledMethodsCounter = new AtomicLong(); + private AtomicLong compileTime = new AtomicLong(); + private AtomicLong memoryUsed = new AtomicLong(); + + private boolean verbose; + private final Config config; + + /** + * Signal that the threads should start compiling in multithreaded mode. + */ + private boolean running; + + private ThreadPoolExecutor threadPool; + + /** + * Creates a compile-the-world instance. + * + * @param files {@link File#pathSeparator} separated list of Zip/Jar files to compile + * @param startAt index of the class file to start compilation at + * @param stopAt index of the class file to stop compilation at + * @param methodFilters + * @param excludeMethodFilters + */ + public CompileTheWorld(String files, Config config, int startAt, int stopAt, String methodFilters, String excludeMethodFilters, boolean verbose) { + this.files = files; + this.startAt = startAt; + this.stopAt = stopAt; + this.methodFilters = methodFilters == null || methodFilters.isEmpty() ? null : MethodFilter.parse(methodFilters); + this.excludeMethodFilters = excludeMethodFilters == null || excludeMethodFilters.isEmpty() ? null : MethodFilter.parse(excludeMethodFilters); + this.verbose = verbose; + this.config = config; + + // We don't want the VM to exit when a method fails to compile... + config.putIfAbsent(ExitVMOnException, false); + + // ...but we want to see exceptions. + config.putIfAbsent(PrintBailout, true); + config.putIfAbsent(PrintStackTraceOnException, true); + config.putIfAbsent(HotSpotResolvedJavaMethodImpl.Options.UseProfilingInformation, false); + } + + /** + * Compiles all methods in all classes in the Zip/Jar archive files in + * {@link Options#CompileTheWorldClasspath}. If {@link Options#CompileTheWorldClasspath} + * contains the magic token {@link #SUN_BOOT_CLASS_PATH} passed up from HotSpot we take the + * files from the boot class path. + */ + public void compile() throws Throwable { + // By default only report statistics for the CTW threads themselves + if (JVMCIDebugConfig.DebugValueThreadFilter.hasDefaultValue()) { + JVMCIDebugConfig.DebugValueThreadFilter.setValue("^CompileTheWorld"); + } + + if (SUN_BOOT_CLASS_PATH.equals(files)) { + final String[] entries = System.getProperty(SUN_BOOT_CLASS_PATH).split(File.pathSeparator); + String bcpFiles = ""; + for (int i = 0; i < entries.length; i++) { + final String entry = entries[i]; + + // We stop at rt.jar, unless it is the first boot class path entry. + if (entry.endsWith("rt.jar") && (i > 0)) { + break; + } + if (i > 0) { + bcpFiles += File.pathSeparator; + } + bcpFiles += entry; + } + compile(bcpFiles); + } else { + compile(files); + } + } + + public void println() { + println(""); + } + + public void println(String format, Object... args) { + println(String.format(format, args)); + } + + public void println(String s) { + if (verbose) { + TTY.println(s); + } + } + + /** + * Compiles all methods in all classes in the Zip/Jar files passed. + * + * @param fileList {@link File#pathSeparator} separated list of Zip/Jar files to compile + * @throws IOException + */ + private void compile(String fileList) throws IOException { + final String[] entries = fileList.split(File.pathSeparator); + long start = System.currentTimeMillis(); + + CompilerThreadFactory factory = new CompilerThreadFactory("CompileTheWorld", new DebugConfigAccess() { + public JVMCIDebugConfig getDebugConfig() { + if (Debug.isEnabled() && DebugScope.getConfig() == null) { + return DebugEnvironment.initialize(System.out); + } + return null; + } + }); + + /* + * Always use a thread pool, even for single threaded mode since it simplifies the use of + * DebugValueThreadFilter to filter on the thread names. + */ + int threadCount = 1; + if (Options.CompileTheWorldMultiThreaded.getValue()) { + threadCount = Options.CompileTheWorldThreads.getValue(); + if (threadCount == 0) { + threadCount = Runtime.getRuntime().availableProcessors(); + } + } else { + running = true; + } + threadPool = new ThreadPoolExecutor(threadCount, threadCount, 0L, TimeUnit.MILLISECONDS, new LinkedBlockingQueue(), factory); + + try (OverrideScope s = config.apply()) { + for (int i = 0; i < entries.length; i++) { + final String entry = entries[i]; + + // For now we only compile all methods in all classes in zip/jar files. + if (!entry.endsWith(".zip") && !entry.endsWith(".jar")) { + println("CompileTheWorld : Skipped classes in " + entry); + println(); + continue; + } + + if (methodFilters == null || methodFilters.length == 0) { + println("CompileTheWorld : Compiling all classes in " + entry); + } else { + String include = Arrays.asList(methodFilters).stream().map(MethodFilter::toString).collect(Collectors.joining(", ")); + println("CompileTheWorld : Compiling all methods in " + entry + " matching one of the following filters: " + include); + } + if (excludeMethodFilters != null && excludeMethodFilters.length > 0) { + String exclude = Arrays.asList(excludeMethodFilters).stream().map(MethodFilter::toString).collect(Collectors.joining(", ")); + println("CompileTheWorld : Excluding all methods matching one of the following filters: " + exclude); + } + println(); + + URL url = new URL("jar", "", "file:" + entry + "!/"); + ClassLoader loader = new URLClassLoader(new URL[]{url}); + + JarFile jarFile = new JarFile(entry); + Enumeration e = jarFile.entries(); + + while (e.hasMoreElements()) { + JarEntry je = e.nextElement(); + if (je.isDirectory() || !je.getName().endsWith(".class")) { + continue; + } + + // Are we done? + if (classFileCounter >= stopAt) { + break; + } + + String className = je.getName().substring(0, je.getName().length() - ".class".length()); + String dottedClassName = className.replace('/', '.'); + classFileCounter++; + + if (methodFilters != null && !MethodFilter.matchesClassName(methodFilters, dottedClassName)) { + continue; + } + if (excludeMethodFilters != null && MethodFilter.matchesClassName(excludeMethodFilters, dottedClassName)) { + continue; + } + + if (dottedClassName.startsWith("jdk.management.") || dottedClassName.startsWith("jdk.internal.cmm.*")) { + continue; + } + + try { + // Load and initialize class + Class javaClass = Class.forName(dottedClassName, true, loader); + + // Pre-load all classes in the constant pool. + try { + HotSpotResolvedObjectType objectType = HotSpotResolvedObjectTypeImpl.fromObjectClass(javaClass); + ConstantPool constantPool = objectType.constantPool(); + for (int cpi = 1; cpi < constantPool.length(); cpi++) { + constantPool.loadReferencedType(cpi, HotSpotConstantPool.Bytecodes.LDC); + } + } catch (Throwable t) { + // If something went wrong during pre-loading we just ignore it. + println("Preloading failed for (%d) %s: %s", classFileCounter, className, t); + } + + // Are we compiling this class? + MetaAccessProvider metaAccess = JVMCI.getRuntime().getHostJVMCIBackend().getMetaAccess(); + if (classFileCounter >= startAt) { + println("CompileTheWorld (%d) : %s", classFileCounter, className); + + // Compile each constructor/method in the class. + for (Constructor constructor : javaClass.getDeclaredConstructors()) { + HotSpotResolvedJavaMethod javaMethod = (HotSpotResolvedJavaMethod) metaAccess.lookupJavaMethod(constructor); + if (canBeCompiled(javaMethod, constructor.getModifiers())) { + compileMethod(javaMethod); + } + } + for (Method method : javaClass.getDeclaredMethods()) { + HotSpotResolvedJavaMethod javaMethod = (HotSpotResolvedJavaMethod) metaAccess.lookupJavaMethod(method); + if (canBeCompiled(javaMethod, method.getModifiers())) { + compileMethod(javaMethod); + } + } + } + } catch (Throwable t) { + println("CompileTheWorld (%d) : Skipping %s %s", classFileCounter, className, t.toString()); + t.printStackTrace(); + } + } + jarFile.close(); + } + } + + if (!running) { + startThreads(); + } + int wakeups = 0; + while (threadPool.getCompletedTaskCount() != threadPool.getTaskCount()) { + if (wakeups % 15 == 0) { + TTY.println("CompileTheWorld : Waiting for " + (threadPool.getTaskCount() - threadPool.getCompletedTaskCount()) + " compiles"); + } + try { + threadPool.awaitTermination(1, TimeUnit.SECONDS); + wakeups++; + } catch (InterruptedException e) { + } + } + threadPool = null; + + long elapsedTime = System.currentTimeMillis() - start; + + println(); + if (Options.CompileTheWorldMultiThreaded.getValue()) { + TTY.println("CompileTheWorld : Done (%d classes, %d methods, %d ms elapsed, %d ms compile time, %d bytes of memory used)", classFileCounter, compiledMethodsCounter.get(), elapsedTime, + compileTime.get(), memoryUsed.get()); + } else { + TTY.println("CompileTheWorld : Done (%d classes, %d methods, %d ms, %d bytes of memory used)", classFileCounter, compiledMethodsCounter.get(), compileTime.get(), memoryUsed.get()); + } + } + + private synchronized void startThreads() { + running = true; + // Wake up any waiting threads + notifyAll(); + } + + private synchronized void waitToRun() { + while (!running) { + try { + wait(); + } catch (InterruptedException e) { + } + } + } + + private void compileMethod(HotSpotResolvedJavaMethod method) throws InterruptedException, ExecutionException { + if (methodFilters != null && !MethodFilter.matches(methodFilters, method)) { + return; + } + if (excludeMethodFilters != null && MethodFilter.matches(excludeMethodFilters, method)) { + return; + } + Future task = threadPool.submit(new Runnable() { + public void run() { + waitToRun(); + try (OverrideScope s = config.apply()) { + compileMethod(method, classFileCounter); + } + } + }); + if (threadPool.getCorePoolSize() == 1) { + task.get(); + } + } + + /** + * Compiles a method and gathers some statistics. + */ + private void compileMethod(HotSpotResolvedJavaMethod method, int counter) { + try { + long start = System.currentTimeMillis(); + long allocatedAtStart = getCurrentThreadAllocatedBytes(); + + CompilationTask task = new CompilationTask(method, Compiler.INVOCATION_ENTRY_BCI, 0L, method.allocateCompileId(Compiler.INVOCATION_ENTRY_BCI), false); + task.runCompilation(); + + memoryUsed.getAndAdd(getCurrentThreadAllocatedBytes() - allocatedAtStart); + compileTime.getAndAdd(System.currentTimeMillis() - start); + compiledMethodsCounter.incrementAndGet(); + } catch (Throwable t) { + // Catch everything and print a message + println("CompileTheWorld (%d) : Error compiling method: %s", counter, method.format("%H.%n(%p):%r")); + t.printStackTrace(TTY.cachedOut); + } + } + + /** + * Determines if a method should be compiled (Cf. CompilationPolicy::can_be_compiled). + * + * @return true if it can be compiled, false otherwise + */ + private static boolean canBeCompiled(HotSpotResolvedJavaMethod javaMethod, int modifiers) { + if (Modifier.isAbstract(modifiers) || Modifier.isNative(modifiers)) { + return false; + } + HotSpotVMConfig c = HotSpotJVMCIRuntime.runtime().getConfig(); + if (c.dontCompileHugeMethods && javaMethod.getCodeSize() > c.hugeMethodLimit) { + return false; + } + // Allow use of -XX:CompileCommand=dontinline to exclude problematic methods + if (!javaMethod.canBeInlined()) { + return false; + } + // Skip @Snippets for now + for (Annotation annotation : javaMethod.getAnnotations()) { + if (annotation.annotationType().getName().equals("com.oracle.graal.replacements.Snippet")) { + return false; + } + } + return true; + } + +} diff -r 20ace3139510 -r 3d15183f3c93 graal/com.oracle.jvmci.hotspot/src/com/oracle/jvmci/hotspot/HotSpotConstantPool.java --- a/graal/com.oracle.jvmci.hotspot/src/com/oracle/jvmci/hotspot/HotSpotConstantPool.java Mon Jun 08 13:20:02 2015 +0200 +++ b/graal/com.oracle.jvmci.hotspot/src/com/oracle/jvmci/hotspot/HotSpotConstantPool.java Wed Jun 03 15:47:54 2015 +0200 @@ -38,7 +38,7 @@ /** * Subset of JVM bytecode opcodes used by {@link HotSpotConstantPool}. */ - static class Bytecodes { + public static class Bytecodes { public static final int LDC = 18; // 0x12 public static final int LDC_W = 19; // 0x13 public static final int LDC2_W = 20; // 0x14 diff -r 20ace3139510 -r 3d15183f3c93 graal/com.oracle.jvmci.hotspot/src/com/oracle/jvmci/hotspot/HotSpotJVMCIRuntime.java --- a/graal/com.oracle.jvmci.hotspot/src/com/oracle/jvmci/hotspot/HotSpotJVMCIRuntime.java Mon Jun 08 13:20:02 2015 +0200 +++ b/graal/com.oracle.jvmci.hotspot/src/com/oracle/jvmci/hotspot/HotSpotJVMCIRuntime.java Wed Jun 03 15:47:54 2015 +0200 @@ -197,7 +197,7 @@ private final Map, JVMCIBackend> backends = new HashMap<>(); - private final HotSpotVMEventListener vmEventListener; + private final Iterable vmEventListeners; private HotSpotJVMCIRuntime() { CompilerToVM toVM = new CompilerToVMImpl(); @@ -220,12 +220,12 @@ hostBackend = registerBackend(factory.createJVMCIBackend(this, null)); } - HotSpotVMEventListener listener = Services.loadSingle(HotSpotVMEventListener.class, false); - if (listener == null) { - listener = new HotSpotVMEventListener() { - }; + Iterable listeners = Services.load(HotSpotVMEventListener.class); + if (!listeners.iterator().hasNext()) { + listeners = Arrays.asList(new HotSpotVMEventListener() { + }); } - vmEventListener = listener; + vmEventListeners = listeners; } private JVMCIBackend registerBackend(JVMCIBackend backend) { @@ -299,7 +299,9 @@ */ @SuppressWarnings({"unused"}) private void compileMetaspaceMethod(long metaspaceMethod, int entryBCI, long jvmciEnv, int id) { - vmEventListener.compileMetaspaceMethod(metaspaceMethod, entryBCI, jvmciEnv, id); + for (HotSpotVMEventListener vmEventListener : vmEventListeners) { + vmEventListener.compileMetaspaceMethod(metaspaceMethod, entryBCI, jvmciEnv, id); + } } /** @@ -307,7 +309,9 @@ */ @SuppressWarnings({"unused"}) private void compileTheWorld() throws Throwable { - vmEventListener.notifyCompileTheWorld(); + for (HotSpotVMEventListener vmEventListener : vmEventListeners) { + vmEventListener.notifyCompileTheWorld(); + } } /** @@ -317,6 +321,8 @@ */ @SuppressWarnings({"unused"}) private void shutdown() throws Exception { - vmEventListener.notifyShutdown(); + for (HotSpotVMEventListener vmEventListener : vmEventListeners) { + vmEventListener.notifyShutdown(); + } } } diff -r 20ace3139510 -r 3d15183f3c93 graal/com.oracle.jvmci.hotspot/src/com/oracle/jvmci/hotspot/HotSpotJVMCIVMEventListener.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.jvmci.hotspot/src/com/oracle/jvmci/hotspot/HotSpotJVMCIVMEventListener.java Wed Jun 03 15:47:54 2015 +0200 @@ -0,0 +1,58 @@ +/* + * Copyright (c) 2015, 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.jvmci.hotspot; + +import static com.oracle.jvmci.hotspot.CompileTheWorld.Options.*; + +import com.oracle.jvmci.debug.*; +import com.oracle.jvmci.hotspot.CompileTheWorld.Config; +import com.oracle.jvmci.service.*; + +@ServiceProvider(HotSpotVMEventListener.class) +public class HotSpotJVMCIVMEventListener implements HotSpotVMEventListener { + + @Override + public void notifyCompileTheWorld() throws Throwable { + CompilerToVM compilerToVM = HotSpotJVMCIRuntime.runtime().getCompilerToVM(); + int iterations = CompileTheWorld.Options.CompileTheWorldIterations.getValue(); + for (int i = 0; i < iterations; i++) { + compilerToVM.resetCompilationStatistics(); + TTY.println("CompileTheWorld : iteration " + i); + CompileTheWorld ctw = new CompileTheWorld(CompileTheWorldClasspath.getValue(), new Config(CompileTheWorldConfig.getValue()), CompileTheWorldStartAt.getValue(), + CompileTheWorldStopAt.getValue(), CompileTheWorldMethodFilter.getValue(), CompileTheWorldExcludeMethodFilter.getValue(), CompileTheWorldVerbose.getValue()); + ctw.compile(); + } + System.exit(0); + } + + @Override + public void notifyShutdown() { + // nothing to do + } + + @Override + public void compileMetaspaceMethod(long metaspaceMethod, int entryBCI, long jvmciEnv, int id) { + HotSpotResolvedJavaMethod method = HotSpotResolvedJavaMethodImpl.fromMetaspace(metaspaceMethod); + CompilationTask.compileMethod(method, entryBCI, jvmciEnv, id); + } +} diff -r 20ace3139510 -r 3d15183f3c93 graal/com.oracle.jvmci.hotspot/src/com/oracle/jvmci/hotspot/HotSpotMethod.java --- a/graal/com.oracle.jvmci.hotspot/src/com/oracle/jvmci/hotspot/HotSpotMethod.java Mon Jun 08 13:20:02 2015 +0200 +++ b/graal/com.oracle.jvmci.hotspot/src/com/oracle/jvmci/hotspot/HotSpotMethod.java Wed Jun 03 15:47:54 2015 +0200 @@ -27,9 +27,10 @@ import java.util.*; +import com.oracle.jvmci.debug.*; import com.oracle.jvmci.meta.*; -public abstract class HotSpotMethod implements JavaMethod, Formattable { +public abstract class HotSpotMethod implements JavaMethod, Formattable, JavaMethodContex { protected String name; @@ -60,4 +61,8 @@ String base = (flags & ALTERNATE) == ALTERNATE ? getName() : toString(); formatter.format(applyFormattingFlagsAndWidth(base, flags & ~ALTERNATE, width)); } + + public JavaMethod asJavaMethod() { + return this; + } } diff -r 20ace3139510 -r 3d15183f3c93 make/defs.make --- a/make/defs.make Mon Jun 08 13:20:02 2015 +0200 +++ b/make/defs.make Wed Jun 03 15:47:54 2015 +0200 @@ -373,6 +373,8 @@ EXPORT_LIST += $(EXPORT_JRE_LIB_JVMCI_OPTIONS_DIR)/com.oracle.jvmci.hotspot.HotSpotJVMCIRuntime EXPORT_LIST += $(EXPORT_JRE_LIB_JVMCI_OPTIONS_DIR)/com.oracle.jvmci.hotspot.HotSpotResolvedJavaFieldImpl EXPORT_LIST += $(EXPORT_JRE_LIB_JVMCI_OPTIONS_DIR)/com.oracle.jvmci.hotspot.HotSpotResolvedJavaMethodImpl +EXPORT_LIST += $(EXPORT_JRE_LIB_JVMCI_OPTIONS_DIR)/com.oracle.jvmci.hotspot.CompileTheWorld +EXPORT_LIST += $(EXPORT_JRE_LIB_JVMCI_OPTIONS_DIR)/com.oracle.jvmci.compiler.Compiler ifeq ($(JVMCI_USE_MAKE),) EXPORT_LIST += $(EXPORT_JRE_LIB_DIR)/truffle.jar @@ -380,8 +382,10 @@ EXPORT_LIST += $(EXPORT_JRE_LIB_JVMCI_DIR)/graal-truffle.jar EXPORT_LIST += $(EXPORT_JRE_LIB_JVMCI_SERVICES_DIR)/com.oracle.jvmci.hotspot.HotSpotVMEventListener +EXPORT_LIST += $(EXPORT_JRE_LIB_JVMCI_SERVICES_DIR)/com.oracle.jvmci.compiler.Compiler EXPORT_LIST += $(EXPORT_JRE_LIB_JVMCI_SERVICES_DIR)/com.oracle.jvmci.debug.DebugInitializationPropertyProvider +EXPORT_LIST += $(EXPORT_JRE_LIB_JVMCI_SERVICES_DIR)/com.oracle.jvmci.debug.DebugConfigCustomizer EXPORT_LIST += $(EXPORT_JRE_LIB_JVMCI_SERVICES_DIR)/com.oracle.graal.api.runtime.GraalRuntimeAccess EXPORT_LIST += $(EXPORT_JRE_LIB_JVMCI_SERVICES_DIR)/com.oracle.graal.code.DisassemblerProvider diff -r 20ace3139510 -r 3d15183f3c93 mx/suite.py --- a/mx/suite.py Mon Jun 08 13:20:02 2015 +0200 +++ b/mx/suite.py Wed Jun 03 15:47:54 2015 +0200 @@ -231,6 +231,8 @@ "sourceDirs" : ["src"], "checkstyle" : "com.oracle.graal.graph", "dependencies" : [ + "com.oracle.jvmci.options", + "com.oracle.jvmci.code", "com.oracle.jvmci.service", ], "javaCompliance" : "1.8", @@ -257,6 +259,18 @@ "workingSets" : "JVMCI", }, + "com.oracle.jvmci.compiler" : { + "subDir" : "graal", + "sourceDirs" : ["src"], + "dependencies" : [ + "com.oracle.jvmci.debug", + ], + "checkstyle" : "com.oracle.graal.graph", + "annotationProcessors" : ["com.oracle.jvmci.options.processor"], + "javaCompliance" : "1.8", + "workingSets" : "JVMCI", + }, + "com.oracle.jvmci.options.processor" : { "subDir" : "graal", "sourceDirs" : ["src"], @@ -306,15 +320,15 @@ "sourceDirs" : ["src"], "dependencies" : [ "com.oracle.jvmci.hotspotvmconfig", - "com.oracle.jvmci.options", - "com.oracle.jvmci.debug", + "FINDBUGS", "com.oracle.jvmci.runtime", "com.oracle.jvmci.common", - "FINDBUGS", + "com.oracle.jvmci.compiler", ], "annotationProcessors" : [ "com.oracle.jvmci.hotspotvmconfig.processor", "com.oracle.jvmci.options.processor", + "com.oracle.jvmci.service.processor", ], "checkstyle" : "com.oracle.graal.graph", "javaCompliance" : "1.8", @@ -480,8 +494,8 @@ "dependencies" : [ "com.oracle.jvmci.hotspot", "com.oracle.graal.replacements", - "com.oracle.graal.printer", "com.oracle.graal.runtime", + "com.oracle.graal.code", ], "checkstyle" : "com.oracle.graal.graph", "annotationProcessors" : [ @@ -731,9 +745,9 @@ "subDir" : "graal", "sourceDirs" : ["src"], "dependencies" : [ - "com.oracle.graal.compiler", + "com.oracle.graal.api.directives", "com.oracle.graal.java", - "com.oracle.graal.api.directives", + "com.oracle.graal.loop", "com.oracle.graal.word", ], "checkstyle" : "com.oracle.graal.graph", @@ -751,6 +765,7 @@ "dependencies" : [ "com.oracle.graal.replacements", "com.oracle.graal.lir.amd64", + "com.oracle.graal.compiler", ], "checkstyle" : "com.oracle.graal.graph", "javaCompliance" : "1.8", @@ -763,6 +778,7 @@ "sourceDirs" : ["src"], "dependencies" : [ "com.oracle.graal.replacements", + "com.oracle.graal.compiler", ], "checkstyle" : "com.oracle.graal.graph", "javaCompliance" : "1.8", @@ -802,6 +818,7 @@ "com.oracle.graal.api.replacements", "com.oracle.graal.lir", "com.oracle.graal.bytecode", + "com.oracle.jvmci.compiler", ], "checkstyle" : "com.oracle.graal.graph", "javaCompliance" : "1.8", @@ -962,7 +979,7 @@ "sourceDirs" : ["src"], "dependencies" : [ "com.oracle.graal.phases", - "com.oracle.graal.graphbuilderconf" + "com.oracle.graal.graphbuilderconf", ], "checkstyle" : "com.oracle.graal.graph", "annotationProcessors" : ["com.oracle.jvmci.service.processor"], @@ -985,10 +1002,8 @@ "subDir" : "graal", "sourceDirs" : ["src"], "dependencies" : [ - "com.oracle.jvmci.options", "com.oracle.jvmci.debug", "com.oracle.jvmci.common", - "com.oracle.jvmci.code", ], "annotationProcessors" : ["com.oracle.jvmci.options.processor"], "checkstyle" : "com.oracle.graal.graph", @@ -1025,9 +1040,9 @@ "subDir" : "graal", "sourceDirs" : ["src"], "dependencies" : [ + "com.oracle.graal.api.directives", + "com.oracle.graal.java", "com.oracle.graal.test", - "com.oracle.graal.api.directives", - "com.oracle.graal.printer", "com.oracle.graal.runtime", "JAVA_ALLOCATION_INSTRUMENTER", ], @@ -1228,7 +1243,6 @@ "dependencies" : [ "com.oracle.truffle.api", "com.oracle.graal.runtime", - "com.oracle.graal.printer", "com.oracle.graal.replacements", ], "checkstyle" : "com.oracle.graal.graph",