/* * 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 org.graalvm.compiler.truffle; import org.graalvm.compiler.options.Option; import org.graalvm.compiler.options.OptionKey; import org.graalvm.compiler.options.OptionType; import org.graalvm.compiler.options.OptionValues; import org.graalvm.util.UnmodifiableEconomicMap; import com.oracle.truffle.api.Truffle; /** * Options for the Truffle compiler. */ public class TruffleCompilerOptions { static class Lazy { static final ThreadLocal<TruffleOptionsOverrideScope> overrideScope = new ThreadLocal<>(); } private static OptionValues getInitialOptions() { return ((GraalTruffleRuntime) Truffle.getRuntime()).getInitialOptions(); } /** * Gets the object holding the values of Truffle options, taking into account any active * {@linkplain #overrideOptions(OptionKey, Object, Object...) overrides}. */ public static OptionValues getOptions() { TruffleOptionsOverrideScope scope = Lazy.overrideScope.get(); return scope != null ? scope.options : getInitialOptions(); } /** * Gets the options defined in the current option * {@linkplain #overrideOptions(OptionKey, Object, Object...) override} scope or {@code null} if * there is no override scope active for the current thread. */ public static OptionValues getCurrentOptionOverrides() { TruffleOptionsOverrideScope scope = Lazy.overrideScope.get(); return scope != null ? scope.options : null; } public static class TruffleOptionsOverrideScope implements AutoCloseable { private final TruffleOptionsOverrideScope outer; private final OptionValues options; TruffleOptionsOverrideScope(UnmodifiableEconomicMap<OptionKey<?>, Object> overrides) { outer = Lazy.overrideScope.get(); options = new OptionValues(outer == null ? getInitialOptions() : outer.options, overrides); Lazy.overrideScope.set(this); } @Override public void close() { Lazy.overrideScope.set(outer); } } /** * Forces specified values in the object returned by {@link #getOptions()} until * {@link TruffleOptionsOverrideScope#close()} is called on the object returned by this method. * The values forced while the override is active are taken from the key/value pairs in * {@code overrides}. The override is thread local. * <p> * The returned object should be used with the try-with-resource construct: * * <pre> * try (TruffleOptionsOverrideScope s = overrideOptions(option1, value1, option2, value2)) { * ... * } * </pre> * * NOTE: This feature is only intended for testing. The caller must be aware whether or not the * options being overridden are accessed inside the new override scope. * * @param extraOverrides overrides in the form {@code [key1, value2, key3, value3, ...]} */ public static TruffleOptionsOverrideScope overrideOptions(OptionKey<?> key1, Object value1, Object... extraOverrides) { return new TruffleOptionsOverrideScope(OptionValues.asMap(key1, value1, extraOverrides)); } public static TruffleOptionsOverrideScope overrideOptions(UnmodifiableEconomicMap<OptionKey<?>, Object> overrides) { return new TruffleOptionsOverrideScope(overrides); } /** * Gets the value of a given Truffle option key taking into account any active * {@linkplain #overrideOptions overrides}. */ public static <T> T getValue(OptionKey<T> key) { return key.getValue(getOptions()); } // @formatter:off // configuration /** * Instructs the Truffle Compiler to compile call targets only if their name contains at least one element of a comma-separated list of includes. * Excludes are prefixed with a tilde (~). * * The format in EBNF: * <pre> * CompileOnly = Element, { ',', Element } ; * Element = Include | '~' Exclude ; * </pre> */ @Option(help = "Restrict compilation to comma-separated list of includes (or excludes prefixed with tilde)", type = OptionType.Debug) public static final OptionKey<String> TruffleCompileOnly = new OptionKey<>(null); @Option(help = "Compile immediately to test truffle compiler", type = OptionType.Debug) public static final OptionKey<Boolean> TruffleCompileImmediately = new OptionKey<>(false); @Option(help = "Exclude assertion code from Truffle compilations", type = OptionType.Debug) public static final OptionKey<Boolean> TruffleExcludeAssertions = new OptionKey<>(true); @Option(help = "Compile call target when call count exceeds this threshold", type = OptionType.User) public static final OptionKey<Integer> TruffleCompilationThreshold = new OptionKey<>(1000); @Option(help = "Defines the maximum timespan in milliseconds that is required for a call target to be queued for compilation.", type = OptionType.User) public static final OptionKey<Integer> TruffleTimeThreshold = new OptionKey<>(25000); @Option(help = "Minimum number of calls before a call target is compiled", type = OptionType.Expert) public static final OptionKey<Integer> TruffleMinInvokeThreshold = new OptionKey<>(3); @Option(help = "Delay compilation after an invalidation to allow for reprofiling", type = OptionType.Expert) public static final OptionKey<Integer> TruffleInvalidationReprofileCount = new OptionKey<>(3); @Option(help = "Delay compilation after a node replacement", type = OptionType.Expert) public static final OptionKey<Integer> TruffleReplaceReprofileCount = new OptionKey<>(3); @Option(help = "Enable automatic inlining of call targets", type = OptionType.Debug) public static final OptionKey<Boolean> TruffleFunctionInlining = new OptionKey<>(true); @Option(help = "Stop inlining if caller's cumulative tree size would exceed this limit", type = OptionType.Expert) public static final OptionKey<Integer> TruffleInliningMaxCallerSize = new OptionKey<>(2250); @Option(help = "Maximum level of recursive inlining", type = OptionType.Expert) public static final OptionKey<Integer> TruffleMaximumRecursiveInlining = new OptionKey<>(4); @Option(help = "Enable call target splitting", type = OptionType.Expert) public static final OptionKey<Boolean> TruffleSplitting = new OptionKey<>(true); @Option(help = "Enable on stack replacement for Truffle loops.", type = OptionType.Debug) public static final OptionKey<Boolean> TruffleOSR = new OptionKey<>(true); @Option(help = "Number of loop iterations until on-stack-replacement compilation is triggered.", type = OptionType.Debug) public static final OptionKey<Integer> TruffleOSRCompilationThreshold = new OptionKey<>(100000); @Option(help = "Disable call target splitting if tree size exceeds this limit", type = OptionType.Debug) public static final OptionKey<Integer> TruffleSplittingMaxCalleeSize = new OptionKey<>(100); @Option(help = "Enable asynchronous truffle compilation in background thread", type = OptionType.Expert) public static final OptionKey<Boolean> TruffleBackgroundCompilation = new OptionKey<>(true); @Option(help = "Manually set the number of compiler threads", type = OptionType.Expert) public static final OptionKey<Integer> TruffleCompilerThreads = new OptionKey<>(0); @Option(help = "Enable inlining across Truffle boundary", type = OptionType.Expert) public static final OptionKey<Boolean> TruffleInlineAcrossTruffleBoundary = new OptionKey<>(false); @Option(help = "", type = OptionType.Debug) public static final OptionKey<Boolean> TruffleReturnTypeSpeculation = new OptionKey<>(true); @Option(help = "", type = OptionType.Debug) public static final OptionKey<Boolean> TruffleArgumentTypeSpeculation = new OptionKey<>(true); @Option(help = "", type = OptionType.Debug) public static final OptionKey<Boolean> TruffleUseFrameWithoutBoxing = new OptionKey<>(true); // tracing @Option(help = "Print potential performance problems", type = OptionType.Debug) public static final OptionKey<Boolean> TraceTrufflePerformanceWarnings = new OptionKey<>(false); @Option(help = "Print information for compilation results", type = OptionType.Debug) public static final OptionKey<Boolean> TraceTruffleCompilation = new OptionKey<>(false); @Option(help = "Compile time benchmarking: repeat Truffle compilation n times and then exit the VM", type = OptionType.Debug) public static final OptionKey<Integer> TruffleCompilationRepeats = new OptionKey<>(0); @Option(help = "Print information for compilation queuing", type = OptionType.Debug) public static final OptionKey<Boolean> TraceTruffleCompilationDetails = new OptionKey<>(false); @Option(help = "Print all polymorphic and generic nodes after each compilation", type = OptionType.Debug) public static final OptionKey<Boolean> TraceTruffleCompilationPolymorphism = new OptionKey<>(false); @Option(help = "Print all polymorphic and generic nodes after each compilation", type = OptionType.Debug) public static final OptionKey<Boolean> TraceTruffleCompilationAST = new OptionKey<>(false); @Option(help = "Print the inlined call tree for each compiled method", type = OptionType.Debug) public static final OptionKey<Boolean> TraceTruffleCompilationCallTree = new OptionKey<>(false); @Option(help = "Print source secions for printed expansion trees", type = OptionType.Debug) public static final OptionKey<Boolean> TraceTruffleExpansionSource = new OptionKey<>(false); @Option(help = "Prints a histogram of all expanded Java methods.", type = OptionType.Debug) public static final OptionKey<Boolean> PrintTruffleExpansionHistogram = new OptionKey<>(false); @Option(help = "Treat compilation exceptions as fatal exceptions that will exit the application", type = OptionType.Debug) public static final OptionKey<Boolean> TruffleCompilationExceptionsAreFatal = new OptionKey<>(false); @Option(help = "Treat performance warnings as fatal occurrences that will exit the applications", type = OptionType.Debug) public static final OptionKey<Boolean> TrufflePerformanceWarningsAreFatal = new OptionKey<>(false); @Option(help = "Prints the exception stack trace for compilation exceptions", type = OptionType.Debug) public static final OptionKey<Boolean> TruffleCompilationExceptionsArePrinted = new OptionKey<>(true); @Option(help = "Treat compilation exceptions as thrown runtime exceptions", type = OptionType.Debug) public static final OptionKey<Boolean> TruffleCompilationExceptionsAreThrown = new OptionKey<>(false); @Option(help = "Print information for inlining for each compilation.", type = OptionType.Debug) public static final OptionKey<Boolean> TraceTruffleInlining = new OptionKey<>(false); @Option(help = "Print information for each splitted call site.", type = OptionType.Debug) public static final OptionKey<Boolean> TraceTruffleSplitting = new OptionKey<>(false); @Option(help = "Print stack trace on transfer to interpreter", type = OptionType.Debug) public static final OptionKey<Boolean> TraceTruffleTransferToInterpreter = new OptionKey<>(false); @Option(help = "Print stack trace on assumption invalidation", type = OptionType.Debug) public static final OptionKey<Boolean> TraceTruffleAssumptions = new OptionKey<>(false); @Option(help = "Number of stack trace elements printed by TraceTruffleTransferToInterpreter and TraceTruffleAssumptions", type = OptionType.Debug) public static final OptionKey<Integer> TraceTruffleStackTraceLimit = new OptionKey<>(20); @Option(help = "Print a summary of execution counts for all executed CallTargets. Introduces counter overhead for each call.", type = OptionType.Debug) public static final OptionKey<Boolean> TruffleCallTargetProfiling = new OptionKey<>(false); @Option(help = "Print Truffle compilation statistics at the end of a run.", type = OptionType.Debug) public static final OptionKey<Boolean> TruffleCompilationStatistics = new OptionKey<>(false); @Option(help = "Print additional more verbose Truffle compilation statistics at the end of a run.", type = OptionType.Debug) public static final OptionKey<Boolean> TruffleCompilationStatisticDetails = new OptionKey<>(false); @Option(help = "Enable support for simple infopoints in truffle partial evaluations.", type = OptionType.Expert) public static final OptionKey<Boolean> TruffleEnableInfopoints = new OptionKey<>(false); @Option(help = "Run the partial escape analysis iteratively in Truffle compilation.", type = OptionType.Debug) public static final OptionKey<Boolean> TruffleIterativePartialEscape = new OptionKey<>(false); @Option(help = "Enable/disable builtin profiles in com.oracle.truffle.api.profiles.", type = OptionType.Debug) public static final OptionKey<Boolean> TruffleProfilingEnabled = new OptionKey<>(true); @Option(help = "Instrument branches and output profiling information to the standard output.") public static final OptionKey<Boolean> TruffleInstrumentBranches = new OptionKey<>(false); @Option(help = "Instrument branches by considering different inlining sites as different branches.") public static final OptionKey<Boolean> TruffleInstrumentBranchesPerInlineSite = new OptionKey<>(false); @Option(help = "Method filter for methods in which to add branch instrumentation.") public static final OptionKey<String> TruffleInstrumentBranchesFilter = new OptionKey<>(null); @Option(help = "Prettify stack traces for branch-instrumented callsites.") public static final OptionKey<Boolean> TruffleInstrumentBranchesPretty = new OptionKey<>(true); @Option(help = "Maximum number of instrumentation counters available.") public static final OptionKey<Integer> TruffleInstrumentBranchesCount = new OptionKey<>(10000); @Option(help = "Instrument Truffle boundaries and output profiling information to the standard output.") public static final OptionKey<Boolean> TruffleInstrumentBoundaries = new OptionKey<>(false); @Option(help = "Instrument Truffle boundaries by considering different inlining sites as different branches.") public static final OptionKey<Boolean> TruffleInstrumentBoundariesPerInlineSite = new OptionKey<>(false); @Option(help = "Method filter for host methods in which to add instrumentation.") public static final OptionKey<String> TruffleInstrumentFilter = new OptionKey<>("*.*.*"); @Option(help = "Maximum number of instrumentation counters available.") public static final OptionKey<Integer> TruffleInstrumentationTableSize = new OptionKey<>(10000); // @formatter:on }