# HG changeset patch # User Christian Humer # Date 1391028994 -3600 # Node ID 460e453d6fecc62c92217dae900a7e3fd8e48679 # Parent f270f09616daca0fda0022939c3b09163837bc83# Parent 3e13ec26127842fc761e8eab11f9d5be0e3f238e Merge. diff -r f270f09616da -r 460e453d6fec graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/deopt/SynchronizedMethodDeoptimizationTest.java --- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/deopt/SynchronizedMethodDeoptimizationTest.java Wed Jan 29 21:26:26 2014 +0100 +++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/deopt/SynchronizedMethodDeoptimizationTest.java Wed Jan 29 21:56:34 2014 +0100 @@ -22,52 +22,29 @@ */ package com.oracle.graal.compiler.test.deopt; -import java.lang.reflect.*; - import org.junit.*; -import com.oracle.graal.api.code.*; -import com.oracle.graal.api.meta.*; import com.oracle.graal.compiler.test.*; -import com.oracle.graal.nodes.*; +import com.oracle.graal.compiler.test.ea.EATestBase.TestClassObject; /** * In the following tests, we try to deoptimize out of synchronized methods. */ public class SynchronizedMethodDeoptimizationTest extends GraalCompilerTest { - public static final int N = 15000; + public static final TestClassObject testObject = null; public static synchronized Object testMethodSynchronized(Object o) { if (o == null) { - return null; + // this branch will always deoptimize + return testObject.x; } return o; } @Test public void test1() { - Method method = getMethod("testMethodSynchronized"); - String testString = "test"; - for (int i = 0; i < N; ++i) { - Assert.assertEquals(testString, testMethodSynchronized(testString)); - } - final StructuredGraph graph = parseProfiled(method); - final ResolvedJavaMethod javaMethod = getMetaAccess().lookupJavaMethod(method); - InstalledCode compiledMethod = getCode(javaMethod, graph); - try { - Object result = compiledMethod.executeVarargs(testString); - Assert.assertEquals(testString, result); - } catch (InvalidInstalledCodeException t) { - Assert.fail("method invalidated"); - } - - try { - Object result = compiledMethod.executeVarargs(new Object[]{null}); - Assert.assertEquals(null, result); - Assert.assertFalse(compiledMethod.isValid()); - } catch (InvalidInstalledCodeException t) { - Assert.fail("method invalidated"); - } + test("testMethodSynchronized", "test"); + test("testMethodSynchronized", (Object) null); } } diff -r f270f09616da -r 460e453d6fec graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotLoweringProvider.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotLoweringProvider.java Wed Jan 29 21:26:26 2014 +0100 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotLoweringProvider.java Wed Jan 29 21:56:34 2014 +0100 @@ -282,7 +282,7 @@ write.setStateAfter(store.stateAfter()); graph.replaceFixedWithFixed(store, write); } else if (n instanceof LoadHubNode) { - if (graph.getGuardsStage().ordinal() == StructuredGraph.GuardsStage.FIXED_DEOPTS.ordinal()) { + if (graph.getGuardsStage().ordinal() >= StructuredGraph.GuardsStage.FIXED_DEOPTS.ordinal()) { LoadHubNode loadHub = (LoadHubNode) n; assert loadHub.kind() == wordKind; ValueNode object = loadHub.object(); @@ -443,11 +443,11 @@ newObjectSnippets.lower((DynamicNewArrayNode) n, registers, tool); } } else if (n instanceof MonitorEnterNode) { - if (graph.getGuardsStage() == StructuredGraph.GuardsStage.FIXED_DEOPTS) { + if (graph.getGuardsStage() == StructuredGraph.GuardsStage.AFTER_FSA) { monitorSnippets.lower((MonitorEnterNode) n, registers, tool); } } else if (n instanceof MonitorExitNode) { - if (graph.getGuardsStage() == StructuredGraph.GuardsStage.FIXED_DEOPTS) { + if (graph.getGuardsStage() == StructuredGraph.GuardsStage.AFTER_FSA) { monitorSnippets.lower((MonitorExitNode) n, tool); } } else if (n instanceof G1PreWriteBarrier) { diff -r f270f09616da -r 460e453d6fec graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/InstanceOfSnippets.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/InstanceOfSnippets.java Wed Jan 29 21:26:26 2014 +0100 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/InstanceOfSnippets.java Wed Jan 29 21:56:34 2014 +0100 @@ -230,7 +230,7 @@ Arguments args; StructuredGraph graph = instanceOf.graph(); - if (hintInfo.hintHitProbability >= hintHitProbabilityThresholdForDeoptimizingSnippet()) { + if (hintInfo.hintHitProbability >= hintHitProbabilityThresholdForDeoptimizingSnippet() && hintInfo.exact == null) { Hints hints = createHints(hintInfo, providers.getMetaAccess(), false, graph); args = new Arguments(instanceofWithProfile, graph.getGuardsStage(), tool.getLoweringStage()); args.add("object", object); @@ -256,7 +256,7 @@ } args.add("trueValue", replacer.trueValue); args.add("falseValue", replacer.falseValue); - if (hintInfo.hintHitProbability >= hintHitProbabilityThresholdForDeoptimizingSnippet()) { + if (hintInfo.hintHitProbability >= hintHitProbabilityThresholdForDeoptimizingSnippet() && hintInfo.exact == null) { args.addConst("nullSeen", hintInfo.profile.getNullSeen() != TriState.FALSE); } return args; diff -r f270f09616da -r 460e453d6fec graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/MonitorSnippets.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/MonitorSnippets.java Wed Jan 29 21:26:26 2014 +0100 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/MonitorSnippets.java Wed Jan 29 21:56:34 2014 +0100 @@ -34,7 +34,6 @@ import com.oracle.graal.api.code.*; import com.oracle.graal.api.meta.*; -import com.oracle.graal.graph.*; import com.oracle.graal.graph.Node.ConstantNodeParameter; import com.oracle.graal.graph.Node.NodeIntrinsic; import com.oracle.graal.graph.iterators.*; @@ -425,7 +424,6 @@ public void lower(MonitorEnterNode monitorenterNode, HotSpotRegistersProvider registers, LoweringTool tool) { StructuredGraph graph = monitorenterNode.graph(); checkBalancedMonitors(graph, tool); - FrameState stateAfter = monitorenterNode.stateAfter(); Arguments args; if (useFastLocking) { @@ -435,24 +433,15 @@ } args.add("object", monitorenterNode.object()); args.addConst("lockDepth", monitorenterNode.getMonitorId().getLockDepth()); - boolean tracingEnabledForMethod = stateAfter != null && (isTracingEnabledForMethod(stateAfter.method()) || isTracingEnabledForMethod(graph.method())); args.addConst("threadRegister", registers.getThreadRegister()); args.addConst("stackPointerRegister", registers.getStackPointerRegister()); - args.addConst("trace", isTracingEnabledForType(monitorenterNode.object()) || tracingEnabledForMethod); - - Map nodes = template(args).instantiate(providers.getMetaAccess(), monitorenterNode, DEFAULT_REPLACER, args); + args.addConst("trace", isTracingEnabledForType(monitorenterNode.object()) || isTracingEnabledForMethod(graph.method())); - for (Node n : nodes.values()) { - if (n instanceof BeginLockScopeNode) { - BeginLockScopeNode begin = (BeginLockScopeNode) n; - begin.setStateAfter(stateAfter); - } - } + template(args).instantiate(providers.getMetaAccess(), monitorenterNode, DEFAULT_REPLACER, args); } public void lower(MonitorExitNode monitorexitNode, LoweringTool tool) { StructuredGraph graph = monitorexitNode.graph(); - FrameState stateAfter = monitorexitNode.stateAfter(); Arguments args; if (useFastLocking) { @@ -462,16 +451,9 @@ } args.add("object", monitorexitNode.object()); args.addConst("lockDepth", monitorexitNode.getMonitorId().getLockDepth()); - args.addConst("trace", isTracingEnabledForType(monitorexitNode.object()) || isTracingEnabledForMethod(stateAfter.method()) || isTracingEnabledForMethod(graph.method())); - - Map nodes = template(args).instantiate(providers.getMetaAccess(), monitorexitNode, DEFAULT_REPLACER, args); + args.addConst("trace", isTracingEnabledForType(monitorexitNode.object()) || isTracingEnabledForMethod(graph.method())); - for (Node n : nodes.values()) { - if (n instanceof EndLockScopeNode) { - EndLockScopeNode end = (EndLockScopeNode) n; - end.setStateAfter(stateAfter); - } - } + template(args).instantiate(providers.getMetaAccess(), monitorexitNode, DEFAULT_REPLACER, args); } static boolean isTracingEnabledForType(ValueNode object) { diff -r f270f09616da -r 460e453d6fec 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 Wed Jan 29 21:26:26 2014 +0100 +++ b/graal/com.oracle.graal.java/src/com/oracle/graal/java/GraphBuilderPhase.java Wed Jan 29 21:56:34 2014 +0100 @@ -1067,15 +1067,6 @@ } } - private ConstantNode genTypeOrDeopt(Representation representation, JavaType type, boolean initialized) { - if (initialized) { - return appendConstant(((ResolvedJavaType) type).getEncoding(representation)); - } else { - handleUnresolvedExceptionType(representation, type); - return null; - } - } - private void appendOptimizedStoreField(StoreFieldNode store) { append(store); } @@ -1721,8 +1712,7 @@ } } - ConstantNode typeInstruction = genTypeOrDeopt(Representation.ObjectHub, catchType, initialized); - if (typeInstruction != null) { + if (initialized) { Block nextBlock = block.successors.size() == 1 ? unwindBlock(block.deoptBci) : block.successors.get(1); ValueNode exception = frameState.stackAt(0); CheckCastNode checkCast = currentGraph.add(new CheckCastNode((ResolvedJavaType) catchType, exception, null, false)); @@ -1734,6 +1724,8 @@ FixedNode nextDispatch = createTarget(nextBlock, frameState); checkCast.setNext(catchSuccessor); append(new IfNode(currentGraph.unique(new InstanceOfNode((ResolvedJavaType) catchType, exception, null)), checkCast, nextDispatch, 0.5)); + } else { + handleUnresolvedExceptionType(Representation.ObjectHub, catchType); } } diff -r f270f09616da -r 460e453d6fec 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 Wed Jan 29 21:26:26 2014 +0100 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/FixedGuardNode.java Wed Jan 29 21:56:34 2014 +0100 @@ -51,7 +51,7 @@ tool.deleteBranch(next); } - DeoptimizeNode deopt = graph().add(new DeoptimizeNode(DeoptimizationAction.InvalidateRecompile, getReason())); + DeoptimizeNode deopt = graph().add(new DeoptimizeNode(getAction(), getReason())); deopt.setDeoptimizationState(getDeoptimizationState()); setNext(deopt); } diff -r f270f09616da -r 460e453d6fec graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/AccessMonitorNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/AccessMonitorNode.java Wed Jan 29 21:26:26 2014 +0100 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/AccessMonitorNode.java Wed Jan 29 21:56:34 2014 +0100 @@ -33,11 +33,34 @@ * The Java bytecode specification allows non-balanced locking. Graal does not handle such cases and * throws a {@link BailoutException} instead during graph building. */ -public abstract class AccessMonitorNode extends AbstractMemoryCheckpoint implements MemoryCheckpoint { +public abstract class AccessMonitorNode extends AbstractMemoryCheckpoint implements MemoryCheckpoint, DeoptimizingNode { + @Input private FrameState deoptState; @Input private ValueNode object; @Input private MonitorIdNode monitorId; + @Override + public boolean canDeoptimize() { + return true; + } + + @Override + public FrameState getDeoptimizationState() { + return deoptState; + } + + @Override + public void setDeoptimizationState(FrameState f) { + updateUsages(deoptState, f); + deoptState = f; + } + + @Override + public FrameState getState() { + assert deoptState == null || stateAfter() == null; + return deoptState == null ? stateAfter() : deoptState; + } + public ValueNode object() { return object; } diff -r f270f09616da -r 460e453d6fec graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/MonitorExitNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/MonitorExitNode.java Wed Jan 29 21:26:26 2014 +0100 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/MonitorExitNode.java Wed Jan 29 21:56:34 2014 +0100 @@ -58,7 +58,7 @@ @Override public void simplify(SimplifierTool tool) { - if (escapedReturnValue != null && stateAfter().bci != FrameState.AFTER_BCI) { + if (escapedReturnValue != null && stateAfter() != null && stateAfter().bci != FrameState.AFTER_BCI) { ValueNode returnValue = escapedReturnValue; setEscapedReturnValue(null); tool.removeIfUnused(returnValue); diff -r f270f09616da -r 460e453d6fec graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/ConditionalEliminationPhase.java --- a/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/ConditionalEliminationPhase.java Wed Jan 29 21:26:26 2014 +0100 +++ b/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/ConditionalEliminationPhase.java Wed Jan 29 21:56:34 2014 +0100 @@ -626,7 +626,7 @@ if (type != ObjectStamp.typeOrNull(receiver)) { ResolvedJavaMethod method = type.resolveMethod(callTarget.targetMethod()); if (method != null) { - if ((method.getModifiers() & Modifier.FINAL) != 0 || (type.getModifiers() & Modifier.FINAL) != 0) { + if (Modifier.isFinal(method.getModifiers()) || Modifier.isFinal(type.getModifiers())) { callTarget.setInvokeKind(InvokeKind.Special); callTarget.setTargetMethod(method); } diff -r f270f09616da -r 460e453d6fec graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/TruffleCompilerImpl.java --- a/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/TruffleCompilerImpl.java Wed Jan 29 21:26:26 2014 +0100 +++ b/graal/com.oracle.graal.truffle/src/com/oracle/graal/truffle/TruffleCompilerImpl.java Wed Jan 29 21:56:34 2014 +0100 @@ -69,10 +69,11 @@ private final TruffleCache truffleCache; private final ThreadPoolExecutor compileQueue; - private static final Class[] SKIPPED_EXCEPTION_CLASSES = new Class[]{SlowPathException.class, UnexpectedResultException.class, ArithmeticException.class}; + private static final Class[] SKIPPED_EXCEPTION_CLASSES = new Class[]{UnexpectedResultException.class, SlowPathException.class, ArithmeticException.class}; public static final OptimisticOptimizations Optimizations = OptimisticOptimizations.ALL.remove(OptimisticOptimizations.Optimization.UseExceptionProbability, OptimisticOptimizations.Optimization.RemoveNeverExecutedCode, OptimisticOptimizations.Optimization.UseTypeCheckedInlining, OptimisticOptimizations.Optimization.UseTypeCheckHints); + private static final OptimisticOptimizations OptimizationsGraal = OptimisticOptimizations.ALL.remove(OptimisticOptimizations.Optimization.UseExceptionProbability); public TruffleCompilerImpl() { this.runtime = Graal.getRequiredCapability(RuntimeProvider.class); @@ -224,8 +225,8 @@ CodeCacheProvider codeCache = providers.getCodeCache(); CallingConvention cc = getCallingConvention(codeCache, Type.JavaCallee, graph.method(), false); CompilationResult compilationResult = new CompilationResult(name); - result = compileGraph(graph, cc, graph.method(), providers, backend, codeCache.getTarget(), null, createGraphBuilderSuite(), OptimisticOptimizations.ALL, getProfilingInfo(graph), - speculationLog, suites, false, compilationResult, CompilationResultBuilderFactory.Default); + result = compileGraph(graph, cc, graph.method(), providers, backend, codeCache.getTarget(), null, createGraphBuilderSuite(), OptimizationsGraal, getProfilingInfo(graph), speculationLog, + suites, false, compilationResult, CompilationResultBuilderFactory.Default); } catch (Throwable e) { throw Debug.handle(e); }