# HG changeset patch # User Doug Simon # Date 1450711175 -3600 # Node ID f35e653aa876265e4b8a5c4545830b90cf7393f6 # Parent 58eb143a82590bc12bb5efd0f69f4ebe1390393b moved @Option mechanism from JVMCI to Graal (GRAAL-1371) diff -r 58eb143a8259 -r f35e653aa876 graal/com.oracle.graal.compiler.common/src/com/oracle/graal/compiler/common/BackendOptions.java --- a/graal/com.oracle.graal.compiler.common/src/com/oracle/graal/compiler/common/BackendOptions.java Mon Dec 21 00:20:11 2015 +0100 +++ b/graal/com.oracle.graal.compiler.common/src/com/oracle/graal/compiler/common/BackendOptions.java Mon Dec 21 16:19:35 2015 +0100 @@ -22,11 +22,11 @@ */ package com.oracle.graal.compiler.common; -import jdk.vm.ci.options.DerivedOptionValue; -import jdk.vm.ci.options.DerivedOptionValue.OptionSupplier; -import jdk.vm.ci.options.Option; -import jdk.vm.ci.options.OptionType; -import jdk.vm.ci.options.OptionValue; +import com.oracle.graal.options.DerivedOptionValue; +import com.oracle.graal.options.Option; +import com.oracle.graal.options.OptionType; +import com.oracle.graal.options.OptionValue; +import com.oracle.graal.options.DerivedOptionValue.OptionSupplier; /** * Options to control the backend configuration. diff -r 58eb143a8259 -r f35e653aa876 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 Dec 21 00:20:11 2015 +0100 +++ b/graal/com.oracle.graal.compiler.common/src/com/oracle/graal/compiler/common/GraalOptions.java Mon Dec 21 16:19:35 2015 +0100 @@ -22,10 +22,10 @@ */ package com.oracle.graal.compiler.common; -import jdk.vm.ci.options.Option; -import jdk.vm.ci.options.OptionType; -import jdk.vm.ci.options.OptionValue; -import jdk.vm.ci.options.StableOptionValue; +import com.oracle.graal.options.Option; +import com.oracle.graal.options.OptionType; +import com.oracle.graal.options.OptionValue; +import com.oracle.graal.options.StableOptionValue; /** * This class encapsulates options that control the behavior of the Graal compiler. diff -r 58eb143a8259 -r f35e653aa876 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 Dec 21 00:20:11 2015 +0100 +++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/GraalCompilerTest.java Mon Dec 21 16:19:35 2015 +0100 @@ -58,7 +58,6 @@ import jdk.vm.ci.meta.ResolvedJavaMethod; import jdk.vm.ci.meta.ResolvedJavaType; import jdk.vm.ci.meta.SpeculationLog; -import jdk.vm.ci.options.DerivedOptionValue; import org.junit.After; import org.junit.Assert; @@ -102,6 +101,7 @@ import com.oracle.graal.nodes.spi.LoweringProvider; import com.oracle.graal.nodes.spi.Replacements; import com.oracle.graal.nodes.virtual.VirtualObjectNode; +import com.oracle.graal.options.DerivedOptionValue; import com.oracle.graal.phases.BasePhase; import com.oracle.graal.phases.OptimisticOptimizations; import com.oracle.graal.phases.Phase; diff -r 58eb143a8259 -r f35e653aa876 graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/MemoryScheduleTest.java --- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/MemoryScheduleTest.java Mon Dec 21 00:20:11 2015 +0100 +++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/MemoryScheduleTest.java Mon Dec 21 16:19:35 2015 +0100 @@ -31,9 +31,6 @@ import java.util.ArrayList; import java.util.List; -import jdk.vm.ci.options.OptionValue; -import jdk.vm.ci.options.OptionValue.OverrideScope; - import org.junit.Assert; import org.junit.Test; @@ -53,6 +50,8 @@ import com.oracle.graal.nodes.memory.WriteNode; import com.oracle.graal.nodes.spi.LoweringTool; import com.oracle.graal.nodes.util.GraphUtil; +import com.oracle.graal.options.OptionValue; +import com.oracle.graal.options.OptionValue.OverrideScope; import com.oracle.graal.phases.OptimisticOptimizations; import com.oracle.graal.phases.common.CanonicalizerPhase; import com.oracle.graal.phases.common.FloatingReadPhase; diff -r 58eb143a8259 -r f35e653aa876 graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/OptionsVerifierTest.java --- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/OptionsVerifierTest.java Mon Dec 21 00:20:11 2015 +0100 +++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/OptionsVerifierTest.java Mon Dec 21 16:19:35 2015 +0100 @@ -48,12 +48,13 @@ import jdk.internal.org.objectweb.asm.MethodVisitor; import jdk.internal.org.objectweb.asm.Opcodes; import jdk.internal.org.objectweb.asm.Type; -import jdk.vm.ci.options.OptionDescriptor; -import jdk.vm.ci.options.OptionDescriptors; -import jdk.vm.ci.options.OptionValue; import org.junit.Test; +import com.oracle.graal.options.OptionDescriptor; +import com.oracle.graal.options.OptionDescriptors; +import com.oracle.graal.options.OptionValue; + /** * Verifies a class declaring one or more {@linkplain OptionValue options} has a class initializer * that only initializes the option(s). This sanity check mitigates the possibility of an option diff -r 58eb143a8259 -r f35e653aa876 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 Dec 21 00:20:11 2015 +0100 +++ b/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/GraalCompiler.java Mon Dec 21 16:19:35 2015 +0100 @@ -44,8 +44,6 @@ import jdk.vm.ci.meta.ResolvedJavaMethod; import jdk.vm.ci.meta.TriState; import jdk.vm.ci.meta.VMConstant; -import jdk.vm.ci.options.OptionValue; -import jdk.vm.ci.options.OptionValue.OverrideScope; import com.oracle.graal.compiler.LIRGenerationPhase.LIRGenerationContext; import com.oracle.graal.compiler.common.alloc.ComputeBlockOrder; @@ -72,6 +70,8 @@ import com.oracle.graal.nodes.StructuredGraph; import com.oracle.graal.nodes.cfg.Block; import com.oracle.graal.nodes.spi.NodeLIRBuilderTool; +import com.oracle.graal.options.OptionValue; +import com.oracle.graal.options.OptionValue.OverrideScope; import com.oracle.graal.phases.OptimisticOptimizations; import com.oracle.graal.phases.PhaseSuite; import com.oracle.graal.phases.common.DeadCodeEliminationPhase; diff -r 58eb143a8259 -r f35e653aa876 graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/GraalCompilerOptions.java --- a/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/GraalCompilerOptions.java Mon Dec 21 00:20:11 2015 +0100 +++ b/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/GraalCompilerOptions.java Mon Dec 21 16:19:35 2015 +0100 @@ -22,9 +22,9 @@ */ package com.oracle.graal.compiler; -import jdk.vm.ci.options.Option; -import jdk.vm.ci.options.OptionType; -import jdk.vm.ci.options.OptionValue; +import com.oracle.graal.options.Option; +import com.oracle.graal.options.OptionType; +import com.oracle.graal.options.OptionValue; /** * Options related to {@link GraalCompiler}. diff -r 58eb143a8259 -r f35e653aa876 graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/phases/HighTier.java --- a/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/phases/HighTier.java Mon Dec 21 00:20:11 2015 +0100 +++ b/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/phases/HighTier.java Mon Dec 21 16:19:35 2015 +0100 @@ -33,9 +33,6 @@ import static com.oracle.graal.compiler.common.GraalOptions.PartialEscapeAnalysis; import static com.oracle.graal.compiler.common.GraalOptions.UseGraalInstrumentation; import static com.oracle.graal.phases.common.DeadCodeEliminationPhase.Optionality.Optional; -import jdk.vm.ci.options.Option; -import jdk.vm.ci.options.OptionType; -import jdk.vm.ci.options.OptionValue; import com.oracle.graal.loop.DefaultLoopPolicies; import com.oracle.graal.loop.LoopPolicies; @@ -43,6 +40,9 @@ import com.oracle.graal.loop.phases.LoopPeelingPhase; import com.oracle.graal.loop.phases.LoopUnswitchingPhase; import com.oracle.graal.nodes.spi.LoweringTool; +import com.oracle.graal.options.Option; +import com.oracle.graal.options.OptionType; +import com.oracle.graal.options.OptionValue; import com.oracle.graal.phases.PhaseSuite; import com.oracle.graal.phases.common.CanonicalizerPhase; import com.oracle.graal.phases.common.ConvertDeoptimizeToGuardPhase; diff -r 58eb143a8259 -r f35e653aa876 graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/phases/LowTier.java --- a/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/phases/LowTier.java Mon Dec 21 00:20:11 2015 +0100 +++ b/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/phases/LowTier.java Mon Dec 21 16:19:35 2015 +0100 @@ -27,11 +27,11 @@ import static com.oracle.graal.compiler.common.GraalOptions.OptCanonicalizer; import static com.oracle.graal.compiler.common.GraalOptions.UseGraalInstrumentation; import static com.oracle.graal.phases.common.DeadCodeEliminationPhase.Optionality.Required; -import jdk.vm.ci.options.Option; -import jdk.vm.ci.options.OptionType; -import jdk.vm.ci.options.OptionValue; import com.oracle.graal.nodes.spi.LoweringTool; +import com.oracle.graal.options.Option; +import com.oracle.graal.options.OptionType; +import com.oracle.graal.options.OptionValue; import com.oracle.graal.phases.PhaseSuite; import com.oracle.graal.phases.common.CanonicalizerPhase; import com.oracle.graal.phases.common.DeadCodeEliminationPhase; diff -r 58eb143a8259 -r f35e653aa876 graal/com.oracle.graal.debug/src/com/oracle/graal/debug/GraalDebugConfig.java --- a/graal/com.oracle.graal.debug/src/com/oracle/graal/debug/GraalDebugConfig.java Mon Dec 21 00:20:11 2015 +0100 +++ b/graal/com.oracle.graal.debug/src/com/oracle/graal/debug/GraalDebugConfig.java Mon Dec 21 16:19:35 2015 +0100 @@ -29,11 +29,12 @@ import java.util.List; import java.util.Set; +import com.oracle.graal.options.Option; +import com.oracle.graal.options.OptionType; +import com.oracle.graal.options.OptionValue; + import jdk.vm.ci.code.BailoutException; import jdk.vm.ci.meta.JavaMethod; -import jdk.vm.ci.options.Option; -import jdk.vm.ci.options.OptionType; -import jdk.vm.ci.options.OptionValue; public class GraalDebugConfig implements DebugConfig { @SuppressWarnings("all") diff -r 58eb143a8259 -r f35e653aa876 graal/com.oracle.graal.graph/src/com/oracle/graal/graph/Graph.java --- a/graal/com.oracle.graal.graph/src/com/oracle/graal/graph/Graph.java Mon Dec 21 00:20:11 2015 +0100 +++ b/graal/com.oracle.graal.graph/src/com/oracle/graal/graph/Graph.java Mon Dec 21 16:19:35 2015 +0100 @@ -32,9 +32,6 @@ import java.util.function.Consumer; import jdk.vm.ci.common.JVMCIError; -import jdk.vm.ci.options.Option; -import jdk.vm.ci.options.OptionType; -import jdk.vm.ci.options.OptionValue; import com.oracle.graal.compiler.common.CollectionsFactory; import com.oracle.graal.debug.Debug; @@ -44,6 +41,9 @@ import com.oracle.graal.debug.Fingerprint; import com.oracle.graal.graph.Node.ValueNumberable; import com.oracle.graal.graph.iterators.NodeIterable; +import com.oracle.graal.options.Option; +import com.oracle.graal.options.OptionType; +import com.oracle.graal.options.OptionValue; /** * This class is a graph container, it contains the set of nodes that belong to this graph. diff -r 58eb143a8259 -r f35e653aa876 graal/com.oracle.graal.hotspot.amd64.test/src/com/oracle/graal/hotspot/amd64/test/CompressedNullCheckTest.java --- a/graal/com.oracle.graal.hotspot.amd64.test/src/com/oracle/graal/hotspot/amd64/test/CompressedNullCheckTest.java Mon Dec 21 00:20:11 2015 +0100 +++ b/graal/com.oracle.graal.hotspot.amd64.test/src/com/oracle/graal/hotspot/amd64/test/CompressedNullCheckTest.java Mon Dec 21 16:19:35 2015 +0100 @@ -24,8 +24,6 @@ import static jdk.vm.ci.hotspot.HotSpotVMConfig.config; import jdk.vm.ci.meta.ResolvedJavaMethod; -import jdk.vm.ci.options.OptionValue; -import jdk.vm.ci.options.OptionValue.OverrideScope; import org.junit.Assert; import org.junit.Assume; @@ -37,6 +35,8 @@ import com.oracle.graal.nodes.StructuredGraph; import com.oracle.graal.nodes.ValueNode; import com.oracle.graal.nodes.calc.IsNullNode; +import com.oracle.graal.options.OptionValue; +import com.oracle.graal.options.OptionValue.OverrideScope; /** * Ensures that frame omission works in cases where it is expected to. diff -r 58eb143a8259 -r f35e653aa876 graal/com.oracle.graal.hotspot.test/src/com/oracle/graal/hotspot/test/AheadOfTimeCompilationTest.java --- a/graal/com.oracle.graal.hotspot.test/src/com/oracle/graal/hotspot/test/AheadOfTimeCompilationTest.java Mon Dec 21 00:20:11 2015 +0100 +++ b/graal/com.oracle.graal.hotspot.test/src/com/oracle/graal/hotspot/test/AheadOfTimeCompilationTest.java Mon Dec 21 16:19:35 2015 +0100 @@ -34,8 +34,6 @@ import jdk.vm.ci.meta.JavaConstant; import jdk.vm.ci.meta.JavaKind; import jdk.vm.ci.meta.ResolvedJavaMethod; -import jdk.vm.ci.options.OptionValue; -import jdk.vm.ci.options.OptionValue.OverrideScope; import org.junit.Assert; import org.junit.Ignore; @@ -54,6 +52,8 @@ import com.oracle.graal.nodes.StructuredGraph.AllowAssumptions; import com.oracle.graal.nodes.memory.FloatingReadNode; import com.oracle.graal.nodes.memory.ReadNode; +import com.oracle.graal.options.OptionValue; +import com.oracle.graal.options.OptionValue.OverrideScope; import com.oracle.graal.phases.OptimisticOptimizations; import com.oracle.graal.phases.tiers.Suites; import com.oracle.graal.phases.tiers.SuitesProvider; diff -r 58eb143a8259 -r f35e653aa876 graal/com.oracle.graal.hotspot.test/src/com/oracle/graal/hotspot/test/LoadJavaMirrorWithKlassTest.java --- a/graal/com.oracle.graal.hotspot.test/src/com/oracle/graal/hotspot/test/LoadJavaMirrorWithKlassTest.java Mon Dec 21 00:20:11 2015 +0100 +++ b/graal/com.oracle.graal.hotspot.test/src/com/oracle/graal/hotspot/test/LoadJavaMirrorWithKlassTest.java Mon Dec 21 16:19:35 2015 +0100 @@ -25,8 +25,6 @@ import java.util.Objects; import jdk.vm.ci.meta.JavaKind; -import jdk.vm.ci.options.OptionValue; -import jdk.vm.ci.options.OptionValue.OverrideScope; import org.junit.Test; @@ -34,6 +32,8 @@ import com.oracle.graal.compiler.test.GraalCompilerTest; import com.oracle.graal.nodes.ConstantNode; import com.oracle.graal.nodes.StructuredGraph; +import com.oracle.graal.options.OptionValue; +import com.oracle.graal.options.OptionValue.OverrideScope; import com.oracle.graal.phases.tiers.Suites; public class LoadJavaMirrorWithKlassTest extends GraalCompilerTest { diff -r 58eb143a8259 -r f35e653aa876 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 Dec 21 00:20:11 2015 +0100 +++ b/graal/com.oracle.graal.hotspot.test/src/com/oracle/graal/hotspot/test/MemoryUsageBenchmark.java Mon Dec 21 16:19:35 2015 +0100 @@ -143,7 +143,7 @@ HotSpotJVMCIRuntimeProvider runtime = HotSpotJVMCIRuntime.runtime(); int entryBCI = JVMCICompiler.INVOCATION_ENTRY_BCI; HotSpotCompilationRequest request = new HotSpotCompilationRequest(method, entryBCI, jvmciEnv); - CompilationTask task = new CompilationTask(runtime, (HotSpotGraalCompiler) runtime.getCompiler(), request, false); + CompilationTask task = new CompilationTask(runtime, (HotSpotGraalCompiler) runtime.getCompiler(), request, true, false); task.runCompilation(); } } @@ -160,7 +160,7 @@ try (AllocSpy as = AllocSpy.open(methodName)) { HotSpotJVMCIRuntimeProvider runtime = HotSpotJVMCIRuntime.runtime(); HotSpotCompilationRequest request = new HotSpotCompilationRequest(method, JVMCICompiler.INVOCATION_ENTRY_BCI, jvmciEnv); - CompilationTask task = new CompilationTask(runtime, (HotSpotGraalCompiler) runtime.getCompiler(), request, false); + CompilationTask task = new CompilationTask(runtime, (HotSpotGraalCompiler) runtime.getCompiler(), request, true, false); task.runCompilation(); } } diff -r 58eb143a8259 -r f35e653aa876 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 Dec 21 00:20:11 2015 +0100 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/CompilationTask.java Mon Dec 21 16:19:35 2015 +0100 @@ -105,6 +105,8 @@ */ private final boolean installAsDefault; + private final boolean useProfilingInfo; + static class Lazy { /** * A {@link com.sun.management.ThreadMXBean} to be able to query some information about the @@ -113,10 +115,11 @@ static final com.sun.management.ThreadMXBean threadMXBean = (com.sun.management.ThreadMXBean) Management.getThreadMXBean(); } - public CompilationTask(HotSpotJVMCIRuntimeProvider jvmciRuntime, HotSpotGraalCompiler compiler, HotSpotCompilationRequest request, boolean installAsDefault) { + public CompilationTask(HotSpotJVMCIRuntimeProvider jvmciRuntime, HotSpotGraalCompiler compiler, HotSpotCompilationRequest request, boolean useProfilingInfo, boolean installAsDefault) { this.jvmciRuntime = jvmciRuntime; this.compiler = compiler; this.request = request; + this.useProfilingInfo = useProfilingInfo; this.installAsDefault = installAsDefault; } @@ -192,7 +195,7 @@ try (Scope s = Debug.scope("Compiling", new DebugDumpScope(String.valueOf(getId()), true))) { // Begin the compilation event. compilationEvent.begin(); - result = compiler.compile(method, entryBCI); + result = compiler.compile(method, entryBCI, useProfilingInfo); } catch (Throwable e) { throw Debug.handle(e); } finally { diff -r 58eb143a8259 -r f35e653aa876 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 Dec 21 00:20:11 2015 +0100 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/CompileTheWorld.java Mon Dec 21 16:19:35 2015 +0100 @@ -71,11 +71,6 @@ import jdk.vm.ci.hotspot.HotSpotVMConfig; import jdk.vm.ci.meta.ConstantPool; import jdk.vm.ci.meta.MetaAccessProvider; -import jdk.vm.ci.options.OptionDescriptor; -import jdk.vm.ci.options.OptionValue; -import jdk.vm.ci.options.OptionValue.OverrideScope; -import jdk.vm.ci.options.OptionsParser; -import jdk.vm.ci.options.OptionsParser.OptionConsumer; import jdk.vm.ci.runtime.JVMCI; import jdk.vm.ci.runtime.JVMCICompiler; @@ -89,6 +84,11 @@ import com.oracle.graal.debug.TTY; import com.oracle.graal.debug.internal.DebugScope; import com.oracle.graal.debug.internal.MemUseTrackerImpl; +import com.oracle.graal.options.OptionDescriptor; +import com.oracle.graal.options.OptionValue; +import com.oracle.graal.options.OptionValue.OverrideScope; +import com.oracle.graal.options.OptionsParser; +import com.oracle.graal.options.OptionsParser.OptionConsumer; /** * This class implements compile-the-world functionality with JVMCI. @@ -228,7 +228,6 @@ // ...but we want to see exceptions. config.putIfAbsent(PrintBailout, true); config.putIfAbsent(PrintStackTraceOnException, true); - config.putIfAbsent(HotSpotResolvedJavaMethod.Options.UseProfilingInformation, false); } public CompileTheWorld(HotSpotJVMCIRuntimeProvider jvmciRuntime, HotSpotGraalCompiler compiler) { @@ -481,7 +480,9 @@ HotSpotResolvedJavaMethod dummyMethod = (HotSpotResolvedJavaMethod) JVMCI.getRuntime().getHostJVMCIBackend().getMetaAccess().lookupJavaMethod( CompileTheWorld.class.getDeclaredMethod("dummy")); int entryBCI = JVMCICompiler.INVOCATION_ENTRY_BCI; - CompilationTask task = new CompilationTask(jvmciRuntime, compiler, new HotSpotCompilationRequest(dummyMethod, entryBCI, 0L), false); + boolean useProfilingInfo = false; + boolean installAsDefault = false; + CompilationTask task = new CompilationTask(jvmciRuntime, compiler, new HotSpotCompilationRequest(dummyMethod, entryBCI, 0L), useProfilingInfo, installAsDefault); task.runCompilation(); } catch (NoSuchMethodException | SecurityException e1) { e1.printStackTrace(); @@ -676,7 +677,10 @@ long allocatedAtStart = MemUseTrackerImpl.getCurrentThreadAllocatedBytes(); int entryBCI = JVMCICompiler.INVOCATION_ENTRY_BCI; HotSpotCompilationRequest request = new HotSpotCompilationRequest(method, entryBCI, 0L); - CompilationTask task = new CompilationTask(jvmciRuntime, compiler, request, false); + // For more stable CTW execution, disable use of profiling information + boolean useProfilingInfo = false; + boolean installAsDefault = false; + CompilationTask task = new CompilationTask(jvmciRuntime, compiler, request, useProfilingInfo, installAsDefault); task.runCompilation(); memoryUsed.getAndAdd(MemUseTrackerImpl.getCurrentThreadAllocatedBytes() - allocatedAtStart); diff -r 58eb143a8259 -r f35e653aa876 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/CompileTheWorldOptions.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/CompileTheWorldOptions.java Mon Dec 21 00:20:11 2015 +0100 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/CompileTheWorldOptions.java Mon Dec 21 16:19:35 2015 +0100 @@ -22,10 +22,11 @@ */ package com.oracle.graal.hotspot; +import com.oracle.graal.options.Option; +import com.oracle.graal.options.OptionType; +import com.oracle.graal.options.OptionValue; + import jdk.vm.ci.hotspot.HotSpotVMConfig; -import jdk.vm.ci.options.Option; -import jdk.vm.ci.options.OptionType; -import jdk.vm.ci.options.OptionValue; /** * Options related to {@link CompileTheWorld}. diff -r 58eb143a8259 -r f35e653aa876 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotBackend.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotBackend.java Mon Dec 21 00:20:11 2015 +0100 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotBackend.java Mon Dec 21 16:19:35 2015 +0100 @@ -37,9 +37,6 @@ import jdk.vm.ci.hotspot.HotSpotJVMCIRuntime; import jdk.vm.ci.hotspot.HotSpotVMConfig; import jdk.vm.ci.meta.Value; -import jdk.vm.ci.options.Option; -import jdk.vm.ci.options.OptionType; -import jdk.vm.ci.options.OptionValue; import com.oracle.graal.compiler.common.cfg.AbstractBlockBase; import com.oracle.graal.compiler.common.spi.ForeignCallDescriptor; @@ -67,6 +64,9 @@ import com.oracle.graal.lir.framemap.FrameMap; import com.oracle.graal.lir.framemap.ReferenceMapBuilder; import com.oracle.graal.nodes.UnwindNode; +import com.oracle.graal.options.Option; +import com.oracle.graal.options.OptionType; +import com.oracle.graal.options.OptionValue; import com.oracle.graal.phases.tiers.SuitesProvider; import com.oracle.graal.word.Pointer; import com.oracle.graal.word.Word; diff -r 58eb143a8259 -r f35e653aa876 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotGraalCompiler.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotGraalCompiler.java Mon Dec 21 00:20:11 2015 +0100 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotGraalCompiler.java Mon Dec 21 16:19:35 2015 +0100 @@ -48,7 +48,6 @@ import com.oracle.graal.debug.TopLevelDebugConfig; import com.oracle.graal.debug.internal.DebugScope; import com.oracle.graal.hotspot.meta.HotSpotProviders; -import com.oracle.graal.hotspot.meta.HotSpotSuitesProvider; import com.oracle.graal.hotspot.phases.OnStackReplacementPhase; import com.oracle.graal.java.GraphBuilderPhase; import com.oracle.graal.lir.asm.CompilationResultBuilderFactory; @@ -56,8 +55,9 @@ import com.oracle.graal.nodes.StructuredGraph; import com.oracle.graal.nodes.StructuredGraph.AllowAssumptions; import com.oracle.graal.nodes.graphbuilderconf.GraphBuilderConfiguration; +import com.oracle.graal.nodes.graphbuilderconf.GraphBuilderConfiguration.DebugInfoMode; +import com.oracle.graal.nodes.graphbuilderconf.GraphBuilderConfiguration.Plugins; import com.oracle.graal.nodes.graphbuilderconf.IntrinsicContext; -import com.oracle.graal.nodes.graphbuilderconf.GraphBuilderConfiguration.Plugins; import com.oracle.graal.nodes.spi.Replacements; import com.oracle.graal.phases.OptimisticOptimizations; import com.oracle.graal.phases.OptimisticOptimizations.Optimization; @@ -88,7 +88,7 @@ DebugEnvironment.initialize(TTY.out); } - CompilationTask task = new CompilationTask(jvmciRuntime, this, (HotSpotCompilationRequest) request, true); + CompilationTask task = new CompilationTask(jvmciRuntime, this, (HotSpotCompilationRequest) request, true, true); try (DebugConfigScope dcs = Debug.setConfig(new TopLevelDebugConfig())) { task.runCompilation(); } @@ -106,7 +106,7 @@ System.exit(0); } - public CompilationResult compile(ResolvedJavaMethod method, int entryBCI) { + public CompilationResult compile(ResolvedJavaMethod method, int entryBCI, boolean useProfilingInfo) { HotSpotBackend backend = graalRuntime.getHostBackend(); HotSpotProviders providers = backend.getProviders(); final boolean isOSR = entryBCI != JVMCICompiler.INVOCATION_ENTRY_BCI; @@ -139,8 +139,9 @@ } CompilationResult result = new CompilationResult(); result.setEntryBCI(entryBCI); - GraalCompiler.compileGraph(graph, cc, method, providers, backend, getGraphBuilderSuite(providers, isOSR), optimisticOpts, profilingInfo, suites, lirSuites, result, - CompilationResultBuilderFactory.Default); + boolean shouldDebugNonSafepoints = providers.getCodeCache().shouldDebugNonSafepoints(); + PhaseSuite graphBuilderSuite = configGraphBuilderSuite(providers.getSuites().getDefaultGraphBuilderSuite(), shouldDebugNonSafepoints, isOSR, useProfilingInfo); + GraalCompiler.compileGraph(graph, cc, method, providers, backend, graphBuilderSuite, optimisticOpts, profilingInfo, suites, lirSuites, result, CompilationResultBuilderFactory.Default); if (!isOSR) { ProfilingInfo profile = method.getProfilingInfo(); @@ -185,14 +186,46 @@ return providers.getSuites().getDefaultLIRSuites(); } - protected PhaseSuite getGraphBuilderSuite(HotSpotProviders providers, boolean isOSR) { - PhaseSuite suite = providers.getSuites().getDefaultGraphBuilderSuite(); - if (providers.getCodeCache().shouldDebugNonSafepoints()) { - suite = HotSpotSuitesProvider.withSimpleDebugInfo(suite); - } - if (isOSR) { - suite = suite.copy(); - suite.appendPhase(new OnStackReplacementPhase()); + /** + * Reconfigures a given graph builder suite (GBS) if one of the given GBS parameter values is + * not the default. + * + * @param suite the graph builder suite + * @param shouldDebugNonSafepoints specifies if extra debug info should be generated (default is + * false) + * @param isOSR specifies if extra OSR-specific post-processing is required (default is false) + * @param useProfilingInfo specifies if the graph builder should use profiling info (default is + * true) + * @return a new suite derived from {@code suite} if any of the GBS parameters did not have a + * default value otherwise {@code suite} + */ + protected PhaseSuite configGraphBuilderSuite(PhaseSuite suite, boolean shouldDebugNonSafepoints, boolean isOSR, boolean useProfilingInfo) { + if (shouldDebugNonSafepoints || isOSR || !useProfilingInfo) { + PhaseSuite newGbs = suite.copy(); + + if (shouldDebugNonSafepoints || !useProfilingInfo) { + // This complexity below is to ensure exactly one + // GraphBuilderConfiguration copy is made. + GraphBuilderPhase graphBuilderPhase = (GraphBuilderPhase) newGbs.findPhase(GraphBuilderPhase.class).previous(); + GraphBuilderConfiguration graphBuilderConfig = graphBuilderPhase.getGraphBuilderConfig(); + if (shouldDebugNonSafepoints) { + graphBuilderConfig = graphBuilderConfig.withDebugInfoMode(DebugInfoMode.Simple); + if (!useProfilingInfo) { + graphBuilderConfig.setUseProfiling(false); + } + } else { + assert !useProfilingInfo; + graphBuilderConfig = graphBuilderConfig.copy(); + graphBuilderConfig.setUseProfiling(false); + } + + GraphBuilderPhase newGraphBuilderPhase = new GraphBuilderPhase(graphBuilderConfig); + newGbs.findPhase(GraphBuilderPhase.class).set(newGraphBuilderPhase); + } + if (isOSR) { + newGbs.appendPhase(new OnStackReplacementPhase()); + } + return newGbs; } return suite; } diff -r 58eb143a8259 -r f35e653aa876 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotGraalCompilerFactory.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotGraalCompilerFactory.java Mon Dec 21 00:20:11 2015 +0100 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotGraalCompilerFactory.java Mon Dec 21 16:19:35 2015 +0100 @@ -23,20 +23,39 @@ package com.oracle.graal.hotspot; import static jdk.vm.ci.inittimer.InitTimer.timer; + +import java.io.BufferedReader; +import java.io.File; +import java.io.FileReader; +import java.io.IOException; +import java.lang.reflect.Field; +import java.util.ArrayList; +import java.util.List; +import java.util.Map; +import java.util.Properties; + import jdk.vm.ci.code.Architecture; +import jdk.vm.ci.common.JVMCIError; import jdk.vm.ci.hotspot.HotSpotJVMCIRuntime; import jdk.vm.ci.inittimer.InitTimer; -import jdk.vm.ci.options.Option; -import jdk.vm.ci.options.OptionType; -import jdk.vm.ci.options.OptionValue; import jdk.vm.ci.runtime.JVMCICompilerFactory; import jdk.vm.ci.runtime.JVMCIRuntime; import jdk.vm.ci.service.Services; +import sun.misc.VM; +import com.oracle.graal.options.GraalJarsOptionDescriptorsProvider; +import com.oracle.graal.options.Option; +import com.oracle.graal.options.OptionType; +import com.oracle.graal.options.OptionValue; +import com.oracle.graal.options.OptionsParser; import com.oracle.graal.phases.tiers.CompilerConfiguration; public abstract class HotSpotGraalCompilerFactory implements JVMCICompilerFactory { + static { + initializeOptions(); + } + static class Options { // @formatter:off @@ -62,6 +81,73 @@ } } + /** + * Parses the options in the file denoted by the {@linkplain VM#getSavedProperty(String) saved} + * system property named {@code "graal.options.file"} if the file exists followed by the options + * encoded in saved system properties whose names start with {@code "graal.option."}. + */ + @SuppressWarnings("try") + private static void initializeOptions() { + try (InitTimer t = timer("InitializeOptions")) { + boolean jdk8OrEarlier = System.getProperty("java.specification.version").compareTo("1.9") < 0; + GraalJarsOptionDescriptorsProvider odp = jdk8OrEarlier ? GraalJarsOptionDescriptorsProvider.create() : null; + + String optionsFile = System.getProperty("graal.options.file"); + + if (optionsFile != null) { + File graalOptions = new File(optionsFile); + if (graalOptions.exists()) { + try (BufferedReader br = new BufferedReader(new FileReader(graalOptions))) { + String optionSetting = null; + int lineNo = 1; + List optionSettings = new ArrayList<>(); + while ((optionSetting = br.readLine()) != null) { + if (!optionSetting.isEmpty() && optionSetting.charAt(0) != '#') { + try { + OptionsParser.parseOptionSettingTo(optionSetting, optionSettings); + } catch (Throwable e) { + throw new InternalError("Error parsing " + graalOptions + ", line " + lineNo, e); + } + } + lineNo++; + } + try { + OptionsParser.parseOptions(optionSettings.toArray(new String[optionSettings.size()]), null, odp, null); + } catch (Throwable e) { + throw new InternalError("Error parsing an option from " + graalOptions, e); + } + } catch (IOException e) { + throw new InternalError("Error reading " + graalOptions, e); + } + } + } + + Properties savedProps = getSavedProperties(); + + List optionSettings = new ArrayList<>(); + for (Map.Entry e : savedProps.entrySet()) { + String name = (String) e.getKey(); + if (name.startsWith("graal.option.")) { + String value = (String) e.getValue(); + optionSettings.add(name.substring("graal.option.".length())); + optionSettings.add(value); + } + } + + OptionsParser.parseOptions(optionSettings.toArray(new String[optionSettings.size()]), null, odp, null); + } + } + + private static Properties getSavedProperties() { + try { + Field savedPropsField = VM.class.getDeclaredField("savedProps"); + savedPropsField.setAccessible(true); + return (Properties) savedPropsField.get(null); + } catch (Exception e) { + throw new JVMCIError(e); + } + } + protected abstract HotSpotBackendFactory getBackendFactory(Architecture arch); protected abstract CompilerConfiguration createCompilerConfiguration(); diff -r 58eb143a8259 -r f35e653aa876 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotTTYStreamProvider.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotTTYStreamProvider.java Mon Dec 21 00:20:11 2015 +0100 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotTTYStreamProvider.java Mon Dec 21 16:19:35 2015 +0100 @@ -24,11 +24,11 @@ import java.io.PrintStream; -import jdk.vm.ci.options.Option; -import jdk.vm.ci.options.OptionType; import jdk.vm.ci.service.ServiceProvider; import com.oracle.graal.debug.TTYStreamProvider; +import com.oracle.graal.options.Option; +import com.oracle.graal.options.OptionType; @ServiceProvider(TTYStreamProvider.class) public class HotSpotTTYStreamProvider implements TTYStreamProvider { diff -r 58eb143a8259 -r f35e653aa876 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/PrintStreamOption.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/PrintStreamOption.java Mon Dec 21 00:20:11 2015 +0100 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/PrintStreamOption.java Mon Dec 21 16:19:35 2015 +0100 @@ -29,9 +29,10 @@ import java.io.PrintStream; import java.lang.management.ManagementFactory; +import com.oracle.graal.options.OptionValue; + import jdk.vm.ci.hotspot.HotSpotJVMCIRuntime; import jdk.vm.ci.hotspot.HotSpotJVMCIRuntimeProvider; -import jdk.vm.ci.options.OptionValue; /** * An option that encapsulates and configures a print stream. diff -r 58eb143a8259 -r f35e653aa876 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/debug/BenchmarkCounters.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/debug/BenchmarkCounters.java Mon Dec 21 00:20:11 2015 +0100 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/debug/BenchmarkCounters.java Mon Dec 21 16:19:35 2015 +0100 @@ -39,13 +39,13 @@ import jdk.vm.ci.hotspot.HotSpotJVMCIRuntime; import jdk.vm.ci.hotspot.HotSpotVMConfig; import jdk.vm.ci.inittimer.SuppressFBWarnings; -import jdk.vm.ci.options.Option; -import jdk.vm.ci.options.OptionType; -import jdk.vm.ci.options.OptionValue; import com.oracle.graal.debug.TTY; import com.oracle.graal.hotspot.replacements.NewObjectSnippets; import com.oracle.graal.nodes.debug.DynamicCounterNode; +import com.oracle.graal.options.Option; +import com.oracle.graal.options.OptionType; +import com.oracle.graal.options.OptionValue; //JaCoCo Exclude diff -r 58eb143a8259 -r f35e653aa876 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotGraalConstantReflectionProvider.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotGraalConstantReflectionProvider.java Mon Dec 21 00:20:11 2015 +0100 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotGraalConstantReflectionProvider.java Mon Dec 21 16:19:35 2015 +0100 @@ -38,9 +38,12 @@ import jdk.vm.ci.meta.MetaAccessProvider; import jdk.vm.ci.meta.ResolvedJavaField; import jdk.vm.ci.meta.ResolvedJavaMethod; +import jdk.vm.ci.meta.ResolvedJavaType; import jdk.vm.ci.runtime.JVMCI; import com.oracle.graal.graph.NodeClass; +import com.oracle.graal.options.OptionValue; +import com.oracle.graal.options.StableOptionValue; import com.oracle.graal.replacements.ReplacementsImpl; import com.oracle.graal.replacements.SnippetCounter; import com.oracle.graal.replacements.SnippetTemplate; @@ -56,10 +59,24 @@ super(runtime); } + private ResolvedJavaType cachedStableOptionValueType; + + /** + * The {@code value} field in {@link OptionValue} is considered constant if {@code receiver} is + * a {@link StableOptionValue} instance. + */ @Override public JavaConstant readConstantFieldValue(ResolvedJavaField field, JavaConstant receiver) { MetaAccessProvider metaAccess = runtime.getHostJVMCIBackend().getMetaAccess(); assert !ImmutableCode.getValue() || isCalledForSnippets(metaAccess) || SnippetGraphUnderConstruction.get() != null || FieldReadEnabledInImmutableCode.get() == Boolean.TRUE : receiver; + if (!field.isStatic() && field.getName().equals("value")) { + if (cachedStableOptionValueType == null) { + cachedStableOptionValueType = metaAccess.lookupJavaType(StableOptionValue.class); + } + if (cachedStableOptionValueType.isInstance(receiver)) { + return readFieldValue(field, receiver); + } + } return super.readConstantFieldValue(field, receiver); } diff -r 58eb143a8259 -r f35e653aa876 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotGraphBuilderPlugins.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotGraphBuilderPlugins.java Mon Dec 21 00:20:11 2015 +0100 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotGraphBuilderPlugins.java Mon Dec 21 16:19:35 2015 +0100 @@ -38,7 +38,6 @@ import jdk.vm.ci.meta.JavaKind; import jdk.vm.ci.meta.MetaAccessProvider; import jdk.vm.ci.meta.ResolvedJavaMethod; -import jdk.vm.ci.options.StableOptionValue; import jdk.vm.ci.service.Services; import sun.reflect.Reflection; @@ -74,6 +73,7 @@ import com.oracle.graal.nodes.memory.address.OffsetAddressNode; import com.oracle.graal.nodes.spi.StampProvider; import com.oracle.graal.nodes.util.GraphUtil; +import com.oracle.graal.options.StableOptionValue; import com.oracle.graal.replacements.InlineDuringParsingPlugin; import com.oracle.graal.replacements.MethodHandlePlugin; import com.oracle.graal.replacements.NodeIntrinsificationPlugin; diff -r 58eb143a8259 -r f35e653aa876 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotSuitesProvider.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotSuitesProvider.java Mon Dec 21 00:20:11 2015 +0100 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotSuitesProvider.java Mon Dec 21 16:19:35 2015 +0100 @@ -25,8 +25,6 @@ import static com.oracle.graal.compiler.common.GraalOptions.ImmutableCode; import static com.oracle.graal.compiler.common.GraalOptions.VerifyPhases; import jdk.vm.ci.hotspot.HotSpotVMConfig; -import jdk.vm.ci.options.DerivedOptionValue; -import jdk.vm.ci.options.DerivedOptionValue.OptionSupplier; import com.oracle.graal.hotspot.HotSpotBackend; import com.oracle.graal.hotspot.HotSpotGraalRuntimeProvider; @@ -44,6 +42,8 @@ import com.oracle.graal.nodes.StructuredGraph.AllowAssumptions; import com.oracle.graal.nodes.graphbuilderconf.GraphBuilderConfiguration; import com.oracle.graal.nodes.graphbuilderconf.GraphBuilderConfiguration.DebugInfoMode; +import com.oracle.graal.options.DerivedOptionValue; +import com.oracle.graal.options.DerivedOptionValue.OptionSupplier; import com.oracle.graal.phases.BasePhase; import com.oracle.graal.phases.PhaseSuite; import com.oracle.graal.phases.common.AddressLoweringPhase; diff -r 58eb143a8259 -r f35e653aa876 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/InstanceOfSnippetsOptions.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/InstanceOfSnippetsOptions.java Mon Dec 21 00:20:11 2015 +0100 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/InstanceOfSnippetsOptions.java Mon Dec 21 16:19:35 2015 +0100 @@ -22,9 +22,9 @@ */ package com.oracle.graal.hotspot.replacements; -import jdk.vm.ci.options.Option; -import jdk.vm.ci.options.OptionType; -import jdk.vm.ci.options.OptionValue; +import com.oracle.graal.options.Option; +import com.oracle.graal.options.OptionType; +import com.oracle.graal.options.OptionValue; /** * Options related to {@link InstanceOfSnippets}. diff -r 58eb143a8259 -r f35e653aa876 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/MonitorSnippets.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/MonitorSnippets.java Mon Dec 21 00:20:11 2015 +0100 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/MonitorSnippets.java Mon Dec 21 16:19:35 2015 +0100 @@ -62,9 +62,6 @@ import jdk.vm.ci.meta.LocationIdentity; import jdk.vm.ci.meta.ResolvedJavaMethod; import jdk.vm.ci.meta.ResolvedJavaType; -import jdk.vm.ci.options.Option; -import jdk.vm.ci.options.OptionType; -import jdk.vm.ci.options.OptionValue; import com.oracle.graal.api.replacements.Fold; import com.oracle.graal.compiler.common.spi.ForeignCallDescriptor; @@ -99,6 +96,9 @@ import com.oracle.graal.nodes.memory.address.OffsetAddressNode; import com.oracle.graal.nodes.spi.LoweringTool; import com.oracle.graal.nodes.type.StampTool; +import com.oracle.graal.options.Option; +import com.oracle.graal.options.OptionType; +import com.oracle.graal.options.OptionValue; import com.oracle.graal.phases.common.inlining.InliningUtil; import com.oracle.graal.replacements.Log; import com.oracle.graal.replacements.Snippet; diff -r 58eb143a8259 -r f35e653aa876 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/NewObjectSnippetsOptions.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/NewObjectSnippetsOptions.java Mon Dec 21 00:20:11 2015 +0100 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/NewObjectSnippetsOptions.java Mon Dec 21 16:19:35 2015 +0100 @@ -22,9 +22,9 @@ */ package com.oracle.graal.hotspot.replacements; -import jdk.vm.ci.options.Option; -import jdk.vm.ci.options.OptionType; -import jdk.vm.ci.options.OptionValue; +import com.oracle.graal.options.Option; +import com.oracle.graal.options.OptionType; +import com.oracle.graal.options.OptionValue; /** * Options related to {@link NewObjectSnippets}. diff -r 58eb143a8259 -r f35e653aa876 graal/com.oracle.graal.java/src/com/oracle/graal/java/BytecodeParserOptions.java --- a/graal/com.oracle.graal.java/src/com/oracle/graal/java/BytecodeParserOptions.java Mon Dec 21 00:20:11 2015 +0100 +++ b/graal/com.oracle.graal.java/src/com/oracle/graal/java/BytecodeParserOptions.java Mon Dec 21 16:19:35 2015 +0100 @@ -22,10 +22,10 @@ */ package com.oracle.graal.java; -import jdk.vm.ci.options.Option; -import jdk.vm.ci.options.OptionType; -import jdk.vm.ci.options.OptionValue; -import jdk.vm.ci.options.StableOptionValue; +import com.oracle.graal.options.Option; +import com.oracle.graal.options.OptionType; +import com.oracle.graal.options.OptionValue; +import com.oracle.graal.options.StableOptionValue; /** * Options related to {@link BytecodeParser}. diff -r 58eb143a8259 -r f35e653aa876 graal/com.oracle.graal.java/src/com/oracle/graal/java/DefaultSuitesProvider.java --- a/graal/com.oracle.graal.java/src/com/oracle/graal/java/DefaultSuitesProvider.java Mon Dec 21 00:20:11 2015 +0100 +++ b/graal/com.oracle.graal.java/src/com/oracle/graal/java/DefaultSuitesProvider.java Mon Dec 21 16:19:35 2015 +0100 @@ -22,12 +22,11 @@ */ package com.oracle.graal.java; -import jdk.vm.ci.options.DerivedOptionValue; -import jdk.vm.ci.options.DerivedOptionValue.OptionSupplier; - import com.oracle.graal.lir.phases.LIRSuites; import com.oracle.graal.nodes.graphbuilderconf.GraphBuilderConfiguration; import com.oracle.graal.nodes.graphbuilderconf.GraphBuilderConfiguration.Plugins; +import com.oracle.graal.options.DerivedOptionValue; +import com.oracle.graal.options.DerivedOptionValue.OptionSupplier; import com.oracle.graal.phases.PhaseSuite; import com.oracle.graal.phases.tiers.CompilerConfiguration; import com.oracle.graal.phases.tiers.HighTierContext; diff -r 58eb143a8259 -r f35e653aa876 graal/com.oracle.graal.jtt/src/com/oracle/graal/jtt/backend/ConstantPhiTest.java --- a/graal/com.oracle.graal.jtt/src/com/oracle/graal/jtt/backend/ConstantPhiTest.java Mon Dec 21 00:20:11 2015 +0100 +++ b/graal/com.oracle.graal.jtt/src/com/oracle/graal/jtt/backend/ConstantPhiTest.java Mon Dec 21 16:19:35 2015 +0100 @@ -27,13 +27,12 @@ import java.lang.reflect.Method; -import jdk.vm.ci.options.OptionValue; -import jdk.vm.ci.options.OptionValue.OverrideScope; - import org.junit.Test; import com.oracle.graal.compiler.common.GraalOptions; import com.oracle.graal.jtt.JTTTest; +import com.oracle.graal.options.OptionValue; +import com.oracle.graal.options.OptionValue.OverrideScope; public class ConstantPhiTest extends JTTTest { diff -r 58eb143a8259 -r f35e653aa876 graal/com.oracle.graal.jtt/src/com/oracle/graal/jtt/backend/LargeConstantSectionTest.java --- a/graal/com.oracle.graal.jtt/src/com/oracle/graal/jtt/backend/LargeConstantSectionTest.java Mon Dec 21 00:20:11 2015 +0100 +++ b/graal/com.oracle.graal.jtt/src/com/oracle/graal/jtt/backend/LargeConstantSectionTest.java Mon Dec 21 16:19:35 2015 +0100 @@ -34,8 +34,6 @@ import static jdk.internal.org.objectweb.asm.Opcodes.LLOAD; import static jdk.internal.org.objectweb.asm.Opcodes.LRETURN; import static jdk.internal.org.objectweb.asm.Opcodes.RETURN; -import jdk.vm.ci.options.OptionValue; -import jdk.vm.ci.options.OptionValue.OverrideScope; import jdk.internal.org.objectweb.asm.ClassWriter; import jdk.internal.org.objectweb.asm.Label; import jdk.internal.org.objectweb.asm.MethodVisitor; @@ -48,6 +46,8 @@ import com.oracle.graal.api.directives.GraalDirectives; import com.oracle.graal.compiler.common.GraalOptions; import com.oracle.graal.jtt.JTTTest; +import com.oracle.graal.options.OptionValue; +import com.oracle.graal.options.OptionValue.OverrideScope; public class LargeConstantSectionTest extends JTTTest { private static final String NAME = "LargeConstantSection"; diff -r 58eb143a8259 -r f35e653aa876 graal/com.oracle.graal.jtt/src/com/oracle/graal/jtt/bytecode/BC_instanceof01.java --- a/graal/com.oracle.graal.jtt/src/com/oracle/graal/jtt/bytecode/BC_instanceof01.java Mon Dec 21 00:20:11 2015 +0100 +++ b/graal/com.oracle.graal.jtt/src/com/oracle/graal/jtt/bytecode/BC_instanceof01.java Mon Dec 21 16:19:35 2015 +0100 @@ -22,13 +22,12 @@ */ package com.oracle.graal.jtt.bytecode; -import jdk.vm.ci.options.OptionValue; -import jdk.vm.ci.options.OptionValue.OverrideScope; - import org.junit.Test; import com.oracle.graal.compiler.phases.HighTier; import com.oracle.graal.jtt.JTTTest; +import com.oracle.graal.options.OptionValue; +import com.oracle.graal.options.OptionValue.OverrideScope; import com.oracle.graal.phases.tiers.Suites; /** diff -r 58eb143a8259 -r f35e653aa876 graal/com.oracle.graal.jtt/src/com/oracle/graal/jtt/lang/LambdaEagerTest.java --- a/graal/com.oracle.graal.jtt/src/com/oracle/graal/jtt/lang/LambdaEagerTest.java Mon Dec 21 00:20:11 2015 +0100 +++ b/graal/com.oracle.graal.jtt/src/com/oracle/graal/jtt/lang/LambdaEagerTest.java Mon Dec 21 16:19:35 2015 +0100 @@ -28,14 +28,14 @@ import jdk.vm.ci.code.InstalledCode; import jdk.vm.ci.meta.DeoptimizationReason; import jdk.vm.ci.meta.ResolvedJavaMethod; -import jdk.vm.ci.options.OptionValue; -import jdk.vm.ci.options.OptionValue.OverrideScope; import org.junit.Test; import com.oracle.graal.compiler.common.GraalOptions; import com.oracle.graal.compiler.test.GraalCompilerTest; import com.oracle.graal.nodes.StructuredGraph; +import com.oracle.graal.options.OptionValue; +import com.oracle.graal.options.OptionValue.OverrideScope; public class LambdaEagerTest extends GraalCompilerTest { diff -r 58eb143a8259 -r f35e653aa876 graal/com.oracle.graal.lir.amd64/src/com/oracle/graal/lir/amd64/phases/StackMoveOptimizationPhase.java --- a/graal/com.oracle.graal.lir.amd64/src/com/oracle/graal/lir/amd64/phases/StackMoveOptimizationPhase.java Mon Dec 21 00:20:11 2015 +0100 +++ b/graal/com.oracle.graal.lir.amd64/src/com/oracle/graal/lir/amd64/phases/StackMoveOptimizationPhase.java Mon Dec 21 16:19:35 2015 +0100 @@ -32,9 +32,6 @@ import jdk.vm.ci.code.TargetDescription; import jdk.vm.ci.meta.AllocatableValue; import jdk.vm.ci.meta.Value; -import jdk.vm.ci.options.NestedBooleanOptionValue; -import jdk.vm.ci.options.Option; -import jdk.vm.ci.options.OptionType; import com.oracle.graal.compiler.common.cfg.AbstractBlockBase; import com.oracle.graal.debug.Debug; @@ -46,6 +43,9 @@ import com.oracle.graal.lir.amd64.AMD64Move.AMD64StackMove; import com.oracle.graal.lir.gen.LIRGenerationResult; import com.oracle.graal.lir.phases.PostAllocationOptimizationPhase; +import com.oracle.graal.options.NestedBooleanOptionValue; +import com.oracle.graal.options.Option; +import com.oracle.graal.options.OptionType; /** * Replaces sequential {@link AMD64StackMove}s of the same type with a single diff -r 58eb143a8259 -r f35e653aa876 graal/com.oracle.graal.lir/src/com/oracle/graal/lir/alloc/lsra/LinearScan.java --- a/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/alloc/lsra/LinearScan.java Mon Dec 21 00:20:11 2015 +0100 +++ b/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/alloc/lsra/LinearScan.java Mon Dec 21 16:19:35 2015 +0100 @@ -45,10 +45,6 @@ import jdk.vm.ci.meta.AllocatableValue; import jdk.vm.ci.meta.LIRKind; import jdk.vm.ci.meta.Value; -import jdk.vm.ci.options.NestedBooleanOptionValue; -import jdk.vm.ci.options.Option; -import jdk.vm.ci.options.OptionType; -import jdk.vm.ci.options.OptionValue; import com.oracle.graal.compiler.common.alloc.RegisterAllocationConfig; import com.oracle.graal.compiler.common.cfg.AbstractBlockBase; @@ -68,6 +64,10 @@ import com.oracle.graal.lir.gen.LIRGenerationResult; import com.oracle.graal.lir.gen.LIRGeneratorTool.MoveFactory; import com.oracle.graal.lir.phases.AllocationPhase.AllocationContext; +import com.oracle.graal.options.NestedBooleanOptionValue; +import com.oracle.graal.options.Option; +import com.oracle.graal.options.OptionType; +import com.oracle.graal.options.OptionValue; /** * An implementation of the linear scan register allocator algorithm described in { public static class Options { diff -r 58eb143a8259 -r f35e653aa876 graal/com.oracle.graal.lir/src/com/oracle/graal/lir/stackslotalloc/LSStackSlotAllocator.java --- a/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/stackslotalloc/LSStackSlotAllocator.java Mon Dec 21 00:20:11 2015 +0100 +++ b/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/stackslotalloc/LSStackSlotAllocator.java Mon Dec 21 16:19:35 2015 +0100 @@ -40,9 +40,6 @@ import jdk.vm.ci.code.TargetDescription; import jdk.vm.ci.meta.LIRKind; import jdk.vm.ci.meta.Value; -import jdk.vm.ci.options.NestedBooleanOptionValue; -import jdk.vm.ci.options.Option; -import jdk.vm.ci.options.OptionType; import com.oracle.graal.compiler.common.cfg.AbstractBlockBase; import com.oracle.graal.debug.Debug; @@ -61,6 +58,9 @@ import com.oracle.graal.lir.framemap.VirtualStackSlotRange; import com.oracle.graal.lir.gen.LIRGenerationResult; import com.oracle.graal.lir.phases.AllocationPhase; +import com.oracle.graal.options.NestedBooleanOptionValue; +import com.oracle.graal.options.Option; +import com.oracle.graal.options.OptionType; /** * Linear Scan {@link StackSlotAllocator}. diff -r 58eb143a8259 -r f35e653aa876 graal/com.oracle.graal.loop/src/com/oracle/graal/loop/DefaultLoopPolicies.java --- a/graal/com.oracle.graal.loop/src/com/oracle/graal/loop/DefaultLoopPolicies.java Mon Dec 21 00:20:11 2015 +0100 +++ b/graal/com.oracle.graal.loop/src/com/oracle/graal/loop/DefaultLoopPolicies.java Mon Dec 21 16:19:35 2015 +0100 @@ -28,10 +28,6 @@ import java.util.List; -import jdk.vm.ci.options.Option; -import jdk.vm.ci.options.OptionType; -import jdk.vm.ci.options.OptionValue; - import com.oracle.graal.debug.Debug; import com.oracle.graal.debug.DebugMetric; import com.oracle.graal.graph.Node; @@ -44,6 +40,9 @@ import com.oracle.graal.nodes.cfg.Block; import com.oracle.graal.nodes.cfg.ControlFlowGraph; import com.oracle.graal.nodes.debug.ControlFlowAnchorNode; +import com.oracle.graal.options.Option; +import com.oracle.graal.options.OptionType; +import com.oracle.graal.options.OptionValue; public class DefaultLoopPolicies implements LoopPolicies { @Option(help = "", type = OptionType.Expert) public static final OptionValue LoopUnswitchMaxIncrease = new OptionValue<>(500); diff -r 58eb143a8259 -r f35e653aa876 graal/com.oracle.graal.options.processor/src/META-INF/services/javax.annotation.processing.Processor --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.options.processor/src/META-INF/services/javax.annotation.processing.Processor Mon Dec 21 16:19:35 2015 +0100 @@ -0,0 +1,1 @@ +com.oracle.graal.options.processor.OptionProcessor diff -r 58eb143a8259 -r f35e653aa876 graal/com.oracle.graal.options.processor/src/com/oracle/graal/options/processor/OptionProcessor.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.options.processor/src/com/oracle/graal/options/processor/OptionProcessor.java Mon Dec 21 16:19:35 2015 +0100 @@ -0,0 +1,363 @@ +/* + * 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.options.processor; + +import java.io.IOException; +import java.io.PrintWriter; +import java.util.ArrayList; +import java.util.Collections; +import java.util.HashMap; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.Set; + +import javax.annotation.processing.AbstractProcessor; +import javax.annotation.processing.Filer; +import javax.annotation.processing.RoundEnvironment; +import javax.annotation.processing.SupportedAnnotationTypes; +import javax.lang.model.SourceVersion; +import javax.lang.model.element.Element; +import javax.lang.model.element.ElementKind; +import javax.lang.model.element.Modifier; +import javax.lang.model.element.Name; +import javax.lang.model.element.PackageElement; +import javax.lang.model.element.TypeElement; +import javax.lang.model.element.VariableElement; +import javax.lang.model.type.DeclaredType; +import javax.lang.model.type.TypeKind; +import javax.lang.model.type.TypeMirror; +import javax.lang.model.util.Elements; +import javax.lang.model.util.Types; +import javax.tools.Diagnostic.Kind; +import javax.tools.JavaFileObject; + +import com.oracle.graal.options.Option; +import com.oracle.graal.options.OptionDescriptor; +import com.oracle.graal.options.OptionDescriptors; +import com.oracle.graal.options.OptionValue; + +/** + * Processes static fields annotated with {@link Option}. An {@link OptionDescriptors} + * implementation is generated for each top level class containing at least one such field. The name + * of the generated class for top level class {@code com.foo.Bar} is + * {@code com.foo.Bar_OptionDescriptors}. + */ +@SupportedAnnotationTypes({"com.oracle.graal.options.Option"}) +public class OptionProcessor extends AbstractProcessor { + + @Override + public SourceVersion getSupportedSourceVersion() { + return SourceVersion.latest(); + } + + private final Set processed = new HashSet<>(); + + private void processElement(Element element, OptionsInfo info) { + + if (!element.getModifiers().contains(Modifier.STATIC)) { + processingEnv.getMessager().printMessage(Kind.ERROR, "Option field must be static", element); + return; + } + if (element.getModifiers().contains(Modifier.PRIVATE)) { + processingEnv.getMessager().printMessage(Kind.ERROR, "Option field cannot be private", element); + return; + } + + Option annotation = element.getAnnotation(Option.class); + assert annotation != null; + assert element instanceof VariableElement; + assert element.getKind() == ElementKind.FIELD; + VariableElement field = (VariableElement) element; + String fieldName = field.getSimpleName().toString(); + + Elements elements = processingEnv.getElementUtils(); + Types types = processingEnv.getTypeUtils(); + + TypeMirror fieldType = field.asType(); + if (fieldType.getKind() != TypeKind.DECLARED) { + processingEnv.getMessager().printMessage(Kind.ERROR, "Option field must be of type " + OptionValue.class.getName(), element); + return; + } + DeclaredType declaredFieldType = (DeclaredType) fieldType; + + TypeMirror optionValueType = elements.getTypeElement(OptionValue.class.getName()).asType(); + if (!types.isSubtype(fieldType, types.erasure(optionValueType))) { + String msg = String.format("Option field type %s is not a subclass of %s", fieldType, optionValueType); + processingEnv.getMessager().printMessage(Kind.ERROR, msg, element); + return; + } + + if (!field.getModifiers().contains(Modifier.STATIC)) { + processingEnv.getMessager().printMessage(Kind.ERROR, "Option field must be static", element); + return; + } + if (field.getModifiers().contains(Modifier.PRIVATE)) { + processingEnv.getMessager().printMessage(Kind.ERROR, "Option field cannot be private", element); + return; + } + + String help = annotation.help(); + if (help.length() != 0) { + char firstChar = help.charAt(0); + if (!Character.isUpperCase(firstChar)) { + processingEnv.getMessager().printMessage(Kind.ERROR, "Option help text must start with upper case letter", element); + return; + } + } + + String optionName = annotation.name(); + if (optionName.equals("")) { + optionName = fieldName; + } + + DeclaredType declaredOptionValueType = declaredFieldType; + while (!types.isSameType(types.erasure(declaredOptionValueType), types.erasure(optionValueType))) { + List directSupertypes = types.directSupertypes(declaredFieldType); + assert !directSupertypes.isEmpty(); + declaredOptionValueType = (DeclaredType) directSupertypes.get(0); + } + + assert !declaredOptionValueType.getTypeArguments().isEmpty(); + String optionType = declaredOptionValueType.getTypeArguments().get(0).toString(); + if (optionType.startsWith("java.lang.")) { + optionType = optionType.substring("java.lang.".length()); + } + + Element enclosing = element.getEnclosingElement(); + String declaringClass = ""; + String separator = ""; + Set originatingElementsList = info.originatingElements; + originatingElementsList.add(field); + while (enclosing != null) { + if (enclosing.getKind() == ElementKind.CLASS || enclosing.getKind() == ElementKind.INTERFACE) { + if (enclosing.getModifiers().contains(Modifier.PRIVATE)) { + String msg = String.format("Option field cannot be declared in a private %s %s", enclosing.getKind().name().toLowerCase(), enclosing); + processingEnv.getMessager().printMessage(Kind.ERROR, msg, element); + return; + } + originatingElementsList.add(enclosing); + declaringClass = enclosing.getSimpleName() + separator + declaringClass; + separator = "."; + } else { + assert enclosing.getKind() == ElementKind.PACKAGE; + } + enclosing = enclosing.getEnclosingElement(); + } + + info.options.add(new OptionInfo(optionName, help, optionType, declaringClass, field)); + } + + private void createFiles(OptionsInfo info) { + String pkg = ((PackageElement) info.topDeclaringType.getEnclosingElement()).getQualifiedName().toString(); + Name topDeclaringClass = info.topDeclaringType.getSimpleName(); + Element[] originatingElements = info.originatingElements.toArray(new Element[info.originatingElements.size()]); + + createOptionsDescriptorsFile(info, pkg, topDeclaringClass, originatingElements); + } + + private void createOptionsDescriptorsFile(OptionsInfo info, String pkg, Name topDeclaringClass, Element[] originatingElements) { + String optionsClassName = topDeclaringClass + "_" + OptionDescriptors.class.getSimpleName(); + + Filer filer = processingEnv.getFiler(); + try (PrintWriter out = createSourceFile(pkg, optionsClassName, filer, originatingElements)) { + + out.println("// CheckStyle: stop header check"); + out.println("// CheckStyle: stop line length check"); + out.println("// GENERATED CONTENT - DO NOT EDIT"); + out.println("// Source: " + topDeclaringClass + ".java"); + out.println("package " + pkg + ";"); + out.println(""); + out.println("import java.util.*;"); + out.println("import " + OptionDescriptors.class.getPackage().getName() + ".*;"); + out.println(""); + out.println("public class " + optionsClassName + " implements " + OptionDescriptors.class.getSimpleName() + " {"); + + String desc = OptionDescriptor.class.getSimpleName(); + + int i = 0; + Collections.sort(info.options); + + out.println(" @Override"); + out.println(" public OptionDescriptor get(String value) {"); + out.println(" // CheckStyle: stop line length check"); + if (info.options.size() == 1) { + out.println(" if (value.equals(\"" + info.options.get(0).name + "\")) {"); + } else { + out.println(" switch (value) {"); + } + for (OptionInfo option : info.options) { + String name = option.name; + String optionValue; + if (option.field.getModifiers().contains(Modifier.PRIVATE)) { + throw new InternalError(); + } else { + optionValue = option.declaringClass + "." + option.field.getSimpleName(); + } + String type = option.type; + String help = option.help; + String declaringClass = option.declaringClass; + Name fieldName = option.field.getSimpleName(); + if (info.options.size() == 1) { + out.printf(" return %s.create(\"%s\", %s.class, \"%s\", %s.class, \"%s\", %s);\n", desc, name, type, help, declaringClass, fieldName, optionValue); + } else { + out.printf(" case \"" + name + "\": return %s.create(\"%s\", %s.class, \"%s\", %s.class, \"%s\", %s);\n", desc, name, type, help, declaringClass, fieldName, optionValue); + } + } + out.println(" }"); + out.println(" // CheckStyle: resume line length check"); + out.println(" return null;"); + out.println(" }"); + out.println(); + out.println(" @Override"); + out.println(" public Iterator<" + desc + "> iterator() {"); + out.println(" // CheckStyle: stop line length check"); + out.println(" List<" + desc + "> options = Arrays.asList("); + for (OptionInfo option : info.options) { + String optionValue; + if (option.field.getModifiers().contains(Modifier.PRIVATE)) { + throw new InternalError(); + } else { + optionValue = option.declaringClass + "." + option.field.getSimpleName(); + } + String name = option.name; + String type = option.type; + String help = option.help; + String declaringClass = option.declaringClass; + Name fieldName = option.field.getSimpleName(); + String comma = i == info.options.size() - 1 ? "" : ","; + out.printf(" %s.create(\"%s\", %s.class, \"%s\", %s.class, \"%s\", %s)%s\n", desc, name, type, help, declaringClass, fieldName, optionValue, comma); + i++; + } + out.println(" );"); + out.println(" // CheckStyle: resume line length check"); + out.println(" return options.iterator();"); + out.println(" }"); + out.println("}"); + } + } + + protected PrintWriter createSourceFile(String pkg, String relativeName, Filer filer, Element... originatingElements) { + try { + // Ensure Unix line endings to comply with code style guide checked by Checkstyle + JavaFileObject sourceFile = filer.createSourceFile(pkg + "." + relativeName, originatingElements); + return new PrintWriter(sourceFile.openWriter()) { + + @Override + public void println() { + print("\n"); + } + }; + } catch (IOException e) { + throw new RuntimeException(e); + } + } + + static class OptionInfo implements Comparable { + + final String name; + final String help; + final String type; + final String declaringClass; + final VariableElement field; + + public OptionInfo(String name, String help, String type, String declaringClass, VariableElement field) { + this.name = name; + this.help = help; + this.type = type; + this.declaringClass = declaringClass; + this.field = field; + } + + @Override + public int compareTo(OptionInfo other) { + return name.compareTo(other.name); + } + + @Override + public String toString() { + return declaringClass + "." + field; + } + } + + static class OptionsInfo { + + final Element topDeclaringType; + final List options = new ArrayList<>(); + final Set originatingElements = new HashSet<>(); + + public OptionsInfo(Element topDeclaringType) { + this.topDeclaringType = topDeclaringType; + } + } + + private static Element topDeclaringType(Element element) { + Element enclosing = element.getEnclosingElement(); + if (enclosing == null || enclosing.getKind() == ElementKind.PACKAGE) { + assert element.getKind() == ElementKind.CLASS || element.getKind() == ElementKind.INTERFACE; + return element; + } + return topDeclaringType(enclosing); + } + + @Override + public boolean process(Set annotations, RoundEnvironment roundEnv) { + if (roundEnv.processingOver()) { + return true; + } + + Map map = new HashMap<>(); + for (Element element : roundEnv.getElementsAnnotatedWith(Option.class)) { + if (!processed.contains(element)) { + processed.add(element); + Element topDeclaringType = topDeclaringType(element); + OptionsInfo options = map.get(topDeclaringType); + if (options == null) { + options = new OptionsInfo(topDeclaringType); + map.put(topDeclaringType, options); + } + processElement(element, options); + } + } + + boolean ok = true; + Map uniqueness = new HashMap<>(); + for (OptionsInfo info : map.values()) { + for (OptionInfo option : info.options) { + OptionInfo conflict = uniqueness.put(option.name, option); + if (conflict != null) { + processingEnv.getMessager().printMessage(Kind.ERROR, "Duplicate option names for " + option + " and " + conflict, option.field); + ok = false; + } + } + } + + if (ok) { + for (OptionsInfo info : map.values()) { + createFiles(info); + } + } + + return true; + } +} diff -r 58eb143a8259 -r f35e653aa876 graal/com.oracle.graal.options.test/src/com/oracle/graal/options/test/NestedBooleanOptionValueTest.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.options.test/src/com/oracle/graal/options/test/NestedBooleanOptionValueTest.java Mon Dec 21 16:19:35 2015 +0100 @@ -0,0 +1,143 @@ +/* + * Copyright (c) 2013, 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. + */ + +/** + * @test + * @run junit jdk.vm.ci.options.test.NestedBooleanOptionValueTest + */ + +package com.oracle.graal.options.test; + +import static com.oracle.graal.options.test.NestedBooleanOptionValueTest.Options.Master0; +import static com.oracle.graal.options.test.NestedBooleanOptionValueTest.Options.Master1; +import static com.oracle.graal.options.test.NestedBooleanOptionValueTest.Options.Master2; +import static com.oracle.graal.options.test.NestedBooleanOptionValueTest.Options.NestedOption0; +import static com.oracle.graal.options.test.NestedBooleanOptionValueTest.Options.NestedOption1; +import static com.oracle.graal.options.test.NestedBooleanOptionValueTest.Options.NestedOption2; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; + +import org.junit.Test; + +import com.oracle.graal.options.NestedBooleanOptionValue; +import com.oracle.graal.options.OptionDescriptor; +import com.oracle.graal.options.OptionValue; +import com.oracle.graal.options.OptionValue.OverrideScope; + +public class NestedBooleanOptionValueTest { + + public static class Options { + public static final OptionValue Master0 = new OptionValue<>(true); + public static final OptionValue NestedOption0 = new NestedBooleanOptionValue(Master0, true); + public static final OptionValue Master1 = new OptionValue<>(true); + public static final OptionValue NestedOption1 = new NestedBooleanOptionValue(Master1, true); + public static final OptionValue Master2 = new OptionValue<>(true); + public static final OptionValue NestedOption2 = new NestedBooleanOptionValue(Master2, false); + } + + static final OptionDescriptor master0 = OptionDescriptor.create("Master0", Boolean.class, "", Options.class, "Master0", Master0); + static final OptionDescriptor nestedOption0 = OptionDescriptor.create("NestedOption0", Boolean.class, "", Options.class, "NestedOption0", NestedOption0); + static final OptionDescriptor master1 = OptionDescriptor.create("Master1", Boolean.class, "", Options.class, "Master1", Master1); + static final OptionDescriptor nestedOption1 = OptionDescriptor.create("NestedOption1", Boolean.class, "", Options.class, "NestedOption1", NestedOption1); + static final OptionDescriptor master2 = OptionDescriptor.create("Master2", Boolean.class, "", Options.class, "Master2", Master2); + static final OptionDescriptor nestedOption2 = OptionDescriptor.create("NestedOption2", Boolean.class, "", Options.class, "NestedOption2", NestedOption2); + + @SuppressWarnings("try") + @Test + public void runOverrides() { + assertTrue(Master0.getValue()); + assertTrue(NestedOption0.getValue()); + try (OverrideScope s1 = OptionValue.override(Master0, false)) { + assertFalse(Master0.getValue()); + assertFalse(NestedOption0.getValue()); + try (OverrideScope s2 = OptionValue.override(NestedOption0, false)) { + assertFalse(NestedOption0.getValue()); + } + try (OverrideScope s2 = OptionValue.override(NestedOption0, true)) { + assertTrue(NestedOption0.getValue()); + } + } + assertTrue(Master0.getValue()); + try (OverrideScope s1 = OptionValue.override(NestedOption0, false)) { + assertFalse(NestedOption0.getValue()); + } + try (OverrideScope s1 = OptionValue.override(NestedOption0, true)) { + assertTrue(NestedOption0.getValue()); + } + } + + @Test + public void runDefaultTrue() { + Master1.setValue(true); + assertTrue(Master1.getValue()); + assertTrue(NestedOption1.getValue()); + // nested value unset + Master1.setValue(false); + assertFalse(Master1.getValue()); + assertFalse(NestedOption1.getValue()); + // set false + Master1.setValue(false); + NestedOption1.setValue(false); + assertFalse(Master1.getValue()); + assertFalse(NestedOption1.getValue()); + Master1.setValue(true); + assertTrue(Master1.getValue()); + assertFalse(NestedOption1.getValue()); + // set true + Master1.setValue(false); + NestedOption1.setValue(true); + assertFalse(Master1.getValue()); + assertTrue(NestedOption1.getValue()); + Master1.setValue(true); + assertTrue(Master1.getValue()); + assertTrue(NestedOption1.getValue()); + } + + @Test + public void runDefaultFalse() { + Master2.setValue(true); + assertTrue(Master2.getValue()); + assertFalse(NestedOption2.getValue()); + // nested value unset + Master2.setValue(false); + assertFalse(Master2.getValue()); + assertFalse(NestedOption2.getValue()); + // set false + Master2.setValue(false); + NestedOption2.setValue(false); + assertFalse(Master2.getValue()); + assertFalse(NestedOption2.getValue()); + Master2.setValue(true); + assertTrue(Master2.getValue()); + assertFalse(NestedOption2.getValue()); + // set true + Master2.setValue(false); + NestedOption2.setValue(true); + assertFalse(Master2.getValue()); + assertTrue(NestedOption2.getValue()); + Master2.setValue(true); + assertTrue(Master2.getValue()); + assertTrue(NestedOption2.getValue()); + } + +} diff -r 58eb143a8259 -r f35e653aa876 graal/com.oracle.graal.options.test/src/com/oracle/graal/options/test/TestOptionValue.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.options.test/src/com/oracle/graal/options/test/TestOptionValue.java Mon Dec 21 16:19:35 2015 +0100 @@ -0,0 +1,140 @@ +/* + * Copyright (c) 2013, 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. + */ + +/** + * @test + * @run junit com.oracle.graal.options.test.TestOptionValue + */ + +package com.oracle.graal.options.test; + +import static com.oracle.graal.options.test.TestOptionValue.Options.Mutable; +import static com.oracle.graal.options.test.TestOptionValue.Options.SecondMutable; +import static com.oracle.graal.options.test.TestOptionValue.Options.Stable; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; +import static org.junit.Assert.fail; + +import java.util.Arrays; + +import org.junit.Test; + +import com.oracle.graal.options.OptionDescriptor; +import com.oracle.graal.options.OptionValue; +import com.oracle.graal.options.StableOptionValue; +import com.oracle.graal.options.OptionValue.OverrideScope; + +@SuppressWarnings("try") +public class TestOptionValue { + + public static class Options { + public static final OptionValue Stable = new StableOptionValue<>(true); + public static final OptionValue Mutable = new OptionValue<>("original"); + public static final OptionValue SecondMutable = new OptionValue<>("second"); + } + + static final OptionDescriptor stable = OptionDescriptor.create("Stable", Boolean.class, "", Options.class, "Stable", Stable); + static final OptionDescriptor mutable = OptionDescriptor.create("Mutable", String.class, "", Options.class, "Mutable", Mutable); + static final OptionDescriptor secondMutable = OptionDescriptor.create("SecondMutable", String.class, "", Options.class, "SecondMutable", SecondMutable); + + @Test + public void testMutable() { + assertEquals("original", Mutable.getValue()); + try (OverrideScope s1 = OptionValue.override(Mutable, "override1")) { + assertEquals("override1", Mutable.getValue()); + try (OverrideScope s2 = OptionValue.override(Mutable, "override2")) { + assertEquals("override2", Mutable.getValue()); + } + assertEquals("override1", Mutable.getValue()); + try (OverrideScope s3 = OptionValue.override(Mutable, "override3")) { + assertEquals("override3", Mutable.getValue()); + } + assertEquals("override1", Mutable.getValue()); + } + assertEquals("original", Mutable.getValue()); + try (OverrideScope s1 = OptionValue.override(Mutable, "original")) { + assertEquals("original", Mutable.getValue()); + } + } + + @Test + public void testMultiple() { + assertEquals("original", Mutable.getValue()); + assertEquals("second", SecondMutable.getValue()); + try (OverrideScope s1 = OptionValue.override(Mutable, "override1", SecondMutable, "secondOverride1")) { + assertEquals("override1", Mutable.getValue()); + assertEquals("secondOverride1", SecondMutable.getValue()); + try (OverrideScope s2 = OptionValue.override(Mutable, "override2", SecondMutable, "secondOverride2")) { + assertEquals("override2", Mutable.getValue()); + assertEquals("secondOverride2", SecondMutable.getValue()); + } + assertEquals("override1", Mutable.getValue()); + assertEquals("secondOverride1", SecondMutable.getValue()); + try (OverrideScope s3 = OptionValue.override(Mutable, "override3", SecondMutable, "secondOverride3")) { + assertEquals("override3", Mutable.getValue()); + assertEquals("secondOverride3", SecondMutable.getValue()); + } + assertEquals("override1", Mutable.getValue()); + assertEquals("secondOverride1", SecondMutable.getValue()); + } + assertEquals("original", Mutable.getValue()); + assertEquals("second", SecondMutable.getValue()); + try (OverrideScope s1 = OptionValue.override(Mutable, "original", SecondMutable, "second")) { + assertEquals("original", Mutable.getValue()); + assertEquals("second", SecondMutable.getValue()); + } + } + + @Test + public void testStable() { + assertTrue(Stable.getValue()); + try (OverrideScope s = OptionValue.override(Stable, false)) { + fail("cannot override stable option"); + } catch (IllegalArgumentException e) { + // expected + } + } + + @Test + public void toStringTest() { + assertEquals("com.oracle.graal.options.test.TestOptionValue$Options.Mutable=original", Mutable.toString()); + try (OverrideScope s1 = OptionValue.override(Mutable, "override1")) { + assertEquals("com.oracle.graal.options.test.TestOptionValue$Options.Mutable=override1", Mutable.toString()); + try (OverrideScope s2 = OptionValue.override(Mutable, "override2")) { + assertEquals("com.oracle.graal.options.test.TestOptionValue$Options.Mutable=override2", Mutable.toString()); + } + } + } + + @Test + public void getValuesTest() { + assertEquals(Arrays.asList("original"), Mutable.getValues(null)); + assertEquals(Arrays.asList(true), Stable.getValues(null)); + try (OverrideScope s1 = OptionValue.override(Mutable, "override1")) { + assertEquals(Arrays.asList("override1", "original"), Mutable.getValues(null)); + try (OverrideScope s2 = OptionValue.override(Mutable, "override2")) { + assertEquals(Arrays.asList("override2", "override1", "original"), Mutable.getValues(null)); + } + } + } +} diff -r 58eb143a8259 -r f35e653aa876 graal/com.oracle.graal.options/src/com/oracle/graal/options/DerivedOptionValue.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.options/src/com/oracle/graal/options/DerivedOptionValue.java Mon Dec 21 16:19:35 2015 +0100 @@ -0,0 +1,59 @@ +/* + * Copyright (c) 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.options; + +import java.io.Serializable; +import java.util.function.Supplier; + +import com.oracle.graal.options.OptionValue.OverrideScope; + +/** + * A cached value that needs to be recomputed when an option changes. + */ +public class DerivedOptionValue { + + public interface OptionSupplier extends Supplier, Serializable { + } + + private final T initialValue; + private final OptionSupplier supplier; + + public DerivedOptionValue(OptionSupplier supplier) { + this.supplier = supplier; + assert OptionValue.getOverrideScope() == null : "derived option value should be initialized outside any override scope"; + this.initialValue = createValue(); + } + + public T getValue() { + OverrideScope overrideScope = OptionValue.getOverrideScope(); + if (overrideScope != null) { + return overrideScope.getDerived(this); + } else { + return initialValue; + } + } + + T createValue() { + return supplier.get(); + } +} diff -r 58eb143a8259 -r f35e653aa876 graal/com.oracle.graal.options/src/com/oracle/graal/options/GraalJarsOptionDescriptorsProvider.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.options/src/com/oracle/graal/options/GraalJarsOptionDescriptorsProvider.java Mon Dec 21 16:19:35 2015 +0100 @@ -0,0 +1,129 @@ +/* + * Copyright (c) 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.options; + +import java.io.BufferedReader; +import java.io.File; +import java.io.IOException; +import java.io.InputStreamReader; +import java.util.ArrayList; +import java.util.Collections; +import java.util.Iterator; +import java.util.List; +import java.util.jar.JarFile; +import java.util.zip.ZipEntry; + +import com.oracle.graal.options.OptionsParser.OptionDescriptorsProvider; + +/** + * Access to the {@link OptionDescriptors} declared by + * {@code META-INF/services/com.oracle.graal.options.OptionDescriptors} files in + * {@code /lib/jvmci/*.jar}. + */ +public final class GraalJarsOptionDescriptorsProvider implements OptionDescriptorsProvider { + + static final String OptionDescriptorsServiceFile = "META-INF/services/" + OptionDescriptors.class.getName(); + + private final Iterator jars; + private final List optionsDescriptorsList; + + /** + * Creates a {@link GraalJarsOptionDescriptorsProvider} if at least one JVMCI jar is available + * otherwise returns null. + */ + public static GraalJarsOptionDescriptorsProvider create() { + List jarsList = findJVMCIJars(); + if (jarsList.isEmpty()) { + return null; + } + return new GraalJarsOptionDescriptorsProvider(jarsList); + } + + private GraalJarsOptionDescriptorsProvider(List jarsList) { + this.jars = jarsList.iterator(); + this.optionsDescriptorsList = new ArrayList<>(jarsList.size() * 3); + } + + /** + * Finds the list of JVMCI jars. + */ + private static List findJVMCIJars() { + File javaHome = new File(System.getProperty("java.home")); + File lib = new File(javaHome, "lib"); + File jvmci = new File(lib, "jvmci"); + if (!jvmci.exists()) { + return Collections.emptyList(); + } + + List jarFiles = new ArrayList<>(); + for (String fileName : jvmci.list()) { + if (fileName.endsWith(".jar")) { + File file = new File(jvmci, fileName); + if (file.isDirectory()) { + continue; + } + jarFiles.add(file); + } + } + return jarFiles; + } + + public OptionDescriptor get(String name) { + // Look up loaded option descriptors first + for (OptionDescriptors optionDescriptors : optionsDescriptorsList) { + OptionDescriptor desc = optionDescriptors.get(name); + if (desc != null) { + return desc; + } + } + while (jars.hasNext()) { + File path = jars.next(); + try (JarFile jar = new JarFile(path)) { + ZipEntry entry = jar.getEntry(OptionDescriptorsServiceFile); + if (entry != null) { + BufferedReader br = new BufferedReader(new InputStreamReader(jar.getInputStream(entry))); + String line = null; + OptionDescriptor desc = null; + while ((line = br.readLine()) != null) { + OptionDescriptors options; + try { + options = (OptionDescriptors) Class.forName(line).newInstance(); + optionsDescriptorsList.add(options); + if (desc == null) { + desc = options.get(name); + } + } catch (Exception e) { + throw new InternalError("Error instantiating class " + line + " read from " + path, e); + } + } + if (desc != null) { + return desc; + } + } + } catch (IOException e) { + throw new InternalError("Error reading " + path, e); + } + } + return null; + } +} diff -r 58eb143a8259 -r f35e653aa876 graal/com.oracle.graal.options/src/com/oracle/graal/options/NestedBooleanOptionValue.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.options/src/com/oracle/graal/options/NestedBooleanOptionValue.java Mon Dec 21 16:19:35 2015 +0100 @@ -0,0 +1,58 @@ +/* + * Copyright (c) 2015, 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.options; + +/** + * A nested Boolean {@link OptionValue} that can be overridden by a {@link #masterOption master + * option}. + *

