changeset 21763:1ab2c7bb6f0f

Split MonitorEnterNode into RawMonitorEnterNode, null check, and hub load.
author Thomas Wuerthinger <thomas.wuerthinger@oracle.com>
date Sat, 06 Jun 2015 22:19:26 +0200
parents 1025d6dc645a
children cb6d65bcc8cb
files graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/LockEliminationTest.java graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/DefaultHotSpotLoweringProvider.java graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/MonitorSnippets.java graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/LoadHubNode.java graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/RawMonitorEnterNode.java graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/LockEliminationPhase.java graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/DefaultJavaLoweringProvider.java graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/SnippetTemplate.java
diffstat 8 files changed, 125 insertions(+), 22 deletions(-) [+]
line wrap: on
line diff
--- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/LockEliminationTest.java	Sat Jun 06 15:13:09 2015 +0200
+++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/LockEliminationTest.java	Sat Jun 06 22:19:26 2015 +0200
@@ -63,7 +63,7 @@
         StructuredGraph graph = getGraph("testSynchronizedSnippet");
         new CanonicalizerPhase().apply(graph, new PhaseContext(getProviders()));
         new LockEliminationPhase().apply(graph);
-        assertDeepEquals(1, graph.getNodes().filter(MonitorEnterNode.class).count());
+        assertDeepEquals(1, graph.getNodes().filter(RawMonitorEnterNode.class).count());
         assertDeepEquals(1, graph.getNodes().filter(MonitorExitNode.class).count());
     }
 
@@ -81,7 +81,7 @@
         StructuredGraph graph = getGraph("testSynchronizedMethodSnippet");
         new CanonicalizerPhase().apply(graph, new PhaseContext(getProviders()));
         new LockEliminationPhase().apply(graph);
-        assertDeepEquals(1, graph.getNodes().filter(MonitorEnterNode.class).count());
+        assertDeepEquals(1, graph.getNodes().filter(RawMonitorEnterNode.class).count());
         assertDeepEquals(1, graph.getNodes().filter(MonitorExitNode.class).count());
     }
 
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/DefaultHotSpotLoweringProvider.java	Sat Jun 06 15:13:09 2015 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/DefaultHotSpotLoweringProvider.java	Sat Jun 06 22:19:26 2015 +0200
@@ -155,9 +155,9 @@
             if (graph.getGuardsStage().areFrameStatesAtDeopts()) {
                 newObjectSnippets.lower((VerifyHeapNode) n, registers, runtime, tool);
             }
