# HG changeset patch # User Stefan Anzinger # Date 1418769455 -3600 # Node ID d854f8a5256f2d01cead159ef5574d2c6bd843ad # Parent 28e46ea20c93654797e550c3be35cd69e23b8f08# Parent 08b17b73850070b05a67be72a243d6764f7b8e6e Merge diff -r 28e46ea20c93 -r d854f8a5256f graal/com.oracle.graal.api.meta.test/src/com/oracle/graal/api/meta/test/TestResolvedJavaMethod.java --- a/graal/com.oracle.graal.api.meta.test/src/com/oracle/graal/api/meta/test/TestResolvedJavaMethod.java Tue Dec 16 23:36:29 2014 +0100 +++ b/graal/com.oracle.graal.api.meta.test/src/com/oracle/graal/api/meta/test/TestResolvedJavaMethod.java Tue Dec 16 23:37:35 2014 +0100 @@ -313,7 +313,8 @@ "getLocalVariableTable", "isInVirtualMethodTable", "toParameterTypes", - "getParameterAnnotation" + "getParameterAnnotation", + "$jacocoInit" }; // @formatter:on diff -r 28e46ea20c93 -r d854f8a5256f graal/com.oracle.graal.api.meta.test/src/com/oracle/graal/api/meta/test/TestResolvedJavaType.java --- a/graal/com.oracle.graal.api.meta.test/src/com/oracle/graal/api/meta/test/TestResolvedJavaType.java Tue Dec 16 23:36:29 2014 +0100 +++ b/graal/com.oracle.graal.api.meta.test/src/com/oracle/graal/api/meta/test/TestResolvedJavaType.java Tue Dec 16 23:37:35 2014 +0100 @@ -847,7 +847,8 @@ "isJavaLangObject", "isMember", "getElementalType", - "getEnclosingType" + "getEnclosingType", + "$jacocoInit" }; // @formatter:on diff -r 28e46ea20c93 -r d854f8a5256f graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/Kind.java --- a/graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/Kind.java Tue Dec 16 23:36:29 2014 +0100 +++ b/graal/com.oracle.graal.api.meta/src/com/oracle/graal/api/meta/Kind.java Tue Dec 16 23:37:35 2014 +0100 @@ -24,6 +24,8 @@ import java.lang.reflect.*; +//JaCoCo Exclude + /** * Denotes the basic kinds of types in CRI, including the all the Java primitive types, for example, * {@link Kind#Int} for {@code int} and {@link Kind#Object} for all object types. A kind has a diff -r 28e46ea20c93 -r d854f8a5256f graal/com.oracle.graal.compiler.amd64/src/com/oracle/graal/compiler/amd64/AMD64NodeLIRBuilder.java --- a/graal/com.oracle.graal.compiler.amd64/src/com/oracle/graal/compiler/amd64/AMD64NodeLIRBuilder.java Tue Dec 16 23:36:29 2014 +0100 +++ b/graal/com.oracle.graal.compiler.amd64/src/com/oracle/graal/compiler/amd64/AMD64NodeLIRBuilder.java Tue Dec 16 23:37:35 2014 +0100 @@ -50,8 +50,9 @@ @Override protected void emitIndirectCall(IndirectCallTargetNode callTarget, Value result, Value[] parameters, Value[] temps, LIRFrameState callState) { - AllocatableValue targetAddress = AMD64.rax.asValue(); - gen.emitMove(targetAddress, operand(callTarget.computedAddress())); + Value targetAddressSrc = operand(callTarget.computedAddress()); + AllocatableValue targetAddress = AMD64.rax.asValue(targetAddressSrc.getLIRKind()); + gen.emitMove(targetAddress, targetAddressSrc); append(new AMD64Call.IndirectCallOp(callTarget.targetMethod(), result, parameters, temps, targetAddress, callState)); } diff -r 28e46ea20c93 -r d854f8a5256f 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 Tue Dec 16 23:36:29 2014 +0100 +++ b/graal/com.oracle.graal.compiler.common/src/com/oracle/graal/compiler/common/GraalOptions.java Tue Dec 16 23:37:35 2014 +0100 @@ -30,317 +30,317 @@ // @formatter:off public final class GraalOptions { - @Option(help = "Use experimental baseline compiler configuration.") + @Option(help = "Use experimental baseline compiler configuration.", type = OptionType.Debug) public static final OptionValue UseBaselineCompiler = new OptionValue<>(false); - @Option(help = "Use compiler intrinsifications.") + @Option(help = "Use compiler intrinsifications.", type = OptionType.Debug) public static final OptionValue Intrinsify = new OptionValue<>(true); - @Option(help = "Inline calls with monomorphic type profile.") + @Option(help = "Inline calls with monomorphic type profile.", type = OptionType.Expert) public static final OptionValue InlineMonomorphicCalls = new OptionValue<>(true); - @Option(help = "Inline calls with polymorphic type profile.") + @Option(help = "Inline calls with polymorphic type profile.", type = OptionType.Expert) public static final OptionValue InlinePolymorphicCalls = new OptionValue<>(true); - @Option(help = "Inline calls with megamorphic type profile (i.e., not all types could be recorded).") + @Option(help = "Inline calls with megamorphic type profile (i.e., not all types could be recorded).", type = OptionType.Expert) public static final OptionValue InlineMegamorphicCalls = new OptionValue<>(true); - @Option(help = "Maximum desired size of the compiler graph in nodes.") + @Option(help = "Maximum desired size of the compiler graph in nodes.", type = OptionType.User) public static final OptionValue MaximumDesiredSize = new OptionValue<>(20000); - @Option(help = "Minimum probability for methods to be inlined for megamorphic type profiles.") + @Option(help = "Minimum probability for methods to be inlined for megamorphic type profiles.", type = OptionType.Expert) public static final OptionValue MegamorphicInliningMinMethodProbability = new OptionValue<>(0.33D); - @Option(help = "Maximum level of recursive inlining.") + @Option(help = "Maximum level of recursive inlining.", type = OptionType.Expert) public static final OptionValue MaximumRecursiveInlining = new OptionValue<>(5); - @Option(help = "") + @Option(help = "", type = OptionType.Debug) public static final OptionValue IterativeInlining = new OptionValue<>(false); - @Option(help = "Graphs with less than this number of nodes are trivial and therefore always inlined.") + @Option(help = "Graphs with less than this number of nodes are trivial and therefore always inlined.", type = OptionType.Expert) public static final OptionValue TrivialInliningSize = new OptionValue<>(10); - @Option(help = "Inlining is explored up to this number of nodes in the graph for each call site.") + @Option(help = "Inlining is explored up to this number of nodes in the graph for each call site.", type = OptionType.Expert) public static final OptionValue MaximumInliningSize = new OptionValue<>(300); - @Option(help = "If the previous low-level graph size of the method exceeds the threshold, it is not inlined.") + @Option(help = "If the previous low-level graph size of the method exceeds the threshold, it is not inlined.", type = OptionType.Expert) public static final OptionValue SmallCompiledLowLevelGraphSize = new OptionValue<>(300); - @Option(help = "") + @Option(help = "", type = OptionType.Expert) public static final OptionValue LimitInlinedInvokes = new OptionValue<>(5.0); - @Option(help = "") + @Option(help = "", type = OptionType.Expert) public static final OptionValue InlineEverything = new OptionValue<>(false); // escape analysis settings - @Option(help = "") + @Option(help = "", type = OptionType.Debug) public static final OptionValue PartialEscapeAnalysis = new OptionValue<>(true); - @Option(help = "") + @Option(help = "", type = OptionType.Debug) public static final OptionValue EscapeAnalysisIterations = new OptionValue<>(2); - @Option(help = "") + @Option(help = "", type = OptionType.Debug) public static final OptionValue EscapeAnalyzeOnly = new OptionValue<>(null); - @Option(help = "") + @Option(help = "", type = OptionType.Expert) public static final OptionValue MaximumEscapeAnalysisArrayLength = new OptionValue<>(32); - @Option(help = "") + @Option(help = "", type = OptionType.Debug) public static final OptionValue PEAInliningHints = new OptionValue<>(false); - @Option(help = "") + @Option(help = "", type = OptionType.Expert) public static final OptionValue TailDuplicationProbability = new OptionValue<>(0.5); - @Option(help = "") + @Option(help = "", type = OptionType.Expert) public static final OptionValue TailDuplicationTrivialSize = new OptionValue<>(1); - // profiling information - @Option(help = "") + @Option(help = "", type = OptionType.Expert) public static final OptionValue DeoptsToDisableOptimisticOptimization = new OptionValue<>(40); - // graph caching - @Option(help = "") + @Option(help = "", type = OptionType.Expert) public static final OptionValue CacheGraphs = new OptionValue<>(false); - //loop transform settings TODO (gd) tune - @Option(help = "") + @Option(help = "", type = OptionType.Debug) public static final OptionValue LoopPeeling = new OptionValue<>(true); - @Option(help = "") + @Option(help = "", type = OptionType.Debug) public static final OptionValue ReassociateInvariants = new OptionValue<>(true); - @Option(help = "") + @Option(help = "", type = OptionType.Debug) public static final OptionValue FullUnroll = new OptionValue<>(true); - @Option(help = "") + @Option(help = "", type = OptionType.Debug) public static final OptionValue LoopUnswitch = new OptionValue<>(true); - @Option(help = "") + @Option(help = "", type = OptionType.Expert) public static final OptionValue FullUnrollMaxNodes = new OptionValue<>(300); - @Option(help = "") + @Option(help = "", type = OptionType.Expert) public static final OptionValue ExactFullUnrollMaxNodes = new OptionValue<>(1200); - @Option(help = "") + @Option(help = "", type = OptionType.Expert) public static final OptionValue MinimumPeelProbability = new OptionValue<>(0.35f); - @Option(help = "") + @Option(help = "", type = OptionType.Expert) public static final OptionValue LoopMaxUnswitch = new OptionValue<>(3); - @Option(help = "") + @Option(help = "", type = OptionType.Expert) public static final OptionValue LoopUnswitchMaxIncrease = new OptionValue<>(50); - @Option(help = "") + @Option(help = "", type = OptionType.Expert) public static final OptionValue LoopUnswitchUncertaintyBoost = new OptionValue<>(5); - @Option(help = "") + @Option(help = "", type = OptionType.Debug) public static final OptionValue UseLoopLimitChecks = new OptionValue<>(true); // debugging settings - @Option(help = "") + @Option(help = "", type = OptionType.Debug) public static final OptionValue ZapStackOnMethodEntry = new OptionValue<>(false); - @Option(help = "") + @Option(help = "", type = OptionType.Debug) public static final OptionValue DeoptALot = new OptionValue<>(false); - @Option(help = "") + @Option(help = "", type = OptionType.Debug) public static final OptionValue VerifyPhases = new OptionValue<>(false); - @Option(help = "") + @Option(help = "", type = OptionType.Debug) public static final OptionValue PrintFilter = new OptionValue<>(null); // Debug settings: - @Option(help = "") + @Option(help = "", type = OptionType.Debug) public static final OptionValue BootstrapReplacements = new OptionValue<>(false); - @Option(help = "") + @Option(help = "", type = OptionType.Debug) public static final OptionValue GCDebugStartCycle = new OptionValue<>(-1); + @Option(help = "Perform platform dependent validation of the Java heap at returns", type = OptionType.Debug) + public static final OptionValue VerifyHeapAtReturn = new OptionValue<>(false); + // Ideal graph visualizer output settings - @Option(help = "Dump IdealGraphVisualizer output in binary format") + @Option(help = "Dump IdealGraphVisualizer output in binary format", type = OptionType.Debug) public static final OptionValue PrintBinaryGraphs = new OptionValue<>(true); - @Option(help = "Output probabilities for fixed nodes during binary graph dumping") + @Option(help = "Output probabilities for fixed nodes during binary graph dumping", type = OptionType.Debug) public static final OptionValue PrintGraphProbabilities = new OptionValue<>(false); - @Option(help = "Enable dumping to the C1Visualizer. Enabling this option implies PrintBackendCFG.") + @Option(help = "Enable dumping to the C1Visualizer. Enabling this option implies PrintBackendCFG.", type = OptionType.Debug) public static final OptionValue PrintCFG = new OptionValue<>(false); - @Option(help = "Enable dumping LIR, register allocation and code generation info to the C1Visualizer.") + @Option(help = "Enable dumping LIR, register allocation and code generation info to the C1Visualizer.", type = OptionType.Debug) public static final OptionValue PrintBackendCFG = new OptionValue<>(true); - @Option(help = "") + @Option(help = "", type = OptionType.Debug) public static final OptionValue PrintIdealGraphFile = new OptionValue<>(false); - @Option(help = "") + @Option(help = "", type = OptionType.Debug) public static final OptionValue PrintIdealGraphAddress = new OptionValue<>("127.0.0.1"); - @Option(help = "") + @Option(help = "", type = OptionType.Debug) public static final OptionValue PrintIdealGraphPort = new OptionValue<>(4444); - @Option(help = "") + @Option(help = "", type = OptionType.Debug) public static final OptionValue PrintBinaryGraphPort = new OptionValue<>(4445); - @Option(help = "") + @Option(help = "", type = OptionType.Debug) public static final OptionValue PrintIdealGraphSchedule = new OptionValue<>(false); // Other printing settings - @Option(help = "") + @Option(help = "", type = OptionType.Debug) public static final OptionValue PrintCompilation = new OptionValue<>(false); - @Option(help = "") + @Option(help = "", type = OptionType.Debug) public static final OptionValue PrintAfterCompilation = new OptionValue<>(false); - @Option(help = "Print profiling information when parsing a method's bytecode") + @Option(help = "Print profiling information when parsing a method's bytecode", type = OptionType.Debug) public static final OptionValue PrintProfilingInformation = new OptionValue<>(false); - @Option(help = "") + @Option(help = "", type = OptionType.Debug) public static final OptionValue PrintCodeBytes = new OptionValue<>(false); - @Option(help = "") + @Option(help = "", type = OptionType.Debug) public static final OptionValue PrintBailout = new OptionValue<>(false); - @Option(help = "") + @Option(help = "", type = OptionType.Debug) public static final OptionValue TraceEscapeAnalysis = new OptionValue<>(false); - @Option(help = "") + @Option(help = "", type = OptionType.Debug) public static final OptionValue ExitVMOnBailout = new OptionValue<>(false); - @Option(help = "") + @Option(help = "", type = OptionType.Debug) public static final OptionValue ExitVMOnException = new OptionValue<>(true); - @Option(help = "") + @Option(help = "", type = OptionType.Debug) public static final OptionValue PrintStackTraceOnException = new OptionValue<>(false); - @Option(help = "Set a phase after which the decompiler dumps the graph, -G:Dump= required") + @Option(help = "Set a phase after which the decompiler dumps the graph, -G:Dump= required", type = OptionType.Debug) public static final OptionValue DecompileAfterPhase = new OptionValue<>(null); // HotSpot command line options - @Option(help = "Print inlining optimizations") + @Option(help = "Print inlining optimizations", type = OptionType.Debug) public static final OptionValue HotSpotPrintInlining = new OptionValue<>(false); // Register allocator debugging - @Option(help = "Comma separated list of register that the allocation is limited to.") + @Option(help = "Comma separated list of register that the allocation is limited to.", type = OptionType.Debug) public static final OptionValue RegisterPressure = new OptionValue<>(null); // Code generator settings - @Option(help = "") + @Option(help = "", type = OptionType.Debug) public static final OptionValue FlowSensitiveReduction = new OptionValue<>(false); - @Option(help = "") + @Option(help = "", type = OptionType.Debug) public static final OptionValue ConditionalElimination = new OptionValue<>(true); - @Option(help = "") + @Option(help = "", type = OptionType.Debug) public static final OptionValue UseProfilingInformation = new OptionValue<>(true); - @Option(help = "") + @Option(help = "", type = OptionType.Debug) public static final OptionValue RemoveNeverExecutedCode = new OptionValue<>(true); - @Option(help = "") + @Option(help = "", type = OptionType.Debug) public static final OptionValue UseExceptionProbability = new OptionValue<>(true); - @Option(help = "") + @Option(help = "", type = OptionType.Debug) public static final OptionValue UseExceptionProbabilityForOperations = new OptionValue<>(true); - @Option(help = "") + @Option(help = "", type = OptionType.Debug) public static final OptionValue OmitHotExceptionStacktrace = new OptionValue<>(false); - @Option(help = "") + @Option(help = "", type = OptionType.Debug) public static final OptionValue GenSafepoints = new OptionValue<>(true); - @Option(help = "") + @Option(help = "", type = OptionType.Debug) public static final OptionValue GenLoopSafepoints = new OptionValue<>(true); - @Option(help = "") + @Option(help = "", type = OptionType.Debug) public static final OptionValue UseTypeCheckHints = new OptionValue<>(true); - @Option(help = "") + @Option(help = "", type = OptionType.Expert) public static final OptionValue InlineVTableStubs = new OptionValue<>(true); - @Option(help = "") + @Option(help = "", type = OptionType.Expert) public static final OptionValue AlwaysInlineVTableStubs = new OptionValue<>(false); - @Option(help = "") + @Option(help = "", type = OptionType.Debug) public static final OptionValue ResolveClassBeforeStaticInvoke = new OptionValue<>(false); - @Option(help = "") + @Option(help = "", type = OptionType.Debug) public static final OptionValue CanOmitFrame = new OptionValue<>(true); // Ahead of time compilation - @Option(help = "Try to avoid emitting code where patching is required") + @Option(help = "Try to avoid emitting code where patching is required", type = OptionType.Expert) public static final OptionValue ImmutableCode = new OptionValue<>(false); - @Option(help = "Generate position independent code") + @Option(help = "Generate position independent code", type = OptionType.Expert) public static final OptionValue GeneratePIC = new OptionValue<>(false); - @Option(help = "") + @Option(help = "", type = OptionType.Expert) public static final OptionValue CallArrayCopy = new OptionValue<>(true); // Runtime settings - @Option(help = "") + @Option(help = "", type = OptionType.Expert) public static final OptionValue SupportJsrBytecodes = new OptionValue<>(true); - @Option(help = "") + @Option(help = "", type = OptionType.Expert) public static final OptionValue OptAssumptions = new OptionValue<>(true); - @Option(help = "") + @Option(help = "", type = OptionType.Debug) public static final OptionValue OptConvertDeoptsToGuards = new OptionValue<>(true); - @Option(help = "") + @Option(help = "", type = OptionType.Debug) public static final OptionValue OptReadElimination = new OptionValue<>(true); - @Option(help = "") + @Option(help = "", type = OptionType.Debug) public static final OptionValue OptCanonicalizer = new OptionValue<>(true); - @Option(help = "") + @Option(help = "", type = OptionType.Debug) public static final OptionValue OptDeoptimizationGrouping = new OptionValue<>(true); - @Option(help = "") + @Option(help = "", type = OptionType.Debug) public static final OptionValue OptScheduleOutOfLoops = new OptionValue<>(true); - @Option(help = "") + @Option(help = "", type = OptionType.Debug) public static final OptionValue OptEliminateGuards = new OptionValue<>(true); - @Option(help = "") + @Option(help = "", type = OptionType.Debug) public static final OptionValue OptImplicitNullChecks = new OptionValue<>(true); - @Option(help = "") + @Option(help = "", type = OptionType.Debug) public static final OptionValue OptLivenessAnalysis = new OptionValue<>(true); - @Option(help = "") + @Option(help = "", type = OptionType.Debug) public static final OptionValue OptLoopTransform = new OptionValue<>(true); - @Option(help = "") + @Option(help = "", type = OptionType.Debug) public static final OptionValue OptFloatingReads = new OptionValue<>(true); - @Option(help = "") + @Option(help = "", type = OptionType.Debug) public static final OptionValue OptTailDuplication = new OptionValue<>(true); - @Option(help = "") + @Option(help = "", type = OptionType.Debug) public static final OptionValue OptEliminatePartiallyRedundantGuards = new OptionValue<>(true); - @Option(help = "") + @Option(help = "", type = OptionType.Debug) public static final OptionValue OptFilterProfiledTypes = new OptionValue<>(true); - @Option(help = "") + @Option(help = "", type = OptionType.Debug) public static final OptionValue OptDevirtualizeInvokesOptimistically = new OptionValue<>(true); - @Option(help = "") + @Option(help = "", type = OptionType.Debug) public static final OptionValue OptPushThroughPi = new OptionValue<>(true); - @Option(help = "Allow backend to match complex expressions.") + @Option(help = "Allow backend to match complex expressions.", type = OptionType.Debug) public static final OptionValue MatchExpressions = new OptionValue<>(true); - @Option(help = "Constant fold final fields with default values.") + @Option(help = "Constant fold final fields with default values.", type = OptionType.Debug) public static final OptionValue TrustFinalDefaultFields = new OptionValue<>(true); - @Option(help = "Mark well-known stable fields as such.") + @Option(help = "Mark well-known stable fields as such.", type = OptionType.Debug) public static final OptionValue ImplicitStableValues = new OptionValue<>(true); /** * Counts the various paths taken through snippets. */ - @Option(help = "") + @Option(help = "", type = OptionType.Debug) public static final OptionValue SnippetCounters = new OptionValue<>(false); } diff -r 28e46ea20c93 -r d854f8a5256f graal/com.oracle.graal.compiler.common/src/com/oracle/graal/compiler/common/type/ArithmeticOpTable.java --- a/graal/com.oracle.graal.compiler.common/src/com/oracle/graal/compiler/common/type/ArithmeticOpTable.java Tue Dec 16 23:36:29 2014 +0100 +++ b/graal/com.oracle.graal.compiler.common/src/com/oracle/graal/compiler/common/type/ArithmeticOpTable.java Tue Dec 16 23:37:35 2014 +0100 @@ -354,6 +354,10 @@ * Apply the operation to a {@link Stamp}. */ public abstract Stamp foldStamp(Stamp stamp); + + public UnaryOp unwrap() { + return this; + } } /** @@ -479,6 +483,10 @@ return null; } + public BinaryOp unwrap() { + return this; + } + @Override public String toString() { if (associative) { @@ -506,6 +514,11 @@ public FloatConvert getFloatConvert() { return op; } + + @Override + public FloatConvertOp unwrap() { + return this; + } } public abstract static class IntegerConvertOp extends Op { @@ -538,5 +551,9 @@ public abstract Constant foldConstant(int inputBits, int resultBits, Constant value); public abstract Stamp foldStamp(int inputBits, int resultBits, Stamp stamp); + + public IntegerConvertOp unwrap() { + return this; + } } } diff -r 28e46ea20c93 -r d854f8a5256f 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 Tue Dec 16 23:36:29 2014 +0100 +++ b/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/GraalCompiler.java Tue Dec 16 23:37:35 2014 +0100 @@ -84,13 +84,13 @@ */ @Option(help = "Pattern for method(s) to which intrinsification (if available) will be applied. " + "By default, all available intrinsifications are applied except for methods matched " + - "by IntrinsificationsDisabled. See MethodFilter class for pattern syntax.") + "by IntrinsificationsDisabled. See MethodFilter class for pattern syntax.", type = OptionType.Debug) public static final OptionValue IntrinsificationsEnabled = new OptionValue<>(null); /** * @see MethodFilter */ @Option(help = "Pattern for method(s) to which intrinsification will not be applied. " + - "See MethodFilter class for pattern syntax.") + "See MethodFilter class for pattern syntax.", type = OptionType.Debug) public static final OptionValue IntrinsificationsDisabled = new OptionValue<>(null); // @formatter:on diff -r 28e46ea20c93 -r d854f8a5256f graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/GraalDebugConfig.java --- a/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/GraalDebugConfig.java Tue Dec 16 23:36:29 2014 +0100 +++ b/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/GraalDebugConfig.java Tue Dec 16 23:37:35 2014 +0100 @@ -38,31 +38,31 @@ public class GraalDebugConfig implements DebugConfig { // @formatter:off - @Option(help = "Pattern for scope(s) in which dumping is enabled (see DebugFilter and Debug.dump)") + @Option(help = "Pattern for scope(s) in which dumping is enabled (see DebugFilter and Debug.dump)", type = OptionType.Debug) public static final OptionValue Dump = new OptionValue<>(null); - @Option(help = "Pattern for scope(s) in which metering is enabled (see DebugFilter and Debug.metric)") + @Option(help = "Pattern for scope(s) in which metering is enabled (see DebugFilter and Debug.metric)", type = OptionType.Debug) public static final OptionValue Meter = new OptionValue<>(null); - @Option(help = "Pattern for scope(s) in which verification is enabled (see DebugFilter and Debug.verify)") + @Option(help = "Pattern for scope(s) in which verification is enabled (see DebugFilter and Debug.verify)", type = OptionType.Debug) public static final OptionValue Verify = new OptionValue<>(null); - @Option(help = "Pattern for scope(s) in which memory use tracking is enabled (see DebugFilter and Debug.metric)") + @Option(help = "Pattern for scope(s) in which memory use tracking is enabled (see DebugFilter and Debug.metric)", type = OptionType.Debug) public static final OptionValue TrackMemUse = new OptionValue<>(null); - @Option(help = "Pattern for scope(s) in which timing is enabled (see DebugFilter and Debug.timer)") + @Option(help = "Pattern for scope(s) in which timing is enabled (see DebugFilter and Debug.timer)", type = OptionType.Debug) public static final OptionValue Time = new OptionValue<>(null); - @Option(help = "Pattern for scope(s) in which logging is enabled (see DebugFilter and Debug.log)") + @Option(help = "Pattern for scope(s) in which logging is enabled (see DebugFilter and Debug.log)", type = OptionType.Debug) public static final OptionValue Log = new OptionValue<>(null); - @Option(help = "Pattern for filtering debug scope output based on method context (see MethodFilter)") + @Option(help = "Pattern for filtering debug scope output based on method context (see MethodFilter)", type = OptionType.Debug) public static final OptionValue MethodFilter = new OptionValue<>(null); @Option(help = "How to print metric and timing values:%n" + "Name - aggregate by unqualified name%n" + "Partial - aggregate by partially qualified name (e.g., A.B.C.D.Counter and X.Y.Z.D.Counter will be merged to D.Counter)%n" + "Complete - aggregate by qualified name%n" + - "Thread - aggregate by qualified name and thread") + "Thread - aggregate by qualified name and thread", type = OptionType.Debug) public static final OptionValue DebugValueSummary = new OptionValue<>("Name"); - @Option(help = "Omit reporting 0-value metrics") + @Option(help = "Omit reporting 0-value metrics", type = OptionType.Debug) public static final OptionValue SuppressZeroDebugValues = new OptionValue<>(false); - @Option(help = "Send Graal IR to dump handlers on error") + @Option(help = "Send Graal IR to dump handlers on error", type = OptionType.Debug) public static final OptionValue DumpOnError = new OptionValue<>(false); - @Option(help = "Enable expensive assertions") + @Option(help = "Enable expensive assertions", type = OptionType.Debug) public static final OptionValue DetailedAsserts = new StableOptionValue() { @Override protected Boolean initialValue() { @@ -72,7 +72,7 @@ return enabled; } }; - @Option(help = "Enable more verbose log output when available") + @Option(help = "Enable more verbose log output when available", type = OptionType.Debug) public static final OptionValue LogVerbose = new OptionValue<>(false); // @formatter:on diff -r 28e46ea20c93 -r d854f8a5256f graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/alloc/LinearScan.java --- a/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/alloc/LinearScan.java Tue Dec 16 23:36:29 2014 +0100 +++ b/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/alloc/LinearScan.java Tue Dec 16 23:37:35 2014 +0100 @@ -73,7 +73,7 @@ public static class Options { // @formatter:off - @Option(help = "Enable spill position optimization") + @Option(help = "Enable spill position optimization", type = OptionType.Debug) public static final OptionValue LSRAOptimizeSpillPosition = new OptionValue<>(true); // @formatter:on } diff -r 28e46ea20c93 -r d854f8a5256f graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/alloc/LocationMarker.java --- a/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/alloc/LocationMarker.java Tue Dec 16 23:36:29 2014 +0100 +++ b/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/alloc/LocationMarker.java Tue Dec 16 23:37:35 2014 +0100 @@ -40,7 +40,7 @@ public static class Options { // @formatter:off - @Option(help = "Use decoupled pass for location marking (instead of using LSRA marking)") + @Option(help = "Use decoupled pass for location marking (instead of using LSRA marking)", type = OptionType.Debug) public static final OptionValue UseLocationMarker = new OptionValue<>(false); // @formatter:on } diff -r 28e46ea20c93 -r d854f8a5256f graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/alloc/OptimizingLinearScanWalker.java --- a/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/alloc/OptimizingLinearScanWalker.java Tue Dec 16 23:36:29 2014 +0100 +++ b/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/alloc/OptimizingLinearScanWalker.java Tue Dec 16 23:37:35 2014 +0100 @@ -38,9 +38,9 @@ public static class Options { // @formatter:off - @Option(help = "Enable LSRA optimization") + @Option(help = "Enable LSRA optimization", type = OptionType.Debug) public static final OptionValue LSRAOptimization = new OptionValue<>(true); - @Option(help = "LSRA optimization: Only split but do not reassign") + @Option(help = "LSRA optimization: Only split but do not reassign", type = OptionType.Debug) public static final OptionValue LSRAOptSplitOnly = new OptionValue<>(false); // @formatter:on } diff -r 28e46ea20c93 -r d854f8a5256f 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 Tue Dec 16 23:36:29 2014 +0100 +++ b/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/phases/HighTier.java Tue Dec 16 23:37:35 2014 +0100 @@ -41,7 +41,7 @@ public static class Options { // @formatter:off - @Option(help = "Enable inlining") + @Option(help = "Enable inlining", type = OptionType.Expert) public static final OptionValue Inline = new OptionValue<>(true); // @formatter:on } diff -r 28e46ea20c93 -r d854f8a5256f 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 Tue Dec 16 23:36:29 2014 +0100 +++ b/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/phases/LowTier.java Tue Dec 16 23:37:35 2014 +0100 @@ -36,7 +36,7 @@ static class Options { // @formatter:off - @Option(help = "") + @Option(help = "", type = OptionType.Debug) public static final OptionValue ProfileCompiledMethods = new OptionValue<>(false); // @formatter:on diff -r 28e46ea20c93 -r d854f8a5256f graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/phases/MidTier.java --- a/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/phases/MidTier.java Tue Dec 16 23:36:29 2014 +0100 +++ b/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/phases/MidTier.java Tue Dec 16 23:37:35 2014 +0100 @@ -81,6 +81,10 @@ appendPhase(new IncrementalCanonicalizerPhase<>(canonicalizer, new GuardLoweringPhase())); + if (VerifyHeapAtReturn.getValue()) { + appendPhase(new VerifyHeapAtReturnPhase()); + } + appendPhase(new LoweringPhase(canonicalizer, LoweringTool.StandardLoweringStage.MID_TIER)); appendPhase(new FrameStateAssignmentPhase()); diff -r 28e46ea20c93 -r d854f8a5256f graal/com.oracle.graal.debug/src/com/oracle/graal/debug/TopLevelDebugConfig.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.debug/src/com/oracle/graal/debug/TopLevelDebugConfig.java Tue Dec 16 23:37:35 2014 +0100 @@ -0,0 +1,31 @@ +/* + * 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.debug; + +/** + * A marker class for a scoped debug configuration covering a compilation region. Useful for + * programmatically enabling debug config features. + * + */ +public class TopLevelDebugConfig extends DelegatingDebugConfig { +} diff -r 28e46ea20c93 -r d854f8a5256f graal/com.oracle.graal.debug/src/com/oracle/graal/debug/internal/DebugScope.java --- a/graal/com.oracle.graal.debug/src/com/oracle/graal/debug/internal/DebugScope.java Tue Dec 16 23:36:29 2014 +0100 +++ b/graal/com.oracle.graal.debug/src/com/oracle/graal/debug/internal/DebugScope.java Tue Dec 16 23:37:35 2014 +0100 @@ -169,6 +169,58 @@ return currentDumpLevel >= dumpLevel; } + /** + * Enable dumping at the new {@code dumpLevel} for remainder of compile. Requires a + * TopLevelDebugConfig + * + * @param dumpLevel + */ + public static void setDumpLevel(int dumpLevel) { + TopLevelDebugConfig config = fetchTopLevelDebugConfig("setLogLevel"); + if (config != null) { + config.override(DelegatingDebugConfig.Level.DUMP, dumpLevel); + recursiveUpdateFlags(); + } + } + + /** + * Enable logging at the new {@code logLevel} for remainder of compile. Requires a + * TopLevelDebugConfig + * + * @param logLevel + */ + public static void setLogLevel(int logLevel) { + TopLevelDebugConfig config = fetchTopLevelDebugConfig("setLogLevel"); + if (config != null) { + config.override(DelegatingDebugConfig.Level.LOG, logLevel); + config.delegate(DelegatingDebugConfig.Feature.LOG_METHOD); + recursiveUpdateFlags(); + } + } + + private static void recursiveUpdateFlags() { + DebugScope c = DebugScope.getInstance(); + while (c != null) { + c.updateFlags(); + c = c.parent; + } + } + + private static TopLevelDebugConfig fetchTopLevelDebugConfig(String msg) { + DebugConfig config = getConfig(); + if (config instanceof TopLevelDebugConfig) { + return (TopLevelDebugConfig) config; + } else { + PrintStream out = System.out; + if (config == null) { + out.printf("DebugScope.%s ignored because debugging is disabled%n", msg); + } else { + out.printf("DebugScope.%s ignored because top level delegate config missing%n", msg); + } + return null; + } + } + public boolean isVerifyEnabled() { return verifyEnabled; } diff -r 28e46ea20c93 -r d854f8a5256f 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 Tue Dec 16 23:36:29 2014 +0100 +++ b/graal/com.oracle.graal.graph/src/com/oracle/graal/graph/Graph.java Tue Dec 16 23:37:35 2014 +0100 @@ -40,7 +40,7 @@ public class Graph { static class Options { - @Option(help = "Verify graphs often during compilation when assertions are turned on")// + @Option(help = "Verify graphs often during compilation when assertions are turned on", type = OptionType.Debug)// public static final OptionValue VerifyGraalGraphs = new OptionValue<>(true); } diff -r 28e46ea20c93 -r d854f8a5256f graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotLIRGenerator.java --- a/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotLIRGenerator.java Tue Dec 16 23:36:29 2014 +0100 +++ b/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotLIRGenerator.java Tue Dec 16 23:37:35 2014 +0100 @@ -377,8 +377,9 @@ getResult().getFrameMapBuilder().callsMethod(nativeCallingConvention); // TODO(mg): in case a native function uses floating point varargs, the ABI requires that // RAX contains the length of the varargs - AllocatableValue numberOfFloatingPointArgumentsRegister = AMD64.rax.asValue(); - emitMove(numberOfFloatingPointArgumentsRegister, JavaConstant.forInt(numberOfFloatingPointArguments)); + PrimitiveConstant intConst = JavaConstant.forInt(numberOfFloatingPointArguments); + AllocatableValue numberOfFloatingPointArgumentsRegister = AMD64.rax.asValue(intConst.getLIRKind()); + emitMove(numberOfFloatingPointArgumentsRegister, intConst); for (int i = 0; i < args.length; i++) { Value arg = args[i]; AllocatableValue loc = nativeCallingConvention.getArgument(i); diff -r 28e46ea20c93 -r d854f8a5256f graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotNodeLIRBuilder.java --- a/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotNodeLIRBuilder.java Tue Dec 16 23:36:29 2014 +0100 +++ b/graal/com.oracle.graal.hotspot.amd64/src/com/oracle/graal/hotspot/amd64/AMD64HotSpotNodeLIRBuilder.java Tue Dec 16 23:37:35 2014 +0100 @@ -163,11 +163,13 @@ @Override protected void emitIndirectCall(IndirectCallTargetNode callTarget, Value result, Value[] parameters, Value[] temps, LIRFrameState callState) { if (callTarget instanceof HotSpotIndirectCallTargetNode) { - AllocatableValue metaspaceMethod = AMD64.rbx.asValue(); - gen.emitMove(metaspaceMethod, operand(((HotSpotIndirectCallTargetNode) callTarget).metaspaceMethod())); - AllocatableValue targetAddress = AMD64.rax.asValue(); - gen.emitMove(targetAddress, operand(callTarget.computedAddress())); - append(new AMD64IndirectCallOp(callTarget.targetMethod(), result, parameters, temps, metaspaceMethod, targetAddress, callState)); + Value metaspaceMethodSrc = operand(((HotSpotIndirectCallTargetNode) callTarget).metaspaceMethod()); + Value targetAddressSrc = operand(callTarget.computedAddress()); + AllocatableValue metaspaceMethodDst = AMD64.rbx.asValue(metaspaceMethodSrc.getLIRKind()); + AllocatableValue targetAddressDst = AMD64.rax.asValue(targetAddressSrc.getLIRKind()); + gen.emitMove(metaspaceMethodDst, metaspaceMethodSrc); + gen.emitMove(targetAddressDst, targetAddressSrc); + append(new AMD64IndirectCallOp(callTarget.targetMethod(), result, parameters, temps, metaspaceMethodDst, targetAddressDst, callState)); } else { super.emitIndirectCall(callTarget, result, parameters, temps, callState); } diff -r 28e46ea20c93 -r d854f8a5256f graal/com.oracle.graal.hotspot.hsail/src/com/oracle/graal/hotspot/hsail/HSAILHotSpotBackend.java --- a/graal/com.oracle.graal.hotspot.hsail/src/com/oracle/graal/hotspot/hsail/HSAILHotSpotBackend.java Tue Dec 16 23:36:29 2014 +0100 +++ b/graal/com.oracle.graal.hotspot.hsail/src/com/oracle/graal/hotspot/hsail/HSAILHotSpotBackend.java Tue Dec 16 23:37:35 2014 +0100 @@ -89,7 +89,7 @@ public static class Options { // @formatter:off - @Option(help = "Number of TLABs used for HSAIL kernels which allocate") + @Option(help = "Number of TLABs used for HSAIL kernels which allocate", type = OptionType.Debug) public static final OptionValue HsailKernelTlabs = new OptionValue<>(4); // @formatter:on } diff -r 28e46ea20c93 -r d854f8a5256f graal/com.oracle.graal.hotspot.hsail/src/com/oracle/graal/hotspot/hsail/replacements/HSAILNewObjectSnippets.java --- a/graal/com.oracle.graal.hotspot.hsail/src/com/oracle/graal/hotspot/hsail/replacements/HSAILNewObjectSnippets.java Tue Dec 16 23:36:29 2014 +0100 +++ b/graal/com.oracle.graal.hotspot.hsail/src/com/oracle/graal/hotspot/hsail/replacements/HSAILNewObjectSnippets.java Tue Dec 16 23:37:35 2014 +0100 @@ -59,13 +59,13 @@ public static class Options { // @formatter:off - @Option(help = "In HSAIL allocation, allow allocation from eden as fallback if TLAB is full") + @Option(help = "In HSAIL allocation, allow allocation from eden as fallback if TLAB is full", type = OptionType.Debug) static final OptionValue HsailUseEdenAllocate = new OptionValue<>(false); - @Option(help = "In HSAIL allocation, allow GPU to allocate a new tlab if TLAB is full") + @Option(help = "In HSAIL allocation, allow GPU to allocate a new tlab if TLAB is full", type = OptionType.Debug) static final OptionValue HsailNewTlabAllocate = new OptionValue<>(true); - @Option(help = "Estimate of number of bytes allocated by each HSAIL workitem, used to size TLABs") + @Option(help = "Estimate of number of bytes allocated by each HSAIL workitem, used to size TLABs", type = OptionType.Debug) public static final OptionValue HsailAllocBytesPerWorkitem = new OptionValue<>(64); // @formatter:on diff -r 28e46ea20c93 -r d854f8a5256f graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotNodeLIRBuilder.java --- a/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotNodeLIRBuilder.java Tue Dec 16 23:36:29 2014 +0100 +++ b/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotNodeLIRBuilder.java Tue Dec 16 23:37:35 2014 +0100 @@ -111,11 +111,13 @@ @Override protected void emitIndirectCall(IndirectCallTargetNode callTarget, Value result, Value[] parameters, Value[] temps, LIRFrameState callState) { - AllocatableValue metaspaceMethod = g5.asValue(); - gen.emitMove(metaspaceMethod, operand(((HotSpotIndirectCallTargetNode) callTarget).metaspaceMethod())); + Value metaspaceMethodSrc = operand(((HotSpotIndirectCallTargetNode) callTarget).metaspaceMethod()); + AllocatableValue metaspaceMethod = g5.asValue(metaspaceMethodSrc.getLIRKind()); + gen.emitMove(metaspaceMethod, metaspaceMethodSrc); - AllocatableValue targetAddress = o7.asValue(); - gen.emitMove(targetAddress, operand(callTarget.computedAddress())); + Value targetAddressSrc = operand(callTarget.computedAddress()); + AllocatableValue targetAddress = o7.asValue(targetAddressSrc.getLIRKind()); + gen.emitMove(targetAddress, targetAddressSrc); append(new SPARCIndirectCallOp(callTarget.targetMethod(), result, parameters, temps, metaspaceMethod, targetAddress, callState)); } diff -r 28e46ea20c93 -r d854f8a5256f 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 Tue Dec 16 23:36:29 2014 +0100 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/CompilationTask.java Tue Dec 16 23:37:35 2014 +0100 @@ -27,6 +27,7 @@ import static com.oracle.graal.compiler.GraalCompiler.*; import static com.oracle.graal.compiler.common.GraalOptions.*; import static com.oracle.graal.compiler.common.UnsafeAccess.*; +import static com.oracle.graal.debug.Debug.*; import static com.oracle.graal.hotspot.HotSpotGraalRuntime.*; import static com.oracle.graal.hotspot.InitTimer.*; import static com.oracle.graal.hotspot.meta.HotSpotSuitesProvider.*; @@ -365,7 +366,9 @@ static void compileMethod(HotSpotResolvedJavaMethod method, int entryBCI, long ctask, int id) { HotSpotBackend backend = runtime().getHostBackend(); CompilationTask task = new CompilationTask(backend, method, entryBCI, ctask, id, true); - task.runCompilation(); + try (DebugConfigScope dcs = setConfig(new TopLevelDebugConfig())) { + task.runCompilation(); + } return; } } diff -r 28e46ea20c93 -r d854f8a5256f 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 Tue Dec 16 23:36:29 2014 +0100 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/CompileTheWorld.java Tue Dec 16 23:37:35 2014 +0100 @@ -38,9 +38,9 @@ import com.oracle.graal.bytecode.*; import com.oracle.graal.compiler.common.*; import com.oracle.graal.debug.*; -import com.oracle.graal.hotspot.HotSpotOptions.OptionConsumer; import com.oracle.graal.hotspot.meta.*; import com.oracle.graal.options.*; +import com.oracle.graal.options.OptionUtils.OptionConsumer; import com.oracle.graal.options.OptionValue.OverrideScope; import com.oracle.graal.replacements.*; @@ -56,19 +56,19 @@ public static class Options { // @formatter:off - @Option(help = "Compile all methods in all classes on given class path") + @Option(help = "Compile all methods in all classes on given class path", type = OptionType.Debug) public static final OptionValue CompileTheWorldClasspath = new OptionValue<>(SUN_BOOT_CLASS_PATH); - @Option(help = "Verbose CompileTheWorld operation") + @Option(help = "Verbose CompileTheWorld operation", type = OptionType.Debug) public static final OptionValue CompileTheWorldVerbose = new OptionValue<>(true); - @Option(help = "The number of CompileTheWorld iterations to perform") + @Option(help = "The number of CompileTheWorld iterations to perform", type = OptionType.Debug) public static final OptionValue CompileTheWorldIterations = new OptionValue<>(1); - @Option(help = "First class to consider when using -XX:+CompileTheWorld") + @Option(help = "First class to consider when using -XX:+CompileTheWorld", type = OptionType.Debug) public static final OptionValue CompileTheWorldStartAt = new OptionValue<>(1); - @Option(help = "Last class to consider when using -XX:+CompileTheWorld") + @Option(help = "Last class to consider when using -XX:+CompileTheWorld", type = OptionType.Debug) public static final OptionValue CompileTheWorldStopAt = new OptionValue<>(Integer.MAX_VALUE); @Option(help = "Option value overrides to use during compile the world. For example, " + "to disable inlining and partial escape analysis specify '-PartialEscapeAnalysis -Inline'. " + - "The format for each option is the same as on the command line just without the '-G:' prefix.") + "The format for each option is the same as on the command line just without the '-G:' prefix.", type = OptionType.Debug) public static final OptionValue CompileTheWorldConfig = new OptionValue<>(null); // @formatter:on diff -r 28e46ea20c93 -r d854f8a5256f graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotGraalRuntime.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotGraalRuntime.java Tue Dec 16 23:36:29 2014 +0100 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotGraalRuntime.java Tue Dec 16 23:37:35 2014 +0100 @@ -189,10 +189,10 @@ public static class Options { // @formatter:off - @Option(help = "The runtime configuration to use") + @Option(help = "The runtime configuration to use", type = OptionType.Expert) static final OptionValue GraalRuntime = new OptionValue<>(""); - @Option(help = "File to which logging is sent. A %p in the name will be replaced with a string identifying the process, usually the process id.") + @Option(help = "File to which logging is sent. A %p in the name will be replaced with a string identifying the process, usually the process id.", type = OptionType.Expert) public static final PrintStreamOption LogFile = new PrintStreamOption(); // @formatter:on } diff -r 28e46ea20c93 -r d854f8a5256f graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotOptions.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotOptions.java Tue Dec 16 23:36:29 2014 +0100 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotOptions.java Tue Dec 16 23:37:35 2014 +0100 @@ -27,22 +27,24 @@ import static java.lang.Double.*; import java.lang.reflect.*; -import java.util.*; import com.oracle.graal.api.runtime.*; import com.oracle.graal.compiler.common.*; import com.oracle.graal.debug.*; import com.oracle.graal.options.*; +import com.oracle.graal.options.OptionUtils.OptionConsumer; import com.oracle.graal.phases.common.inlining.*; //JaCoCo Exclude /** - * Sets Graal options from the HotSpot command line. Such options are distinguished by a - * {@code "-G:"} prefix. + * Sets Graal options from the HotSpot command line. Such options are distinguished by the + * {@link #GRAAL_OPTION_PREFIX} prefix. */ public class HotSpotOptions { + private static final String GRAAL_OPTION_PREFIX = "-G:"; + /** * Parses the Graal specific options specified to HotSpot (e.g., on the command line). * @@ -69,10 +71,6 @@ public static void initialize() { } - interface OptionConsumer { - void set(OptionDescriptor desc, Object value); - } - /** * Helper for the VM code called by {@link #parseVMOptions()}. * @@ -89,10 +87,10 @@ option.setValue(Boolean.FALSE); break; case '?': - printFlags(); + OptionUtils.printFlags(options, GRAAL_OPTION_PREFIX); break; case ' ': - printNoMatchMessage(name); + OptionUtils.printNoMatchMessage(options, name, GRAAL_OPTION_PREFIX); break; case 'i': option.setValue((int) primitiveValue); @@ -118,104 +116,7 @@ * instead. */ public static boolean parseOption(String option, OptionConsumer setter) { - if (option.length() == 0) { - return false; - } - - Object value = null; - String optionName = null; - String valueString = null; - - if (option.equals("+PrintFlags")) { - printFlags(); - return true; - } - - char first = option.charAt(0); - if (first == '+' || first == '-') { - optionName = option.substring(1); - value = (first == '+'); - } else { - int index = option.indexOf('='); - if (index == -1) { - optionName = option; - valueString = null; - } else { - optionName = option.substring(0, index); - valueString = option.substring(index + 1); - } - } - - OptionDescriptor desc = options.get(optionName); - if (desc == null) { - printNoMatchMessage(optionName); - return false; - } - - Class optionType = desc.getType(); - - if (value == null) { - if (optionType == Boolean.TYPE || optionType == Boolean.class) { - System.err.println("Value for boolean option '" + optionName + "' must use '-G:+" + optionName + "' or '-G:-" + optionName + "' format"); - return false; - } - - if (valueString == null) { - System.err.println("Value for option '" + optionName + "' must use '-G:" + optionName + "=' format"); - return false; - } - - if (optionType == Float.class) { - value = Float.parseFloat(valueString); - } else if (optionType == Double.class) { - value = Double.parseDouble(valueString); - } else if (optionType == Integer.class) { - value = Integer.parseInt(valueString); - } else if (optionType == String.class) { - value = valueString; - } - } else { - if (optionType != Boolean.class) { - System.err.println("Value for option '" + optionName + "' must use '-G:" + optionName + "=' format"); - return false; - } - } - - if (value != null) { - if (setter != null) { - setter.set(desc, value); - } else { - OptionValue optionValue = desc.getOptionValue(); - optionValue.setValue(value); - // System.err.println("Set option " + desc.getName() + " to " + value); - } - } else { - System.err.println("Wrong value \"" + valueString + "\" for option " + optionName); - return false; - } - - return true; - } - - protected static void printNoMatchMessage(String optionName) { - OptionDescriptor desc = options.get(optionName); - if (desc != null) { - if (desc.getType() == Boolean.class) { - System.err.println("Boolean option " + optionName + " must be prefixed with '+' or '-'"); - } else { - System.err.println(desc.getType().getSimpleName() + " option " + optionName + " must not be prefixed with '+' or '-'"); - } - } else { - System.err.println("Could not find option " + optionName + " (use -G:+PrintFlags to see Graal options)"); - List matches = fuzzyMatch(optionName); - if (!matches.isEmpty()) { - System.err.println("Did you mean one of the following?"); - for (OptionDescriptor match : matches) { - boolean isBoolean = match.getType() == Boolean.class; - System.err.println(String.format(" %s%s%s", isBoolean ? "(+/-)" : "", match.getName(), isBoolean ? "" : "=")); - } - } - } + return OptionUtils.parseOption(options, option, GRAAL_OPTION_PREFIX, setter); } /** @@ -246,97 +147,4 @@ throw new GraalInternalError(e); } } - - /** - * 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() { - System.out.println("[Graal flags]"); - SortedMap sortedOptions = options; - for (Map.Entry e : sortedOptions.entrySet()) { - e.getKey(); - OptionDescriptor desc = e.getValue(); - Object value = desc.getOptionValue().getValue(); - List helpLines = wrap(desc.getHelp(), 70); - System.out.println(String.format("%9s %-40s = %-14s %s", desc.getType().getSimpleName(), e.getKey(), value, helpLines.get(0))); - for (int i = 1; i < helpLines.size(); i++) { - System.out.println(String.format("%67s %s", " ", helpLines.get(i))); - } - } - - System.exit(0); - } - - /** - * 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(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 28e46ea20c93 -r d854f8a5256f graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotReferenceMap.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotReferenceMap.java Tue Dec 16 23:36:29 2014 +0100 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotReferenceMap.java Tue Dec 16 23:37:35 2014 +0100 @@ -168,11 +168,11 @@ } public BitSet getFrameMap() { - return (BitSet) frameRefMap.clone(); + return frameRefMap == null ? null : (BitSet) frameRefMap.clone(); } public BitSet getRegisterMap() { - return (BitSet) registerRefMap.clone(); + return registerRefMap == null ? null : (BitSet) registerRefMap.clone(); } // clear diff -r 28e46ea20c93 -r d854f8a5256f graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotVMConfig.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotVMConfig.java Tue Dec 16 23:36:29 2014 +0100 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotVMConfig.java Tue Dec 16 23:37:35 2014 +0100 @@ -67,6 +67,11 @@ */ public final int maxFrameSize = 16 * 1024; + @Override + public String toString() { + return getClass().getSimpleName(); + } + HotSpotVMConfig(CompilerToVM compilerToVm) { compilerToVm.initializeConfiguration(this); assert verifyInitialization(); diff -r 28e46ea20c93 -r d854f8a5256f 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 Tue Dec 16 23:36:29 2014 +0100 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/debug/BenchmarkCounters.java Tue Dec 16 23:37:35 2014 +0100 @@ -84,16 +84,16 @@ static class Options { //@formatter:off - @Option(help = "Turn on the benchmark counters, and displays the results on VM shutdown") + @Option(help = "Turn on the benchmark counters, and displays the results on VM shutdown", type = OptionType.Debug) private static final OptionValue GenericDynamicCounters = new OptionValue<>(false); - @Option(help = "Turn on the benchmark counters, and displays the results every n milliseconds") + @Option(help = "Turn on the benchmark counters, and displays the results every n milliseconds", type = OptionType.Debug) private static final OptionValue TimedDynamicCounters = new OptionValue<>(-1); @Option(help = "Turn on the benchmark counters, and listen for specific patterns on System.out/System.err:%n" + "Format: (err|out),start pattern,end pattern (~ matches multiple digits)%n" + "Examples:%n" + " dacapo = 'err, starting =====, PASSED in'%n" + - " specjvm2008 = 'out,Iteration ~ (~s) begins:,Iteration ~ (~s) ends:'") + " specjvm2008 = 'out,Iteration ~ (~s) begins:,Iteration ~ (~s) ends:'", type = OptionType.Debug) private static final OptionValue BenchmarkDynamicCounters = new OptionValue<>(null); //@formatter:on } @@ -374,6 +374,8 @@ } } + private static final LocationIdentity COUNTER_LOCATION = NamedLocationIdentity.mutable("COUNTER_LOCATION"); + public static void lower(DynamicCounterNode counter, HotSpotRegistersProvider registers, HotSpotVMConfig config, Kind wordKind) { StructuredGraph graph = counter.graph(); @@ -383,9 +385,9 @@ if (index >= config.graalCountersSize) { throw new GraalInternalError("too many counters, reduce number of counters or increase -XX:GraalCounterSize=... (current value: " + config.graalCountersSize + ")"); } - ConstantLocationNode arrayLocation = ConstantLocationNode.create(LocationIdentity.ANY_LOCATION, config.graalCountersThreadOffset, graph); + ConstantLocationNode arrayLocation = ConstantLocationNode.create(COUNTER_LOCATION, config.graalCountersThreadOffset, graph); ReadNode readArray = graph.add(ReadNode.create(thread, arrayLocation, StampFactory.forKind(wordKind), BarrierType.NONE)); - ConstantLocationNode location = ConstantLocationNode.create(LocationIdentity.ANY_LOCATION, Unsafe.ARRAY_LONG_INDEX_SCALE * index, graph); + ConstantLocationNode location = ConstantLocationNode.create(COUNTER_LOCATION, Unsafe.ARRAY_LONG_INDEX_SCALE * index, graph); ReadNode read = graph.add(ReadNode.create(readArray, location, StampFactory.forKind(Kind.Long), BarrierType.NONE)); AddNode add = graph.unique(AddNode.create(read, counter.getIncrement())); WriteNode write = graph.add(WriteNode.create(readArray, add, location, BarrierType.NONE)); diff -r 28e46ea20c93 -r d854f8a5256f graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/DefaultHotSpotLoweringProvider.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/DefaultHotSpotLoweringProvider.java Tue Dec 16 23:36:29 2014 +0100 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/DefaultHotSpotLoweringProvider.java Tue Dec 16 23:37:35 2014 +0100 @@ -137,6 +137,10 @@ if (graph.getGuardsStage() == StructuredGraph.GuardsStage.AFTER_FSA) { newObjectSnippets.lower((DynamicNewArrayNode) n, registers, tool); } + } else if (n instanceof VerifyHeapNode) { + if (graph.getGuardsStage() == StructuredGraph.GuardsStage.AFTER_FSA) { + newObjectSnippets.lower((VerifyHeapNode) n, registers, runtime, tool); + } } else if (n instanceof MonitorEnterNode) { if (graph.getGuardsStage() == StructuredGraph.GuardsStage.AFTER_FSA) { monitorSnippets.lower((MonitorEnterNode) n, registers, tool); diff -r 28e46ea20c93 -r d854f8a5256f graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotConstantReflectionProvider.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotConstantReflectionProvider.java Tue Dec 16 23:36:29 2014 +0100 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotConstantReflectionProvider.java Tue Dec 16 23:37:35 2014 +0100 @@ -210,8 +210,7 @@ } else { Class clazz = object.getClass(); if (StableOptionValue.class.isAssignableFrom(clazz)) { - if (hotspotField.isInObject(object)) { - assert hotspotField.getName().equals("value") : "Unexpected field in " + StableOptionValue.class.getName() + " hierarchy:" + this; + if (hotspotField.isInObject(object) && hotspotField.getName().equals("value")) { StableOptionValue option = (StableOptionValue) object; return HotSpotObjectConstantImpl.forObject(option.getValue()); } diff -r 28e46ea20c93 -r d854f8a5256f graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/AssertionSnippets.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/AssertionSnippets.java Tue Dec 16 23:36:29 2014 +0100 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/AssertionSnippets.java Tue Dec 16 23:37:35 2014 +0100 @@ -65,7 +65,7 @@ } @NodeIntrinsic(ForeignCallNode.class) - private static native void vmMessageC(@ConstantNodeParameter ForeignCallDescriptor stubPrintfC, boolean vmError, Word format, long v1, long v2, long v3); + static native void vmMessageC(@ConstantNodeParameter ForeignCallDescriptor stubPrintfC, boolean vmError, Word format, long v1, long v2, long v3); public static class Templates extends AbstractTemplates { diff -r 28e46ea20c93 -r d854f8a5256f graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/InstanceOfSnippets.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/InstanceOfSnippets.java Tue Dec 16 23:36:29 2014 +0100 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/InstanceOfSnippets.java Tue Dec 16 23:37:35 2014 +0100 @@ -198,11 +198,11 @@ // @formatter:off @Option(help = "If the probability that a type check will hit one the profiled types (up to " + - "TypeCheckMaxHints) is below this value, the type check will be compiled without profiling info") + "TypeCheckMaxHints) is below this value, the type check will be compiled without profiling info", type = OptionType.Expert) static final OptionValue TypeCheckMinProfileHitProbability = new OptionValue<>(0.5); @Option(help = "The maximum number of profiled types that will be used when compiling a profiled type check. " + - "Note that TypeCheckMinProfileHitProbability also influences whether profiling info is used in compiled type checks.") + "Note that TypeCheckMinProfileHitProbability also influences whether profiling info is used in compiled type checks.", type = OptionType.Expert) static final OptionValue TypeCheckMaxHints = new OptionValue<>(2); // @formatter:on } diff -r 28e46ea20c93 -r d854f8a5256f 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 Tue Dec 16 23:36:29 2014 +0100 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/MonitorSnippets.java Tue Dec 16 23:37:35 2014 +0100 @@ -70,7 +70,7 @@ public static class Options { //@formatter:off - @Option(help = "") + @Option(help = "", type = OptionType.Debug) private static final OptionValue ProfileMonitors = new OptionValue<>(false); //@formatter:on } diff -r 28e46ea20c93 -r d854f8a5256f graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/NewObjectSnippets.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/NewObjectSnippets.java Tue Dec 16 23:36:29 2014 +0100 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/NewObjectSnippets.java Tue Dec 16 23:37:35 2014 +0100 @@ -24,6 +24,7 @@ import static com.oracle.graal.api.code.UnsignedMath.*; import static com.oracle.graal.compiler.common.GraalOptions.*; +import static com.oracle.graal.hotspot.nodes.CStringNode.*; import static com.oracle.graal.hotspot.replacements.HotSpotReplacementsUtil.*; import static com.oracle.graal.hotspot.replacements.NewObjectSnippets.Options.*; import static com.oracle.graal.nodes.PiArrayNode.*; @@ -49,6 +50,7 @@ import com.oracle.graal.nodes.extended.*; import com.oracle.graal.nodes.java.*; import com.oracle.graal.nodes.spi.*; +import com.oracle.graal.nodes.util.*; import com.oracle.graal.options.*; import com.oracle.graal.replacements.*; import com.oracle.graal.replacements.Snippet.ConstantParameter; @@ -69,7 +71,7 @@ static class Options { //@formatter:off - @Option(help = "") + @Option(help = "", type = OptionType.Debug) static final OptionValue ProfileAllocations = new OptionValue<>(false); //@formatter:on } @@ -354,6 +356,18 @@ return memory.toObject(); } + @Snippet + protected static void verifyHeap(@ConstantParameter Register threadRegister) { + Word thread = registerAsWord(threadRegister); + Word topValue = readTlabTop(thread); + if (!topValue.equal(Word.zero())) { + Word topValueContents = topValue.readWord(0, MARK_WORD_LOCATION); + if (topValueContents.equal(Word.zero())) { + AssertionSnippets.vmMessageC(AssertionSnippets.ASSERTION_VM_MESSAGE_C, true, cstring("overzeroing of TLAB detected"), 0L, 0L, 0L); + } + } + } + /** * Formats some allocated memory with an object header and zeroes out the rest. */ @@ -378,6 +392,7 @@ private final SnippetInfo allocateArrayDynamic = snippet(NewObjectSnippets.class, "allocateArrayDynamic"); private final SnippetInfo allocateInstanceDynamic = snippet(NewObjectSnippets.class, "allocateInstanceDynamic"); private final SnippetInfo newmultiarray = snippet(NewObjectSnippets.class, "newmultiarray"); + private final SnippetInfo verifyHeap = snippet(NewObjectSnippets.class, "verifyHeap"); public Templates(HotSpotProviders providers, TargetDescription target) { super(providers, providers.getSnippetReflection(), target); @@ -482,6 +497,28 @@ assert size >= 0; return size; } + + static class WarnOnce { + static { + System.out.println("VerifyHeapNode requires a VM with asserts enabled."); + } + + static void warn() { + } + } + + public void lower(VerifyHeapNode verifyHeapNode, HotSpotRegistersProvider registers, HotSpotGraalRuntimeProvider runtime, LoweringTool tool) { + if (runtime.getConfig().cAssertions) { + Arguments args = new Arguments(verifyHeap, verifyHeapNode.graph().getGuardsStage(), tool.getLoweringStage()); + args.addConst("threadRegister", registers.getThreadRegister()); + + SnippetTemplate template = template(args); + template.instantiate(providers.getMetaAccess(), verifyHeapNode, DEFAULT_REPLACER, args); + } else { + WarnOnce.warn(); + GraphUtil.removeFixedWithUnusedInputs(verifyHeapNode); + } + } } private static final SnippetCounter.Group countersNew = SnippetCounters.getValue() ? new SnippetCounter.Group("NewInstance") : null; diff -r 28e46ea20c93 -r d854f8a5256f graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/ObjectCloneSnippets.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/ObjectCloneSnippets.java Tue Dec 16 23:36:29 2014 +0100 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/ObjectCloneSnippets.java Tue Dec 16 23:37:35 2014 +0100 @@ -114,7 +114,7 @@ @Snippet(removeAllFrameStates = true) public static Object[] objectArrayClone(Object[] src) { - Object[] result = (Object[]) DynamicNewArrayNode.newUninitializedArray(GuardingPiNode.guardingNonNull(src.getClass().getComponentType()), src.length); + Object[] result = (Object[]) DynamicNewArrayNode.newUninitializedArray(GuardingPiNode.guardingNonNull(src.getClass().getComponentType()), src.length, Kind.Object); ArrayCopyCallNode.disjointUninitializedArraycopy(src, 0, result, 0, src.length, Kind.Object); return result; } diff -r 28e46ea20c93 -r d854f8a5256f graal/com.oracle.graal.java/src/com/oracle/graal/java/AbstractBytecodeParser.java --- a/graal/com.oracle.graal.java/src/com/oracle/graal/java/AbstractBytecodeParser.java Tue Dec 16 23:36:29 2014 +0100 +++ b/graal/com.oracle.graal.java/src/com/oracle/graal/java/AbstractBytecodeParser.java Tue Dec 16 23:37:35 2014 +0100 @@ -44,7 +44,7 @@ static class Options { // @formatter:off - @Option(help = "The trace level for the bytecode parser used when building a graph from bytecode") + @Option(help = "The trace level for the bytecode parser used when building a graph from bytecode", type = OptionType.Debug) public static final OptionValue TraceBytecodeParserLevel = new OptionValue<>(0); // @formatter:on } diff -r 28e46ea20c93 -r d854f8a5256f graal/com.oracle.graal.lir/src/com/oracle/graal/lir/constopt/ConstantLoadOptimization.java --- a/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/constopt/ConstantLoadOptimization.java Tue Dec 16 23:36:29 2014 +0100 +++ b/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/constopt/ConstantLoadOptimization.java Tue Dec 16 23:37:35 2014 +0100 @@ -49,7 +49,7 @@ public static class Options { // @formatter:off - @Option(help = "Enable constant load optimization.") + @Option(help = "Enable constant load optimization.", type = OptionType.Debug) public static final OptionValue ConstantLoadOptimization = new OptionValue<>(true); // @formatter:on } diff -r 28e46ea20c93 -r d854f8a5256f graal/com.oracle.graal.lir/src/com/oracle/graal/lir/gen/LIRGenerator.java --- a/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/gen/LIRGenerator.java Tue Dec 16 23:36:29 2014 +0100 +++ b/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/gen/LIRGenerator.java Tue Dec 16 23:37:35 2014 +0100 @@ -48,9 +48,9 @@ public static class Options { // @formatter:off - @Option(help = "Print HIR along side LIR as the latter is generated") + @Option(help = "Print HIR along side LIR as the latter is generated", type = OptionType.Debug) public static final OptionValue PrintIRWithLIR = new OptionValue<>(false); - @Option(help = "The trace level for the LIR generator") + @Option(help = "The trace level for the LIR generator", type = OptionType.Debug) public static final OptionValue TraceLIRGeneratorLevel = new OptionValue<>(0); // @formatter:on } diff -r 28e46ea20c93 -r d854f8a5256f graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/debug/VerifyHeapNode.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/debug/VerifyHeapNode.java Tue Dec 16 23:37:35 2014 +0100 @@ -0,0 +1,60 @@ +/* + * 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.nodes.debug; + +import com.oracle.graal.compiler.common.type.*; +import com.oracle.graal.nodeinfo.*; +import com.oracle.graal.nodes.*; +import com.oracle.graal.nodes.spi.*; + +/** + * A node for platform dependent verification of the Java heap. Intended to be used for debugging + * heap corruption issues. + */ +@NodeInfo +public class VerifyHeapNode extends FixedWithNextNode implements Lowerable { + + public static VerifyHeapNode create() { + return new VerifyHeapNode(); + } + + protected VerifyHeapNode() { + super(StampFactory.forVoid()); + } + + @Override + public void lower(LoweringTool tool) { + tool.getLowerer().lower(this, tool); + } + + public static void addBefore(FixedNode position) { + StructuredGraph graph = position.graph(); + graph.addBeforeFixed(position, graph.add(VerifyHeapNode.create())); + } + + public static void addAfter(FixedWithNextNode position) { + StructuredGraph graph = position.graph(); + graph.addAfterFixed(position, graph.add(VerifyHeapNode.create())); + } + +} diff -r 28e46ea20c93 -r d854f8a5256f graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/SwitchNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/SwitchNode.java Tue Dec 16 23:36:29 2014 +0100 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/SwitchNode.java Tue Dec 16 23:37:35 2014 +0100 @@ -156,6 +156,6 @@ if (defaultSuccessorIndex() == -1) { throw new GraalInternalError("unexpected"); } - return defaultSuccessorIndex() == -1 ? null : successors.get(defaultSuccessorIndex()); + return successors.get(defaultSuccessorIndex()); } } diff -r 28e46ea20c93 -r d854f8a5256f graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/DynamicNewArrayNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/DynamicNewArrayNode.java Tue Dec 16 23:36:29 2014 +0100 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/DynamicNewArrayNode.java Tue Dec 16 23:37:35 2014 +0100 @@ -42,27 +42,38 @@ @Input ValueNode elementType; + /** + * A non-null value indicating the worst case element type. Mainly useful for distinguishing + * Object arrays from primitive arrays. + */ + protected final Kind knownElementKind; + public static DynamicNewArrayNode create(ValueNode elementType, ValueNode length) { return new DynamicNewArrayNode(elementType, length); } protected DynamicNewArrayNode(ValueNode elementType, ValueNode length) { - this(elementType, length, true); + this(elementType, length, true, null); } - public static DynamicNewArrayNode create(ValueNode elementType, ValueNode length, boolean fillContents) { - return new DynamicNewArrayNode(elementType, length, fillContents); + public static DynamicNewArrayNode create(ValueNode elementType, ValueNode length, boolean fillContents, Kind knownElementKind) { + return new DynamicNewArrayNode(elementType, length, fillContents, knownElementKind); } - protected DynamicNewArrayNode(ValueNode elementType, ValueNode length, boolean fillContents) { + protected DynamicNewArrayNode(ValueNode elementType, ValueNode length, boolean fillContents, Kind knownElementKind) { super(StampFactory.objectNonNull(), length, fillContents); this.elementType = elementType; + this.knownElementKind = knownElementKind; } public ValueNode getElementType() { return elementType; } + public Kind getKnownElementKind() { + return knownElementKind; + } + protected NewArrayNode forConstantType(ResolvedJavaType type) { ValueNode len = length(); NewArrayNode ret = graph().add(NewArrayNode.create(type, len.isAlive() ? len : graph().addOrUniqueWithInputs(len), fillContents())); @@ -94,10 +105,10 @@ } @NodeIntrinsic - private static native Object newArray(Class componentType, int length, @ConstantNodeParameter boolean fillContents); + private static native Object newArray(Class componentType, int length, @ConstantNodeParameter boolean fillContents, @ConstantNodeParameter Kind knownElementKind); - public static Object newUninitializedArray(Class componentType, int length) { - return newArray(componentType, length, false); + public static Object newUninitializedArray(Class componentType, int length, Kind knownElementKind) { + return newArray(componentType, length, false, knownElementKind); } } diff -r 28e46ea20c93 -r d854f8a5256f graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/MethodCallTargetNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/MethodCallTargetNode.java Tue Dec 16 23:36:29 2014 +0100 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/MethodCallTargetNode.java Tue Dec 16 23:37:35 2014 +0100 @@ -112,20 +112,52 @@ } // check if the type of the receiver can narrow the result - if (tryToResolveMethod(tool)) { - return; + ValueNode receiver = receiver(); + ResolvedJavaType type = StampTool.typeOrNull(receiver); + if (type == null && invokeKind == InvokeKind.Virtual) { + // For virtual calls, we are guaranteed to receive a correct receiver type. + type = targetMethod.getDeclaringClass(); } + if (type != null && (invoke().stateAfter() != null || invoke().stateDuring() != null)) { + /* + * either the holder class is exact, or the receiver object has an exact type, or + * it's an array type + */ + ResolvedJavaMethod resolvedMethod = type.resolveConcreteMethod(targetMethod(), invoke().getContextType()); + if (resolvedMethod != null && (resolvedMethod.canBeStaticallyBound() || StampTool.isExactType(receiver) || type.isArray())) { + setInvokeKind(InvokeKind.Special); + setTargetMethod(resolvedMethod); + return; + } + if (tool.assumptions() != null && tool.assumptions().useOptimisticAssumptions()) { + ResolvedJavaType uniqueConcreteType = type.findUniqueConcreteSubtype(); + if (uniqueConcreteType != null) { + ResolvedJavaMethod methodFromUniqueType = uniqueConcreteType.resolveConcreteMethod(targetMethod(), invoke().getContextType()); + if (methodFromUniqueType != null) { + tool.assumptions().recordConcreteSubtype(type, uniqueConcreteType); + setInvokeKind(InvokeKind.Special); + setTargetMethod(methodFromUniqueType); + return; + } + } - ValueNode receiver = receiver(); - - // try to turn an interface call into a virtual call + ResolvedJavaMethod uniqueConcreteMethod = type.findUniqueConcreteMethod(targetMethod()); + if (uniqueConcreteMethod != null) { + tool.assumptions().recordConcreteMethod(targetMethod(), type, uniqueConcreteMethod); + setInvokeKind(InvokeKind.Special); + setTargetMethod(uniqueConcreteMethod); + return; + } + } + } + // try to turn a interface call into a virtual call ResolvedJavaType declaredReceiverType = targetMethod().getDeclaringClass(); /* * We need to check the invoke kind to avoid recursive simplification for virtual * interface methods calls. */ if (declaredReceiverType.isInterface() && !invokeKind().equals(InvokeKind.Virtual)) { - tryCheckCastSingleImplementor(tool, receiver, declaredReceiverType); + tryCheckCastSingleImplementor(receiver, declaredReceiverType); } if (invokeKind().equals(InvokeKind.Interface) && receiver instanceof UncheckedInterfaceProvider) { @@ -134,62 +166,14 @@ if (uncheckedStamp != null) { ResolvedJavaType uncheckedReceiverType = StampTool.typeOrNull(uncheckedStamp); if (uncheckedReceiverType.isInterface()) { - tryCheckCastSingleImplementor(tool, receiver, uncheckedReceiverType); + tryCheckCastSingleImplementor(receiver, uncheckedReceiverType); } } } } } - /** - * Try to use receiver type information to statically bind the method. - * - * @param tool - * @return true if successfully converted to InvokeKind.Special - */ - private boolean tryToResolveMethod(SimplifierTool tool) { - ValueNode receiver = receiver(); - ResolvedJavaType type = StampTool.typeOrNull(receiver); - if (type == null && invokeKind == InvokeKind.Virtual) { - // For virtual calls, we are guaranteed to receive a correct receiver type. - type = targetMethod.getDeclaringClass(); - } - if (type != null && (invoke().stateAfter() != null || invoke().stateDuring() != null)) { - /* - * either the holder class is exact, or the receiver object has an exact type, or it's - * an array type - */ - ResolvedJavaMethod resolvedMethod = type.resolveConcreteMethod(targetMethod(), invoke().getContextType()); - if (resolvedMethod != null && (resolvedMethod.canBeStaticallyBound() || StampTool.isExactType(receiver) || type.isArray())) { - setInvokeKind(InvokeKind.Special); - setTargetMethod(resolvedMethod); - return true; - } - if (tool.assumptions() != null && tool.assumptions().useOptimisticAssumptions()) { - ResolvedJavaType uniqueConcreteType = type.findUniqueConcreteSubtype(); - if (uniqueConcreteType != null) { - ResolvedJavaMethod methodFromUniqueType = uniqueConcreteType.resolveConcreteMethod(targetMethod(), invoke().getContextType()); - if (methodFromUniqueType != null) { - tool.assumptions().recordConcreteSubtype(type, uniqueConcreteType); - setInvokeKind(InvokeKind.Special); - setTargetMethod(methodFromUniqueType); - return true; - } - } - - ResolvedJavaMethod uniqueConcreteMethod = type.findUniqueConcreteMethod(targetMethod()); - if (uniqueConcreteMethod != null) { - tool.assumptions().recordConcreteMethod(targetMethod(), type, uniqueConcreteMethod); - setInvokeKind(InvokeKind.Special); - setTargetMethod(uniqueConcreteMethod); - return true; - } - } - } - return false; - } - - private void tryCheckCastSingleImplementor(SimplifierTool tool, ValueNode receiver, ResolvedJavaType declaredReceiverType) { + private void tryCheckCastSingleImplementor(ValueNode receiver, ResolvedJavaType declaredReceiverType) { ResolvedJavaType singleImplementor = declaredReceiverType.getSingleImplementor(); if (singleImplementor != null && !singleImplementor.equals(declaredReceiverType)) { ResolvedJavaMethod singleImplementorMethod = singleImplementor.resolveMethod(targetMethod(), invoke().getContextType(), true); @@ -214,8 +198,6 @@ arguments().set(0, piNode); setInvokeKind(InvokeKind.Virtual); setTargetMethod(singleImplementorMethod); - // Now try to bind the method exactly. - tryToResolveMethod(tool); } } } diff -r 28e46ea20c93 -r d854f8a5256f graal/com.oracle.graal.options/src/com/oracle/graal/options/Option.java --- a/graal/com.oracle.graal.options/src/com/oracle/graal/options/Option.java Tue Dec 16 23:36:29 2014 +0100 +++ b/graal/com.oracle.graal.options/src/com/oracle/graal/options/Option.java Tue Dec 16 23:37:35 2014 +0100 @@ -27,7 +27,7 @@ /** * Describes the attributes of an option whose {@link OptionValue value} is in a static field * annotated by this annotation type. - * + * * @see OptionProcessor * @see OptionDescriptor */ @@ -45,4 +45,9 @@ * 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 28e46ea20c93 -r d854f8a5256f 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 Tue Dec 16 23:37:35 2014 +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 Graal 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 28e46ea20c93 -r d854f8a5256f graal/com.oracle.graal.options/src/com/oracle/graal/options/OptionUtils.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.options/src/com/oracle/graal/options/OptionUtils.java Tue Dec 16 23:37:35 2014 +0100 @@ -0,0 +1,234 @@ +/* + * 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.*; + +public class OptionUtils { + + public interface OptionConsumer { + void set(OptionDescriptor desc, Object value); + } + + /** + * Parses a given option value specification. + * + * @param option the specification of an option and its value + * @param setter the object to notify of the parsed option and value. If null, the + * {@link OptionValue#setValue(Object)} method of the specified option is called + * instead. + */ + public static boolean parseOption(SortedMap options, String option, String prefix, OptionConsumer setter) { + if (option.length() == 0) { + return false; + } + + Object value = null; + String optionName = null; + String valueString = null; + + if (option.equals("+PrintFlags")) { + printFlags(options, prefix); + return true; + } + + char first = option.charAt(0); + if (first == '+' || first == '-') { + optionName = option.substring(1); + value = (first == '+'); + } else { + int index = option.indexOf('='); + if (index == -1) { + optionName = option; + valueString = null; + } else { + optionName = option.substring(0, index); + valueString = option.substring(index + 1); + } + } + + OptionDescriptor desc = options.get(optionName); + if (desc == null) { + printNoMatchMessage(options, optionName, prefix); + return false; + } + + Class optionType = desc.getType(); + + if (value == null) { + if (optionType == Boolean.TYPE || optionType == Boolean.class) { + System.err.println("Value for boolean option '" + optionName + "' must use '" + prefix + "+" + optionName + "' or '" + prefix + "-" + optionName + "' format"); + return false; + } + + if (valueString == null) { + System.err.println("Value for option '" + optionName + "' must use '" + prefix + optionName + "=' format"); + return false; + } + + if (optionType == Float.class) { + value = Float.parseFloat(valueString); + } else if (optionType == Double.class) { + value = Double.parseDouble(valueString); + } else if (optionType == Integer.class) { + value = Integer.parseInt(valueString); + } else if (optionType == String.class) { + value = valueString; + } + } else { + if (optionType != Boolean.class) { + System.err.println("Value for option '" + optionName + "' must use '" + prefix + optionName + "=' format"); + return false; + } + } + + if (value != null) { + if (setter != null) { + setter.set(desc, value); + } else { + OptionValue optionValue = desc.getOptionValue(); + optionValue.setValue(value); + // System.err.println("Set option " + desc.getName() + " to " + value); + } + } else { + System.err.println("Wrong value \"" + valueString + "\" for option " + optionName); + return false; + } + + return true; + } + + public static void printNoMatchMessage(SortedMap options, String optionName, String prefix) { + OptionDescriptor desc = options.get(optionName); + if (desc != null) { + if (desc.getType() == Boolean.class) { + System.err.println("Boolean option " + optionName + " must be prefixed with '+' or '-'"); + } else { + System.err.println(desc.getType().getSimpleName() + " option " + optionName + " must not be prefixed with '+' or '-'"); + } + } else { + System.err.println("Could not find option " + optionName + " (use " + prefix + "+PrintFlags to see options)"); + List matches = fuzzyMatch(options, optionName); + if (!matches.isEmpty()) { + System.err.println("Did you mean one of the following?"); + for (OptionDescriptor match : matches) { + boolean isBoolean = match.getType() == Boolean.class; + System.err.println(String.format(" %s%s%s", isBoolean ? "(+/-)" : "", match.getName(), isBoolean ? "" : "=")); + } + } + } + } + + /** + * 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; + } + + public static void printFlags(SortedMap options, String prefix) { + System.out.println("[List of " + prefix + " options]"); + SortedMap sortedOptions = options; + for (Map.Entry e : sortedOptions.entrySet()) { + e.getKey(); + OptionDescriptor desc = e.getValue(); + Object value = desc.getOptionValue().getValue(); + List helpLines = wrap(desc.getHelp(), 70); + System.out.println(String.format("%9s %-40s = %-14s %s", desc.getType().getSimpleName(), e.getKey(), value, helpLines.get(0))); + for (int i = 1; i < helpLines.size(); i++) { + System.out.println(String.format("%67s %s", " ", helpLines.get(i))); + } + } + + System.exit(0); + } + + /** + * 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 28e46ea20c93 -r d854f8a5256f graal/com.oracle.graal.options/src/com/oracle/graal/options/OptionValue.java --- a/graal/com.oracle.graal.options/src/com/oracle/graal/options/OptionValue.java Tue Dec 16 23:36:29 2014 +0100 +++ b/graal/com.oracle.graal.options/src/com/oracle/graal/options/OptionValue.java Tue Dec 16 23:37:35 2014 +0100 @@ -130,6 +130,8 @@ static final ThreadLocal overrideScopes = new ThreadLocal<>(); + private T initialValue; + /** * The raw option value. */ @@ -152,8 +154,10 @@ } } + @SuppressWarnings("unchecked") public OptionValue(T value) { - this.value = value; + this.initialValue = value; + this.value = (T) UNINITIALIZED; addToHistogram(this); } @@ -165,6 +169,7 @@ */ @SuppressWarnings("unchecked") protected OptionValue() { + this.initialValue = (T) UNINITIALIZED; this.value = (T) UNINITIALIZED; addToHistogram(this); } @@ -184,6 +189,14 @@ } /** + * 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()}. @@ -198,6 +211,34 @@ } /** + * 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 getInitialValue() { + if (initialValue == UNINITIALIZED) { + initialValue = initialValue(); + } + return initialValue; + } + + /** + * Returns true if the option has the same value that was set in the source code. + */ + public boolean hasInitialValue() { + if (!(this instanceof StableOptionValue)) { + OverrideScope overrideScope = overrideScopes.get(); + if (overrideScope != null) { + T override = overrideScope.getOverride(this); + if (override != null) { + return false; + } + } + } + return value == UNINITIALIZED || Objects.equals(value, getInitialValue()); + } + + /** * Gets the value of this option. */ public T getValue() { @@ -213,10 +254,11 @@ } } } - if (value == UNINITIALIZED) { - value = initialValue(); + if (value != UNINITIALIZED) { + return value; + } else { + return getInitialValue(); } - return value; } /** @@ -235,7 +277,11 @@ overrideScope.getOverrides(this, (Collection) values); } } - values.add(value); + if (value != UNINITIALIZED) { + values.add(value); + } else { + values.add(getInitialValue()); + } return values; } diff -r 28e46ea20c93 -r d854f8a5256f 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 Tue Dec 16 23:36:29 2014 +0100 +++ b/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/DeadCodeEliminationPhase.java Tue Dec 16 23:37:35 2014 +0100 @@ -34,7 +34,7 @@ public static class Options { // @formatter:off - @Option(help = "Disable optional dead code eliminations") + @Option(help = "Disable optional dead code eliminations", type = OptionType.Debug) public static final OptionValue ReduceDCE = new OptionValue<>(true); // @formatter:on } diff -r 28e46ea20c93 -r d854f8a5256f graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/VerifyHeapAtReturnPhase.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/VerifyHeapAtReturnPhase.java Tue Dec 16 23:37:35 2014 +0100 @@ -0,0 +1,37 @@ +/* + * 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.phases.common; + +import com.oracle.graal.nodes.*; +import com.oracle.graal.nodes.debug.*; +import com.oracle.graal.phases.*; + +public class VerifyHeapAtReturnPhase extends Phase { + + @Override + protected void run(StructuredGraph graph) { + for (ReturnNode returnNode : graph.getNodes(ReturnNode.class)) { + VerifyHeapNode.addBefore(returnNode); + } + } +} diff -r 28e46ea20c93 -r d854f8a5256f 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 Tue Dec 16 23:36:29 2014 +0100 +++ b/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/inlining/InliningPhase.java Tue Dec 16 23:37:35 2014 +0100 @@ -37,7 +37,7 @@ public static class Options { // @formatter:off - @Option(help = "Unconditionally inline intrinsics") + @Option(help = "Unconditionally inline intrinsics", type = OptionType.Debug) public static final OptionValue AlwaysInlineIntrinsics = new OptionValue<>(false); // @formatter:on } diff -r 28e46ea20c93 -r d854f8a5256f graal/com.oracle.graal.phases/src/com/oracle/graal/phases/tiers/Suites.java --- a/graal/com.oracle.graal.phases/src/com/oracle/graal/phases/tiers/Suites.java Tue Dec 16 23:36:29 2014 +0100 +++ b/graal/com.oracle.graal.phases/src/com/oracle/graal/phases/tiers/Suites.java Tue Dec 16 23:37:35 2014 +0100 @@ -36,7 +36,7 @@ static class Options { // @formatter:off - @Option(help = "The compiler configuration to use") + @Option(help = "The compiler configuration to use", type = OptionType.User) static final OptionValue CompilerConfiguration = new OptionValue<>(""); // @formatter:on } diff -r 28e46ea20c93 -r d854f8a5256f 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 Tue Dec 16 23:36:29 2014 +0100 +++ b/graal/com.oracle.graal.printer/src/com/oracle/graal/printer/NoDeadCodeVerifyHandler.java Tue Dec 16 23:37:35 2014 +0100 @@ -48,7 +48,7 @@ static class Options { // @formatter:off - @Option(help = "Run level for NoDeadCodeVerifyHandler (0 = off, 1 = info, 2 = verbose, 3 = fatal)") + @Option(help = "Run level for NoDeadCodeVerifyHandler (0 = off, 1 = info, 2 = verbose, 3 = fatal)", type = OptionType.Debug) public static final OptionValue NDCV = new OptionValue<>(0); // @formatter:on } diff -r 28e46ea20c93 -r d854f8a5256f graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/BoxingSnippets.java --- a/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/BoxingSnippets.java Tue Dec 16 23:36:29 2014 +0100 +++ b/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/BoxingSnippets.java Tue Dec 16 23:37:35 2014 +0100 @@ -177,7 +177,7 @@ if (value.isConstant()) { JavaConstant sourceConstant = value.asJavaConstant(); JavaConstant boxedConstant = constantReflection.boxPrimitive(sourceConstant); - if (boxedConstant != null && boxedConstant.getKind() == box.getBoxingKind()) { + if (boxedConstant != null && sourceConstant.getKind() == box.getBoxingKind()) { return ConstantNode.forConstant(boxedConstant, metaAccess, box.graph()); } } diff -r 28e46ea20c93 -r d854f8a5256f graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/DefaultJavaLoweringProvider.java --- a/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/DefaultJavaLoweringProvider.java Tue Dec 16 23:36:29 2014 +0100 +++ b/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/DefaultJavaLoweringProvider.java Tue Dec 16 23:37:35 2014 +0100 @@ -40,10 +40,12 @@ import com.oracle.graal.nodes.*; import com.oracle.graal.nodes.HeapAccess.BarrierType; import com.oracle.graal.nodes.calc.*; +import com.oracle.graal.nodes.debug.*; import com.oracle.graal.nodes.extended.*; import com.oracle.graal.nodes.java.*; import com.oracle.graal.nodes.spi.*; import com.oracle.graal.nodes.type.*; +import com.oracle.graal.nodes.util.*; import com.oracle.graal.nodes.virtual.*; import com.oracle.graal.phases.util.*; @@ -99,11 +101,17 @@ boxingSnippets.lower((BoxNode) n, tool); } else if (n instanceof UnboxNode) { boxingSnippets.lower((UnboxNode) n, tool); + } else if (n instanceof VerifyHeapNode) { + lowerVerifyHeap((VerifyHeapNode) n); } else { throw GraalInternalError.shouldNotReachHere("Node implementing Lowerable not handled: " + n); } } + protected void lowerVerifyHeap(VerifyHeapNode n) { + GraphUtil.removeFixedWithUnusedInputs(n); + } + protected void lowerLoadFieldNode(LoadFieldNode loadField, LoweringTool tool) { assert loadField.getKind() != Kind.Illegal; StructuredGraph graph = loadField.graph(); diff -r 28e46ea20c93 -r d854f8a5256f 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 Tue Dec 16 23:36:29 2014 +0100 +++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/PartialEvaluator.java Tue Dec 16 23:37:35 2014 +0100 @@ -224,10 +224,29 @@ PhaseContext phaseContext = new PhaseContext(providers, assumptions); boolean changed = false; boolean changedInIteration; + ArrayDeque queue = new ArrayDeque<>(); + MetaAccessProvider metaAccess = providers.getMetaAccess(); + ResolvedJavaType profileClass = metaAccess.lookupJavaType(NodeCloneable.class); do { changedInIteration = false; for (MethodCallTargetNode methodCallTargetNode : graph.getNodes(MethodCallTargetNode.class)) { InvokeKind kind = methodCallTargetNode.invokeKind(); + if (kind == InvokeKind.Static || kind == InvokeKind.Special) { + ValueNode receiver = methodCallTargetNode.receiver(); + if (receiver != null && receiver.isConstant() && profileClass.isAssignableFrom(receiver.stamp().javaType(metaAccess))) { + queue.addFirst(methodCallTargetNode); + } else { + queue.addLast(methodCallTargetNode); + } + } + } + + while (!queue.isEmpty()) { + MethodCallTargetNode methodCallTargetNode = queue.removeFirst(); + if (!methodCallTargetNode.isAlive()) { + continue; + } + InvokeKind kind = methodCallTargetNode.invokeKind(); try (Indent id1 = Debug.logAndIndent("try inlining %s, kind = %s", methodCallTargetNode.targetMethod(), kind)) { if (kind == InvokeKind.Static || kind == InvokeKind.Special) { if ((TraceTruffleCompilationHistogram.getValue() || TraceTruffleCompilationDetails.getValue()) && kind == InvokeKind.Special && methodCallTargetNode.receiver().isConstant()) { diff -r 28e46ea20c93 -r d854f8a5256f 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 Tue Dec 16 23:36:29 2014 +0100 +++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/TruffleCompilerOptions.java Tue Dec 16 23:37:35 2014 +0100 @@ -41,99 +41,137 @@ * Element = Include | '~' Exclude ; * */ - @Option(help = "Restrict compilation to comma-separated list of includes (or excludes prefixed with tilde)") + @Option(help = "Restrict compilation to comma-separated list of includes (or excludes prefixed with tilde)", type = OptionType.Debug) public static final OptionValue TruffleCompileOnly = new OptionValue<>(null); - @Option(help = "Compile call target when call count exceeds this threshold") + + @Option(help = "Compile call target when call count exceeds this threshold", type = OptionType.User) public static final OptionValue TruffleCompilationThreshold = new OptionValue<>(1000); - @Option(help = "Defines the maximum timespan in milliseconds that is required for a call target to be queued for compilation.") + + @Option(help = "Defines the maximum timespan in milliseconds that is required for a call target to be queued for compilation.", type = OptionType.User) public static final OptionValue TruffleTimeThreshold = new OptionValue<>(25000); - @Option(help = "Minimum number of calls before a call target is compiled") + + @Option(help = "Minimum number of calls before a call target is compiled", type = OptionType.Expert) public static final OptionValue TruffleMinInvokeThreshold = new OptionValue<>(3); - @Option(help = "Delay compilation after an invalidation to allow for reprofiling") + + @Option(help = "Delay compilation after an invalidation to allow for reprofiling", type = OptionType.Expert) public static final OptionValue TruffleInvalidationReprofileCount = new OptionValue<>(3); - @Option(help = "Delay compilation after a node replacement") + + @Option(help = "Delay compilation after a node replacement", type = OptionType.Expert) public static final OptionValue TruffleReplaceReprofileCount = new OptionValue<>(10); - @Option(help = "Enable automatic inlining of call targets") + + @Option(help = "Enable automatic inlining of call targets", type = OptionType.Debug) public static final OptionValue TruffleFunctionInlining = new OptionValue<>(true); - @Option(help = "Enable an expansion cache per CallTarget. Only functionable with TruffleContextSensitiveInlining enabled.") + + @Option(help = "Enable an expansion cache per CallTarget. Only functionable with TruffleContextSensitiveInlining enabled.", type = OptionType.Debug) public static final OptionValue TruffleFunctionInliningCache = new OptionValue<>(true); - @Option(help = "Maximum number of Graal IR nodes during partial evaluation") + + @Option(help = "Maximum number of Graal IR nodes during partial evaluation", type = OptionType.Expert) public static final OptionValue TruffleGraphMaxNodes = new OptionValue<>(200000); - @Option(help = "Stop inlining if caller's cumulative tree size would exceed this limit") + + @Option(help = "Stop inlining if caller's cumulative tree size would exceed this limit", type = OptionType.Expert) public static final OptionValue TruffleInliningMaxCallerSize = new OptionValue<>(2250); - @Option(help = "Defines the number of graal nodes that triggers a performance warning.") + @Option(help = "Defines the number of graal nodes that triggers a performance warning.", type = OptionType.Debug) public static final OptionValue TrufflePerformanceWarningGraalNodeCount = new OptionValue<>(1000); - @Option(help = "Enable call target splitting") + @Option(help = "Enable call target splitting", type = OptionType.Expert) public static final OptionValue TruffleSplitting = new OptionValue<>(true); - @Option(help = "Experimental: Enable the new version of truffle splitting.") + + @Option(help = "Experimental: Enable the new version of truffle splitting.", type = OptionType.Debug) public static final OptionValue TruffleSplittingNew = new OptionValue<>(false); - @Option(help = "Experimental. New splitting only: Whether or not splitting should be based instance comparisons of non TypedObjects") + + @Option(help = "Experimental. New splitting only: Whether or not splitting should be based instance comparisons of non TypedObjects", type = OptionType.Debug) public static final OptionValue TruffleSplittingClassInstanceStamps = new OptionValue<>(false); - @Option(help = "Experimental. New splitting only: Whether or not splitting should be based instance comparisons of TypedObjects") + + @Option(help = "Experimental. New splitting only: Whether or not splitting should be based instance comparisons of TypedObjects", type = OptionType.Debug) public static final OptionValue TruffleSplittingTypeInstanceStamps = new OptionValue<>(true); - @Option(help = "Experimental. New splitting only: The number of calls until splitting is performed. ") + + @Option(help = "Experimental. New splitting only: The number of calls until splitting is performed. ", type = OptionType.Debug) public static final OptionValue TruffleSplittingStartCallCount = new OptionValue<>(3); - @Option(help = "Experimental. New splitting only: Split everything aggressively. ") + + @Option(help = "Experimental. New splitting only: Split everything aggressively. ", type = OptionType.Debug) public static final OptionValue TruffleSplittingAggressive = new OptionValue<>(false); - - @Option(help = "Disable call target splitting if tree size exceeds this limit") + @Option(help = "Disable call target splitting if tree size exceeds this limit", type = OptionType.Debug) public static final OptionValue TruffleSplittingMaxCalleeSize = new OptionValue<>(100); - @Option(help = "Number of most recently used methods in truffle cache") + + @Option(help = "Number of most recently used methods in truffle cache", type = OptionType.Debug) public static final OptionValue TruffleMaxCompilationCacheSize = new OptionValue<>(512); - @Option(help = "Enable asynchronous truffle compilation in background thread") + + @Option(help = "Enable asynchronous truffle compilation in background thread", type = OptionType.Expert) public static final OptionValue TruffleBackgroundCompilation = new OptionValue<>(true); - @Option(help = "") + + @Option(help = "", type = OptionType.Debug) public static final OptionValue TruffleCompilationDecisionTime = new OptionValue<>(100); - @Option(help = "") + + @Option(help = "", type = OptionType.Debug) public static final OptionValue TruffleCompilationDecisionTimePrintFail = new OptionValue<>(false); - @Option(help = "") + + @Option(help = "", type = OptionType.Debug) public static final OptionValue TruffleReturnTypeSpeculation = new StableOptionValue<>(true); - @Option(help = "") + + @Option(help = "", type = OptionType.Debug) public static final OptionValue TruffleArgumentTypeSpeculation = new StableOptionValue<>(true); // tracing - @Option(help = "Print potential performance problems") + @Option(help = "Print potential performance problems", type = OptionType.Debug) public static final OptionValue TraceTrufflePerformanceWarnings = new OptionValue<>(false); - @Option(help = "Print information for compilation results") + + @Option(help = "Print information for compilation results", type = OptionType.Debug) public static final OptionValue TraceTruffleCompilation = new OptionValue<>(false); - @Option(help = "Print information for compilation queuing") + + @Option(help = "Print information for compilation queuing", type = OptionType.Debug) public static final OptionValue TraceTruffleCompilationDetails = new OptionValue<>(false); - @Option(help = "Print a node count histogram after each compilation") + + @Option(help = "Print a node count histogram after each compilation", type = OptionType.Debug) public static final OptionValue TraceTruffleCompilationHistogram = new OptionValue<>(false); - @Option(help = "Print all polymorphic and generic nodes after each compilation") + + @Option(help = "Print all polymorphic and generic nodes after each compilation", type = OptionType.Debug) public static final OptionValue TraceTruffleCompilationPolymorphism = new OptionValue<>(false); - @Option(help = "Print all polymorphic and generic nodes after each compilation") + + @Option(help = "Print all polymorphic and generic nodes after each compilation", type = OptionType.Debug) public static final OptionValue TraceTruffleCompilationAST = new OptionValue<>(false); - @Option(help = "Print the inlined call tree for each compiled method") + + @Option(help = "Print the inlined call tree for each compiled method", type = OptionType.Debug) public static final OptionValue TraceTruffleCompilationCallTree = new OptionValue<>(false); - @Option(help = "Print the expansion trees for each compilation") + + @Option(help = "Print the expansion trees for each compilation", type = OptionType.Debug) public static final OptionValue TraceTruffleExpansion = new OptionValue<>(false); - @Option(help = "Print source secions for printed expansion trees") + + @Option(help = "Print source secions for printed expansion trees", type = OptionType.Debug) public static final OptionValue TraceTruffleExpansionSource = new OptionValue<>(false); - @Option(help = "Print detailed information for the Truffle compilation cache") + + @Option(help = "Print detailed information for the Truffle compilation cache", type = OptionType.Debug) public static final OptionValue TraceTruffleCacheDetails = new OptionValue<>(false); - @Option(help = "Treat compilation exceptions as fatal exceptions that will exit the application") + + @Option(help = "Treat compilation exceptions as fatal exceptions that will exit the application", type = OptionType.Debug) public static final OptionValue TruffleCompilationExceptionsAreFatal = new OptionValue<>(false); - @Option(help = "Treat compilation exceptions as thrown runtime exceptions") + + @Option(help = "Treat compilation exceptions as thrown runtime exceptions", type = OptionType.Debug) public static final OptionValue TruffleCompilationExceptionsAreThrown = new OptionValue<>(false); - @Option(help = "Print information for inlining for each compilation.") + + @Option(help = "Print information for inlining for each compilation.", type = OptionType.Debug) public static final OptionValue TraceTruffleInlining = new OptionValue<>(false); - @Option(help = "Print information for each splitted call site.") + + @Option(help = "Print information for each splitted call site.", type = OptionType.Debug) public static final OptionValue TraceTruffleSplitting = new OptionValue<>(false); - @Option(help = "Print stack trace on transfer to interpreter") + + @Option(help = "Print stack trace on transfer to interpreter", type = OptionType.Debug) public static final OptionValue TraceTruffleTransferToInterpreter = new StableOptionValue<>(false); - @Option(help = "Print stack trace on assumption invalidation") + + @Option(help = "Print stack trace on assumption invalidation", type = OptionType.Debug) public static final OptionValue TraceTruffleAssumptions = new StableOptionValue<>(false); - @Option(help = "Number of stack trace elements printed by TraceTruffleTransferToInterpreter and TraceTruffleAssumptions") + + @Option(help = "Number of stack trace elements printed by TraceTruffleTransferToInterpreter and TraceTruffleAssumptions", type = OptionType.Debug) public static final OptionValue TraceTruffleStackTraceLimit = new OptionValue<>(20); - @Option(help = "Print a summary of execution counts for all executed CallTargets. Introduces counter overhead for each call.") + + @Option(help = "Print a summary of execution counts for all executed CallTargets. Introduces counter overhead for each call.", type = OptionType.Debug) public static final OptionValue TruffleCallTargetProfiling = new StableOptionValue<>(false); - @Option(help = "Print Truffle compilation statistics at the end of a run.") + + @Option(help = "Print Truffle compilation statistics at the end of a run.", type = OptionType.Debug) public static final OptionValue TruffleCompilationStatistics = new OptionValue<>(false); - @Option(help = "Print additional more verbose Truffle compilation statistics at the end of a run.") + + @Option(help = "Print additional more verbose Truffle compilation statistics at the end of a run.", type = OptionType.Debug) public static final OptionValue TruffleCompilationStatisticDetails = new OptionValue<>(false); // @formatter:on } diff -r 28e46ea20c93 -r d854f8a5256f 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 Tue Dec 16 23:36:29 2014 +0100 +++ b/graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/PartialEscapePhase.java Tue Dec 16 23:37:35 2014 +0100 @@ -45,7 +45,7 @@ static class Options { //@formatter:off - @Option(help = "") + @Option(help = "", type = OptionType.Debug) public static final OptionValue OptEarlyReadElimination = new OptionValue<>(true); //@formatter:on } diff -r 28e46ea20c93 -r d854f8a5256f graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/ReadEliminationClosure.java --- a/graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/ReadEliminationClosure.java Tue Dec 16 23:36:29 2014 +0100 +++ b/graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/ReadEliminationClosure.java Tue Dec 16 23:37:35 2014 +0100 @@ -62,7 +62,7 @@ LoadCacheEntry identifier = new LoadCacheEntry(object, access.field()); ValueNode cachedValue = state.getCacheEntry(identifier); if (node instanceof LoadFieldNode) { - if (cachedValue != null) { + if (cachedValue != null && access.stamp().isCompatible(cachedValue.stamp())) { effects.replaceAtUsages(access, cachedValue); addScalarAlias(access, cachedValue); deleted = true; @@ -87,7 +87,7 @@ ValueNode object = GraphUtil.unproxify(read.object()); ReadCacheEntry identifier = new ReadCacheEntry(object, read.location()); ValueNode cachedValue = state.getCacheEntry(identifier); - if (cachedValue != null) { + if (cachedValue != null && read.stamp().isCompatible(cachedValue.stamp())) { if (read.getGuard() != null && !(read.getGuard() instanceof FixedNode)) { effects.addFixedNodeBefore(ValueAnchorNode.create((ValueNode) read.getGuard()), read); } @@ -122,7 +122,7 @@ ValueNode object = GraphUtil.unproxify(load.object()); UnsafeLoadCacheEntry identifier = new UnsafeLoadCacheEntry(object, load.offset(), load.getLocationIdentity()); ValueNode cachedValue = state.getCacheEntry(identifier); - if (cachedValue != null) { + if (cachedValue != null && load.stamp().isCompatible(cachedValue.stamp())) { effects.replaceAtUsages(load, cachedValue); addScalarAlias(load, cachedValue); deleted = true; diff -r 28e46ea20c93 -r d854f8a5256f graal/com.oracle.truffle.api/src/com/oracle/truffle/api/source/Source.java --- a/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/source/Source.java Tue Dec 16 23:36:29 2014 +0100 +++ b/graal/com.oracle.truffle.api/src/com/oracle/truffle/api/source/Source.java Tue Dec 16 23:37:35 2014 +0100 @@ -35,7 +35,7 @@ *
    *
  • Literal: A named text string. These are not indexed and should be considered * value objects; equality is defined based on contents.
    - * See {@link Source#fromText(String, String)}
  • + * See {@link Source#fromText(CharSequence, String)} *

    *

  • File: Each file is represented as a canonical object, indexed by the * absolute, canonical path name of the file. File contents are read lazily and contents @@ -53,7 +53,7 @@ *

    *

  • Pseudo File: A literal text string that can be retrieved by name as if it * were a file, unlike literal sources; useful for testing.
    - * See {@link Source#asPseudoFile(String, String)}
  • + * See {@link Source#asPseudoFile(CharSequence, String)} *
*

* File cache: @@ -122,27 +122,28 @@ } /** - * Creates a non-canonical source from literal text. + * Creates a non-canonical source from literal text. If an already created literal source must + * be retrievable by name, use {@link #asPseudoFile(CharSequence, String)}. * - * @param code textual source code + * @param chars textual source code * @param description a note about the origin, for error messages and debugging * @return a newly created, non-indexed source representation */ - public static Source fromText(String code, String description) { - assert code != null; - return new LiteralSource(description, code); + public static Source fromText(CharSequence chars, String description) { + assert chars != null; + return new LiteralSource(description, chars.toString()); } /** * Creates a source whose contents will be read immediately from a URL and cached. * * @param url - * @param name identifies the origin, possibly useful for debugging + * @param description identifies the origin, possibly useful for debugging * @return a newly created, non-indexed source representation * @throws IOException if reading fails */ - public static Source fromURL(URL url, String name) throws IOException { - return URLSource.get(url, name); + public static Source fromURL(URL url, String description) throws IOException { + return URLSource.get(url, description); } /** @@ -192,12 +193,12 @@ * Creates a source from literal text, but which acts as a file and can be retrieved by name * (unlike other literal sources); intended for testing. * - * @param code textual source code + * @param chars textual source code * @param pseudoFileName string to use for indexing/lookup * @return a newly created, source representation, canonical with respect to its name */ - public static Source asPseudoFile(String code, String pseudoFileName) { - final Source source = new LiteralSource(pseudoFileName, code); + public static Source asPseudoFile(CharSequence chars, String pseudoFileName) { + final Source source = new LiteralSource(pseudoFileName, chars.toString()); filePathToSource.put(pseudoFileName, new WeakReference<>(source)); return source; } @@ -212,11 +213,12 @@ } private static String read(Reader reader) throws IOException { + final BufferedReader bufferedReader = new BufferedReader(reader); final StringBuilder builder = new StringBuilder(); final char[] buffer = new char[1024]; while (true) { - final int n = reader.read(buffer); + final int n = bufferedReader.read(buffer); if (n == -1) { break; } @@ -597,6 +599,23 @@ } @Override + public int hashCode() { + return path.hashCode(); + } + + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + if (obj instanceof FileSource) { + FileSource other = (FileSource) obj; + return path.equals(other.path); + } + return false; + } + + @Override protected void reset() { this.code = null; } diff -r 28e46ea20c93 -r d854f8a5256f graal/com.oracle.truffle.object/src/com/oracle/truffle/object/DynamicObjectImpl.java --- a/graal/com.oracle.truffle.object/src/com/oracle/truffle/object/DynamicObjectImpl.java Tue Dec 16 23:36:29 2014 +0100 +++ b/graal/com.oracle.truffle.object/src/com/oracle/truffle/object/DynamicObjectImpl.java Tue Dec 16 23:37:35 2014 +0100 @@ -156,24 +156,25 @@ } public final void copyProperties(DynamicObject fromObject, Shape ancestor) { - Shape fromShape = fromObject.getShape(); - Shape toShape = getShape(); + ShapeImpl fromShape = (ShapeImpl) fromObject.getShape(); + ShapeImpl toShape = getShape(); assert toShape.isRelated(ancestor); assert toShape.isValid(); assert ancestor.isValid(); for (; toShape != ancestor; toShape = toShape.getParent()) { - Property toProperty = toShape.getLastProperty(); - // assumption: hidden properties won't change and don't need copying - if (!toProperty.isHidden()) { - assert fromShape.hasProperty(toProperty.getKey()); + Transition transitionFromParent = toShape.getTransitionFromParent(); + if (transitionFromParent instanceof Transition.AddPropertyTransition) { + Property toProperty = ((Transition.AddPropertyTransition) transitionFromParent).getProperty(); Property fromProperty = fromShape.getProperty(toProperty.getKey()); + // copy only if property has a location and it's not the same as the source location if (toProperty.getLocation() != null && !(toProperty.getLocation() instanceof ValueLocation) && !toProperty.getLocation().equals(fromProperty.getLocation())) { toProperty.setInternal(this, fromProperty.get(fromObject, false)); assert toShape.isValid(); } - if (fromShape.getLastProperty() == fromProperty) { + if (fromShape.getTransitionFromParent() instanceof Transition.AddPropertyTransition && + ((Transition.AddPropertyTransition) fromShape.getTransitionFromParent()).getProperty() == fromProperty) { // no property is looked up twice, so we can skip over to parent fromShape = fromShape.getParent(); } diff -r 28e46ea20c93 -r d854f8a5256f src/share/vm/compiler/compilerOracle.cpp --- a/src/share/vm/compiler/compilerOracle.cpp Tue Dec 16 23:36:29 2014 +0100 +++ b/src/share/vm/compiler/compilerOracle.cpp Tue Dec 16 23:37:35 2014 +0100 @@ -397,7 +397,8 @@ int match = MethodMatcher::Exact; while (name[0] == '*') { match |= MethodMatcher::Suffix; - strcpy(name, name + 1); + // Copy remaining string plus NUL to the beginning + memmove(name, name + 1, strlen(name + 1) + 1); } if (strcmp(name, "*") == 0) return MethodMatcher::Any; diff -r 28e46ea20c93 -r d854f8a5256f src/share/vm/graal/graalEnv.cpp --- a/src/share/vm/graal/graalEnv.cpp Tue Dec 16 23:36:29 2014 +0100 +++ b/src/share/vm/graal/graalEnv.cpp Tue Dec 16 23:37:35 2014 +0100 @@ -428,7 +428,9 @@ if (witness != NULL) { return false; } - deps.log_dependency(); + if (LogCompilation) { + deps.log_dependency(); + } } return true; diff -r 28e46ea20c93 -r d854f8a5256f src/share/vm/memory/threadLocalAllocBuffer.cpp --- a/src/share/vm/memory/threadLocalAllocBuffer.cpp Tue Dec 16 23:36:29 2014 +0100 +++ b/src/share/vm/memory/threadLocalAllocBuffer.cpp Tue Dec 16 23:37:35 2014 +0100 @@ -42,6 +42,9 @@ void ThreadLocalAllocBuffer::clear_before_allocation() { _slow_refill_waste += (unsigned)remaining(); + // In debug mode we expect the storage above top to be uninitialized + // or filled with a padding object. + assert(top() == NULL || *(intptr_t*)top() != 0, "overzeroing detected"); make_parsable(true); // also retire the TLAB }