# HG changeset patch # User Christian Haeubl # Date 1332193395 25200 # Node ID dad1ac9dba7d417e2cdead40823d90071887d1b1 # Parent e6a45067e42cb533678abbbd00bbcbfcfe92fdca finished first implementation of disabling runtime feedback selectively based on deoptimization history diff -r e6a45067e42c -r dad1ac9dba7d 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 Thu Mar 15 17:01:44 2012 -0700 +++ b/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/GraalCompiler.java Mon Mar 19 14:43:15 2012 -0700 @@ -26,10 +26,6 @@ import java.util.*; import java.util.concurrent.*; -import com.oracle.max.asm.*; -import com.oracle.max.cri.ci.*; -import com.oracle.max.cri.ri.*; -import com.oracle.max.cri.xir.*; import com.oracle.graal.alloc.simple.*; import com.oracle.graal.compiler.alloc.*; import com.oracle.graal.compiler.gen.*; @@ -38,13 +34,16 @@ import com.oracle.graal.compiler.schedule.*; import com.oracle.graal.compiler.target.*; import com.oracle.graal.compiler.types.*; -import com.oracle.graal.compiler.util.*; import com.oracle.graal.cri.*; import com.oracle.graal.debug.*; import com.oracle.graal.lir.*; import com.oracle.graal.lir.asm.*; import com.oracle.graal.lir.cfg.*; import com.oracle.graal.nodes.*; +import com.oracle.max.asm.*; +import com.oracle.max.cri.ci.*; +import com.oracle.max.cri.ri.*; +import com.oracle.max.cri.xir.*; public class GraalCompiler { @@ -75,7 +74,7 @@ this.backend = backend; } - public CiTargetMethod compileMethod(final RiResolvedMethod method, final StructuredGraph graph, int osrBCI, final PhasePlan plan, final ProfilingInfoConfiguration profilingInfoConfig) { + public CiTargetMethod compileMethod(final RiResolvedMethod method, final StructuredGraph graph, int osrBCI, final PhasePlan plan, final OptimisticOptimizations optimisticOpts) { assert (method.accessFlags() & Modifier.NATIVE) == 0 : "compiling native methods is not supported"; if (osrBCI != -1) { throw new CiBailout("No OSR supported"); @@ -86,7 +85,7 @@ final CiAssumptions assumptions = GraalOptions.OptAssumptions ? new CiAssumptions() : null; final LIR lir = Debug.scope("FrontEnd", new Callable() { public LIR call() { - return emitHIR(graph, assumptions, plan, profilingInfoConfig); + return emitHIR(graph, assumptions, plan, optimisticOpts); } }); final FrameMap frameMap = Debug.scope("BackEnd", lir, new Callable() { @@ -123,7 +122,7 @@ /** * Builds the graph, optimizes it. */ - public LIR emitHIR(StructuredGraph graph, CiAssumptions assumptions, PhasePlan plan, ProfilingInfoConfiguration profilingInfoConfig) { + public LIR emitHIR(StructuredGraph graph, CiAssumptions assumptions, PhasePlan plan, OptimisticOptimizations optimisticOpts) { if (graph.start().next() == null) { plan.runPhases(PhasePosition.AFTER_PARSING, graph); @@ -151,7 +150,7 @@ } if (GraalOptions.Inline && !plan.isPhaseDisabled(InliningPhase.class)) { - new InliningPhase(target, runtime, null, assumptions, plan, profilingInfoConfig).apply(graph); + new InliningPhase(target, runtime, null, assumptions, plan, optimisticOpts).apply(graph); new DeadCodeEliminationPhase().apply(graph); new PhiStampPhase().apply(graph); } @@ -171,7 +170,7 @@ } if (GraalOptions.EscapeAnalysis && !plan.isPhaseDisabled(EscapeAnalysisPhase.class)) { - new EscapeAnalysisPhase(target, runtime, assumptions, plan, profilingInfoConfig).apply(graph); + new EscapeAnalysisPhase(target, runtime, assumptions, plan, optimisticOpts).apply(graph); new PhiStampPhase().apply(graph); if (GraalOptions.OptCanonicalizer) { new CanonicalizerPhase(target, runtime, assumptions).apply(graph); diff -r e6a45067e42c -r dad1ac9dba7d graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/GraalOptions.java --- a/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/GraalOptions.java Thu Mar 15 17:01:44 2012 -0700 +++ b/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/GraalOptions.java Mon Mar 19 14:43:15 2012 -0700 @@ -44,9 +44,9 @@ public static boolean Inline = true; public static boolean Intrinsify = true; public static boolean CacheGraphs = ____; - public static boolean InlineMonomorphicCalls = true; - public static boolean InlinePolymorphicCalls = true; - public static boolean InlineMegamorphicCalls = ____; + static boolean InlineMonomorphicCalls = true; + static boolean InlinePolymorphicCalls = true; + static boolean InlineMegamorphicCalls = ____; public static int InliningPolicy = 4; public static int WeightComputationPolicy = 2; public static int MaximumTrivialSize = 10; @@ -81,6 +81,7 @@ public static int LoopFrequencyPropagationPolicy = -2; // profiling information + public static int MaximumDeoptsBeforeDisablingOptimisticOptimization = 25; public static int MatureExecutionsBranch = 1; public static int MatureExecutionsPerSwitchCase = 1; public static int MatureExecutionsTypeProfile = 1; @@ -150,13 +151,13 @@ // Code generator settings public static boolean PropagateTypes = ____; public static boolean UseProfilingInformation = true; - public static boolean RemoveNeverExecutedCode = true; - public static boolean UseExceptionProbability = true; + static boolean RemoveNeverExecutedCode = true; + static boolean UseExceptionProbability = true; public static boolean AllowExplicitExceptionChecks = true; public static boolean OmitHotExceptionStacktrace = ____; public static boolean GenSafepoints = true; public static boolean GenLoopSafepoints = true; - public static boolean UseTypeCheckHints = true; + static boolean UseTypeCheckHints = true; public static boolean InlineVTableStubs = ____; public static boolean AlwaysInlineVTableStubs = ____; diff -r e6a45067e42c -r dad1ac9dba7d graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/OptimisticOptimizations.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/OptimisticOptimizations.java Mon Mar 19 14:43:15 2012 -0700 @@ -0,0 +1,76 @@ +/* + * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package com.oracle.graal.compiler; + +import com.oracle.max.cri.ri.*; + + + +public final class OptimisticOptimizations { + public static OptimisticOptimizations ALL = new OptimisticOptimizations(true, true, true, true); + public static OptimisticOptimizations NONE = new OptimisticOptimizations(false, false, false, false); + + private final boolean removeNeverExecutedCode; + private final boolean useTypeCheckedInlining; + private final boolean useTypeCheckHints; + private final boolean useExceptionProbability; + + public OptimisticOptimizations(RiResolvedMethod method) { + RiProfilingInfo profilingInfo = method.profilingInfo(); + removeNeverExecutedCode = profilingInfo.getDeoptimizationCount(RiDeoptReason.UnreachedCode) < GraalOptions.MaximumDeoptsBeforeDisablingOptimisticOptimization; + useTypeCheckedInlining = profilingInfo.getDeoptimizationCount(RiDeoptReason.TypeCheckedInliningViolated) < GraalOptions.MaximumDeoptsBeforeDisablingOptimisticOptimization; + useTypeCheckHints = profilingInfo.getDeoptimizationCount(RiDeoptReason.OptimizedTypeCheckViolated) < GraalOptions.MaximumDeoptsBeforeDisablingOptimisticOptimization; + useExceptionProbability = profilingInfo.getDeoptimizationCount(RiDeoptReason.NotCompiledExceptionHandler) < GraalOptions.MaximumDeoptsBeforeDisablingOptimisticOptimization; + } + + public OptimisticOptimizations(boolean removeNeverExecutedCode, boolean useTypeCheckedInlining, boolean useTypeCheckHints, boolean useExceptionProbability) { + this.removeNeverExecutedCode = removeNeverExecutedCode; + this.useTypeCheckedInlining = useTypeCheckedInlining; + this.useTypeCheckHints = useTypeCheckHints; + this.useExceptionProbability = useExceptionProbability; + } + + public boolean removeNeverExecutedCode() { + return GraalOptions.RemoveNeverExecutedCode && removeNeverExecutedCode; + } + + public boolean useUseTypeCheckHints() { + return GraalOptions.UseTypeCheckHints && useTypeCheckHints; + } + + public boolean inlineMonomorphicCalls() { + return GraalOptions.InlineMonomorphicCalls && useTypeCheckedInlining; + } + + public boolean inlinePolymorphicCalls() { + return GraalOptions.InlinePolymorphicCalls && useTypeCheckedInlining; + } + + public boolean inlineMegamorphicCalls() { + return GraalOptions.InlineMegamorphicCalls && useTypeCheckedInlining; + } + + public boolean useExceptionProbability() { + return useExceptionProbability; + } +} diff -r e6a45067e42c -r dad1ac9dba7d graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/gen/LIRGenerator.java --- a/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/gen/LIRGenerator.java Thu Mar 15 17:01:44 2012 -0700 +++ b/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/gen/LIRGenerator.java Mon Mar 19 14:43:15 2012 -0700 @@ -744,7 +744,7 @@ } @Override - public void emitGuardCheck(BooleanNode comp, DeoptReason deoptReason) { + public void emitGuardCheck(BooleanNode comp, RiDeoptReason deoptReason) { if (comp instanceof NullCheckNode && !((NullCheckNode) comp).expectedNull) { emitNullCheckGuard((NullCheckNode) comp); } else if (comp instanceof ConstantNode && comp.asConstant().asBoolean()) { @@ -752,7 +752,7 @@ } else { // Fall back to a normal branch. LIRDebugInfo info = state(); - LabelRef stubEntry = createDeoptStub(DeoptAction.InvalidateReprofile, deoptReason, info, comp); + LabelRef stubEntry = createDeoptStub(RiDeoptAction.InvalidateReprofile, deoptReason, info, comp); emitBranch(comp, null, stubEntry, info); } } @@ -985,7 +985,7 @@ } - protected abstract LabelRef createDeoptStub(DeoptAction action, DeoptReason reason, LIRDebugInfo info, Object deoptInfo); + protected abstract LabelRef createDeoptStub(RiDeoptAction action, RiDeoptReason reason, LIRDebugInfo info, Object deoptInfo); @Override public Variable emitCallToRuntime(CiRuntimeCall runtimeCall, boolean canTrap, CiValue... args) { diff -r e6a45067e42c -r dad1ac9dba7d graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/phases/EscapeAnalysisPhase.java --- a/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/phases/EscapeAnalysisPhase.java Thu Mar 15 17:01:44 2012 -0700 +++ b/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/phases/EscapeAnalysisPhase.java Mon Mar 19 14:43:15 2012 -0700 @@ -215,14 +215,14 @@ private final GraalRuntime runtime; private final CiAssumptions assumptions; private final PhasePlan plan; - private final ProfilingInfoConfiguration profilingInfoConfig; + private final OptimisticOptimizations optimisticOpts; - public EscapeAnalysisPhase(CiTarget target, GraalRuntime runtime, CiAssumptions assumptions, PhasePlan plan, ProfilingInfoConfiguration profilingInfoConfig) { + public EscapeAnalysisPhase(CiTarget target, GraalRuntime runtime, CiAssumptions assumptions, PhasePlan plan, OptimisticOptimizations optimisticOpts) { this.runtime = runtime; this.target = target; this.assumptions = assumptions; this.plan = plan; - this.profilingInfoConfig = profilingInfoConfig; + this.optimisticOpts = optimisticOpts; } public static class EscapeRecord { @@ -389,7 +389,7 @@ if (GraalOptions.TraceEscapeAnalysis || GraalOptions.PrintEscapeAnalysis) { TTY.println("Trying inlining to get a non-escaping object for %s", node); } - new InliningPhase(target, runtime, invokes, assumptions, plan, profilingInfoConfig).apply(graph); + new InliningPhase(target, runtime, invokes, assumptions, plan, optimisticOpts).apply(graph); new DeadCodeEliminationPhase().apply(graph); if (node.isDeleted()) { if (GraalOptions.TraceEscapeAnalysis || GraalOptions.PrintEscapeAnalysis) { diff -r e6a45067e42c -r dad1ac9dba7d graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/phases/InliningPhase.java --- a/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/phases/InliningPhase.java Thu Mar 15 17:01:44 2012 -0700 +++ b/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/phases/InliningPhase.java Mon Mar 19 14:43:15 2012 -0700 @@ -54,22 +54,22 @@ private CiAssumptions assumptions; private final PhasePlan plan; - private final boolean allowTypeCheckedInlining; private final WeightComputationPolicy weightComputationPolicy; private final InliningPolicy inliningPolicy; + private final OptimisticOptimizations optimisticOpts; // Metrics private static final DebugMetric metricInliningPerformed = Debug.metric("InliningPerformed"); private static final DebugMetric metricInliningConsidered = Debug.metric("InliningConsidered"); private static final DebugMetric metricInliningStoppedByMaxDesiredSize = Debug.metric("InliningStoppedByMaxDesiredSize"); - public InliningPhase(CiTarget target, GraalRuntime runtime, Collection hints, CiAssumptions assumptions, PhasePlan plan, ProfilingInfoConfiguration profilingInfoConfig) { + public InliningPhase(CiTarget target, GraalRuntime runtime, Collection hints, CiAssumptions assumptions, PhasePlan plan, OptimisticOptimizations optimisticOpts) { this.target = target; this.runtime = runtime; this.hints = hints; this.assumptions = assumptions; this.plan = plan; - this.allowTypeCheckedInlining = profilingInfoConfig.useTypeProfile(); + this.optimisticOpts = optimisticOpts; this.weightComputationPolicy = createWeightComputationPolicy(); this.inliningPolicy = createInliningPolicy(); } @@ -141,7 +141,7 @@ } private void scanInvoke(Invoke invoke, int level) { - InlineInfo info = InliningUtil.getInlineInfo(invoke, level >= 0 ? level : computeInliningLevel(invoke), runtime, assumptions, this, allowTypeCheckedInlining); + InlineInfo info = InliningUtil.getInlineInfo(invoke, level >= 0 ? level : computeInliningLevel(invoke), runtime, assumptions, this, optimisticOpts); if (info != null) { assert level == -1 || computeInliningLevel(invoke) == level : "outer FramesStates must match inlining level"; metricInliningConsidered.increment(); diff -r e6a45067e42c -r dad1ac9dba7d graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/phases/LoweringPhase.java --- a/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/phases/LoweringPhase.java Thu Mar 15 17:01:44 2012 -0700 +++ b/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/phases/LoweringPhase.java Mon Mar 19 14:43:15 2012 -0700 @@ -28,6 +28,7 @@ import com.oracle.graal.lir.cfg.*; import com.oracle.graal.nodes.*; import com.oracle.graal.nodes.spi.*; +import com.oracle.max.cri.ri.*; public class LoweringPhase extends Phase { @@ -59,7 +60,7 @@ } @Override - public Node createGuard(Node condition, DeoptReason deoptReason) { + public Node createGuard(Node condition, RiDeoptReason deoptReason) { // TODO (thomaswue): Document why this must not be called on floating nodes. throw new UnsupportedOperationException(); } @@ -117,7 +118,7 @@ } @Override - public Node createGuard(Node condition, DeoptReason deoptReason) { + public Node createGuard(Node condition, RiDeoptReason deoptReason) { FixedNode guardAnchor = (FixedNode) getGuardAnchor(); if (GraalOptions.OptEliminateGuards) { for (Node usage : condition.usages()) { diff -r e6a45067e42c -r dad1ac9dba7d graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/target/amd64/AMD64DeoptimizationStub.java --- a/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/target/amd64/AMD64DeoptimizationStub.java Thu Mar 15 17:01:44 2012 -0700 +++ b/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/target/amd64/AMD64DeoptimizationStub.java Mon Mar 19 14:43:15 2012 -0700 @@ -25,23 +25,22 @@ import java.util.*; import com.oracle.graal.compiler.*; -import com.oracle.graal.graph.*; import com.oracle.graal.lir.*; import com.oracle.graal.lir.amd64.*; import com.oracle.graal.lir.asm.*; -import com.oracle.graal.nodes.*; import com.oracle.max.asm.*; import com.oracle.max.asm.target.amd64.*; import com.oracle.max.cri.ci.*; +import com.oracle.max.cri.ri.*; public class AMD64DeoptimizationStub extends AMD64SlowPath { public final Label label = new Label(); public final LIRDebugInfo info; - public final DeoptAction action; - public final DeoptReason reason; + public final RiDeoptAction action; + public final RiDeoptReason reason; public final Object deoptInfo; - public AMD64DeoptimizationStub(DeoptAction action, DeoptReason reason, LIRDebugInfo info, Object deoptInfo) { + public AMD64DeoptimizationStub(RiDeoptAction action, RiDeoptReason reason, LIRDebugInfo info, Object deoptInfo) { this.action = action; this.reason = reason; this.info = info; @@ -64,51 +63,9 @@ AMD64Call.directCall(tasm, masm, CiRuntimeCall.SetDeoptInfo, info); } - masm.movl(scratch, encodeDeoptActionAndReason(action, reason)); + masm.movl(scratch, tasm.runtime.encodeDeoptActionAndReason(action, reason)); // TODO Make this an explicit calling convention instead of using a scratch register AMD64Call.directCall(tasm, masm, CiRuntimeCall.Deoptimize, info); AMD64Call.shouldNotReachHere(tasm, masm); } - - // TODO (chaeubl) this is HotSpot specific -> move it somewhere else - public static int encodeDeoptActionAndReason(DeoptAction action, DeoptReason reason) { - final int actionShift = 0; - final int reasonShift = 3; - - int actionValue = getDeoptActionValue(action); - int reasonValue = getDeoptReasonValue(reason); - return (~(((reasonValue) << reasonShift) + ((actionValue) << actionShift))); - } - - // TODO (chaeubl) this is HotSpot specific -> move it somewhere else - private static int getDeoptActionValue(DeoptAction action) { - switch(action) { - case None: return 0; - case RecompileIfTooManyDeopts: return 1; - case InvalidateReprofile: return 2; - case InvalidateRecompile: return 3; - case InvalidateStopCompiling: return 4; - default: throw GraalInternalError.shouldNotReachHere(); - } - } - - // TODO (chaeubl) this is HotSpot specific -> move it somewhere else - private static int getDeoptReasonValue(DeoptReason reason) { - switch(reason) { - case None: return 0; - case NullCheckException: return 1; - case BoundsCheckException: return 2; - case ClassCastException: return 3; - case ArrayStoreException: return 4; - case UnreachedCode: return 5; - case TypeCheckedInliningViolated: return 6; - case OptimizedTypeCheckViolated: return 7; - case NotCompiledExceptionHandler: return 8; - case Unresolved: return 9; - case JavaSubroutineMismatch: return 10; - case ArithmeticException: return 11; - case RuntimeConstraint: return 12; - default: throw GraalInternalError.shouldNotReachHere(); - } - } } diff -r e6a45067e42c -r dad1ac9dba7d graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/target/amd64/AMD64LIRGenerator.java --- a/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/target/amd64/AMD64LIRGenerator.java Thu Mar 15 17:01:44 2012 -0700 +++ b/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/target/amd64/AMD64LIRGenerator.java Mon Mar 19 14:43:15 2012 -0700 @@ -499,7 +499,7 @@ @Override - public void emitDeoptimizeOn(Condition cond, DeoptAction action, DeoptReason reason, Object deoptInfo) { + public void emitDeoptimizeOn(Condition cond, RiDeoptAction action, RiDeoptReason reason, Object deoptInfo) { LIRDebugInfo info = state(); LabelRef stubEntry = createDeoptStub(action, reason, info, deoptInfo); if (cond != null) { @@ -546,7 +546,7 @@ } @Override - protected LabelRef createDeoptStub(DeoptAction action, DeoptReason reason, LIRDebugInfo info, Object deoptInfo) { + protected LabelRef createDeoptStub(RiDeoptAction action, RiDeoptReason reason, LIRDebugInfo info, Object deoptInfo) { assert info.topFrame.bci >= 0 : "invalid bci for deopt framestate"; AMD64DeoptimizationStub stub = new AMD64DeoptimizationStub(action, reason, info, deoptInfo); lir.deoptimizationStubs.add(stub); diff -r e6a45067e42c -r dad1ac9dba7d graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/util/InliningUtil.java --- a/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/util/InliningUtil.java Thu Mar 15 17:01:44 2012 -0700 +++ b/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/util/InliningUtil.java Mon Mar 19 14:43:15 2012 -0700 @@ -175,7 +175,7 @@ ValueNode receiver = invoke.callTarget().receiver(); ReadHubNode objectClass = graph.add(new ReadHubNode(receiver)); IsTypeNode isTypeNode = graph.unique(new IsTypeNode(objectClass, type)); - FixedGuardNode guard = graph.add(new FixedGuardNode(isTypeNode, DeoptReason.TypeCheckedInliningViolated)); + FixedGuardNode guard = graph.add(new FixedGuardNode(isTypeNode, RiDeoptReason.TypeCheckedInliningViolated)); AnchorNode anchor = graph.add(new AnchorNode()); assert invoke.predecessor() != null; @@ -303,7 +303,7 @@ if (shouldFallbackToInvoke()) { unknownTypeNode = createInvocationBlock(graph, invoke, returnMerge, returnValuePhi, exceptionMerge, exceptionObjectPhi, 1, notRecordedTypeProbability, false); } else { - unknownTypeNode = graph.add(new DeoptimizeNode(DeoptAction.InvalidateReprofile, DeoptReason.TypeCheckedInliningViolated)); + unknownTypeNode = graph.add(new DeoptimizeNode(RiDeoptAction.InvalidateReprofile, RiDeoptReason.TypeCheckedInliningViolated)); } // replace the invoke exception edge @@ -368,7 +368,7 @@ ReadHubNode objectClassNode = graph.add(new ReadHubNode(invoke.callTarget().receiver())); graph.addBeforeFixed(invoke.node(), objectClassNode); - FixedNode unknownTypeNode = graph.add(new DeoptimizeNode(DeoptAction.InvalidateReprofile, DeoptReason.TypeCheckedInliningViolated)); + FixedNode unknownTypeNode = graph.add(new DeoptimizeNode(RiDeoptAction.InvalidateReprofile, RiDeoptReason.TypeCheckedInliningViolated)); FixedNode dispatchOnType = createDispatchOnType(graph, objectClassNode, new BeginNode[] {calleeEntryNode}, unknownTypeNode); FixedWithNextNode pred = (FixedWithNextNode) invoke.node().predecessor(); @@ -540,7 +540,7 @@ * @param callback a callback that is used to determine the weight of a specific inlining * @return an instance of InlineInfo, or null if no inlining is possible at the given invoke */ - public static InlineInfo getInlineInfo(Invoke invoke, int level, GraalRuntime runtime, CiAssumptions assumptions, InliningCallback callback, boolean allowTypeCheckedInlining) { + public static InlineInfo getInlineInfo(Invoke invoke, int level, GraalRuntime runtime, CiAssumptions assumptions, InliningCallback callback, OptimisticOptimizations optimisticOpts) { if (!checkInvokeConditions(invoke)) { return null; } @@ -591,15 +591,10 @@ } // type check based inlining - if (allowTypeCheckedInlining) { - return getTypeCheckedInlineInfo(invoke, level, callback, parent, targetMethod); - } else { - Debug.log("not inlining %s because type checked inlining is prohibited", methodName(targetMethod, invoke)); - return null; - } + return getTypeCheckedInlineInfo(invoke, level, callback, parent, targetMethod, optimisticOpts); } - private static InlineInfo getTypeCheckedInlineInfo(Invoke invoke, int level, InliningCallback callback, RiResolvedMethod parent, RiResolvedMethod targetMethod) { + private static InlineInfo getTypeCheckedInlineInfo(Invoke invoke, int level, InliningCallback callback, RiResolvedMethod parent, RiResolvedMethod targetMethod, OptimisticOptimizations optimisticOpts) { RiProfilingInfo profilingInfo = parent.profilingInfo(); RiTypeProfile typeProfile = profilingInfo.getTypeProfile(invoke.bci()); if (typeProfile != null) { @@ -610,7 +605,7 @@ assert types.length == probabilities.length : "length must match"; double notRecordedTypeProbability = typeProfile.getNotRecordedProbability(); if (types.length == 1 && notRecordedTypeProbability == 0) { - if (GraalOptions.InlineMonomorphicCalls) { + if (optimisticOpts.inlineMonomorphicCalls()) { RiResolvedType type = types[0]; RiResolvedMethod concrete = type.resolveMethodImpl(targetMethod); if (checkTargetConditions(invoke, concrete)) { @@ -626,7 +621,7 @@ } } else { invoke.setMegamorph(true); - if (GraalOptions.InlinePolymorphicCalls && notRecordedTypeProbability == 0 || GraalOptions.InlineMegamorphicCalls && notRecordedTypeProbability > 0) { + if (optimisticOpts.inlinePolymorphicCalls() && notRecordedTypeProbability == 0 || optimisticOpts.inlineMegamorphicCalls() && notRecordedTypeProbability > 0) { // TODO (chaeubl) inlining of multiple methods should work differently // 1. check which methods can be inlined // 2. for those methods, use weight and probability to compute which of them should be inlined @@ -666,7 +661,7 @@ return null; } } else { - if (!GraalOptions.InlinePolymorphicCalls && notRecordedTypeProbability == 0) { + if (!optimisticOpts.inlinePolymorphicCalls() && notRecordedTypeProbability == 0) { Debug.log("not inlining %s because GraalOptions.InlinePolymorphicCalls == false", methodName(targetMethod, invoke)); } else { Debug.log("not inlining %s because GraalOptions.InlineMegamorphicCalls == false", methodName(targetMethod, invoke)); @@ -820,7 +815,7 @@ } else { if (unwindNode != null) { UnwindNode unwindDuplicate = (UnwindNode) duplicates.get(unwindNode); - DeoptimizeNode deoptimizeNode = new DeoptimizeNode(DeoptAction.InvalidateRecompile, DeoptReason.NotCompiledExceptionHandler); + DeoptimizeNode deoptimizeNode = new DeoptimizeNode(RiDeoptAction.InvalidateRecompile, RiDeoptReason.NotCompiledExceptionHandler); unwindDuplicate.replaceAndDelete(graph.add(deoptimizeNode)); // move the deopt upwards if there is a monitor exit that tries to use the "after exception" frame state // (because there is no "after exception" frame state!) @@ -908,7 +903,7 @@ NodeInputList parameters = callTarget.arguments(); ValueNode firstParam = parameters.size() <= 0 ? null : parameters.get(0); if (!callTarget.isStatic() && firstParam.kind() == CiKind.Object && !firstParam.stamp().nonNull()) { - graph.addBeforeFixed(invoke.node(), graph.add(new FixedGuardNode(graph.unique(new NullCheckNode(firstParam, false)), DeoptReason.ClassCastException))); + graph.addBeforeFixed(invoke.node(), graph.add(new FixedGuardNode(graph.unique(new NullCheckNode(firstParam, false)), RiDeoptReason.ClassCastException))); } } } diff -r e6a45067e42c -r dad1ac9dba7d graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/util/ProfilingInfoConfiguration.java --- a/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/util/ProfilingInfoConfiguration.java Thu Mar 15 17:01:44 2012 -0700 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,51 +0,0 @@ -/* - * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package com.oracle.graal.compiler.util; - - -public final class ProfilingInfoConfiguration { - public static ProfilingInfoConfiguration ALL = new ProfilingInfoConfiguration(true, true, true); - public static ProfilingInfoConfiguration NONE = new ProfilingInfoConfiguration(false, false, false); - - private final boolean useBranchProbability; - private final boolean useTypeProfile; - private final boolean useExceptionSeen; - - public ProfilingInfoConfiguration(boolean useBranchProbability, boolean useTypeProfile, boolean useExceptionSeen) { - this.useBranchProbability = useBranchProbability; - this.useTypeProfile = useTypeProfile; - this.useExceptionSeen = useExceptionSeen; - } - - public boolean useBranchProbability() { - return useBranchProbability; - } - - public boolean useTypeProfile() { - return useTypeProfile; - } - - public boolean useExceptionProbability() { - return useExceptionSeen; - } -} diff -r e6a45067e42c -r dad1ac9dba7d 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 Thu Mar 15 17:01:44 2012 -0700 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotVMConfig.java Mon Mar 19 14:43:15 2012 -0700 @@ -76,6 +76,7 @@ // methodData information public int methodDataOopDataOffset; + public int methodDataOopTrapHistoryOffset; public int dataLayoutHeaderSize; public int dataLayoutTagOffset; public int dataLayoutFlagsOffset; diff -r e6a45067e42c -r dad1ac9dba7d graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/bridge/VMToCompilerImpl.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/bridge/VMToCompilerImpl.java Thu Mar 15 17:01:44 2012 -0700 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/bridge/VMToCompilerImpl.java Mon Mar 19 14:43:15 2012 -0700 @@ -27,13 +27,9 @@ import java.util.*; import java.util.concurrent.*; -import com.oracle.max.cri.ci.*; -import com.oracle.max.cri.ri.*; -import com.oracle.max.criutils.*; import com.oracle.graal.compiler.*; import com.oracle.graal.compiler.phases.*; import com.oracle.graal.compiler.phases.PhasePlan.PhasePosition; -import com.oracle.graal.compiler.util.*; import com.oracle.graal.debug.*; import com.oracle.graal.debug.internal.*; import com.oracle.graal.hotspot.*; @@ -44,6 +40,9 @@ import com.oracle.graal.java.*; import com.oracle.graal.nodes.*; import com.oracle.graal.snippets.*; +import com.oracle.max.cri.ci.*; +import com.oracle.max.cri.ri.*; +import com.oracle.max.criutils.*; /** * Exits from the HotSpot VM into Java code. @@ -300,8 +299,8 @@ public void run() { try { - final ProfilingInfoConfiguration profilingInfoConfig = new ProfilingInfoConfiguration(true, true, true); - final PhasePlan plan = createHotSpotSpecificPhasePlan(profilingInfoConfig); + final OptimisticOptimizations optimisticOpts = new OptimisticOptimizations(method); + final PhasePlan plan = createHotSpotSpecificPhasePlan(optimisticOpts); long startTime = System.nanoTime(); int index = compiledMethodCount++; final boolean printCompilation = GraalOptions.PrintCompilation && !TTY.isSuppressed(); @@ -317,7 +316,7 @@ @Override public CiTargetMethod call() throws Exception { StructuredGraph graph = new StructuredGraph(method); - return compiler.getCompiler().compileMethod(method, graph, -1, plan, profilingInfoConfig); + return compiler.getCompiler().compileMethod(method, graph, -1, plan, optimisticOpts); } }); } finally { @@ -450,9 +449,9 @@ return CiConstant.forObject(object); } - private PhasePlan createHotSpotSpecificPhasePlan(ProfilingInfoConfiguration profilingInfoConfig) { + private PhasePlan createHotSpotSpecificPhasePlan(OptimisticOptimizations optimisticOpts) { PhasePlan phasePlan = new PhasePlan(); - GraphBuilderPhase graphBuilderPhase = new GraphBuilderPhase(compiler.getRuntime(), GraphBuilderConfiguration.getDefault(), profilingInfoConfig); + GraphBuilderPhase graphBuilderPhase = new GraphBuilderPhase(compiler.getRuntime(), GraphBuilderConfiguration.getDefault(), optimisticOpts); phasePlan.addPhase(PhasePosition.AFTER_PARSING, graphBuilderPhase); if (GraalOptions.Intrinsify) { phasePlan.addPhase(PhasePosition.HIGH_LEVEL, intrinsifyArrayCopy); diff -r e6a45067e42c -r dad1ac9dba7d graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/ri/HotSpotMethodData.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/ri/HotSpotMethodData.java Thu Mar 15 17:01:44 2012 -0700 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/ri/HotSpotMethodData.java Mon Mar 19 14:43:15 2012 -0700 @@ -26,10 +26,10 @@ import sun.misc.*; -import com.oracle.max.cri.ri.*; import com.oracle.graal.compiler.*; import com.oracle.graal.hotspot.*; import com.oracle.graal.hotspot.Compiler; +import com.oracle.max.cri.ri.*; public final class HotSpotMethodData extends CompilerObject { @@ -80,6 +80,11 @@ return position >= 0 && position < normalDataSize + extraDataSize; } + public int getDeoptimizationCount(RiDeoptReason reason) { + int reasonIndex = compiler.getRuntime().convertDeoptReason(reason); + return unsafe.getByte(hotspotMirror, (long) config.methodDataOopTrapHistoryOffset + reasonIndex) & 0xFF; + } + public HotSpotMethodDataAccessor getNormalData(int position) { if (position >= normalDataSize) { return null; diff -r e6a45067e42c -r dad1ac9dba7d graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/ri/HotSpotMethodResolvedImpl.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/ri/HotSpotMethodResolvedImpl.java Thu Mar 15 17:01:44 2012 -0700 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/ri/HotSpotMethodResolvedImpl.java Mon Mar 19 14:43:15 2012 -0700 @@ -280,6 +280,17 @@ TTY.println(" not recorded (%f)", typeProfile.getNotRecordedProbability()); } } + + boolean firstDeoptReason = true; + for (RiDeoptReason reason: RiDeoptReason.values()) { + int count = profilingInfo.getDeoptimizationCount(reason); + if (count > 0) { + if (firstDeoptReason) { + TTY.println("Deopt Statistics"); + } + TTY.println(" %s: %d", reason.name(), count); + } + } } } diff -r e6a45067e42c -r dad1ac9dba7d graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/ri/HotSpotProfilingInfo.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/ri/HotSpotProfilingInfo.java Thu Mar 15 17:01:44 2012 -0700 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/ri/HotSpotProfilingInfo.java Mon Mar 19 14:43:15 2012 -0700 @@ -79,6 +79,11 @@ return dataAccessor.getExecutionCount(methodData, position); } + @Override + public int getDeoptimizationCount(RiDeoptReason reason) { + return methodData.getDeoptimizationCount(reason); + } + private void findBCI(int targetBCI, boolean searchExtraData) { assert targetBCI >= 0 : "invalid BCI"; diff -r e6a45067e42c -r dad1ac9dba7d graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/ri/HotSpotRuntime.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/ri/HotSpotRuntime.java Thu Mar 15 17:01:44 2012 -0700 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/ri/HotSpotRuntime.java Mon Mar 19 14:43:15 2012 -0700 @@ -25,18 +25,9 @@ import java.lang.reflect.*; import java.util.*; -import com.oracle.max.cri.ci.*; -import com.oracle.max.cri.ci.CiTargetMethod.Call; -import com.oracle.max.cri.ci.CiTargetMethod.DataPatch; -import com.oracle.max.cri.ci.CiTargetMethod.Safepoint; -import com.oracle.max.cri.ci.CiUtil.RefMapFormatter; -import com.oracle.max.cri.ri.*; -import com.oracle.max.cri.ri.RiType.Representation; -import com.oracle.max.criutils.*; import com.oracle.graal.compiler.*; import com.oracle.graal.compiler.phases.*; -import com.oracle.graal.compiler.phases.PhasePlan.*; -import com.oracle.graal.compiler.util.*; +import com.oracle.graal.compiler.phases.PhasePlan.PhasePosition; import com.oracle.graal.cri.*; import com.oracle.graal.graph.*; import com.oracle.graal.hotspot.*; @@ -48,6 +39,14 @@ import com.oracle.graal.nodes.extended.*; import com.oracle.graal.nodes.java.*; import com.oracle.graal.snippets.nodes.*; +import com.oracle.max.cri.ci.*; +import com.oracle.max.cri.ci.CiTargetMethod.Call; +import com.oracle.max.cri.ci.CiTargetMethod.DataPatch; +import com.oracle.max.cri.ci.CiTargetMethod.Safepoint; +import com.oracle.max.cri.ci.CiUtil.RefMapFormatter; +import com.oracle.max.cri.ri.*; +import com.oracle.max.cri.ri.RiType.Representation; +import com.oracle.max.criutils.*; /** * CRI runtime implementation for the HotSpot VM. @@ -229,7 +228,7 @@ int displacement = ((HotSpotField) field.field()).offset(); assert field.kind() != CiKind.Illegal; ReadNode memoryRead = graph.add(new ReadNode(field.field().kind(true).stackKind(), field.object(), LocationNode.create(field.field(), field.field().kind(true), displacement, graph))); - memoryRead.setGuard((GuardNode) tool.createGuard(graph.unique(new NullCheckNode(field.object(), false)), DeoptReason.NullCheckException)); + memoryRead.setGuard((GuardNode) tool.createGuard(graph.unique(new NullCheckNode(field.object(), false)), RiDeoptReason.NullCheckException)); graph.replaceFixedWithFixed(field, memoryRead); } else if (n instanceof StoreFieldNode) { StoreFieldNode storeField = (StoreFieldNode) n; @@ -238,7 +237,7 @@ } HotSpotField field = (HotSpotField) storeField.field(); WriteNode memoryWrite = graph.add(new WriteNode(storeField.object(), storeField.value(), LocationNode.create(storeField.field(), storeField.field().kind(true), field.offset(), graph))); - memoryWrite.setGuard((GuardNode) tool.createGuard(graph.unique(new NullCheckNode(storeField.object(), false)), DeoptReason.NullCheckException)); + memoryWrite.setGuard((GuardNode) tool.createGuard(graph.unique(new NullCheckNode(storeField.object(), false)), RiDeoptReason.NullCheckException)); memoryWrite.setStateAfter(storeField.stateAfter()); graph.replaceFixedWithFixed(storeField, memoryWrite); @@ -277,7 +276,7 @@ } else { AnchorNode anchor = graph.add(new AnchorNode()); graph.addBeforeFixed(storeIndexed, anchor); - GuardNode guard = (GuardNode) tool.createGuard(graph.unique(new NullCheckNode(array, false)), DeoptReason.NullCheckException); + GuardNode guard = (GuardNode) tool.createGuard(graph.unique(new NullCheckNode(array, false)), RiDeoptReason.NullCheckException); ReadNode arrayClass = graph.add(new ReadNode(CiKind.Object, array, LocationNode.create(LocationNode.FINAL_LOCATION, CiKind.Object, config.hubOffset, graph))); arrayClass.setGuard(guard); graph.addBeforeFixed(storeIndexed, arrayClass); @@ -300,7 +299,7 @@ IndexedLocationNode location = IndexedLocationNode.create(LocationNode.ANY_LOCATION, load.loadKind(), load.displacement(), load.offset(), graph); location.setIndexScalingEnabled(false); ReadNode memoryRead = graph.add(new ReadNode(load.kind(), load.object(), location)); - memoryRead.setGuard((GuardNode) tool.createGuard(graph.unique(new NullCheckNode(load.object(), false)), DeoptReason.NullCheckException)); + memoryRead.setGuard((GuardNode) tool.createGuard(graph.unique(new NullCheckNode(load.object(), false)), RiDeoptReason.NullCheckException)); graph.replaceFixedWithFixed(load, memoryRead); } else if (n instanceof UnsafeStoreNode) { UnsafeStoreNode store = (UnsafeStoreNode) n; @@ -318,7 +317,7 @@ ReadHubNode objectClassNode = (ReadHubNode) n; LocationNode location = LocationNode.create(LocationNode.FINAL_LOCATION, CiKind.Object, config.hubOffset, graph); ReadNode memoryRead = graph.add(new ReadNode(CiKind.Object, objectClassNode.object(), location)); - memoryRead.setGuard((GuardNode) tool.createGuard(graph.unique(new NullCheckNode(objectClassNode.object(), false)), DeoptReason.NullCheckException)); + memoryRead.setGuard((GuardNode) tool.createGuard(graph.unique(new NullCheckNode(objectClassNode.object(), false)), RiDeoptReason.NullCheckException)); graph.replaceFixed(objectClassNode, memoryRead); } } @@ -328,7 +327,7 @@ } private static GuardNode createBoundsCheck(AccessIndexedNode n, CiLoweringTool tool) { - return (GuardNode) tool.createGuard(n.graph().unique(new CompareNode(n.index(), Condition.BT, n.length())), DeoptReason.BoundsCheckException); + return (GuardNode) tool.createGuard(n.graph().unique(new CompareNode(n.index(), Condition.BT, n.length())), RiDeoptReason.BoundsCheckException); } @Override @@ -424,8 +423,50 @@ @Override public CiTargetMethod compile(RiResolvedMethod method, StructuredGraph graph) { final PhasePlan plan = new PhasePlan(); - GraphBuilderPhase graphBuilderPhase = new GraphBuilderPhase(compiler.getRuntime(), GraphBuilderConfiguration.getDefault(), ProfilingInfoConfiguration.ALL); + GraphBuilderPhase graphBuilderPhase = new GraphBuilderPhase(compiler.getRuntime(), GraphBuilderConfiguration.getDefault(), OptimisticOptimizations.ALL); plan.addPhase(PhasePosition.AFTER_PARSING, graphBuilderPhase); - return compiler.getCompiler().compileMethod(method, graph, -1, plan, ProfilingInfoConfiguration.ALL); + return compiler.getCompiler().compileMethod(method, graph, -1, plan, OptimisticOptimizations.ALL); + } + + @Override + public int encodeDeoptActionAndReason(RiDeoptAction action, RiDeoptReason reason) { + final int actionShift = 0; + final int reasonShift = 3; + + int actionValue = convertDeoptAction(action); + int reasonValue = convertDeoptReason(reason); + return (~(((reasonValue) << reasonShift) + ((actionValue) << actionShift))); + } + + @Override + public int convertDeoptAction(RiDeoptAction action) { + switch(action) { + case None: return 0; + case RecompileIfTooManyDeopts: return 1; + case InvalidateReprofile: return 2; + case InvalidateRecompile: return 3; + case InvalidateStopCompiling: return 4; + default: throw GraalInternalError.shouldNotReachHere(); + } + } + + @Override + public int convertDeoptReason(RiDeoptReason reason) { + switch(reason) { + case None: return 0; + case NullCheckException: return 1; + case BoundsCheckException: return 2; + case ClassCastException: return 3; + case ArrayStoreException: return 4; + case UnreachedCode: return 5; + case TypeCheckedInliningViolated: return 6; + case OptimizedTypeCheckViolated: return 7; + case NotCompiledExceptionHandler: return 8; + case Unresolved: return 9; + case JavaSubroutineMismatch: return 10; + case ArithmeticException: return 11; + case RuntimeConstraint: return 12; + default: throw GraalInternalError.shouldNotReachHere(); + } } } diff -r e6a45067e42c -r dad1ac9dba7d graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/ri/HotSpotXirGenerator.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/ri/HotSpotXirGenerator.java Thu Mar 15 17:01:44 2012 -0700 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/ri/HotSpotXirGenerator.java Mon Mar 19 14:43:15 2012 -0700 @@ -22,27 +22,29 @@ */ package com.oracle.graal.hotspot.ri; +import static com.oracle.graal.hotspot.ri.TemplateFlag.*; import static com.oracle.max.cri.ci.CiCallingConvention.Type.*; import static com.oracle.max.cri.ci.CiValueUtil.*; -import static com.oracle.graal.hotspot.ri.TemplateFlag.*; import java.lang.reflect.*; import java.util.*; import java.util.concurrent.*; -import com.oracle.max.asm.target.amd64.*; -import com.oracle.max.cri.ci.*; -import com.oracle.max.cri.ci.CiAddress.*; -import com.oracle.max.cri.ci.CiRegister.*; -import com.oracle.max.cri.ri.*; -import com.oracle.max.cri.ri.RiType.*; -import com.oracle.max.cri.xir.*; -import com.oracle.max.cri.xir.CiXirAssembler.*; import com.oracle.graal.compiler.*; -import com.oracle.graal.compiler.target.amd64.*; import com.oracle.graal.hotspot.*; import com.oracle.graal.hotspot.Compiler; -import com.oracle.graal.nodes.*; +import com.oracle.max.asm.target.amd64.*; +import com.oracle.max.cri.ci.CiAddress.Scale; +import com.oracle.max.cri.ci.*; +import com.oracle.max.cri.ci.CiRegister.RegisterFlag; +import com.oracle.max.cri.ri.*; +import com.oracle.max.cri.ri.RiType.Representation; +import com.oracle.max.cri.xir.*; +import com.oracle.max.cri.xir.CiXirAssembler.XirConstant; +import com.oracle.max.cri.xir.CiXirAssembler.XirLabel; +import com.oracle.max.cri.xir.CiXirAssembler.XirMark; +import com.oracle.max.cri.xir.CiXirAssembler.XirOperand; +import com.oracle.max.cri.xir.CiXirAssembler.XirParameter; public class HotSpotXirGenerator implements RiXirGenerator { @@ -75,6 +77,7 @@ private final RiRegisterConfig registerConfig; private final Compiler compiler; + private CiXirAssembler globalAsm; public HotSpotXirGenerator(HotSpotVMConfig config, CiTarget target, RiRegisterConfig registerConfig, Compiler compiler) { @@ -713,9 +716,9 @@ } } - DeoptReason deoptReason = is(EXACT_HINTS, flags) ? DeoptReason.OptimizedTypeCheckViolated : DeoptReason.ClassCastException; + RiDeoptReason deoptReason = is(EXACT_HINTS, flags) ? RiDeoptReason.OptimizedTypeCheckViolated : RiDeoptReason.ClassCastException; XirOperand scratch = asm.createRegisterTemp("scratch", target.wordKind, AMD64.r10); - asm.mov(scratch, wordConst(asm, AMD64DeoptimizationStub.encodeDeoptActionAndReason(DeoptAction.InvalidateReprofile, deoptReason))); + asm.mov(scratch, wordConst(asm, compiler.getRuntime().encodeDeoptActionAndReason(RiDeoptAction.InvalidateReprofile, deoptReason))); asm.callRuntime(CiRuntimeCall.Deoptimize, null); asm.shouldNotReachHere(); @@ -893,7 +896,7 @@ if (is(BOUNDS_CHECK, flags)) { asm.bindOutOfLine(failBoundsCheck); XirOperand scratch = asm.createRegisterTemp("scratch", target.wordKind, AMD64.r10); - asm.mov(scratch, wordConst(asm, AMD64DeoptimizationStub.encodeDeoptActionAndReason(DeoptAction.None, DeoptReason.BoundsCheckException))); + asm.mov(scratch, wordConst(asm, compiler.getRuntime().encodeDeoptActionAndReason(RiDeoptAction.None, RiDeoptReason.BoundsCheckException))); asm.callRuntime(CiRuntimeCall.Deoptimize, null); asm.shouldNotReachHere(); } @@ -1083,7 +1086,7 @@ checkSubtype(asm, temp, valueHub, compHub); asm.jneq(store, temp, wordConst(asm, 0)); XirOperand scratch = asm.createRegisterTemp("scratch", target.wordKind, AMD64.r10); - asm.mov(scratch, wordConst(asm, AMD64DeoptimizationStub.encodeDeoptActionAndReason(DeoptAction.None, DeoptReason.ClassCastException))); + asm.mov(scratch, wordConst(asm, compiler.getRuntime().encodeDeoptActionAndReason(RiDeoptAction.None, RiDeoptReason.ClassCastException))); asm.callRuntime(CiRuntimeCall.Deoptimize, null); asm.jmp(store); } @@ -1164,7 +1167,7 @@ if (is(BOUNDS_CHECK, flags)) { asm.bindOutOfLine(failBoundsCheck); XirOperand scratch = asm.createRegisterTemp("scratch", target.wordKind, AMD64.r10); - asm.mov(scratch, wordConst(asm, AMD64DeoptimizationStub.encodeDeoptActionAndReason(DeoptAction.None, DeoptReason.BoundsCheckException))); + asm.mov(scratch, wordConst(asm, compiler.getRuntime().encodeDeoptActionAndReason(RiDeoptAction.None, RiDeoptReason.BoundsCheckException))); asm.callRuntime(CiRuntimeCall.Deoptimize, null); asm.shouldNotReachHere(); } @@ -1174,7 +1177,7 @@ checkSubtype(asm, temp, valueHub, compHub); asm.jneq(store, temp, wordConst(asm, 0)); XirOperand scratch = asm.createRegisterTemp("scratch", target.wordKind, AMD64.r10); - asm.mov(scratch, wordConst(asm, AMD64DeoptimizationStub.encodeDeoptActionAndReason(DeoptAction.None, DeoptReason.ArrayStoreException))); + asm.mov(scratch, wordConst(asm, compiler.getRuntime().encodeDeoptActionAndReason(RiDeoptAction.None, RiDeoptReason.ArrayStoreException))); asm.callRuntime(CiRuntimeCall.Deoptimize, null); asm.shouldNotReachHere(); } diff -r e6a45067e42c -r dad1ac9dba7d graal/com.oracle.graal.java/src/com/oracle/graal/java/BciBlockMapping.java --- a/graal/com.oracle.graal.java/src/com/oracle/graal/java/BciBlockMapping.java Thu Mar 15 17:01:44 2012 -0700 +++ b/graal/com.oracle.graal.java/src/com/oracle/graal/java/BciBlockMapping.java Mon Mar 19 14:43:15 2012 -0700 @@ -27,7 +27,6 @@ import java.util.*; import com.oracle.graal.compiler.*; -import com.oracle.graal.compiler.util.*; import com.oracle.graal.debug.*; import com.oracle.graal.graph.*; import com.oracle.graal.java.bytecode.*; @@ -188,7 +187,7 @@ public boolean hasJsrBytecodes; public Block startBlock; - private final ProfilingInfoConfiguration profilingInfoConfig; + private final OptimisticOptimizations optimisticOpts; private final BytecodeStream stream; private final RiExceptionHandler[] exceptionHandlers; private Block[] blockMap; @@ -197,9 +196,9 @@ * Creates a new BlockMap instance from bytecode of the given method . * @param method the compiler interface method containing the code */ - public BciBlockMapping(RiResolvedMethod method, ProfilingInfoConfiguration profilingInfoConfig) { + public BciBlockMapping(RiResolvedMethod method, OptimisticOptimizations optimisticOpts) { this.method = method; - this.profilingInfoConfig = profilingInfoConfig; + this.optimisticOpts = optimisticOpts; exceptionHandlers = method.exceptionHandlers(); stream = new BytecodeStream(method.code()); this.blockMap = new Block[method.codeSize()]; @@ -377,7 +376,7 @@ case PUTFIELD: case GETFIELD: { if (GraalOptions.AllowExplicitExceptionChecks) { - if (!GraalOptions.UseExceptionProbability || !profilingInfoConfig.useExceptionProbability() || profilingInfo.getExceptionSeen(bci) != RiExceptionSeen.FALSE) { + if (!optimisticOpts.useExceptionProbability() || profilingInfo.getExceptionSeen(bci) != RiExceptionSeen.FALSE) { canTrap.set(bci); } } diff -r e6a45067e42c -r dad1ac9dba7d graal/com.oracle.graal.java/src/com/oracle/graal/java/GraphBuilderPhase.java --- a/graal/com.oracle.graal.java/src/com/oracle/graal/java/GraphBuilderPhase.java Thu Mar 15 17:01:44 2012 -0700 +++ b/graal/com.oracle.graal.java/src/com/oracle/graal/java/GraphBuilderPhase.java Mon Mar 19 14:43:15 2012 -0700 @@ -28,11 +28,6 @@ import java.lang.reflect.*; import java.util.*; - -import com.oracle.max.cri.ci.*; -import com.oracle.max.cri.ri.*; -import com.oracle.max.cri.ri.RiType.Representation; -import com.oracle.max.criutils.*; import com.oracle.graal.compiler.*; import com.oracle.graal.compiler.phases.*; import com.oracle.graal.compiler.util.*; @@ -48,6 +43,10 @@ import com.oracle.graal.nodes.java.*; import com.oracle.graal.nodes.java.MethodCallTargetNode.InvokeKind; import com.oracle.graal.nodes.type.*; +import com.oracle.max.cri.ci.*; +import com.oracle.max.cri.ri.*; +import com.oracle.max.cri.ri.RiType.Representation; +import com.oracle.max.criutils.*; /** * The {@code GraphBuilder} class parses the bytecode of a method and builds the IR graph. @@ -91,7 +90,7 @@ public static final Map cachedGraphs = new WeakHashMap<>(); private final GraphBuilderConfiguration graphBuilderConfig; - private final ProfilingInfoConfiguration profilingInfoConfig; + private final OptimisticOptimizations optimisticOpts; /** @@ -106,9 +105,9 @@ } } - public GraphBuilderPhase(RiRuntime runtime, GraphBuilderConfiguration graphBuilderConfig, ProfilingInfoConfiguration profilingInfoConfig) { + public GraphBuilderPhase(RiRuntime runtime, GraphBuilderConfiguration graphBuilderConfig, OptimisticOptimizations optimisticOpts) { this.graphBuilderConfig = graphBuilderConfig; - this.profilingInfoConfig = profilingInfoConfig; + this.optimisticOpts = optimisticOpts; this.runtime = runtime; this.log = GraalOptions.TraceBytecodeParserLevel > 0 ? new LogStream(TTY.out()) : null; } @@ -135,7 +134,7 @@ } private BciBlockMapping createBlockMap() { - BciBlockMapping map = new BciBlockMapping(method, profilingInfoConfig); + BciBlockMapping map = new BciBlockMapping(method, optimisticOpts); map.build(); Debug.dump(map, CiUtil.format("After block building %f %R %H.%n(%P)", method)); @@ -251,7 +250,7 @@ private BeginNode handleException(ValueNode exceptionObject, int bci) { assert bci == FrameState.BEFORE_BCI || bci == bci() : "invalid bci"; - if (GraalOptions.UseExceptionProbability && profilingInfoConfig.useExceptionProbability()) { + if (optimisticOpts.useExceptionProbability()) { // be conservative if information was not recorded (could result in endless recompiles otherwise) if (bci != FrameState.BEFORE_BCI && exceptionObject == null && profilingInfo.getExceptionSeen(bci) == RiExceptionSeen.FALSE) { return null; @@ -324,7 +323,7 @@ if (riType instanceof RiResolvedType) { frameState.push(CiKind.Object, append(ConstantNode.forCiConstant(((RiResolvedType) riType).getEncoding(Representation.JavaClass), runtime, currentGraph))); } else { - append(currentGraph.add(new DeoptimizeNode(DeoptAction.InvalidateRecompile, DeoptReason.Unresolved))); + append(currentGraph.add(new DeoptimizeNode(RiDeoptAction.InvalidateRecompile, RiDeoptReason.Unresolved))); frameState.push(CiKind.Object, append(ConstantNode.forObject(null, runtime, currentGraph))); } } else if (con instanceof CiConstant) { @@ -583,7 +582,7 @@ private void genThrow(int bci) { ValueNode exception = frameState.apop(); - FixedGuardNode node = currentGraph.add(new FixedGuardNode(currentGraph.unique(new NullCheckNode(exception, false)), DeoptReason.NullCheckException)); + FixedGuardNode node = currentGraph.add(new FixedGuardNode(currentGraph.unique(new NullCheckNode(exception, false)), RiDeoptReason.NullCheckException)); append(node); append(handleException(exception, bci)); } @@ -631,7 +630,7 @@ private static final RiResolvedType[] EMPTY_TYPE_ARRAY = new RiResolvedType[0]; private RiResolvedType[] getTypeCheckHints(RiResolvedType type, int maxHints) { - if (!GraalOptions.UseTypeCheckHints || !profilingInfoConfig.useTypeProfile() || Util.isFinalClass(type)) { + if (!optimisticOpts.useUseTypeCheckHints() || Util.isFinalClass(type)) { return new RiResolvedType[] {type}; } else { RiResolvedType uniqueSubtype = type.uniqueConcreteSubtype(); @@ -675,7 +674,7 @@ frameState.apush(checkCast); } else { ValueNode object = frameState.apop(); - append(currentGraph.add(new FixedGuardNode(currentGraph.unique(new CompareNode(object, Condition.EQ, ConstantNode.forObject(null, runtime, currentGraph))), DeoptReason.Unresolved))); + append(currentGraph.add(new FixedGuardNode(currentGraph.unique(new CompareNode(object, Condition.EQ, ConstantNode.forObject(null, runtime, currentGraph))), RiDeoptReason.Unresolved))); frameState.apush(appendConstant(CiConstant.NULL_OBJECT)); } } @@ -693,7 +692,7 @@ frameState.ipush(append(MaterializeNode.create(currentGraph.unique(instanceOfNode), currentGraph))); } else { BlockPlaceholderNode trueSucc = currentGraph.add(new BlockPlaceholderNode()); - DeoptimizeNode deopt = currentGraph.add(new DeoptimizeNode(DeoptAction.InvalidateRecompile, DeoptReason.Unresolved)); + DeoptimizeNode deopt = currentGraph.add(new DeoptimizeNode(RiDeoptAction.InvalidateRecompile, RiDeoptReason.Unresolved)); IfNode ifNode = currentGraph.add(new IfNode(currentGraph.unique(new NullCheckNode(object, true)), trueSucc, deopt, 1)); append(ifNode); lastInstr = trueSucc; @@ -707,7 +706,7 @@ NewInstanceNode n = currentGraph.add(new NewInstanceNode((RiResolvedType) type)); frameState.apush(append(n)); } else { - append(currentGraph.add(new DeoptimizeNode(DeoptAction.InvalidateRecompile, DeoptReason.Unresolved))); + append(currentGraph.add(new DeoptimizeNode(RiDeoptAction.InvalidateRecompile, RiDeoptReason.Unresolved))); frameState.apush(appendConstant(CiConstant.NULL_OBJECT)); } } @@ -748,7 +747,7 @@ NewArrayNode n = currentGraph.add(new NewObjectArrayNode((RiResolvedType) type, length)); frameState.apush(append(n)); } else { - append(currentGraph.add(new DeoptimizeNode(DeoptAction.InvalidateRecompile, DeoptReason.Unresolved))); + append(currentGraph.add(new DeoptimizeNode(RiDeoptAction.InvalidateRecompile, RiDeoptReason.Unresolved))); frameState.apush(appendConstant(CiConstant.NULL_OBJECT)); } @@ -765,7 +764,7 @@ FixedWithNextNode n = currentGraph.add(new NewMultiArrayNode((RiResolvedType) type, dims)); frameState.apush(append(n)); } else { - append(currentGraph.add(new DeoptimizeNode(DeoptAction.InvalidateRecompile, DeoptReason.Unresolved))); + append(currentGraph.add(new DeoptimizeNode(RiDeoptAction.InvalidateRecompile, RiDeoptReason.Unresolved))); frameState.apush(appendConstant(CiConstant.NULL_OBJECT)); } } @@ -779,7 +778,7 @@ LoadFieldNode load = currentGraph.add(new LoadFieldNode(receiver, (RiResolvedField) field)); appendOptimizedLoadField(kind, load); } else { - append(currentGraph.add(new DeoptimizeNode(DeoptAction.InvalidateRecompile, DeoptReason.Unresolved))); + append(currentGraph.add(new DeoptimizeNode(RiDeoptAction.InvalidateRecompile, RiDeoptReason.Unresolved))); frameState.push(kind.stackKind(), append(ConstantNode.defaultForKind(kind, currentGraph))); } } @@ -880,7 +879,7 @@ StoreFieldNode store = currentGraph.add(new StoreFieldNode(receiver, (RiResolvedField) field, value)); appendOptimizedStoreField(store); } else { - append(currentGraph.add(new DeoptimizeNode(DeoptAction.InvalidateRecompile, DeoptReason.Unresolved))); + append(currentGraph.add(new DeoptimizeNode(RiDeoptAction.InvalidateRecompile, RiDeoptReason.Unresolved))); } } @@ -922,7 +921,7 @@ if (initialized) { return appendConstant(((RiResolvedType) holder).getEncoding(representation)); } else { - append(currentGraph.add(new DeoptimizeNode(DeoptAction.InvalidateRecompile, DeoptReason.Unresolved))); + append(currentGraph.add(new DeoptimizeNode(RiDeoptAction.InvalidateRecompile, RiDeoptReason.Unresolved))); return null; } } @@ -983,7 +982,7 @@ } private void genInvokeDeopt(RiMethod unresolvedTarget, boolean withReceiver) { - append(currentGraph.add(new DeoptimizeNode(DeoptAction.InvalidateRecompile, DeoptReason.Unresolved))); + append(currentGraph.add(new DeoptimizeNode(RiDeoptAction.InvalidateRecompile, RiDeoptReason.Unresolved))); frameState.popArguments(unresolvedTarget.signature().argumentSlots(withReceiver), unresolvedTarget.signature().argumentCount(withReceiver)); CiKind kind = unresolvedTarget.signature().returnKind(false); if (kind != CiKind.Void) { @@ -1020,7 +1019,7 @@ private void appendInvoke(InvokeKind invokeKind, RiResolvedMethod targetMethod, ValueNode[] args) { CiKind resultType = targetMethod.signature().returnKind(false); if (GraalOptions.DeoptALot) { - DeoptimizeNode deoptimize = currentGraph.add(new DeoptimizeNode(DeoptAction.None, DeoptReason.RuntimeConstraint)); + DeoptimizeNode deoptimize = currentGraph.add(new DeoptimizeNode(RiDeoptAction.None, RiDeoptReason.RuntimeConstraint)); deoptimize.setMessage("invoke " + targetMethod.name()); append(deoptimize); frameState.pushReturn(resultType, ConstantNode.defaultForKind(resultType, currentGraph)); @@ -1109,7 +1108,7 @@ ValueNode local = frameState.loadLocal(localIndex); JsrScope scope = currentBlock.jsrScope; int retAddress = scope.nextReturnAddress(); - append(currentGraph.add(new FixedGuardNode(currentGraph.unique(new CompareNode(local, Condition.EQ, ConstantNode.forJsr(retAddress, currentGraph))), DeoptReason.JavaSubroutineMismatch))); + append(currentGraph.add(new FixedGuardNode(currentGraph.unique(new CompareNode(local, Condition.EQ, ConstantNode.forJsr(retAddress, currentGraph))), RiDeoptReason.JavaSubroutineMismatch))); if (!successor.jsrScope.equals(scope.pop())) { throw new JsrNotSupportedBailout("unstructured control flow (ret leaves more than one scope)"); } @@ -1194,8 +1193,8 @@ private FixedNode createTarget(double probability, Block block, FrameStateBuilder stateAfter) { assert probability >= 0 && probability <= 1; - if (probability == 0 && GraalOptions.RemoveNeverExecutedCode && profilingInfoConfig.useBranchProbability()) { - return currentGraph.add(new DeoptimizeNode(DeoptAction.InvalidateReprofile, DeoptReason.UnreachedCode)); + if (probability == 0 && optimisticOpts.removeNeverExecutedCode()) { + return currentGraph.add(new DeoptimizeNode(RiDeoptAction.InvalidateReprofile, RiDeoptReason.UnreachedCode)); } else { return createTarget(block, stateAfter); } diff -r e6a45067e42c -r dad1ac9dba7d graal/com.oracle.graal.nodes/src/com/oracle/graal/cri/CiLoweringTool.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/cri/CiLoweringTool.java Thu Mar 15 17:01:44 2012 -0700 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/cri/CiLoweringTool.java Mon Mar 19 14:43:15 2012 -0700 @@ -23,11 +23,11 @@ package com.oracle.graal.cri; import com.oracle.graal.graph.*; -import com.oracle.graal.nodes.*; +import com.oracle.max.cri.ri.*; public interface CiLoweringTool { GraalRuntime getRuntime(); Node getGuardAnchor(); - Node createGuard(Node condition, DeoptReason deoptReason); + Node createGuard(Node condition, RiDeoptReason deoptReason); } diff -r e6a45067e42c -r dad1ac9dba7d graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/DeoptAction.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/DeoptAction.java Thu Mar 15 17:01:44 2012 -0700 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,32 +0,0 @@ -/* - * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package com.oracle.graal.nodes; - - -public enum DeoptAction { - None, // just interpret, do not invalidate nmethod - RecompileIfTooManyDeopts, // recompile the nmethod; need not invalidate - InvalidateReprofile, // invalidate the nmethod, reset IC, maybe recompile - InvalidateRecompile, // invalidate the nmethod, recompile (probably) - InvalidateStopCompiling; // invalidate the nmethod and do not compile -} diff -r e6a45067e42c -r dad1ac9dba7d graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/DeoptReason.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/DeoptReason.java Thu Mar 15 17:01:44 2012 -0700 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,40 +0,0 @@ -/* - * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved. - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. - * - * This code is free software; you can redistribute it and/or modify it - * under the terms of the GNU General Public License version 2 only, as - * published by the Free Software Foundation. - * - * This code is distributed in the hope that it will be useful, but WITHOUT - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License - * version 2 for more details (a copy is included in the LICENSE file that - * accompanied this code). - * - * You should have received a copy of the GNU General Public License version - * 2 along with this work; if not, write to the Free Software Foundation, - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. - * - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA - * or visit www.oracle.com if you need additional information or have any - * questions. - */ -package com.oracle.graal.nodes; - - -public enum DeoptReason { - None, - NullCheckException, - BoundsCheckException, - ClassCastException, - ArrayStoreException, - UnreachedCode, - TypeCheckedInliningViolated, - OptimizedTypeCheckViolated, - NotCompiledExceptionHandler, - Unresolved, - JavaSubroutineMismatch, - ArithmeticException, - RuntimeConstraint; -} diff -r e6a45067e42c -r dad1ac9dba7d graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/DeoptimizeNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/DeoptimizeNode.java Thu Mar 15 17:01:44 2012 -0700 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/DeoptimizeNode.java Mon Mar 19 14:43:15 2012 -0700 @@ -25,15 +25,16 @@ import com.oracle.graal.graph.*; import com.oracle.graal.nodes.spi.*; import com.oracle.graal.nodes.type.*; +import com.oracle.max.cri.ri.*; @NodeInfo(shortName = "Deopt") public class DeoptimizeNode extends FixedNode implements Node.IterableNodeType, LIRLowerable { @Data private String message; - @Data private final DeoptAction action; - @Data private final DeoptReason reason; + @Data private final RiDeoptAction action; + @Data private final RiDeoptReason reason; - public DeoptimizeNode(DeoptAction action, DeoptReason reason) { + public DeoptimizeNode(RiDeoptAction action, RiDeoptReason reason) { super(StampFactory.illegal()); this.action = action; this.reason = reason; @@ -47,11 +48,11 @@ return message; } - public DeoptAction action() { + public RiDeoptAction action() { return action; } - public DeoptReason reason() { + public RiDeoptReason reason() { return reason; } diff -r e6a45067e42c -r dad1ac9dba7d graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/FixedGuardNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/FixedGuardNode.java Thu Mar 15 17:01:44 2012 -0700 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/FixedGuardNode.java Mon Mar 19 14:43:15 2012 -0700 @@ -26,13 +26,14 @@ import com.oracle.graal.graph.*; import com.oracle.graal.nodes.spi.*; import com.oracle.graal.nodes.type.*; +import com.oracle.max.cri.ri.*; public final class FixedGuardNode extends FixedWithNextNode implements Simplifiable, Lowerable, LIRLowerable { @Input private final NodeInputList conditions; - @Data private final DeoptReason deoptReason; + @Data private final RiDeoptReason deoptReason; - public FixedGuardNode(BooleanNode condition, DeoptReason deoptReason) { + public FixedGuardNode(BooleanNode condition, RiDeoptReason deoptReason) { super(StampFactory.illegal()); this.conditions = new NodeInputList<>(this, new BooleanNode[] {condition}); this.deoptReason = deoptReason; @@ -65,7 +66,7 @@ if (next != null) { tool.deleteBranch(next); } - setNext(graph().add(new DeoptimizeNode(DeoptAction.InvalidateRecompile, deoptReason))); + setNext(graph().add(new DeoptimizeNode(RiDeoptAction.InvalidateRecompile, deoptReason))); return; } } diff -r e6a45067e42c -r dad1ac9dba7d graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/GuardNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/GuardNode.java Thu Mar 15 17:01:44 2012 -0700 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/GuardNode.java Mon Mar 19 14:43:15 2012 -0700 @@ -25,12 +25,13 @@ import com.oracle.graal.nodes.calc.*; import com.oracle.graal.nodes.spi.*; import com.oracle.graal.nodes.type.*; +import com.oracle.max.cri.ri.*; public final class GuardNode extends FloatingNode implements Canonicalizable, LIRLowerable { @Input private BooleanNode condition; @Input(notDataflow = true) private FixedNode anchor; - @Data private DeoptReason reason; + @Data private RiDeoptReason reason; public FixedNode anchor() { return anchor; @@ -48,11 +49,11 @@ return condition; } - public DeoptReason reason() { + public RiDeoptReason reason() { return reason; } - public GuardNode(BooleanNode condition, FixedNode anchor, DeoptReason reason) { + public GuardNode(BooleanNode condition, FixedNode anchor, RiDeoptReason reason) { super(StampFactory.illegal()); this.condition = condition; this.anchor = anchor; diff -r e6a45067e42c -r dad1ac9dba7d graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/SafeReadNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/SafeReadNode.java Thu Mar 15 17:01:44 2012 -0700 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/SafeReadNode.java Mon Mar 19 14:43:15 2012 -0700 @@ -27,6 +27,7 @@ import com.oracle.graal.nodes.calc.*; import com.oracle.graal.nodes.spi.*; import com.oracle.max.cri.ci.*; +import com.oracle.max.cri.ri.*; public class SafeReadNode extends SafeAccessNode implements Lowerable { @@ -39,7 +40,7 @@ @Override public void lower(CiLoweringTool tool) { StructuredGraph graph = (StructuredGraph) graph(); - GuardNode guard = (GuardNode) tool.createGuard(graph.unique(new NullCheckNode(object(), false)), DeoptReason.NullCheckException); + GuardNode guard = (GuardNode) tool.createGuard(graph.unique(new NullCheckNode(object(), false)), RiDeoptReason.NullCheckException); ReadNode read = graph.add(new ReadNode(kind(), object(), location())); read.setGuard(guard); diff -r e6a45067e42c -r dad1ac9dba7d graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/SafeWriteNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/SafeWriteNode.java Thu Mar 15 17:01:44 2012 -0700 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/SafeWriteNode.java Mon Mar 19 14:43:15 2012 -0700 @@ -27,6 +27,7 @@ import com.oracle.graal.nodes.calc.*; import com.oracle.graal.nodes.spi.*; import com.oracle.max.cri.ci.*; +import com.oracle.max.cri.ri.*; public class SafeWriteNode extends SafeAccessNode implements Lowerable{ @@ -45,7 +46,7 @@ @Override public void lower(CiLoweringTool tool) { StructuredGraph graph = (StructuredGraph) graph(); - GuardNode guard = (GuardNode) tool.createGuard(graph.unique(new NullCheckNode(object(), false)), DeoptReason.NullCheckException); + GuardNode guard = (GuardNode) tool.createGuard(graph.unique(new NullCheckNode(object(), false)), RiDeoptReason.NullCheckException); WriteNode write = graph.add(new WriteNode(object(), value(), location())); write.setGuard(guard); graph.replaceFixedWithFixed(this, write); diff -r e6a45067e42c -r dad1ac9dba7d graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/spi/LIRGeneratorTool.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/spi/LIRGeneratorTool.java Thu Mar 15 17:01:44 2012 -0700 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/spi/LIRGeneratorTool.java Mon Mar 19 14:43:15 2012 -0700 @@ -27,6 +27,7 @@ import com.oracle.graal.nodes.extended.*; import com.oracle.graal.nodes.java.*; import com.oracle.max.cri.ci.*; +import com.oracle.max.cri.ri.*; public abstract class LIRGeneratorTool { public abstract CiTarget target(); @@ -78,12 +79,12 @@ public abstract CiValue emitConvert(ConvertNode.Op opcode, CiValue inputVal); public abstract void emitMembar(int barriers); - public abstract void emitDeoptimizeOn(Condition of, DeoptAction action, DeoptReason reason, Object deoptInfo); + public abstract void emitDeoptimizeOn(Condition of, RiDeoptAction action, RiDeoptReason reason, Object deoptInfo); public abstract CiValue emitCallToRuntime(CiRuntimeCall runtimeCall, boolean canTrap, CiValue... args); public abstract void emitIf(IfNode i); public abstract void emitConditional(ConditionalNode i); - public abstract void emitGuardCheck(BooleanNode comp, DeoptReason deoptReason); + public abstract void emitGuardCheck(BooleanNode comp, RiDeoptReason deoptReason); public abstract void emitLookupSwitch(LookupSwitchNode i); public abstract void emitTableSwitch(TableSwitchNode i); diff -r e6a45067e42c -r dad1ac9dba7d graal/com.oracle.graal.snippets/src/com/oracle/graal/snippets/Snippets.java --- a/graal/com.oracle.graal.snippets/src/com/oracle/graal/snippets/Snippets.java Thu Mar 15 17:01:44 2012 -0700 +++ b/graal/com.oracle.graal.snippets/src/com/oracle/graal/snippets/Snippets.java Mon Mar 19 14:43:15 2012 -0700 @@ -94,7 +94,7 @@ @Override public StructuredGraph call() throws Exception { GraphBuilderConfiguration config = GraphBuilderConfiguration.getSnippetDefault(); - GraphBuilderPhase graphBuilder = new GraphBuilderPhase(runtime, config, ProfilingInfoConfiguration.NONE); + GraphBuilderPhase graphBuilder = new GraphBuilderPhase(runtime, config, OptimisticOptimizations.NONE); StructuredGraph graph = new StructuredGraph(snippetRiMethod); graphBuilder.apply(graph); diff -r e6a45067e42c -r dad1ac9dba7d graal/com.oracle.graal.tests/src/com/oracle/graal/compiler/tests/BoxingEliminationTest.java --- a/graal/com.oracle.graal.tests/src/com/oracle/graal/compiler/tests/BoxingEliminationTest.java Thu Mar 15 17:01:44 2012 -0700 +++ b/graal/com.oracle.graal.tests/src/com/oracle/graal/compiler/tests/BoxingEliminationTest.java Mon Mar 19 14:43:15 2012 -0700 @@ -28,9 +28,9 @@ import org.junit.*; +import com.oracle.graal.compiler.*; import com.oracle.graal.compiler.phases.*; import com.oracle.graal.compiler.phases.PhasePlan.PhasePosition; -import com.oracle.graal.compiler.util.*; import com.oracle.graal.debug.*; import com.oracle.graal.graph.*; import com.oracle.graal.nodes.*; @@ -125,7 +125,7 @@ hints.add(invoke); } - new InliningPhase(null, runtime(), hints, null, phasePlan, ProfilingInfoConfiguration.ALL).apply(graph); + new InliningPhase(null, runtime(), hints, null, phasePlan, OptimisticOptimizations.ALL).apply(graph); new CanonicalizerPhase(null, runtime(), null).apply(graph); Debug.dump(graph, "Graph"); new BoxingEliminationPhase().apply(graph); diff -r e6a45067e42c -r dad1ac9dba7d graal/com.oracle.graal.tests/src/com/oracle/graal/compiler/tests/CompiledMethodTest.java --- a/graal/com.oracle.graal.tests/src/com/oracle/graal/compiler/tests/CompiledMethodTest.java Thu Mar 15 17:01:44 2012 -0700 +++ b/graal/com.oracle.graal.tests/src/com/oracle/graal/compiler/tests/CompiledMethodTest.java Mon Mar 19 14:43:15 2012 -0700 @@ -26,14 +26,14 @@ import org.junit.*; +import com.oracle.graal.compiler.*; +import com.oracle.graal.compiler.phases.*; +import com.oracle.graal.graph.*; +import com.oracle.graal.java.*; +import com.oracle.graal.nodes.*; import com.oracle.max.cri.ci.*; import com.oracle.max.cri.ri.*; import com.oracle.max.cri.ri.RiCompiledMethod.MethodInvalidatedException; -import com.oracle.graal.compiler.phases.*; -import com.oracle.graal.compiler.util.*; -import com.oracle.graal.graph.*; -import com.oracle.graal.java.*; -import com.oracle.graal.nodes.*; /** * In the following tests, the usages of local variable "a" are replaced with the integer constant 0. Then @@ -79,7 +79,7 @@ Method method = CompilableObjectImpl.class.getDeclaredMethod("executeHelper", ObjectCompiler.class, String.class); RiResolvedMethod riMethod = runtime.getRiMethod(method); StructuredGraph graph = new StructuredGraph(riMethod); - new GraphBuilderPhase(runtime, GraphBuilderConfiguration.getSnippetDefault(), ProfilingInfoConfiguration.NONE).apply(graph); + new GraphBuilderPhase(runtime, GraphBuilderConfiguration.getSnippetDefault(), OptimisticOptimizations.NONE).apply(graph); new CanonicalizerPhase(null, runtime, null).apply(graph); new DeadCodeEliminationPhase().apply(graph); diff -r e6a45067e42c -r dad1ac9dba7d graal/com.oracle.graal.tests/src/com/oracle/graal/compiler/tests/EscapeAnalysisTest.java --- a/graal/com.oracle.graal.tests/src/com/oracle/graal/compiler/tests/EscapeAnalysisTest.java Thu Mar 15 17:01:44 2012 -0700 +++ b/graal/com.oracle.graal.tests/src/com/oracle/graal/compiler/tests/EscapeAnalysisTest.java Mon Mar 19 14:43:15 2012 -0700 @@ -22,16 +22,16 @@ */ package com.oracle.graal.compiler.tests; -import junit.framework.*; +import junit.framework.Assert; import org.junit.Test; -import com.oracle.max.cri.ci.*; +import com.oracle.graal.compiler.*; import com.oracle.graal.compiler.phases.*; -import com.oracle.graal.compiler.util.*; import com.oracle.graal.debug.*; import com.oracle.graal.nodes.*; import com.oracle.graal.nodes.java.*; +import com.oracle.max.cri.ci.*; /** * In these test cases the probability of all invokes is set to a high value, such that an InliningPhase should inline them all. @@ -122,10 +122,10 @@ n.node().setProbability(100000); } - new InliningPhase(null, runtime(), null, null, getDefaultPhasePlan(), ProfilingInfoConfiguration.ALL).apply(graph); + new InliningPhase(null, runtime(), null, null, getDefaultPhasePlan(), OptimisticOptimizations.ALL).apply(graph); new DeadCodeEliminationPhase().apply(graph); Debug.dump(graph, "Graph"); - new EscapeAnalysisPhase(null, runtime(), null, getDefaultPhasePlan(), ProfilingInfoConfiguration.ALL).apply(graph); + new EscapeAnalysisPhase(null, runtime(), null, getDefaultPhasePlan(), OptimisticOptimizations.ALL).apply(graph); Debug.dump(graph, "Graph"); int retCount = 0; for (ReturnNode ret : graph.getNodes(ReturnNode.class)) { diff -r e6a45067e42c -r dad1ac9dba7d graal/com.oracle.graal.tests/src/com/oracle/graal/compiler/tests/GraphTest.java --- a/graal/com.oracle.graal.tests/src/com/oracle/graal/compiler/tests/GraphTest.java Thu Mar 15 17:01:44 2012 -0700 +++ b/graal/com.oracle.graal.tests/src/com/oracle/graal/compiler/tests/GraphTest.java Mon Mar 19 14:43:15 2012 -0700 @@ -24,16 +24,16 @@ import java.lang.reflect.*; -import junit.framework.Assert; +import junit.framework.*; -import com.oracle.max.cri.ri.*; +import com.oracle.graal.compiler.*; import com.oracle.graal.compiler.phases.*; -import com.oracle.graal.compiler.phases.PhasePlan.*; -import com.oracle.graal.compiler.util.*; +import com.oracle.graal.compiler.phases.PhasePlan.PhasePosition; import com.oracle.graal.cri.*; import com.oracle.graal.debug.*; import com.oracle.graal.java.*; import com.oracle.graal.nodes.*; +import com.oracle.max.cri.ri.*; /** * Base class for Graal compiler unit tests. These are white box tests @@ -110,7 +110,7 @@ protected StructuredGraph parse(Method m) { RiResolvedMethod riMethod = runtime.getRiMethod(m); StructuredGraph graph = new StructuredGraph(riMethod); - new GraphBuilderPhase(runtime, GraphBuilderConfiguration.getSnippetDefault(), ProfilingInfoConfiguration.NONE).apply(graph); + new GraphBuilderPhase(runtime, GraphBuilderConfiguration.getSnippetDefault(), OptimisticOptimizations.NONE).apply(graph); return graph; } @@ -120,13 +120,13 @@ protected StructuredGraph parseProfiled(Method m) { RiResolvedMethod riMethod = runtime.getRiMethod(m); StructuredGraph graph = new StructuredGraph(riMethod); - new GraphBuilderPhase(runtime, GraphBuilderConfiguration.getDefault(), ProfilingInfoConfiguration.ALL).apply(graph); + new GraphBuilderPhase(runtime, GraphBuilderConfiguration.getDefault(), OptimisticOptimizations.ALL).apply(graph); return graph; } protected PhasePlan getDefaultPhasePlan() { PhasePlan plan = new PhasePlan(); - plan.addPhase(PhasePosition.AFTER_PARSING, new GraphBuilderPhase(runtime, GraphBuilderConfiguration.getSnippetDefault(), ProfilingInfoConfiguration.NONE)); + plan.addPhase(PhasePosition.AFTER_PARSING, new GraphBuilderPhase(runtime, GraphBuilderConfiguration.getSnippetDefault(), OptimisticOptimizations.NONE)); return plan; } } diff -r e6a45067e42c -r dad1ac9dba7d graal/com.oracle.graal.tests/src/com/oracle/graal/compiler/tests/IfBoxingEliminationTest.java --- a/graal/com.oracle.graal.tests/src/com/oracle/graal/compiler/tests/IfBoxingEliminationTest.java Thu Mar 15 17:01:44 2012 -0700 +++ b/graal/com.oracle.graal.tests/src/com/oracle/graal/compiler/tests/IfBoxingEliminationTest.java Mon Mar 19 14:43:15 2012 -0700 @@ -26,9 +26,9 @@ import org.junit.*; +import com.oracle.graal.compiler.*; import com.oracle.graal.compiler.phases.*; import com.oracle.graal.compiler.phases.PhasePlan.PhasePosition; -import com.oracle.graal.compiler.util.*; import com.oracle.graal.debug.*; import com.oracle.graal.nodes.*; import com.oracle.graal.nodes.extended.*; @@ -85,7 +85,7 @@ for (Invoke invoke : graph.getInvokes()) { hints.add(invoke); } - new InliningPhase(null, runtime(), hints, null, phasePlan, ProfilingInfoConfiguration.ALL).apply(graph); + new InliningPhase(null, runtime(), hints, null, phasePlan, OptimisticOptimizations.ALL).apply(graph); new CanonicalizerPhase(null, runtime(), null).apply(graph); new PhiStampPhase().apply(graph); new CanonicalizerPhase(null, runtime(), null).apply(graph); diff -r e6a45067e42c -r dad1ac9dba7d graal/com.oracle.graal.tests/src/com/oracle/graal/compiler/tests/InvokeExceptionTest.java --- a/graal/com.oracle.graal.tests/src/com/oracle/graal/compiler/tests/InvokeExceptionTest.java Thu Mar 15 17:01:44 2012 -0700 +++ b/graal/com.oracle.graal.tests/src/com/oracle/graal/compiler/tests/InvokeExceptionTest.java Mon Mar 19 14:43:15 2012 -0700 @@ -26,8 +26,8 @@ import org.junit.*; +import com.oracle.graal.compiler.*; import com.oracle.graal.compiler.phases.*; -import com.oracle.graal.compiler.util.*; import com.oracle.graal.nodes.*; public class InvokeExceptionTest extends GraphTest { @@ -63,7 +63,7 @@ for (Invoke invoke : graph.getInvokes()) { hints.add(invoke); } - new InliningPhase(null, runtime(), hints, null, getDefaultPhasePlan(), ProfilingInfoConfiguration.ALL).apply(graph); + new InliningPhase(null, runtime(), hints, null, getDefaultPhasePlan(), OptimisticOptimizations.ALL).apply(graph); new CanonicalizerPhase(null, runtime(), null).apply(graph); new DeadCodeEliminationPhase().apply(graph); } diff -r e6a45067e42c -r dad1ac9dba7d graal/com.oracle.graal.tests/src/com/oracle/graal/compiler/tests/InvokeTest.java --- a/graal/com.oracle.graal.tests/src/com/oracle/graal/compiler/tests/InvokeTest.java Thu Mar 15 17:01:44 2012 -0700 +++ b/graal/com.oracle.graal.tests/src/com/oracle/graal/compiler/tests/InvokeTest.java Mon Mar 19 14:43:15 2012 -0700 @@ -28,8 +28,8 @@ import org.junit.*; +import com.oracle.graal.compiler.*; import com.oracle.graal.compiler.phases.*; -import com.oracle.graal.compiler.util.*; import com.oracle.graal.graph.*; import com.oracle.graal.nodes.*; @@ -82,7 +82,7 @@ for (Invoke invoke : graph.getInvokes()) { hints.add(invoke); } - new InliningPhase(null, runtime(), hints, null, getDefaultPhasePlan(), ProfilingInfoConfiguration.ALL).apply(graph); + new InliningPhase(null, runtime(), hints, null, getDefaultPhasePlan(), OptimisticOptimizations.ALL).apply(graph); new CanonicalizerPhase(null, runtime(), null).apply(graph); new DeadCodeEliminationPhase().apply(graph); StructuredGraph referenceGraph = parse(REFERENCE_SNIPPET); diff -r e6a45067e42c -r dad1ac9dba7d graal/com.oracle.graal.tests/src/com/oracle/graal/compiler/tests/MonitorTest.java --- a/graal/com.oracle.graal.tests/src/com/oracle/graal/compiler/tests/MonitorTest.java Thu Mar 15 17:01:44 2012 -0700 +++ b/graal/com.oracle.graal.tests/src/com/oracle/graal/compiler/tests/MonitorTest.java Mon Mar 19 14:43:15 2012 -0700 @@ -31,8 +31,8 @@ import org.junit.Assert; import org.junit.Test; +import com.oracle.graal.compiler.*; import com.oracle.graal.compiler.phases.*; -import com.oracle.graal.compiler.util.*; import com.oracle.graal.graph.*; import com.oracle.graal.graph.iterators.*; import com.oracle.graal.nodes.*; @@ -94,7 +94,7 @@ for (Invoke invoke : graph.getInvokes()) { hints.add(invoke); } - new InliningPhase(null, runtime(), hints, null, getDefaultPhasePlan(), ProfilingInfoConfiguration.ALL).apply(graph); + new InliningPhase(null, runtime(), hints, null, getDefaultPhasePlan(), OptimisticOptimizations.ALL).apply(graph); new CanonicalizerPhase(null, runtime(), null).apply(graph); new DeadCodeEliminationPhase().apply(graph); return graph; diff -r e6a45067e42c -r dad1ac9dba7d graal/com.oracle.max.cri/src/com/oracle/max/cri/ri/RiDeoptAction.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.max.cri/src/com/oracle/max/cri/ri/RiDeoptAction.java Mon Mar 19 14:43:15 2012 -0700 @@ -0,0 +1,32 @@ +/* + * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package com.oracle.max.cri.ri; + + +public enum RiDeoptAction { + None, // just interpret, do not invalidate nmethod + RecompileIfTooManyDeopts, // recompile the nmethod; need not invalidate + InvalidateReprofile, // invalidate the nmethod, reset IC, maybe recompile + InvalidateRecompile, // invalidate the nmethod, recompile (probably) + InvalidateStopCompiling; // invalidate the nmethod and do not compile +} diff -r e6a45067e42c -r dad1ac9dba7d graal/com.oracle.max.cri/src/com/oracle/max/cri/ri/RiDeoptReason.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.max.cri/src/com/oracle/max/cri/ri/RiDeoptReason.java Mon Mar 19 14:43:15 2012 -0700 @@ -0,0 +1,40 @@ +/* + * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package com.oracle.max.cri.ri; + + +public enum RiDeoptReason { + None, + NullCheckException, + BoundsCheckException, + ClassCastException, + ArrayStoreException, + UnreachedCode, + TypeCheckedInliningViolated, + OptimizedTypeCheckViolated, + NotCompiledExceptionHandler, + Unresolved, + JavaSubroutineMismatch, + ArithmeticException, + RuntimeConstraint; +} diff -r e6a45067e42c -r dad1ac9dba7d graal/com.oracle.max.cri/src/com/oracle/max/cri/ri/RiProfilingInfo.java --- a/graal/com.oracle.max.cri/src/com/oracle/max/cri/ri/RiProfilingInfo.java Thu Mar 15 17:01:44 2012 -0700 +++ b/graal/com.oracle.max.cri/src/com/oracle/max/cri/ri/RiProfilingInfo.java Mon Mar 19 14:43:15 2012 -0700 @@ -64,4 +64,12 @@ * @return the estimated execution count or -1 if not available. */ int getExecutionCount(int bci); + + /** + * Returns how frequently a method was deoptimized for the given deoptimization reason. This only indicates how + * often the method did fall back to the interpreter for the execution and does not indicate how often it was recompiled. + * @param reason the reason for which the number of deoptimizations should be queried + * @return the number of times the compiled method deoptimized for the given reason. + */ + int getDeoptimizationCount(RiDeoptReason reason); } diff -r e6a45067e42c -r dad1ac9dba7d graal/com.oracle.max.cri/src/com/oracle/max/cri/ri/RiRuntime.java --- a/graal/com.oracle.max.cri/src/com/oracle/max/cri/ri/RiRuntime.java Thu Mar 15 17:01:44 2012 -0700 +++ b/graal/com.oracle.max.cri/src/com/oracle/max/cri/ri/RiRuntime.java Mon Mar 19 14:43:15 2012 -0700 @@ -195,4 +195,22 @@ * @return a reference to the compiled and ready-to-run code */ RiCompiledMethod addMethod(RiResolvedMethod method, CiTargetMethod code); + + /** + * Encodes a deoptimization action and a deoptimization reason in an integer value. + * @return the encoded value as an integer + */ + int encodeDeoptActionAndReason(RiDeoptAction action, RiDeoptReason reason); + + /** + * Converts a RiDeoptReason into an integer value. + * @return An integer value representing the given RiDeoptReason. + */ + int convertDeoptReason(RiDeoptReason reason); + + /** + * Converts a RiDeoptAction into an integer value. + * @return An integer value representing the given RiDeoptAction. + */ + int convertDeoptAction(RiDeoptAction action); } diff -r e6a45067e42c -r dad1ac9dba7d graal/com.oracle.max.criutils/src/com/oracle/max/criutils/BaseProfilingInfo.java --- a/graal/com.oracle.max.criutils/src/com/oracle/max/criutils/BaseProfilingInfo.java Thu Mar 15 17:01:44 2012 -0700 +++ b/graal/com.oracle.max.criutils/src/com/oracle/max/criutils/BaseProfilingInfo.java Mon Mar 19 14:43:15 2012 -0700 @@ -70,4 +70,9 @@ public static RiProfilingInfo get(RiExceptionSeen exceptionSeen) { return NO_PROFILING_INFO[exceptionSeen.ordinal()]; } + + @Override + public int getDeoptimizationCount(RiDeoptReason reason) { + return 0; + } } diff -r e6a45067e42c -r dad1ac9dba7d src/share/vm/graal/graalCompilerToVM.cpp --- a/src/share/vm/graal/graalCompilerToVM.cpp Thu Mar 15 17:01:44 2012 -0700 +++ b/src/share/vm/graal/graalCompilerToVM.cpp Mon Mar 19 14:43:15 2012 -0700 @@ -775,6 +775,7 @@ set_int(env, config, "classMirrorOffset", in_bytes(Klass::java_mirror_offset())); set_int(env, config, "methodDataOopDataOffset", in_bytes(methodDataOopDesc::data_offset())); + set_int(env, config, "methodDataOopTrapHistoryOffset", in_bytes(methodDataOopDesc::trap_history_offset())); set_int(env, config, "dataLayoutHeaderSize", DataLayout::header_size_in_bytes()); set_int(env, config, "dataLayoutTagOffset", in_bytes(DataLayout::tag_offset())); set_int(env, config, "dataLayoutFlagsOffset", in_bytes(DataLayout::flags_offset())); diff -r e6a45067e42c -r dad1ac9dba7d src/share/vm/oops/methodDataOop.hpp --- a/src/share/vm/oops/methodDataOop.hpp Thu Mar 15 17:01:44 2012 -0700 +++ b/src/share/vm/oops/methodDataOop.hpp Mon Mar 19 14:43:15 2012 -0700 @@ -1485,17 +1485,13 @@ uint inc_trap_count(int reason) { // Count another trap, anywhere in this method. assert(reason >= 0, "must be single trap"); - if ((uint)reason < _trap_hist_limit) { - uint cnt1 = 1 + _trap_hist._array[reason]; - if ((cnt1 & _trap_hist_mask) != 0) { // if no counter overflow... - _trap_hist._array[reason] = cnt1; - return cnt1; - } else { - return _trap_hist_mask + (++_nof_overflow_traps); - } + assert((uint)reason < _trap_hist_limit, "oob"); + uint cnt1 = 1 + _trap_hist._array[reason]; + if ((cnt1 & _trap_hist_mask) != 0) { // if no counter overflow... + _trap_hist._array[reason] = cnt1; + return cnt1; } else { - // Could not represent the count in the histogram. - return (++_nof_overflow_traps); + return _trap_hist_mask + (++_nof_overflow_traps); } } @@ -1518,6 +1514,10 @@ return byte_offset_of(methodDataOopDesc, _data[0]); } + static ByteSize trap_history_offset() { + return byte_offset_of(methodDataOopDesc, _trap_hist._array); + } + static ByteSize invocation_counter_offset() { return byte_offset_of(methodDataOopDesc, _invocation_counter); } diff -r e6a45067e42c -r dad1ac9dba7d src/share/vm/runtime/deoptimization.cpp --- a/src/share/vm/runtime/deoptimization.cpp Thu Mar 15 17:01:44 2012 -0700 +++ b/src/share/vm/runtime/deoptimization.cpp Mon Mar 19 14:43:15 2012 -0700 @@ -1502,7 +1502,7 @@ uint this_trap_count = 0; bool maybe_prior_trap = false; bool maybe_prior_recompile = false; - pdata = query_update_method_data(trap_mdo, trap_bci, reason, + pdata = query_update_method_data(trap_mdo, trap_bci, reason, true, //outputs: this_trap_count, maybe_prior_trap, @@ -1636,25 +1636,31 @@ Deoptimization::query_update_method_data(methodDataHandle trap_mdo, int trap_bci, Deoptimization::DeoptReason reason, + bool update_total_trap_count, //outputs: uint& ret_this_trap_count, bool& ret_maybe_prior_trap, bool& ret_maybe_prior_recompile) { - uint prior_trap_count = trap_mdo->trap_count(reason); - uint this_trap_count = trap_mdo->inc_trap_count(reason); + bool maybe_prior_trap = false; + bool maybe_prior_recompile = false; + uint this_trap_count = 0; + if (update_total_trap_count) { + uint prior_trap_count = trap_mdo->trap_count(reason); + this_trap_count = trap_mdo->inc_trap_count(reason); - // If the runtime cannot find a place to store trap history, - // it is estimated based on the general condition of the method. - // If the method has ever been recompiled, or has ever incurred - // a trap with the present reason , then this BCI is assumed - // (pessimistically) to be the culprit. - bool maybe_prior_trap = (prior_trap_count != 0); - bool maybe_prior_recompile = (trap_mdo->decompile_count() != 0); - ProfileData* pdata = NULL; - + // If the runtime cannot find a place to store trap history, + // it is estimated based on the general condition of the method. + // If the method has ever been recompiled, or has ever incurred + // a trap with the present reason , then this BCI is assumed + // (pessimistically) to be the culprit. + maybe_prior_trap = (prior_trap_count != 0); + maybe_prior_recompile = (trap_mdo->decompile_count() != 0); + } // For reasons which are recorded per bytecode, we check per-BCI data. + ProfileData* pdata = NULL; DeoptReason per_bc_reason = reason_recorded_per_bytecode_if_any(reason); + assert(per_bc_reason != NULL || update_total_trap_count, "must be"); if (per_bc_reason != Reason_none) { // Find the profile data for this BCI. If there isn't one, // try to allocate one from the MDO's set of spares. @@ -1699,8 +1705,11 @@ uint ignore_this_trap_count; bool ignore_maybe_prior_trap; bool ignore_maybe_prior_recompile; + // Graal uses the total counts to determine if deoptimizations are happening too frequently -> do not adjust total counts + bool update_total_counts = IS_GRAAL(false) NOT_GRAAL(true); query_update_method_data(trap_mdo, trap_bci, (DeoptReason)reason, + update_total_counts, ignore_this_trap_count, ignore_maybe_prior_trap, ignore_maybe_prior_recompile); diff -r e6a45067e42c -r dad1ac9dba7d src/share/vm/runtime/deoptimization.hpp --- a/src/share/vm/runtime/deoptimization.hpp Thu Mar 15 17:01:44 2012 -0700 +++ b/src/share/vm/runtime/deoptimization.hpp Mon Mar 19 14:43:15 2012 -0700 @@ -42,7 +42,13 @@ #ifdef GRAAL Reason_many = -1, // indicates presence of several reasons Reason_none = 0, // indicates absence of a relevant deopt. - // Next 7 reasons are recorded per bytecode in DataLayout::trap_bits + // Next 7 reasons are recorded per bytecode in DataLayout::trap_bits. + // This is more complicated for Graal as Graal may deoptimize to *some* bytecode before the + // bytecode that actually caused the deopt (with inlining, Graal may even deoptimize to a + // bytecode in another method): + // - bytecode y in method b() causes deopt + // - Graal deoptimizes to bytecode x in method a() + // -> the deopt reason will be recorded for method a() at bytecode x Reason_null_check, Reason_range_check, Reason_class_check, @@ -382,6 +388,7 @@ static ProfileData* query_update_method_data(methodDataHandle trap_mdo, int trap_bci, DeoptReason reason, + bool update_total_trap_count, //outputs: uint& ret_this_trap_count, bool& ret_maybe_prior_trap, diff -r e6a45067e42c -r dad1ac9dba7d src/share/vm/utilities/macros.hpp --- a/src/share/vm/utilities/macros.hpp Thu Mar 15 17:01:44 2012 -0700 +++ b/src/share/vm/utilities/macros.hpp Mon Mar 19 14:43:15 2012 -0700 @@ -76,8 +76,10 @@ #ifdef GRAAL #define IS_GRAAL(code) code +#define NOT_GRAAL(code) #else #define IS_GRAAL(code) +#define NOT_GRAAL(code) code #endif #ifdef TIERED