# HG changeset patch # User Lukas Stadler # Date 1391016642 -3600 # Node ID 3e13ec26127842fc761e8eab11f9d5be0e3f238e # Parent 1be015fac5e3ef59f82d9cf0fd4ae990e842cfb8 later lowering of MonitorEnterNode and MonitorExitNode diff -r 1be015fac5e3 -r 3e13ec261278 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 18:32:19 2014 +0100 +++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/deopt/SynchronizedMethodDeoptimizationTest.java Wed Jan 29 18:30:42 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 1be015fac5e3 -r 3e13ec261278 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 18:32:19 2014 +0100 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotLoweringProvider.java Wed Jan 29 18:30:42 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 1be015fac5e3 -r 3e13ec261278 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 18:32:19 2014 +0100 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/MonitorSnippets.java Wed Jan 29 18:30:42 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 1be015fac5e3 -r 3e13ec261278 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 18:32:19 2014 +0100 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/AccessMonitorNode.java Wed Jan 29 18:30:42 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 1be015fac5e3 -r 3e13ec261278 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 18:32:19 2014 +0100 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/MonitorExitNode.java Wed Jan 29 18:30:42 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);