+ *

  • If the option is present on the command line the specified value is used. + *
  • Otherwise {@link #getValue()} depends on the {@link #masterOption} and evaluates as follows: + *
      + *
    • If {@link #masterOption} is set, this value equals to {@link #initialValue}. + *
    • Otherwise, if {@link #masterOption} is {@code false}, this option is {@code false}. + */ +public class NestedBooleanOptionValue extends OptionValue { + private final OptionValue masterOption; + private final Boolean initialValue; + + public NestedBooleanOptionValue(OptionValue masterOption, Boolean initialValue) { + super(null); + this.masterOption = masterOption; + this.initialValue = initialValue; + } + + public OptionValue getMasterOption() { + return masterOption; + } + + @Override + public Boolean getValue() { + Boolean v = super.getValue(); + if (v == null) { + return initialValue && masterOption.getValue(); + } + return v; + } + +} diff -r 58eb143a8259 -r f35e653aa876 graal/com.oracle.graal.options/src/com/oracle/graal/options/Option.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.options/src/com/oracle/graal/options/Option.java Mon Dec 21 16:19:35 2015 +0100 @@ -0,0 +1,55 @@ +/* + * 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.options; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +/** + * Describes the attributes of an option whose {@link OptionValue value} is in a static field + * annotated by this annotation type. + * + * @see OptionDescriptor + */ +@Retention(RetentionPolicy.CLASS) +@Target(ElementType.FIELD) +public @interface Option { + + /** + * Gets a help message for the option. New lines can be embedded in the message with + * {@code "%n"}. + */ + String help(); + + /** + * The name of the option. By default, the name of the annotated field should be used. + */ + String name() default ""; + + /** + * Specifies the type of the option. + */ + OptionType type() default OptionType.Debug; +} diff -r 58eb143a8259 -r f35e653aa876 graal/com.oracle.graal.options/src/com/oracle/graal/options/OptionDescriptor.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.options/src/com/oracle/graal/options/OptionDescriptor.java Mon Dec 21 16:19:35 2015 +0100 @@ -0,0 +1,102 @@ +/* + * 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.options; + +/** + * Describes the attributes of a static field {@linkplain Option option} and provides access to its + * {@linkplain OptionValue value}. + */ +public final class OptionDescriptor { + + protected final String name; + protected final Class type; + protected final String help; + protected final OptionValue option; + protected final Class declaringClass; + protected final String fieldName; + + public static OptionDescriptor create(String name, Class type, String help, Class declaringClass, String fieldName, OptionValue option) { + OptionDescriptor result = option.getDescriptor(); + if (result == null) { + result = new OptionDescriptor(name, type, help, declaringClass, fieldName, option); + option.setDescriptor(result); + } + assert result.name.equals(name) && result.type == type && result.declaringClass == declaringClass && result.fieldName.equals(fieldName) && result.option == option; + return result; + } + + private OptionDescriptor(String name, Class type, String help, Class declaringClass, String fieldName, OptionValue option) { + this.name = name; + this.type = type; + this.help = help; + this.option = option; + this.declaringClass = declaringClass; + this.fieldName = fieldName; + assert !type.isPrimitive() : "must used boxed type instead of " + type; + } + + /** + * Gets the type of values stored in the option. This will be the boxed type for a primitive + * option. + */ + public Class getType() { + return type; + } + + /** + * Gets a descriptive help message for the option. + */ + public String getHelp() { + return help; + } + + /** + * Gets the name of the option. It's up to the client of this object how to use the name to get + * a user specified value for the option from the environment. + */ + public String getName() { + return name; + } + + /** + * Gets the boxed option value. + */ + public OptionValue getOptionValue() { + return option; + } + + public Class getDeclaringClass() { + return declaringClass; + } + + public String getFieldName() { + return fieldName; + } + + /** + * Gets a description of the location where this option is stored. + */ + public String getLocation() { + return getDeclaringClass().getName() + "." + getFieldName(); + } +} diff -r 58eb143a8259 -r f35e653aa876 graal/com.oracle.graal.options/src/com/oracle/graal/options/OptionDescriptors.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.options/src/com/oracle/graal/options/OptionDescriptors.java Mon Dec 21 16:19:35 2015 +0100 @@ -0,0 +1,34 @@ +/* + * 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.options; + +/** + * An interface to a set of {@link OptionDescriptor}s. + */ +public interface OptionDescriptors extends Iterable { + /** + * Gets the {@link OptionDescriptor} matching a given option name or {@code null} if this option + * descriptor set doesn't contain a matching option. + */ + OptionDescriptor get(String value); +} diff -r 58eb143a8259 -r f35e653aa876 graal/com.oracle.graal.options/src/com/oracle/graal/options/OptionType.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.options/src/com/oracle/graal/options/OptionType.java Mon Dec 21 16:19:35 2015 +0100 @@ -0,0 +1,44 @@ +/* + * Copyright (c) 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.options; + +/** + * Classifies JVMCI options in several categories depending on who this option is relevant for. + * + */ +public enum OptionType { + /** + * An option common for users to apply. + */ + User, + + /** + * An option only relevant in corner cases and for fine-tuning. + */ + Expert, + + /** + * An option only relevant when debugging the compiler. + */ + Debug +} diff -r 58eb143a8259 -r f35e653aa876 graal/com.oracle.graal.options/src/com/oracle/graal/options/OptionValue.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.options/src/com/oracle/graal/options/OptionValue.java Mon Dec 21 16:19:35 2015 +0100 @@ -0,0 +1,484 @@ +/* + * 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.options; + +import java.io.PrintStream; +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; +import java.util.Comparator; +import java.util.HashMap; +import java.util.Map; +import java.util.Map.Entry; +import java.util.Objects; + +/** + * An option value. + */ +public class OptionValue { + /** + * Temporarily changes the value for an option. The {@linkplain OptionValue#getValue() value} of + * {@code option} is set to {@code value} until {@link OverrideScope#close()} is called on the + * object returned by this method. + *

      + * Since the returned object is {@link AutoCloseable} the try-with-resource construct can be + * used: + * + *

      +     * try (OverrideScope s = OptionValue.override(myOption, myValue) {
      +     *     // code that depends on myOption == myValue
      +     * }
      +     * 
      + */ + public static OverrideScope override(OptionValue option, Object value) { + OverrideScope current = getOverrideScope(); + if (current == null) { + if (!value.equals(option.getValue())) { + return new SingleOverrideScope(option, value); + } + Map, Object> overrides = Collections.emptyMap(); + return new MultipleOverridesScope(current, overrides); + } + return new MultipleOverridesScope(current, option, value); + } + + /** + * Temporarily changes the values for a set of options. The {@linkplain OptionValue#getValue() + * value} of each {@code option} in {@code overrides} is set to the corresponding {@code value} + * in {@code overrides} until {@link OverrideScope#close()} is called on the object returned by + * this method. + *

      + * Since the returned object is {@link AutoCloseable} the try-with-resource construct can be + * used: + * + *

      +     * Map<OptionValue, Object> overrides = new HashMap<>();
      +     * overrides.put(myOption1, myValue1);
      +     * overrides.put(myOption2, myValue2);
      +     * try (OverrideScope s = OptionValue.override(overrides) {
      +     *     // code that depends on myOption == myValue
      +     * }
      +     * 
      + */ + public static OverrideScope override(Map, Object> overrides) { + OverrideScope current = getOverrideScope(); + if (current == null && overrides.size() == 1) { + Entry, Object> single = overrides.entrySet().iterator().next(); + OptionValue option = single.getKey(); + Object overrideValue = single.getValue(); + if (!overrideValue.equals(option.getValue())) { + return new SingleOverrideScope(option, overrideValue); + } + } + return new MultipleOverridesScope(current, overrides); + } + + /** + * Temporarily changes the values for a set of options. The {@linkplain OptionValue#getValue() + * value} of each {@code option} in {@code overrides} is set to the corresponding {@code value} + * in {@code overrides} until {@link OverrideScope#close()} is called on the object returned by + * this method. + *

      + * Since the returned object is {@link AutoCloseable} the try-with-resource construct can be + * used: + * + *

      +     * try (OverrideScope s = OptionValue.override(myOption1, myValue1, myOption2, myValue2) {
      +     *     // code that depends on myOption == myValue
      +     * }
      +     * 
      + * + * @param overrides overrides in the form {@code [option1, override1, option2, override2, ...]} + */ + public static OverrideScope override(Object... overrides) { + OverrideScope current = getOverrideScope(); + if (current == null && overrides.length == 2) { + OptionValue option = (OptionValue) overrides[0]; + Object overrideValue = overrides[1]; + if (!overrideValue.equals(option.getValue())) { + return new SingleOverrideScope(option, overrideValue); + } + } + Map, Object> map = Collections.emptyMap(); + for (int i = 0; i < overrides.length; i += 2) { + OptionValue option = (OptionValue) overrides[i]; + Object overrideValue = overrides[i + 1]; + if (!overrideValue.equals(option.getValue())) { + if (map.isEmpty()) { + map = new HashMap<>(); + } + map.put(option, overrideValue); + } + } + return new MultipleOverridesScope(current, map); + } + + private static final ThreadLocal overrideScopeTL = new ThreadLocal<>(); + + protected static OverrideScope getOverrideScope() { + return overrideScopeTL.get(); + } + + protected static void setOverrideScope(OverrideScope overrideScope) { + overrideScopeTL.set(overrideScope); + } + + private T defaultValue; + + /** + * The raw option value. + */ + protected T value; + + private OptionDescriptor descriptor; + + private long reads; + private OptionValue next; + private static OptionValue head; + + private static final boolean ShowReadsHistogram = Boolean.getBoolean("jvmci.showOptionValueReadsHistogram"); + + private static void addToHistogram(OptionValue option) { + if (ShowReadsHistogram) { + synchronized (OptionValue.class) { + option.next = head; + head = option; + } + } + } + + @SuppressWarnings("unchecked") + public OptionValue(T value) { + this.defaultValue = value; + this.value = (T) DEFAULT; + addToHistogram(this); + } + + private static final Object DEFAULT = "DEFAULT"; + private static final Object UNINITIALIZED = "UNINITIALIZED"; + + /** + * Creates an uninitialized option value for a subclass that initializes itself + * {@link #defaultValue() lazily}. + */ + @SuppressWarnings("unchecked") + protected OptionValue() { + this.defaultValue = (T) UNINITIALIZED; + this.value = (T) DEFAULT; + addToHistogram(this); + } + + /** + * Lazy initialization of default value. + */ + protected T defaultValue() { + throw new InternalError("Option without a default value value must override defaultValue()"); + } + + /** + * Sets the descriptor for this option. + */ + public void setDescriptor(OptionDescriptor descriptor) { + assert this.descriptor == null : "Overwriting existing descriptor"; + this.descriptor = descriptor; + } + + /** + * Returns the descriptor for this option, if it has been set by + * {@link #setDescriptor(OptionDescriptor)}. + */ + public OptionDescriptor getDescriptor() { + return descriptor; + } + + /** + * Gets the name of this option. The name for an option value with a null + * {@linkplain #setDescriptor(OptionDescriptor) descriptor} is the value of + * {@link Object#toString()}. + */ + public String getName() { + return descriptor == null ? super.toString() : (descriptor.getDeclaringClass().getName() + "." + descriptor.getName()); + } + + @Override + public String toString() { + return getName() + "=" + getValue(); + } + + /** + * The initial value specified in source code. The returned value is not affected by calls to + * {@link #setValue(Object)} or registering {@link OverrideScope}s. Therefore, it is also not + * affected by options set on the command line. + */ + public T getDefaultValue() { + if (defaultValue == UNINITIALIZED) { + defaultValue = defaultValue(); + } + return defaultValue; + } + + /** + * Returns true if the option has the same value that was set in the source code. + */ + public boolean hasDefaultValue() { + if (!(this instanceof StableOptionValue)) { + getValue(); // ensure initialized + } + return value == DEFAULT || Objects.equals(value, getDefaultValue()); + } + + /** + * Gets the value of this option. + */ + public T getValue() { + if (ShowReadsHistogram) { + reads++; + } + if (!(this instanceof StableOptionValue)) { + OverrideScope overrideScope = getOverrideScope(); + if (overrideScope != null) { + T override = overrideScope.getOverride(this); + if (override != null) { + return override; + } + } + } + if (value != DEFAULT) { + return value; + } else { + return getDefaultValue(); + } + } + + /** + * Gets the values of this option including overridden values. + * + * @param c the collection to which the values are added. If null, one is allocated. + * @return the collection to which the values were added in order from most overridden to + * current value + */ + @SuppressWarnings("unchecked") + public Collection getValues(Collection c) { + Collection values = c == null ? new ArrayList<>() : c; + if (!(this instanceof StableOptionValue)) { + OverrideScope overrideScope = getOverrideScope(); + if (overrideScope != null) { + overrideScope.getOverrides(this, (Collection) values); + } + } + if (value != DEFAULT) { + values.add(value); + } else { + values.add(getDefaultValue()); + } + return values; + } + + /** + * Sets the value of this option. + */ + @SuppressWarnings("unchecked") + public void setValue(Object v) { + this.value = (T) v; + } + + /** + * An object whose {@link #close()} method reverts the option value overriding initiated by + * {@link OptionValue#override(OptionValue, Object)} or {@link OptionValue#override(Map)}. + */ + public abstract static class OverrideScope implements AutoCloseable { + + private Map, Object> derivedCache = null; + + public T getDerived(DerivedOptionValue key) { + if (derivedCache == null) { + derivedCache = new HashMap<>(); + } + @SuppressWarnings("unchecked") + T ret = (T) derivedCache.get(key); + if (ret == null) { + ret = key.createValue(); + derivedCache.put(key, ret); + } + return ret; + } + + abstract void addToInherited(Map, Object> inherited); + + abstract T getOverride(OptionValue option); + + abstract void getOverrides(OptionValue option, Collection c); + + public abstract void close(); + } + + static class SingleOverrideScope extends OverrideScope { + + private final OptionValue option; + private final Object value; + + public SingleOverrideScope(OptionValue option, Object value) { + if (option instanceof StableOptionValue) { + throw new IllegalArgumentException("Cannot override stable option " + option); + } + this.option = option; + this.value = value; + setOverrideScope(this); + } + + @Override + void addToInherited(Map, Object> inherited) { + inherited.put(option, value); + } + + @SuppressWarnings("unchecked") + @Override + T getOverride(OptionValue key) { + if (key == this.option) { + return (T) value; + } + return null; + } + + @Override + void getOverrides(OptionValue key, Collection c) { + if (key == this.option) { + c.add(value); + } + } + + @Override + public void close() { + setOverrideScope(null); + } + } + + static class MultipleOverridesScope extends OverrideScope { + final OverrideScope parent; + final Map, Object> overrides; + + public MultipleOverridesScope(OverrideScope parent, OptionValue option, Object value) { + this.parent = parent; + this.overrides = new HashMap<>(); + if (parent != null) { + parent.addToInherited(overrides); + } + if (option instanceof StableOptionValue) { + throw new IllegalArgumentException("Cannot override stable option " + option); + } + if (!value.equals(option.getValue())) { + this.overrides.put(option, value); + } + if (!overrides.isEmpty()) { + setOverrideScope(this); + } + } + + MultipleOverridesScope(OverrideScope parent, Map, Object> overrides) { + this.parent = parent; + if (overrides.isEmpty() && parent == null) { + this.overrides = Collections.emptyMap(); + return; + } + this.overrides = new HashMap<>(); + if (parent != null) { + parent.addToInherited(this.overrides); + } + for (Map.Entry, Object> e : overrides.entrySet()) { + OptionValue option = e.getKey(); + if (option instanceof StableOptionValue) { + throw new IllegalArgumentException("Cannot override stable option " + option); + } + if (!e.getValue().equals(option.getValue())) { + this.overrides.put(option, e.getValue()); + } + } + if (!this.overrides.isEmpty()) { + setOverrideScope(this); + } + } + + @Override + void addToInherited(Map, Object> inherited) { + if (parent != null) { + parent.addToInherited(inherited); + } + inherited.putAll(overrides); + } + + @SuppressWarnings("unchecked") + @Override + T getOverride(OptionValue option) { + return (T) overrides.get(option); + } + + @Override + void getOverrides(OptionValue option, Collection c) { + Object v = overrides.get(option); + if (v != null) { + c.add(v); + } + if (parent != null) { + parent.getOverrides(option, c); + } + } + + @Override + public void close() { + if (!overrides.isEmpty()) { + setOverrideScope(parent); + } + } + } + + static { + if (ShowReadsHistogram) { + Runtime.getRuntime().addShutdownHook(new Thread() { + @Override + public void run() { + ArrayList> options = new ArrayList<>(); + for (OptionValue option = head; option != null; option = option.next) { + options.add(option); + } + Collections.sort(options, new Comparator>() { + + public int compare(OptionValue o1, OptionValue o2) { + if (o1.reads < o2.reads) { + return -1; + } else if (o1.reads > o2.reads) { + return 1; + } else { + return o1.getName().compareTo(o2.getName()); + } + } + }); + PrintStream out = System.out; + out.println("=== OptionValue reads histogram ==="); + for (OptionValue option : options) { + out.println(option.reads + "\t" + option); + } + } + }); + } + } +} diff -r 58eb143a8259 -r f35e653aa876 graal/com.oracle.graal.options/src/com/oracle/graal/options/OptionsLoader.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.options/src/com/oracle/graal/options/OptionsLoader.java Mon Dec 21 16:19:35 2015 +0100 @@ -0,0 +1,47 @@ +/* + * Copyright (c) 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.options; + +import java.util.ServiceLoader; +import java.util.SortedMap; +import java.util.TreeMap; + +/** + * Helper class used to load option descriptors. Only to be used in the slow-path. + */ +public class OptionsLoader { + public static final SortedMap options = new TreeMap<>(); + + /** + * Initializes {@link #options} from {@link Options} services. + */ + static { + for (OptionDescriptors opts : ServiceLoader.load(OptionDescriptors.class, OptionsLoader.class.getClassLoader())) { + for (OptionDescriptor desc : opts) { + String name = desc.getName(); + OptionDescriptor existing = options.put(name, desc); + assert existing == null : "Option named \"" + name + "\" has multiple definitions: " + existing.getLocation() + " and " + desc.getLocation(); + } + } + } +} diff -r 58eb143a8259 -r f35e653aa876 graal/com.oracle.graal.options/src/com/oracle/graal/options/OptionsParser.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.options/src/com/oracle/graal/options/OptionsParser.java Mon Dec 21 16:19:35 2015 +0100 @@ -0,0 +1,324 @@ +/* + * Copyright (c) 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.options; + +import java.io.PrintStream; +import java.util.ArrayList; +import java.util.Collections; +import java.util.Formatter; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.ServiceLoader; +import java.util.Set; +import java.util.SortedMap; + +/** + * This class contains methods for parsing JVMCI options and matching them against a set of + * {@link OptionDescriptors}. The {@link OptionDescriptors} are loaded from JVMCI jars, either + * {@linkplain GraalJarsOptionDescriptorsProvider directly} or via a {@link ServiceLoader}. + */ +public class OptionsParser { + + private static final OptionValue PrintFlags = new OptionValue<>(false); + private static final OptionValue ShowFlags = new OptionValue<>(false); + + /** + * A service for looking up {@link OptionDescriptor}s. + */ + public interface OptionDescriptorsProvider { + /** + * Gets the {@link OptionDescriptor} matching a given option {@linkplain Option#name() name} + * or null if no option of that name is provided by this object. + */ + OptionDescriptor get(String name); + } + + public interface OptionConsumer { + void set(OptionDescriptor desc, Object value); + } + + /** + * Parses an ordered list of (name, value) pairs assigning values to JVMCI options. + * + * @param optionSettings JVMCI options as serialized (name, value) pairs + * @param setter the object to notify of the parsed option and value + * @param odp if non-null, the service to use for looking up {@link OptionDescriptor}s + * @param options the options database to use if {@code odp == null}. If + * {@code options == null && odp == null}, {@link OptionsLoader#options} is used. + * @throws IllegalArgumentException if there's a problem parsing {@code option} + */ + public static void parseOptions(String[] optionSettings, OptionConsumer setter, OptionDescriptorsProvider odp, SortedMap options) { + if (optionSettings != null && optionSettings.length != 0) { + assert optionSettings.length % 2 == 0; + + moveHelpFlagsToTail(optionSettings); + + for (int i = 0; i < optionSettings.length / 2; i++) { + String name = optionSettings[i * 2]; + String value = optionSettings[i * 2 + 1]; + parseOption(name, value, setter, odp, options); + } + if (PrintFlags.getValue() || ShowFlags.getValue()) { + Set explicitlyAssigned = new HashSet<>(optionSettings.length / 2); + for (int i = 0; i < optionSettings.length / 2; i++) { + String name = optionSettings[i * 2]; + explicitlyAssigned.add(name); + } + printFlags(resolveOptions(options), "JVMCI", System.out, explicitlyAssigned); + if (PrintFlags.getValue()) { + System.exit(0); + } + } + } + } + + /** + * Moves all {@code PrintFlags} and {@code ShowFlags} option settings to the back of + * {@code optionSettings}. This allows the help message to show which options had their value + * explicitly set (even if to their default value). + */ + private static void moveHelpFlagsToTail(String[] optionSettings) { + List tail = null; + int insert = 0; + for (int i = 0; i < optionSettings.length / 2; i++) { + String name = optionSettings[i * 2]; + String value = optionSettings[i * 2 + 1]; + if (name.equals("ShowFlags") || name.equals("PrintFlags")) { + if (tail == null) { + tail = new ArrayList<>(4); + insert = i * 2; + } + tail.add(name); + tail.add(value); + } else if (tail != null) { + optionSettings[insert++] = name; + optionSettings[insert++] = value; + } + } + if (tail != null) { + assert tail.size() + insert == optionSettings.length; + String[] tailArr = tail.toArray(new String[tail.size()]); + System.arraycopy(tailArr, 0, optionSettings, insert, tailArr.length); + } + } + + /** + * Parses a given option setting string to a list of (name, value) pairs. + * + * @param optionSetting a string matching the pattern {@code =} + */ + public static void parseOptionSettingTo(String optionSetting, List dst) { + int eqIndex = optionSetting.indexOf('='); + if (eqIndex == -1) { + throw new InternalError("Option setting has does not match the pattern =: " + optionSetting); + } + dst.add(optionSetting.substring(0, eqIndex)); + dst.add(optionSetting.substring(eqIndex + 1)); + } + + /** + * Resolves {@code options} to a non-null value. This ensures {@link OptionsLoader#options} is + * only loaded if necessary. + */ + private static SortedMap resolveOptions(SortedMap options) { + return options != null ? options : OptionsLoader.options; + } + + /** + * Parses a given option name and value. + * + * @param name the option name + * @param valueString the option value as a string + * @param setter the object to notify of the parsed option and value + * @param odp if non-null, the service to use for looking up {@link OptionDescriptor}s + * @param options the options database to use if {@code odp == null}. If + * {@code options == null && odp == null}, {@link OptionsLoader#options} is used. + * @throws IllegalArgumentException if there's a problem parsing {@code option} + */ + private static void parseOption(String name, String valueString, OptionConsumer setter, OptionDescriptorsProvider odp, SortedMap options) { + + OptionDescriptor desc = odp != null ? odp.get(name) : resolveOptions(options).get(name); + if (desc == null) { + if (name.equals("PrintFlags")) { + desc = OptionDescriptor.create("PrintFlags", Boolean.class, "Prints all JVMCI flags and exits", OptionsParser.class, "PrintFlags", PrintFlags); + } else if (name.equals("ShowFlags")) { + desc = OptionDescriptor.create("ShowFlags", Boolean.class, "Prints all JVMCI flags and continues", OptionsParser.class, "ShowFlags", ShowFlags); + } + } + if (desc == null) { + List matches = fuzzyMatch(resolveOptions(options), name); + Formatter msg = new Formatter(); + msg.format("Could not find option %s", name); + if (!matches.isEmpty()) { + msg.format("%nDid you mean one of the following?"); + for (OptionDescriptor match : matches) { + msg.format("%n %s=", match.getName()); + } + } + throw new IllegalArgumentException(msg.toString()); + } + + Class optionType = desc.getType(); + Object value; + if (optionType == Boolean.class) { + if ("true".equals(valueString)) { + value = Boolean.TRUE; + } else if ("false".equals(valueString)) { + value = Boolean.FALSE; + } else { + throw new IllegalArgumentException("Boolean option '" + name + "' must have value \"true\" or \"false\", not \"" + valueString + "\""); + } + } else if (optionType == Float.class) { + value = Float.parseFloat(valueString); + } else if (optionType == Double.class) { + value = Double.parseDouble(valueString); + } else if (optionType == Integer.class) { + value = Integer.valueOf((int) parseLong(valueString)); + } else if (optionType == Long.class) { + value = Long.valueOf(parseLong(valueString)); + } else if (optionType == String.class) { + value = valueString; + } else { + throw new IllegalArgumentException("Wrong value for option '" + name + "'"); + } + if (setter == null) { + desc.getOptionValue().setValue(value); + } else { + setter.set(desc, value); + } + } + + private static long parseLong(String v) { + String valueString = v.toLowerCase(); + long scale = 1; + if (valueString.endsWith("k")) { + scale = 1024L; + } else if (valueString.endsWith("m")) { + scale = 1024L * 1024L; + } else if (valueString.endsWith("g")) { + scale = 1024L * 1024L * 1024L; + } else if (valueString.endsWith("t")) { + scale = 1024L * 1024L * 1024L * 1024L; + } + + if (scale != 1) { + /* Remove trailing scale character. */ + valueString = valueString.substring(0, valueString.length() - 1); + } + + return Long.parseLong(valueString) * scale; + } + + /** + * Wraps some given text to one or more lines of a given maximum width. + * + * @param text text to wrap + * @param width maximum width of an output line, exception for words in {@code text} longer than + * this value + * @return {@code text} broken into lines + */ + private static List wrap(String text, int width) { + List lines = Collections.singletonList(text); + if (text.length() > width) { + String[] chunks = text.split("\\s+"); + lines = new ArrayList<>(); + StringBuilder line = new StringBuilder(); + for (String chunk : chunks) { + if (line.length() + chunk.length() > width) { + lines.add(line.toString()); + line.setLength(0); + } + if (line.length() != 0) { + line.append(' '); + } + String[] embeddedLines = chunk.split("%n", -2); + if (embeddedLines.length == 1) { + line.append(chunk); + } else { + for (int i = 0; i < embeddedLines.length; i++) { + line.append(embeddedLines[i]); + if (i < embeddedLines.length - 1) { + lines.add(line.toString()); + line.setLength(0); + } + } + } + } + if (line.length() != 0) { + lines.add(line.toString()); + } + } + return lines; + } + + private static void printFlags(SortedMap sortedOptions, String prefix, PrintStream out, Set explicitlyAssigned) { + out.println("[List of " + prefix + " options]"); + for (Map.Entry e : sortedOptions.entrySet()) { + e.getKey(); + OptionDescriptor desc = e.getValue(); + Object value = desc.getOptionValue().getValue(); + List helpLines = wrap(desc.getHelp(), 70); + String name = e.getKey(); + String assign = explicitlyAssigned.contains(name) ? ":=" : " ="; + out.printf("%9s %-40s %s %-14s %s%n", desc.getType().getSimpleName(), name, assign, value, helpLines.get(0)); + for (int i = 1; i < helpLines.size(); i++) { + out.printf("%67s %s%n", " ", helpLines.get(i)); + } + } + } + + /** + * Compute string similarity based on Dice's coefficient. + * + * Ported from str_similar() in globals.cpp. + */ + static float stringSimiliarity(String str1, String str2) { + int hit = 0; + for (int i = 0; i < str1.length() - 1; ++i) { + for (int j = 0; j < str2.length() - 1; ++j) { + if ((str1.charAt(i) == str2.charAt(j)) && (str1.charAt(i + 1) == str2.charAt(j + 1))) { + ++hit; + break; + } + } + } + return 2.0f * hit / (str1.length() + str2.length()); + } + + private static final float FUZZY_MATCH_THRESHOLD = 0.7F; + + /** + * Returns the set of options that fuzzy match a given option name. + */ + private static List fuzzyMatch(SortedMap options, String optionName) { + List matches = new ArrayList<>(); + for (Map.Entry e : options.entrySet()) { + float score = stringSimiliarity(e.getKey(), optionName); + if (score >= FUZZY_MATCH_THRESHOLD) { + matches.add(e.getValue()); + } + } + return matches; + } +} diff -r 58eb143a8259 -r f35e653aa876 graal/com.oracle.graal.options/src/com/oracle/graal/options/StableOptionValue.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.options/src/com/oracle/graal/options/StableOptionValue.java Mon Dec 21 16:19:35 2015 +0100 @@ -0,0 +1,75 @@ +/* + * 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.options; + +/** + * An option that always returns the same {@linkplain #getValue() value}. + */ +public class StableOptionValue extends OptionValue { + + /** + * Creates a stable option value. + */ + public StableOptionValue(T value) { + super(value); + } + + /** + * Used to assert the invariant for stability. Without using locks, this check is not safe + * against races and so it's only an assertion. + */ + private boolean getValueCalled; + + /** + * Creates an uninitialized stable option value for a subclass that initializes itself + * {@link #defaultValue() lazily}. + */ + public StableOptionValue() { + } + + /** + * Gets the value of this option. + */ + @Override + public final T getValue() { + T result = super.getValue(); + assert initGetValueCalled(); + return result; + } + + private boolean initGetValueCalled() { + getValueCalled = true; + return true; + } + + /** + * {@inheritDoc} + *

      + * This must only be called if {@link #getValue()} has never been called. + */ + @Override + public final void setValue(Object v) { + assert !getValueCalled; + super.setValue(v); + } +} diff -r 58eb143a8259 -r f35e653aa876 graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/DeadCodeEliminationPhase.java --- a/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/DeadCodeEliminationPhase.java Mon Dec 21 00:20:11 2015 +0100 +++ b/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/DeadCodeEliminationPhase.java Mon Dec 21 16:19:35 2015 +0100 @@ -24,16 +24,15 @@ import java.util.function.BiConsumer; -import jdk.vm.ci.options.Option; -import jdk.vm.ci.options.OptionType; -import jdk.vm.ci.options.OptionValue; - import com.oracle.graal.debug.Debug; import com.oracle.graal.debug.DebugMetric; import com.oracle.graal.graph.Node; import com.oracle.graal.graph.NodeFlood; import com.oracle.graal.nodes.AbstractEndNode; import com.oracle.graal.nodes.StructuredGraph; +import com.oracle.graal.options.Option; +import com.oracle.graal.options.OptionType; +import com.oracle.graal.options.OptionValue; import com.oracle.graal.phases.Phase; public class DeadCodeEliminationPhase extends Phase { diff -r 58eb143a8259 -r f35e653aa876 graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/inlining/InliningPhase.java --- a/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/inlining/InliningPhase.java Mon Dec 21 00:20:11 2015 +0100 +++ b/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/inlining/InliningPhase.java Mon Dec 21 16:19:35 2015 +0100 @@ -24,12 +24,11 @@ import java.util.Map; -import jdk.vm.ci.options.Option; -import jdk.vm.ci.options.OptionType; -import jdk.vm.ci.options.OptionValue; - import com.oracle.graal.nodes.Invoke; import com.oracle.graal.nodes.StructuredGraph; +import com.oracle.graal.options.Option; +import com.oracle.graal.options.OptionType; +import com.oracle.graal.options.OptionValue; import com.oracle.graal.phases.common.AbstractInliningPhase; import com.oracle.graal.phases.common.CanonicalizerPhase; import com.oracle.graal.phases.common.inlining.policy.GreedyInliningPolicy; diff -r 58eb143a8259 -r f35e653aa876 graal/com.oracle.graal.printer/src/com/oracle/graal/printer/NoDeadCodeVerifyHandler.java --- a/graal/com.oracle.graal.printer/src/com/oracle/graal/printer/NoDeadCodeVerifyHandler.java Mon Dec 21 00:20:11 2015 +0100 +++ b/graal/com.oracle.graal.printer/src/com/oracle/graal/printer/NoDeadCodeVerifyHandler.java Mon Dec 21 16:19:35 2015 +0100 @@ -27,13 +27,13 @@ import java.util.concurrent.ConcurrentHashMap; import jdk.vm.ci.common.JVMCIError; -import jdk.vm.ci.options.Option; -import jdk.vm.ci.options.OptionType; -import jdk.vm.ci.options.OptionValue; import com.oracle.graal.debug.DebugVerifyHandler; import com.oracle.graal.graph.Node; import com.oracle.graal.nodes.StructuredGraph; +import com.oracle.graal.options.Option; +import com.oracle.graal.options.OptionType; +import com.oracle.graal.options.OptionValue; import com.oracle.graal.phases.common.DeadCodeEliminationPhase; /** diff -r 58eb143a8259 -r f35e653aa876 graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/PEGraphDecoder.java --- a/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/PEGraphDecoder.java Mon Dec 21 00:20:11 2015 +0100 +++ b/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/PEGraphDecoder.java Mon Dec 21 16:19:35 2015 +0100 @@ -44,8 +44,6 @@ import jdk.vm.ci.meta.JavaType; import jdk.vm.ci.meta.MetaAccessProvider; import jdk.vm.ci.meta.ResolvedJavaMethod; -import jdk.vm.ci.options.Option; -import jdk.vm.ci.options.OptionValue; import com.oracle.graal.compiler.common.type.StampFactory; import com.oracle.graal.debug.Debug; @@ -91,6 +89,8 @@ import com.oracle.graal.nodes.java.MonitorIdNode; import com.oracle.graal.nodes.spi.StampProvider; import com.oracle.graal.nodes.util.GraphUtil; +import com.oracle.graal.options.Option; +import com.oracle.graal.options.OptionValue; import com.oracle.graal.phases.common.inlining.InliningUtil; /** diff -r 58eb143a8259 -r f35e653aa876 graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/ReplacementsImpl.java --- a/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/ReplacementsImpl.java Mon Dec 21 00:20:11 2015 +0100 +++ b/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/ReplacementsImpl.java Mon Dec 21 16:19:35 2015 +0100 @@ -55,8 +55,6 @@ import jdk.vm.ci.meta.ResolvedJavaMethod; import jdk.vm.ci.meta.ResolvedJavaType; import jdk.vm.ci.meta.Signature; -import jdk.vm.ci.options.OptionValue; -import jdk.vm.ci.options.OptionValue.OverrideScope; import sun.misc.Launcher; import com.oracle.graal.api.replacements.ClassSubstitution; @@ -92,6 +90,8 @@ import com.oracle.graal.nodes.java.MethodCallTargetNode; import com.oracle.graal.nodes.spi.Replacements; import com.oracle.graal.nodes.spi.StampProvider; +import com.oracle.graal.options.OptionValue; +import com.oracle.graal.options.OptionValue.OverrideScope; import com.oracle.graal.phases.OptimisticOptimizations; import com.oracle.graal.phases.common.CanonicalizerPhase; import com.oracle.graal.phases.common.ConvertDeoptimizeToGuardPhase; diff -r 58eb143a8259 -r f35e653aa876 graal/com.oracle.graal.salver/src/com/oracle/graal/salver/SalverOptions.java --- a/graal/com.oracle.graal.salver/src/com/oracle/graal/salver/SalverOptions.java Mon Dec 21 00:20:11 2015 +0100 +++ b/graal/com.oracle.graal.salver/src/com/oracle/graal/salver/SalverOptions.java Mon Dec 21 16:19:35 2015 +0100 @@ -22,9 +22,9 @@ */ package com.oracle.graal.salver; -import jdk.vm.ci.options.Option; -import jdk.vm.ci.options.OptionType; -import jdk.vm.ci.options.OptionValue; +import com.oracle.graal.options.Option; +import com.oracle.graal.options.OptionType; +import com.oracle.graal.options.OptionValue; public final class SalverOptions { diff -r 58eb143a8259 -r f35e653aa876 graal/com.oracle.graal.truffle.hotspot/src/com/oracle/graal/truffle/hotspot/HotSpotTruffleRuntimeAccess.java --- a/graal/com.oracle.graal.truffle.hotspot/src/com/oracle/graal/truffle/hotspot/HotSpotTruffleRuntimeAccess.java Mon Dec 21 00:20:11 2015 +0100 +++ b/graal/com.oracle.graal.truffle.hotspot/src/com/oracle/graal/truffle/hotspot/HotSpotTruffleRuntimeAccess.java Mon Dec 21 16:19:35 2015 +0100 @@ -25,8 +25,6 @@ import java.util.function.Supplier; import jdk.vm.ci.common.JVMCIError; -import jdk.vm.ci.options.Option; -import jdk.vm.ci.options.OptionValue; import jdk.vm.ci.runtime.JVMCI; import jdk.vm.ci.runtime.JVMCICompiler; import jdk.vm.ci.runtime.JVMCICompilerFactory; @@ -36,6 +34,8 @@ import com.oracle.graal.api.runtime.GraalJVMCICompiler; import com.oracle.graal.api.runtime.GraalRuntime; import com.oracle.graal.hotspot.HotSpotGraalCompilerFactory; +import com.oracle.graal.options.Option; +import com.oracle.graal.options.OptionValue; import com.oracle.truffle.api.TruffleRuntime; import com.oracle.truffle.api.TruffleRuntimeAccess; diff -r 58eb143a8259 -r f35e653aa876 graal/com.oracle.graal.truffle.test/src/com/oracle/graal/truffle/test/BytecodeInterpreterPartialEvaluationTest.java --- a/graal/com.oracle.graal.truffle.test/src/com/oracle/graal/truffle/test/BytecodeInterpreterPartialEvaluationTest.java Mon Dec 21 00:20:11 2015 +0100 +++ b/graal/com.oracle.graal.truffle.test/src/com/oracle/graal/truffle/test/BytecodeInterpreterPartialEvaluationTest.java Mon Dec 21 16:19:35 2015 +0100 @@ -24,15 +24,14 @@ import java.util.Random; -import jdk.vm.ci.options.OptionValue; -import jdk.vm.ci.options.OptionValue.OverrideScope; - import org.junit.After; import org.junit.Assert; import org.junit.Before; import org.junit.Ignore; import org.junit.Test; +import com.oracle.graal.options.OptionValue; +import com.oracle.graal.options.OptionValue.OverrideScope; import com.oracle.graal.truffle.PartialEvaluator; import com.oracle.truffle.api.CompilerAsserts; import com.oracle.truffle.api.CompilerDirectives; diff -r 58eb143a8259 -r f35e653aa876 graal/com.oracle.graal.truffle.test/src/com/oracle/graal/truffle/test/LazyInitializationTest.java --- a/graal/com.oracle.graal.truffle.test/src/com/oracle/graal/truffle/test/LazyInitializationTest.java Mon Dec 21 00:20:11 2015 +0100 +++ b/graal/com.oracle.graal.truffle.test/src/com/oracle/graal/truffle/test/LazyInitializationTest.java Mon Dec 21 16:19:35 2015 +0100 @@ -30,15 +30,17 @@ import java.util.HashSet; import java.util.List; -import jdk.vm.ci.options.OptionDescriptor; -import jdk.vm.ci.options.OptionDescriptors; -import jdk.vm.ci.options.OptionValue; import jdk.vm.ci.runtime.JVMCICompilerFactory; import org.junit.Assert; import org.junit.Test; import com.oracle.graal.compiler.CompilerThreadFactory; +import com.oracle.graal.options.OptionDescriptor; +import com.oracle.graal.options.OptionDescriptors; +import com.oracle.graal.options.OptionValue; +import com.oracle.graal.options.OptionsParser; +import com.oracle.graal.options.OptionsParser.OptionDescriptorsProvider; import com.oracle.graal.test.SubprocessUtil; /** @@ -171,11 +173,16 @@ return true; } - if (OptionDescriptors.class.isAssignableFrom(cls)) { + if (OptionDescriptors.class.isAssignableFrom(cls) || OptionDescriptor.class.isAssignableFrom(cls)) { // If options are specified, the corresponding *_OptionDescriptors classes are loaded. return true; } + if (OptionDescriptorsProvider.class.isAssignableFrom(cls) || cls == OptionsParser.class) { + // Classes implementing Graal option loading + return true; + } + if (OptionValue.class.isAssignableFrom(cls)) { // If options are specified, that may implicitly load a custom OptionValue subclass. return true; diff -r 58eb143a8259 -r f35e653aa876 graal/com.oracle.graal.truffle.test/src/com/oracle/graal/truffle/test/builtins/SLGetOptionBuiltin.java --- a/graal/com.oracle.graal.truffle.test/src/com/oracle/graal/truffle/test/builtins/SLGetOptionBuiltin.java Mon Dec 21 00:20:11 2015 +0100 +++ b/graal/com.oracle.graal.truffle.test/src/com/oracle/graal/truffle/test/builtins/SLGetOptionBuiltin.java Mon Dec 21 16:19:35 2015 +0100 @@ -22,8 +22,7 @@ */ package com.oracle.graal.truffle.test.builtins; -import jdk.vm.ci.options.OptionDescriptor; - +import com.oracle.graal.options.OptionDescriptor; import com.oracle.graal.truffle.TruffleCompilerOptions; import com.oracle.graal.truffle.TruffleCompilerOptions_OptionDescriptors; import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary; diff -r 58eb143a8259 -r f35e653aa876 graal/com.oracle.graal.truffle.test/src/com/oracle/graal/truffle/test/builtins/SLSetOptionBuiltin.java --- a/graal/com.oracle.graal.truffle.test/src/com/oracle/graal/truffle/test/builtins/SLSetOptionBuiltin.java Mon Dec 21 00:20:11 2015 +0100 +++ b/graal/com.oracle.graal.truffle.test/src/com/oracle/graal/truffle/test/builtins/SLSetOptionBuiltin.java Mon Dec 21 16:19:35 2015 +0100 @@ -22,8 +22,7 @@ */ package com.oracle.graal.truffle.test.builtins; -import jdk.vm.ci.options.OptionDescriptor; - +import com.oracle.graal.options.OptionDescriptor; import com.oracle.graal.truffle.TruffleCompilerOptions; import com.oracle.graal.truffle.TruffleCompilerOptions_OptionDescriptors; import com.oracle.truffle.api.CompilerDirectives.TruffleBoundary; diff -r 58eb143a8259 -r f35e653aa876 graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/PartialEvaluator.java --- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/PartialEvaluator.java Mon Dec 21 00:20:11 2015 +0100 +++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/PartialEvaluator.java Mon Dec 21 16:19:35 2015 +0100 @@ -40,9 +40,6 @@ import jdk.vm.ci.meta.JavaType; import jdk.vm.ci.meta.ResolvedJavaMethod; import jdk.vm.ci.meta.ResolvedJavaType; -import jdk.vm.ci.options.Option; -import jdk.vm.ci.options.OptionType; -import jdk.vm.ci.options.OptionValue; import jdk.vm.ci.service.Services; import com.oracle.graal.api.replacements.SnippetReflectionProvider; @@ -69,6 +66,9 @@ import com.oracle.graal.nodes.java.MethodCallTargetNode; import com.oracle.graal.nodes.virtual.VirtualInstanceNode; import com.oracle.graal.nodes.virtual.VirtualObjectNode; +import com.oracle.graal.options.Option; +import com.oracle.graal.options.OptionType; +import com.oracle.graal.options.OptionValue; import com.oracle.graal.phases.OptimisticOptimizations; import com.oracle.graal.phases.PhaseSuite; import com.oracle.graal.phases.common.CanonicalizerPhase; diff -r 58eb143a8259 -r f35e653aa876 graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/TruffleCompilerOptions.java --- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/TruffleCompilerOptions.java Mon Dec 21 00:20:11 2015 +0100 +++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/TruffleCompilerOptions.java Mon Dec 21 16:19:35 2015 +0100 @@ -22,10 +22,10 @@ */ package com.oracle.graal.truffle; -import jdk.vm.ci.options.Option; -import jdk.vm.ci.options.OptionType; -import jdk.vm.ci.options.OptionValue; -import jdk.vm.ci.options.StableOptionValue; +import com.oracle.graal.options.Option; +import com.oracle.graal.options.OptionType; +import com.oracle.graal.options.OptionValue; +import com.oracle.graal.options.StableOptionValue; /** * Options for the Truffle compiler. diff -r 58eb143a8259 -r f35e653aa876 graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/PartialEscapePhase.java --- a/graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/PartialEscapePhase.java Mon Dec 21 00:20:11 2015 +0100 +++ b/graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/PartialEscapePhase.java Mon Dec 21 16:19:35 2015 +0100 @@ -27,15 +27,14 @@ import java.util.Set; -import jdk.vm.ci.options.Option; -import jdk.vm.ci.options.OptionType; -import jdk.vm.ci.options.OptionValue; - import com.oracle.graal.graph.Node; import com.oracle.graal.nodes.StructuredGraph; import com.oracle.graal.nodes.cfg.ControlFlowGraph; import com.oracle.graal.nodes.spi.VirtualizableAllocation; import com.oracle.graal.nodes.virtual.VirtualObjectNode; +import com.oracle.graal.options.Option; +import com.oracle.graal.options.OptionType; +import com.oracle.graal.options.OptionValue; import com.oracle.graal.phases.BasePhase; import com.oracle.graal.phases.common.CanonicalizerPhase; import com.oracle.graal.phases.schedule.SchedulePhase; diff -r 58eb143a8259 -r f35e653aa876 mx.graal/mx_graal_8.py --- a/mx.graal/mx_graal_8.py Mon Dec 21 00:20:11 2015 +0100 +++ b/mx.graal/mx_graal_8.py Mon Dec 21 16:19:35 2015 +0100 @@ -31,14 +31,16 @@ import re import mx -from mx_jvmci import JvmciJDKDeployedDist, jdkDeployedDists, add_bootclasspath_prepend, buildvms, get_jvmci_jdk, run_vm, VM, relativeVmLibDirInJdk, isJVMCIEnabled +from mx_jvmci import JvmciJDKDeployedDist, JVMCIArchiveParticipant, jdkDeployedDists, add_bootclasspath_prepend, buildvms, get_jvmci_jdk, VM, relativeVmLibDirInJdk, isJVMCIEnabled from mx_jvmci import get_vm as _jvmci_get_vm +from mx_jvmci import run_vm as _jvmci_run_vm from mx_gate import Task from sanitycheck import _noneAsEmptyList from mx_unittest import unittest from mx_graal_bench import dacapo import mx_gate +import mx_unittest _suite = mx.suite('graal') @@ -85,6 +87,7 @@ fp.write(os.linesep.join(content)) jdkDeployedDists += [ + JvmciJDKDeployedDist('GRAAL_OPTIONS'), JvmciJDKDeployedDist('GRAAL_NODEINFO'), JvmciJDKDeployedDist('GRAAL_API'), JvmciJDKDeployedDist('GRAAL_COMPILER'), @@ -169,7 +172,6 @@ if args.ctwopts: # Replace spaces with '#' since -G: options cannot contain spaces - # when they are collated in the "jvmci.options" system property vmargs.append('-G:CompileTheWorldConfig=' + re.sub(r'\s+', '#', args.ctwopts)) if args.cp: @@ -376,12 +378,64 @@ else: print '{:>10} {}'.format('', jvmLib) +# Support for -G: options +def _translateGOption(arg): + if arg.startswith('-G:+'): + if '=' in arg: + mx.abort('Mixing + and = in -G: option specification: ' + arg) + arg = '-Dgraal.option.' + arg[len('-G:+'):] + '=true' + elif arg.startswith('-G:-'): + if '=' in arg: + mx.abort('Mixing - and = in -G: option specification: ' + arg) + arg = '-Dgraal.option.' + arg[len('-G:+'):] + '=false' + elif arg.startswith('-G:'): + arg = '-Dgraal.option.' + arg[len('-G:'):] + return arg + +def run_vm(*positionalargs, **kwargs): + """run a Java program by executing the java executable in a Graal JDK""" + + # convert positional args to a list so the first element can be updated + positionalargs = list(positionalargs) + args = positionalargs[0] + if '-G:+PrintFlags' in args and '-Xcomp' not in args: + mx.warn('Using -G:+PrintFlags may have no effect without -Xcomp as Graal initialization is lazy') + positionalargs[0] = map(_translateGOption, args) + return _jvmci_run_vm(*positionalargs, **kwargs) + +def _unittest_config_participant(config): + vmArgs, mainClass, mainClassArgs = config + if isJVMCIEnabled(get_vm()): + return (map(_translateGOption, vmArgs), mainClass, mainClassArgs) + return config + +mx_unittest.add_config_participant(_unittest_config_participant) + mx.update_commands(_suite, { + 'vm': [run_vm, '[-options] class [args...]'], 'jdkartifactstats' : [jdkartifactstats, ''], 'ctw': [ctw, '[-vmoptions|noinline|nocomplex|full]'], 'microbench' : [microbench, '[VM options] [-- [JMH options]]'], }) +class GraalArchiveParticipant(JVMCIArchiveParticipant): + def __init__(self, dist): + JVMCIArchiveParticipant.__init__(self, dist) + + def __add__(self, arcname, contents): + if arcname.endswith('_OptionDescriptors.class'): + # Need to create service files for the providers of the + # com.oracle.graal.options.Options service created by + # com.oracle.graal.options.processor.OptionProcessor. + provider = arcname[:-len('.class'):].replace('/', '.') + self.services.setdefault('com.oracle.graal.options.OptionDescriptors', []).append(provider) + return JVMCIArchiveParticipant.__add__(self, arcname, contents) def mx_post_parse_cmd_line(opts): add_bootclasspath_prepend(mx.distribution('truffle:TRUFFLE_API')) + + for jdkDist in jdkDeployedDists: + dist = jdkDist.dist() + # Replace archive participant for Graal suites + if isinstance(jdkDist, JvmciJDKDeployedDist) and dist.suite.name != 'jvmci': + dist.set_archiveparticipant(GraalArchiveParticipant(dist)) diff -r 58eb143a8259 -r f35e653aa876 mx.graal/mx_graal_9.py --- a/mx.graal/mx_graal_9.py Mon Dec 21 00:20:11 2015 +0100 +++ b/mx.graal/mx_graal_9.py Mon Dec 21 16:19:35 2015 +0100 @@ -96,6 +96,7 @@ _compilers = ['graal-economy', 'graal'] _bootClasspathDists = [ + BootClasspathDist('GRAAL_OPTIONS'), BootClasspathDist('GRAAL_NODEINFO'), BootClasspathDist('GRAAL_API'), BootClasspathDist('GRAAL_COMPILER'), @@ -182,7 +183,6 @@ if args.ctwopts: # Replace spaces with '#' since -G: options cannot contain spaces - # when they are collated in the "jvmci.options" system property vmargs.append('-G:CompileTheWorldConfig=' + re.sub(r'\s+', '#', args.ctwopts)) if args.cp: @@ -322,16 +322,19 @@ if arg.startswith('-G:+'): if '=' in arg: mx.abort('Mixing + and = in -G: option specification: ' + arg) - arg = '-Djvmci.option.' + arg[len('-G:+'):] + '=true' + arg = '-Dgraal.option.' + arg[len('-G:+'):] + '=true' elif arg.startswith('-G:-'): if '=' in arg: mx.abort('Mixing - and = in -G: option specification: ' + arg) - arg = '-Djvmci.option.' + arg[len('-G:+'):] + '=false' + arg = '-Dgraal.option.' + arg[len('-G:+'):] + '=false' elif arg.startswith('-G:'): - arg = '-Djvmci.option.' + arg[len('-G:'):] + arg = '-Dgraal.option.' + arg[len('-G:'):] return arg args = map(translateGOption, args) + if '-G:+PrintFlags' in args and '-Xcomp' not in args: + mx.warn('Using -G:+PrintFlags may have no effect without -Xcomp as Graal initialization is lazy') + bcp = [mx.distribution('truffle:TRUFFLE_API').classpath_repr()] if _jvmciModes[_vm.jvmciMode]: bcp.extend([d.get_classpath_repr() for d in _bootClasspathDists]) @@ -400,7 +403,7 @@ # jdk.vm.ci.options.Options service created by # jdk.vm.ci.options.processor.OptionProcessor. provider = arcname[:-len('.class'):].replace('/', '.') - self.services.setdefault('jdk.vm.ci.options.OptionDescriptors', []).append(provider) + self.services.setdefault('com.oracle.graal.options.OptionDescriptors', []).append(provider) return False def __addsrc__(self, arcname, contents): diff -r 58eb143a8259 -r f35e653aa876 mx.graal/suite.py --- a/mx.graal/suite.py Mon Dec 21 00:20:11 2015 +0100 +++ b/mx.graal/suite.py Mon Dec 21 16:19:35 2015 +0100 @@ -39,7 +39,7 @@ { "name" : "jvmci", "optional" : "true", - "version" : "f4c4cc22a31ccc6efec87a3335047722710cf540", + "version" : "a130b51efb072b754f9ecad316dcda01bd2f0e9f", "urls" : [ {"url" : "http://lafo.ssw.uni-linz.ac.at/hg/graal-jvmci-8", "kind" : "hg"}, {"url" : "https://curio.ssw.jku.at/nexus/content/repositories/snapshots", "kind" : "binary"}, @@ -126,16 +126,49 @@ # ------------- Graal ------------- + "com.oracle.graal.options" : { + "subDir" : "graal", + "sourceDirs" : ["src"], + "checkstyle" : "com.oracle.graal.graph", + "dependencies" : ["jvmci:JVMCI_API"], + "javaCompliance" : "1.8", + "workingSets" : "Graal", + }, + + "com.oracle.graal.options.processor" : { + "subDir" : "graal", + "sourceDirs" : ["src"], + "dependencies" : [ + "com.oracle.graal.options", + ], + "checkstyle" : "com.oracle.graal.graph", + "javaCompliance" : "1.8", + "workingSets" : "JVMCI,Codegen", + }, + + "com.oracle.graal.options.test" : { + "subDir" : "graal", + "sourceDirs" : ["src"], + "dependencies" : [ + "com.oracle.graal.options", + "mx:JUNIT", + ], + "checkstyle" : "com.oracle.graal.graph", + "javaCompliance" : "1.8", + "workingSets" : "JVMCI", + }, + "com.oracle.graal.debug" : { "subDir" : "graal", "sourceDirs" : ["src"], "checkstyle" : "com.oracle.graal.graph", "dependencies" : deps([ "jvmci:JVMCI_API", + "com.oracle.graal.options" ]), - "annotationProcessors" : deps(["jvmci:JVMCI_OPTIONS_PROCESSOR"]), + "annotationProcessors" : deps(["GRAAL_OPTIONS_PROCESSOR"]), "javaCompliance" : "1.8", - "workingSets" : "JVMCI,Debug", + "workingSets" : "Graal,Debug", }, "com.oracle.graal.debug.test" : { @@ -147,7 +180,7 @@ ], "checkstyle" : "com.oracle.graal.graph", "javaCompliance" : "1.8", - "workingSets" : "JVMCI,Debug,Test", + "workingSets" : "Graal,Debug,Test", }, "com.oracle.graal.code" : { @@ -237,7 +270,7 @@ "GRAAL_NODEINFO_PROCESSOR", "GRAAL_COMPILER_MATCH_PROCESSOR", "GRAAL_REPLACEMENTS_VERIFIER", - "jvmci:JVMCI_OPTIONS_PROCESSOR", + "GRAAL_OPTIONS_PROCESSOR", "jvmci:JVMCI_SERVICE_PROCESSOR", ]), "javaCompliance" : "1.8", @@ -330,7 +363,7 @@ ], "javaCompliance" : "1.8", "annotationProcessors" : deps([ - "jvmci:JVMCI_OPTIONS_PROCESSOR", + "GRAAL_OPTIONS_PROCESSOR", "GRAAL_NODEINFO_PROCESSOR" ]), "workingSets" : "Graal,Graph", @@ -421,7 +454,7 @@ "com.oracle.graal.compiler.common", "com.oracle.graal.asm", ], - "annotationProcessors" : deps(["jvmci:JVMCI_OPTIONS_PROCESSOR"]), + "annotationProcessors" : deps(["GRAAL_OPTIONS_PROCESSOR"]), "checkstyle" : "com.oracle.graal.graph", "javaCompliance" : "1.8", "workingSets" : "Graal,LIR", @@ -459,7 +492,7 @@ "com.oracle.graal.lir", "com.oracle.graal.asm.amd64", ], - "annotationProcessors" : deps(["jvmci:JVMCI_OPTIONS_PROCESSOR"]), + "annotationProcessors" : deps(["GRAAL_OPTIONS_PROCESSOR"]), "checkstyle" : "com.oracle.graal.graph", "javaCompliance" : "1.8", "workingSets" : "Graal,LIR,AMD64", @@ -499,7 +532,7 @@ "checkstyle" : "com.oracle.graal.graph", "javaCompliance" : "1.8", "annotationProcessors" : deps([ - "jvmci:JVMCI_OPTIONS_PROCESSOR", + "GRAAL_OPTIONS_PROCESSOR", "GRAAL_REPLACEMENTS_VERIFIER", "GRAAL_NODEINFO_PROCESSOR", ]), @@ -595,7 +628,7 @@ "subDir" : "graal", "sourceDirs" : ["src"], "dependencies" : ["com.oracle.graal.nodes"], - "annotationProcessors" : deps(["jvmci:JVMCI_OPTIONS_PROCESSOR"]), + "annotationProcessors" : deps(["GRAAL_OPTIONS_PROCESSOR"]), "checkstyle" : "com.oracle.graal.graph", "javaCompliance" : "1.8", "workingSets" : "Graal,Phases", @@ -607,7 +640,7 @@ "dependencies" : ["com.oracle.graal.phases"], "annotationProcessors" : deps([ "GRAAL_NODEINFO_PROCESSOR", - "jvmci:JVMCI_OPTIONS_PROCESSOR" + "GRAAL_OPTIONS_PROCESSOR" ]), "checkstyle" : "com.oracle.graal.graph", "javaCompliance" : "1.8", @@ -632,7 +665,7 @@ "sourceDirs" : ["src"], "dependencies" : ["com.oracle.graal.phases.common"], "annotationProcessors" : deps([ - "jvmci:JVMCI_OPTIONS_PROCESSOR", + "GRAAL_OPTIONS_PROCESSOR", "GRAAL_NODEINFO_PROCESSOR" ]), "checkstyle" : "com.oracle.graal.graph", @@ -669,7 +702,7 @@ "subDir" : "graal", "sourceDirs" : ["src"], "dependencies" : ["com.oracle.graal.nodes"], - "annotationProcessors" : deps(["jvmci:JVMCI_OPTIONS_PROCESSOR"]), + "annotationProcessors" : deps(["GRAAL_OPTIONS_PROCESSOR"]), "checkstyle" : "com.oracle.graal.graph", "javaCompliance" : "1.8", "workingSets" : "Graal", @@ -682,7 +715,7 @@ "com.oracle.graal.loop", "com.oracle.graal.phases.common", ], - "annotationProcessors" : deps(["jvmci:JVMCI_OPTIONS_PROCESSOR"]), + "annotationProcessors" : deps(["GRAAL_OPTIONS_PROCESSOR"]), "checkstyle" : "com.oracle.graal.graph", "javaCompliance" : "1.8", "workingSets" : "Graal,Phases", @@ -699,7 +732,7 @@ "javaCompliance" : "1.8", "annotationProcessors" : deps([ "jvmci:JVMCI_SERVICE_PROCESSOR", - "jvmci:JVMCI_OPTIONS_PROCESSOR", + "GRAAL_OPTIONS_PROCESSOR", ]), "workingSets" : "Graal", }, @@ -789,7 +822,7 @@ "dependencies" : [ "com.oracle.graal.phases", ], - "annotationProcessors" : deps(["jvmci:JVMCI_OPTIONS_PROCESSOR"]), + "annotationProcessors" : deps(["GRAAL_OPTIONS_PROCESSOR"]), "checkstyle" : "com.oracle.graal.graph", "javaCompliance" : "1.8", "workingSets" : "Graal,Java", @@ -801,7 +834,7 @@ "dependencies" : [ "com.oracle.graal.debug", ], - "annotationProcessors" : deps(["jvmci:JVMCI_OPTIONS_PROCESSOR"]), + "annotationProcessors" : deps(["GRAAL_OPTIONS_PROCESSOR"]), "checkstyle" : "com.oracle.graal.graph", "javaCompliance" : "1.8", "workingSets" : "Graal,Java", @@ -816,7 +849,7 @@ "com.oracle.graal.compiler", ], "annotationProcessors" : deps([ - "jvmci:JVMCI_OPTIONS_PROCESSOR", + "GRAAL_OPTIONS_PROCESSOR", "jvmci:JVMCI_SERVICE_PROCESSOR" ]), "checkstyle" : "com.oracle.graal.graph", @@ -881,7 +914,7 @@ "annotationProcessors" : deps([ "GRAAL_NODEINFO_PROCESSOR", "GRAAL_REPLACEMENTS_VERIFIER", - "jvmci:JVMCI_OPTIONS_PROCESSOR", + "GRAAL_OPTIONS_PROCESSOR", "jvmci:JVMCI_SERVICE_PROCESSOR", "truffle:TRUFFLE_DSL_PROCESSOR", ]), @@ -919,7 +952,7 @@ "checkstyle" : "com.oracle.graal.graph", "javaCompliance" : "1.8", "annotationProcessors" : deps([ - "jvmci:JVMCI_OPTIONS_PROCESSOR", + "GRAAL_OPTIONS_PROCESSOR", "jvmci:JVMCI_SERVICE_PROCESSOR" ]), "workingSets" : "Graal,Truffle", @@ -962,7 +995,7 @@ "com.oracle.graal.java", ], "annotationProcessors" : deps([ - "jvmci:JVMCI_OPTIONS_PROCESSOR", + "GRAAL_OPTIONS_PROCESSOR", "jvmci:JVMCI_SERVICE_PROCESSOR", ]), "checkstyle" : "com.oracle.graal.graph", @@ -975,6 +1008,22 @@ # ------------- Distributions ------------- + "GRAAL_OPTIONS" : { + "subDir" : "graal", + "dependencies" : ["com.oracle.graal.options"], + "distDependencies" : deps([ + "jvmci:JVMCI_API", + ]), + }, + + "GRAAL_OPTIONS_PROCESSOR" : { + "subDir" : "graal", + "dependencies" : ["com.oracle.graal.options.processor"], + "distDependencies" : [ + "GRAAL_OPTIONS", + ], + }, + "GRAAL_NODEINFO" : { "subDir" : "graal", "dependencies" : [ @@ -993,6 +1042,7 @@ "distDependencies" : deps([ "jvmci:JVMCI_API", "GRAAL_NODEINFO", + "GRAAL_OPTIONS", ]), }, @@ -1051,6 +1101,7 @@ "com.oracle.graal.compiler.amd64.test", "com.oracle.graal.compiler.sparc.test", "com.oracle.graal.hotspot.amd64.test", + "com.oracle.graal.options.test", "com.oracle.graal.jtt", "com.oracle.graal.lir.jtt", "com.oracle.graal.lir.test",