# HG changeset patch # User Thomas Wuerthinger # Date 1433621966 -7200 # Node ID 1ab2c7bb6f0f5ee3967252de6f9aa9d215066e30 # Parent 1025d6dc645aa36e6cd1a27194e96571eb4e888c Split MonitorEnterNode into RawMonitorEnterNode, null check, and hub load. diff -r 1025d6dc645a -r 1ab2c7bb6f0f graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/LockEliminationTest.java --- 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()); } diff -r 1025d6dc645a -r 1ab2c7bb6f0f graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/DefaultHotSpotLoweringProvider.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/DefaultHotSpotLoweringProvider.java 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()) { diff -r 1025d6dc645a -r 1ab2c7bb6f0f 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 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()); diff -r 1025d6dc645a -r 1ab2c7bb6f0f graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/LoadHubNode.java --- 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 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 diff -r 1025d6dc645a -r 1ab2c7bb6f0f graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/RawMonitorEnterNode.java --- /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 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; + } +} diff -r 1025d6dc645a -r 1ab2c7bb6f0f graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/LockEliminationPhase.java --- 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); } diff -r 1025d6dc645a -r 1ab2c7bb6f0f graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/DefaultJavaLoweringProvider.java --- a/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/DefaultJavaLoweringProvider.java 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(); diff -r 1025d6dc645a -r 1ab2c7bb6f0f graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/SnippetTemplate.java --- 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()); }