-        } else if (n instanceof MonitorEnterNode) {
+        } else if (n instanceof RawMonitorEnterNode) {
             if (graph.getGuardsStage().areFrameStatesAtDeopts()) {
-                monitorSnippets.lower((MonitorEnterNode) n, registers, tool);
+                monitorSnippets.lower((RawMonitorEnterNode) n, registers, tool);
             }
         } else if (n instanceof MonitorExitNode) {
             if (graph.getGuardsStage().areFrameStatesAtDeopts()) {
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/MonitorSnippets.java	Sat Jun 06 15:13:09 2015 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/MonitorSnippets.java	Sat Jun 06 22:19:26 2015 +0200
@@ -46,6 +46,7 @@
 import java.util.*;
 
 import com.oracle.graal.api.replacements.*;
+import com.oracle.graal.compiler.common.type.*;
 import com.oracle.graal.graph.Node.ConstantNodeParameter;
 import com.oracle.graal.graph.Node.NodeIntrinsic;
 import com.oracle.graal.graph.iterators.*;
@@ -107,15 +108,10 @@
     public static final boolean CHECK_BALANCED_MONITORS = Boolean.getBoolean("graal.monitors.checkBalanced");
 
     @Snippet
-    public static void monitorenter(Object object, @ConstantParameter int lockDepth, @ConstantParameter Register threadRegister, @ConstantParameter Register stackPointerRegister,
+    public static void monitorenter(Object object, KlassPointer hub, @ConstantParameter int lockDepth, @ConstantParameter Register threadRegister, @ConstantParameter Register stackPointerRegister,
                     @ConstantParameter boolean trace) {
         verifyOop(object);
 
-        if (object == null) {
-            DeoptimizeNode.deopt(DeoptimizationAction.InvalidateReprofile, DeoptimizationReason.NullCheckException);
-        }
-        GuardingNode anchorNode = SnippetAnchorNode.anchor();
-
         // Load the mark word - this includes a null-check on object
         final Word mark = loadWordFromObject(object, markOffset());
 
@@ -141,7 +137,6 @@
             } else {
                 // The bias pattern is present in the object's mark word. Need to check
                 // whether the bias owner and the epoch are both still current.
-                KlassPointer hub = loadHubIntrinsic(object, anchorNode);
                 final Word prototypeMarkWord = hub.readWord(prototypeMarkWordOffset(), PROTOTYPE_MARK_WORD_LOCATION);
                 final Word thread = registerAsWord(threadRegister);
                 final Word tmp = prototypeMarkWord.or(thread).xor(mark).and(~ageMaskInPlace());
@@ -445,10 +440,12 @@
             this.useFastLocking = useFastLocking;
         }
 
-        public void lower(MonitorEnterNode monitorenterNode, HotSpotRegistersProvider registers, LoweringTool tool) {
+        public void lower(RawMonitorEnterNode monitorenterNode, HotSpotRegistersProvider registers, LoweringTool tool) {
             StructuredGraph graph = monitorenterNode.graph();
             checkBalancedMonitors(graph, tool);
 
+            assert ((ObjectStamp) monitorenterNode.object().stamp()).nonNull();
+
             Arguments args;
             if (useFastLocking) {
                 args = new Arguments(monitorenter, graph.getGuardsStage(), tool.getLoweringStage());
@@ -456,6 +453,7 @@
                 args = new Arguments(monitorenterStub, graph.getGuardsStage(), tool.getLoweringStage());
             }
             args.add("object", monitorenterNode.object());
+            args.add("hub", monitorenterNode.getHub());
             args.addConst("lockDepth", monitorenterNode.getMonitorId().getLockDepth());
             args.addConst("threadRegister", registers.getThreadRegister());
             args.addConst("stackPointerRegister", registers.getStackPointerRegister());
--- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/LoadHubNode.java	Sat Jun 06 15:13:09 2015 +0200
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/LoadHubNode.java	Sat Jun 06 22:19:26 2015 +0200
@@ -49,6 +49,15 @@
         return stampProvider.createHubStamp(((ObjectStamp) value.stamp()));
     }
 
+    public static ValueNode create(ValueNode value, StampProvider stampProvider, MetaAccessProvider metaAccess) {
+        Stamp stamp = hubStamp(stampProvider, value);
+        ValueNode synonym = findSynonym(value, stamp, null, metaAccess);
+        if (synonym != null) {
+            return synonym;
+        }
+        return new LoadHubNode(stamp, value, null);
+    }
+
     public LoadHubNode(@InjectedNodeParameter StampProvider stampProvider, ValueNode value) {
         this(stampProvider, value, null);
     }
@@ -74,25 +83,33 @@
     @Override
     public ValueNode canonical(CanonicalizerTool tool) {
         MetaAccessProvider metaAccess = tool.getMetaAccess();
-        if (metaAccess != null && getValue().stamp() instanceof ObjectStamp) {
-            ObjectStamp objectStamp = (ObjectStamp) getValue().stamp();
+        ValueNode curValue = getValue();
+        ValueNode newNode = findSynonym(curValue, stamp(), graph(), metaAccess);
+        if (newNode != null) {
+            return newNode;
+        }
+        return this;
+    }
 
+    private static ValueNode findSynonym(ValueNode curValue, Stamp stamp, StructuredGraph graph, MetaAccessProvider metaAccess) {
+        if (metaAccess != null && curValue.stamp() instanceof ObjectStamp) {
+            ObjectStamp objectStamp = (ObjectStamp) curValue.stamp();
             ResolvedJavaType exactType = null;
             if (objectStamp.isExactType()) {
                 exactType = objectStamp.type();
-            } else if (objectStamp.type() != null && graph() != null && graph().getAssumptions() != null) {
+            } else if (objectStamp.type() != null && graph != null && graph.getAssumptions() != null) {
                 AssumptionResult<ResolvedJavaType> leafConcreteSubtype = objectStamp.type().findLeafConcreteSubtype();
                 if (leafConcreteSubtype != null) {
                     exactType = leafConcreteSubtype.getResult();
-                    graph().getAssumptions().record(leafConcreteSubtype);
+                    graph.getAssumptions().record(leafConcreteSubtype);
                 }
             }
 
             if (exactType != null) {
-                return ConstantNode.forConstant(stamp(), exactType.getObjectHub(), metaAccess);
+                return ConstantNode.forConstant(stamp, exactType.getObjectHub(), metaAccess);
             }
         }
-        return this;
+        return null;
     }
 
     @Override
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/RawMonitorEnterNode.java	Sat Jun 06 22:19:26 2015 +0200
@@ -0,0 +1,73 @@
+/*
+ * Copyright (c) 2009, 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.graal.nodes.java;
+
+import com.oracle.graal.compiler.common.type.*;
+import com.oracle.graal.graph.*;
+import com.oracle.graal.nodeinfo.*;
+import com.oracle.graal.nodes.*;
+import com.oracle.graal.nodes.extended.*;
+import com.oracle.graal.nodes.memory.*;
+import com.oracle.graal.nodes.spi.*;
+import com.oracle.jvmci.meta.*;
+
+/**
+ * The {@code MonitorEnterNode} represents the acquisition of a monitor. The object needs already be
+ * non-null and the hub is an additional parameter to the node.
+ */
+@NodeInfo
+public final class RawMonitorEnterNode extends AccessMonitorNode implements Virtualizable, Lowerable, IterableNodeType, MonitorEnter, MemoryCheckpoint.Single {
+
+    public static final NodeClass<RawMonitorEnterNode> TYPE = NodeClass.create(RawMonitorEnterNode.class);
+
+    @Input ValueNode hub;
+
+    public RawMonitorEnterNode(ValueNode object, ValueNode hub, MonitorIdNode monitorId) {
+        super(TYPE, object, monitorId);
+        assert ((ObjectStamp) object.stamp()).nonNull();
+        this.hub = hub;
+    }
+
+    @Override
+    public LocationIdentity getLocationIdentity() {
+        return LocationIdentity.any();
+    }
+
+    @Override
+    public void lower(LoweringTool tool) {
+        tool.getLowerer().lower(this, tool);
+    }
+
+    @Override
+    public void virtualize(VirtualizerTool tool) {
+        State state = tool.getObjectState(object());
+        if (state != null && state.getState() == EscapeState.Virtual && state.getVirtualObject().hasIdentity()) {
+            state.addLock(getMonitorId());
+            tool.delete();
+        }
+    }
+
+    public ValueNode getHub() {
+        return hub;
+    }
+}
--- a/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/LockEliminationPhase.java	Sat Jun 06 15:13:09 2015 +0200
+++ b/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/LockEliminationPhase.java	Sat Jun 06 22:19:26 2015 +0200
@@ -33,9 +33,9 @@
     protected void run(StructuredGraph graph) {
         for (MonitorExitNode node : graph.getNodes(MonitorExitNode.TYPE)) {
             FixedNode next = node.next();
-            if (next instanceof MonitorEnterNode) {
-                MonitorEnterNode monitorEnterNode = (MonitorEnterNode) next;
-                if (monitorEnterNode.object() == node.object()) {
+            if (next instanceof MonitorEnterNode || next instanceof RawMonitorEnterNode) {
+                AccessMonitorNode monitorEnterNode = (AccessMonitorNode) next;
+                if (GraphUtil.unproxify(monitorEnterNode.object()) == GraphUtil.unproxify(node.object())) {
                     GraphUtil.removeFixedWithUnusedInputs(monitorEnterNode);
                     GraphUtil.removeFixedWithUnusedInputs(node);
                 }
--- a/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/DefaultJavaLoweringProvider.java	Sat Jun 06 15:13:09 2015 +0200
+++ b/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/DefaultJavaLoweringProvider.java	Sat Jun 06 22:19:26 2015 +0200
@@ -86,6 +86,8 @@
             lowerArrayLengthNode((ArrayLengthNode) n, tool);
         } else if (n instanceof LoadHubNode) {
             lowerLoadHubNode((LoadHubNode) n);
+        } else if (n instanceof MonitorEnterNode) {
+            lowerMonitorEnterNode((MonitorEnterNode) n, tool, graph);
         } else if (n instanceof CompareAndSwapNode) {
             lowerCompareAndSwapNode((CompareAndSwapNode) n);
         } else if (n instanceof AtomicReadAndWriteNode) {
@@ -244,6 +246,19 @@
         graph.replaceFloating(loadHub, hub);
     }
 
+    protected void lowerMonitorEnterNode(MonitorEnterNode monitorEnter, LoweringTool tool, StructuredGraph graph) {
+        ValueNode object = monitorEnter.object();
+        GuardingNode nullCheck = createNullCheck(object, monitorEnter, tool);
+        if (nullCheck != null) {
+            object = graph.unique(new PiNode(object, ((ObjectStamp) object.stamp()).improveWith(StampFactory.objectNonNull()), (ValueNode) nullCheck));
+        }
+        ValueNode hub = graph.addOrUnique(LoadHubNode.create(object, tool.getStampProvider(), tool.getMetaAccess()));
+        RawMonitorEnterNode rawMonitorEnter = graph.add(new RawMonitorEnterNode(object, hub, monitorEnter.getMonitorId()));
+        rawMonitorEnter.setStateBefore(monitorEnter.stateBefore());
+        rawMonitorEnter.setStateAfter(monitorEnter.stateAfter());
+        graph.replaceFixedWithFixed(monitorEnter, rawMonitorEnter);
+    }
+
     protected void lowerCompareAndSwapNode(CompareAndSwapNode cas) {
         StructuredGraph graph = cas.graph();
         Kind valueKind = cas.getValueKind();
--- a/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/SnippetTemplate.java	Sat Jun 06 15:13:09 2015 +0200
+++ b/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/SnippetTemplate.java	Sat Jun 06 22:19:26 2015 +0200
@@ -1156,7 +1156,7 @@
                         MemoryNode replacement = map.getLastLocationAccess(location);
                         if (replacement == null) {
                             assert LocationIdentity.any().equals(location) || Arrays.stream(info.privateLocations).anyMatch(Predicate.isEqual(location)) : "Snippet " + info.method.format("%h.%n") +
-                                            " contains access to the non-private location " + location + ", but replacee doesn't access this location.";
+                                            " contains access to the non-private location " + location + ", but replacee doesn't access this location." + map.getLocations();
                         } else {
                             pos.set(usage, replacement.asNode());
                         }