# HG changeset patch # User Roland Schatz # Date 1433782078 -7200 # Node ID a858c5f56d8a224b208bc5c0b88183ae0051de49 # Parent 9c454c650b29ff8c5a2e64a5ca93b66549037188 Introduce AddressNode to represent pointer arithmetic, remove LocationNode. diff -r 9c454c650b29 -r a858c5f56d8a graal/com.oracle.graal.compiler.common/src/com/oracle/graal/compiler/common/type/RawPointerStamp.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.compiler.common/src/com/oracle/graal/compiler/common/type/RawPointerStamp.java Mon Jun 08 18:47:58 2015 +0200 @@ -0,0 +1,108 @@ +/* + * Copyright (c) 2015, 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.compiler.common.type; + +import com.oracle.graal.compiler.common.spi.*; +import com.oracle.jvmci.common.*; +import com.oracle.jvmci.meta.*; + +/** + * Type describing pointers to raw memory. This stamp is used for example for direct pointers to + * fields or array elements. + */ +public class RawPointerStamp extends AbstractPointerStamp { + + protected RawPointerStamp() { + super(false, false); + } + + @Override + public LIRKind getLIRKind(LIRKindTool tool) { + return tool.getWordKind(); + } + + @Override + protected AbstractPointerStamp copyWith(boolean newNonNull, boolean newAlwaysNull) { + // RawPointerStamp is a singleton + assert newNonNull == nonNull() && newAlwaysNull == alwaysNull(); + return this; + } + + @Override + public Stamp meet(Stamp other) { + assert isCompatible(other); + return this; + } + + @Override + public Stamp improveWith(Stamp other) { + return this; + } + + @Override + public Stamp join(Stamp other) { + assert isCompatible(other); + return this; + } + + @Override + public Stamp unrestricted() { + return this; + } + + @Override + public Stamp empty() { + // there is no empty pointer stamp + return this; + } + + @Override + public boolean hasValues() { + return true; + } + + @Override + public ResolvedJavaType javaType(MetaAccessProvider metaAccess) { + throw JVMCIError.shouldNotReachHere("pointer has no Java type"); + } + + @Override + public Stamp constant(Constant c, MetaAccessProvider meta) { + return this; + } + + @Override + public boolean isCompatible(Stamp other) { + return other instanceof RawPointerStamp; + } + + @Override + public Constant readConstant(MemoryAccessProvider provider, Constant base, long displacement) { + throw JVMCIError.shouldNotReachHere("can't read raw pointer"); + } + + @Override + public String toString() { + return "void*"; + } +} diff -r 9c454c650b29 -r a858c5f56d8a graal/com.oracle.graal.compiler.common/src/com/oracle/graal/compiler/common/type/StampFactory.java --- a/graal/com.oracle.graal.compiler.common/src/com/oracle/graal/compiler/common/type/StampFactory.java Mon Jun 08 15:57:52 2015 +0200 +++ b/graal/com.oracle.graal.compiler.common/src/com/oracle/graal/compiler/common/type/StampFactory.java Mon Jun 08 18:47:58 2015 +0200 @@ -45,6 +45,7 @@ private static final Stamp positiveInt = forInteger(Kind.Int, 0, Integer.MAX_VALUE, 0, Integer.MAX_VALUE); private static final Stamp booleanTrue = forInteger(Kind.Boolean, -1, -1, 1, 1); private static final Stamp booleanFalse = forInteger(Kind.Boolean, 0, 0, 0, 0); + private static final Stamp rawPointer = new RawPointerStamp(); private static void setCache(Kind kind, Stamp stamp) { stampCache[kind.ordinal()] = stamp; @@ -350,4 +351,8 @@ return result; } + + public static Stamp pointer() { + return rawPointer; + } } diff -r 9c454c650b29 -r a858c5f56d8a graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/PushNodesThroughPiTest.java --- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/PushNodesThroughPiTest.java Mon Jun 08 15:57:52 2015 +0200 +++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/PushNodesThroughPiTest.java Mon Jun 08 18:47:58 2015 +0200 @@ -22,22 +22,20 @@ */ package com.oracle.graal.compiler.test; -import com.oracle.jvmci.meta.ResolvedJavaType; -import com.oracle.jvmci.meta.ResolvedJavaField; import org.junit.*; -import com.oracle.graal.compiler.common.type.*; import com.oracle.graal.nodes.*; import com.oracle.graal.nodes.StructuredGraph.AllowAssumptions; import com.oracle.graal.nodes.calc.*; -import com.oracle.graal.nodes.extended.*; import com.oracle.graal.nodes.memory.*; +import com.oracle.graal.nodes.memory.address.*; import com.oracle.graal.nodes.spi.*; import com.oracle.graal.nodes.type.*; import com.oracle.graal.phases.common.*; import com.oracle.graal.phases.tiers.*; import com.oracle.jvmci.debug.*; import com.oracle.jvmci.debug.Debug.Scope; +import com.oracle.jvmci.meta.*; public class PushNodesThroughPiTest extends GraalCompilerTest { @@ -72,17 +70,17 @@ try (Scope s = Debug.scope("PushThroughPi", new DebugDumpScope(snippet))) { StructuredGraph graph = compileTestSnippet(snippet); for (ReadNode rn : graph.getNodes().filter(ReadNode.class)) { - if (rn.location() instanceof ConstantLocationNode && rn.object().stamp() instanceof ObjectStamp) { - long disp = ((ConstantLocationNode) rn.location()).getDisplacement(); - ResolvedJavaType receiverType = StampTool.typeOrNull(rn.object()); - ResolvedJavaField field = receiverType.findInstanceFieldWithOffset(disp, rn.getKind()); + OffsetAddressNode address = (OffsetAddressNode) rn.getAddress(); + long disp = address.getOffset().asJavaConstant().asLong(); + + ResolvedJavaType receiverType = StampTool.typeOrNull(address.getBase()); + ResolvedJavaField field = receiverType.findInstanceFieldWithOffset(disp, rn.getKind()); - assert field != null : "Node " + rn + " tries to access a field which doesn't exists for this type"; - if (field.getName().equals("x")) { - Assert.assertTrue(rn.object() instanceof ParameterNode); - } else { - Assert.assertTrue(rn.object().toString(), rn.object() instanceof PiNode); - } + assert field != null : "Node " + rn + " tries to access a field which doesn't exists for this type"; + if (field.getName().equals("x")) { + Assert.assertTrue(address.getBase() instanceof ParameterNode); + } else { + Assert.assertTrue(address.getBase().toString(), address.getBase() instanceof PiNode); } } diff -r 9c454c650b29 -r a858c5f56d8a graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/ReadAfterCheckCastTest.java --- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/ReadAfterCheckCastTest.java Mon Jun 08 15:57:52 2015 +0200 +++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/ReadAfterCheckCastTest.java Mon Jun 08 18:47:58 2015 +0200 @@ -94,7 +94,7 @@ for (FloatingReadNode node : graph.getNodes(ParameterNode.TYPE).first().usages().filter(FloatingReadNode.class)) { // Checking that the parameter a is not directly used for the access to field // x10 (because x10 must be guarded by the checkcast). - Assert.assertTrue(node.location().getLocationIdentity().isImmutable()); + Assert.assertTrue(node.getLocationIdentity().isImmutable()); } } catch (Throwable e) { throw Debug.handle(e); diff -r 9c454c650b29 -r a858c5f56d8a graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/gen/NodeLIRBuilder.java --- a/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/gen/NodeLIRBuilder.java Mon Jun 08 15:57:52 2015 +0200 +++ b/graal/com.oracle.graal.compiler/src/com/oracle/graal/compiler/gen/NodeLIRBuilder.java Mon Jun 08 18:47:58 2015 +0200 @@ -68,16 +68,16 @@ */ @MatchableNode(nodeClass = ConstantNode.class, shareable = true) @MatchableNode(nodeClass = FloatConvertNode.class, inputs = {"value"}) -@MatchableNode(nodeClass = FloatingReadNode.class, inputs = {"object", "location"}) +@MatchableNode(nodeClass = FloatingReadNode.class, inputs = {"address"}) @MatchableNode(nodeClass = IfNode.class, inputs = {"condition"}) @MatchableNode(nodeClass = SubNode.class, inputs = {"x", "y"}) @MatchableNode(nodeClass = LeftShiftNode.class, inputs = {"x", "y"}) @MatchableNode(nodeClass = NarrowNode.class, inputs = {"value"}) -@MatchableNode(nodeClass = ReadNode.class, inputs = {"object", "location"}) +@MatchableNode(nodeClass = ReadNode.class, inputs = {"address"}) @MatchableNode(nodeClass = ReinterpretNode.class, inputs = {"value"}) @MatchableNode(nodeClass = SignExtendNode.class, inputs = {"value"}) @MatchableNode(nodeClass = UnsignedRightShiftNode.class, inputs = {"x", "y"}) -@MatchableNode(nodeClass = WriteNode.class, inputs = {"object", "location", "value"}) +@MatchableNode(nodeClass = WriteNode.class, inputs = {"address", "value"}) @MatchableNode(nodeClass = ZeroExtendNode.class, inputs = {"value"}) @MatchableNode(nodeClass = AndNode.class, inputs = {"x", "y"}, commutative = true) @MatchableNode(nodeClass = FloatEqualsNode.class, inputs = {"x", "y"}, commutative = true) @@ -92,7 +92,6 @@ @MatchableNode(nodeClass = OrNode.class, inputs = {"x", "y"}, commutative = true) @MatchableNode(nodeClass = XorNode.class, inputs = {"x", "y"}, commutative = true) @MatchableNode(nodeClass = PiNode.class, inputs = {"object"}) -@MatchableNode(nodeClass = ConstantLocationNode.class, shareable = true) public abstract class NodeLIRBuilder implements NodeLIRBuilderTool, LIRGenerationDebugContext { private final NodeMap nodeOperands; diff -r 9c454c650b29 -r a858c5f56d8a graal/com.oracle.graal.hotspot.test/src/com/oracle/graal/hotspot/test/WriteBarrierAdditionTest.java --- a/graal/com.oracle.graal.hotspot.test/src/com/oracle/graal/hotspot/test/WriteBarrierAdditionTest.java Mon Jun 08 15:57:52 2015 +0200 +++ b/graal/com.oracle.graal.hotspot.test/src/com/oracle/graal/hotspot/test/WriteBarrierAdditionTest.java Mon Jun 08 18:47:58 2015 +0200 @@ -22,7 +22,6 @@ */ package com.oracle.graal.hotspot.test; -import com.oracle.jvmci.meta.ResolvedJavaMethod; import static com.oracle.jvmci.common.UnsafeAccess.*; import java.lang.ref.*; @@ -38,9 +37,9 @@ import com.oracle.graal.hotspot.replacements.*; import com.oracle.graal.nodes.*; import com.oracle.graal.nodes.StructuredGraph.AllowAssumptions; -import com.oracle.graal.nodes.extended.*; import com.oracle.graal.nodes.memory.HeapAccess.BarrierType; import com.oracle.graal.nodes.memory.*; +import com.oracle.graal.nodes.memory.address.*; import com.oracle.graal.nodes.spi.*; import com.oracle.graal.phases.*; import com.oracle.graal.phases.common.*; @@ -50,6 +49,7 @@ import com.oracle.jvmci.debug.*; import com.oracle.jvmci.debug.Debug.Scope; import com.oracle.jvmci.hotspot.*; +import com.oracle.jvmci.meta.*; /** * The following unit tests assert the presence of write barriers for both Serial and G1 GCs. @@ -284,9 +284,10 @@ for (ReadNode read : graph.getNodes().filter(ReadNode.class)) { if (read.getBarrierType() != BarrierType.NONE) { - if (read.location() instanceof ConstantLocationNode) { - Assert.assertEquals(referentOffset, ((ConstantLocationNode) (read.location())).getDisplacement()); - } + Assert.assertTrue(read.getAddress() instanceof OffsetAddressNode); + JavaConstant constDisp = ((OffsetAddressNode) read.getAddress()).getOffset().asJavaConstant(); + Assert.assertNotNull(constDisp); + Assert.assertEquals(referentOffset, constDisp.asLong()); Assert.assertTrue(config.useG1GC); Assert.assertEquals(BarrierType.PRECISE, read.getBarrierType()); Assert.assertTrue(read.next() instanceof G1ReferentFieldReadBarrier); diff -r 9c454c650b29 -r a858c5f56d8a graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotLIRGenerator.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotLIRGenerator.java Mon Jun 08 15:57:52 2015 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotLIRGenerator.java Mon Jun 08 18:47:58 2015 +0200 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 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 @@ -147,4 +147,6 @@ Value emitCompress(Value pointer, CompressEncoding encoding, boolean nonNull); Value emitUncompress(Value pointer, CompressEncoding encoding, boolean nonNull); + + void emitPrefetchAllocate(Value address); } diff -r 9c454c650b29 -r a858c5f56d8a graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotNodeLIRBuilder.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotNodeLIRBuilder.java Mon Jun 08 15:57:52 2015 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotNodeLIRBuilder.java Mon Jun 08 18:47:58 2015 +0200 @@ -43,8 +43,6 @@ void emitJumpToExceptionHandlerInCaller(ValueNode handlerInCallerPc, ValueNode exception, ValueNode exceptionPc); - void emitPrefetchAllocate(ValueNode address, ValueNode distance); - void visitDirectCompareAndSwap(DirectCompareAndSwapNode x); } diff -r 9c454c650b29 -r a858c5f56d8a 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 Mon Jun 08 15:57:52 2015 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/DefaultHotSpotLoweringProvider.java Mon Jun 08 18:47:58 2015 +0200 @@ -22,23 +22,11 @@ */ package com.oracle.graal.hotspot.meta; -import com.oracle.jvmci.code.ForeignCallsProvider; -import com.oracle.jvmci.code.CallingConvention; -import com.oracle.jvmci.code.TargetDescription; -import com.oracle.jvmci.meta.ResolvedJavaField; -import com.oracle.jvmci.meta.JavaType; -import com.oracle.jvmci.meta.MetaAccessProvider; -import com.oracle.jvmci.meta.JavaConstant; -import com.oracle.jvmci.meta.LocationIdentity; -import com.oracle.jvmci.meta.ResolvedJavaType; -import com.oracle.jvmci.meta.ForeignCallDescriptor; -import com.oracle.jvmci.meta.Kind; - -import static com.oracle.jvmci.meta.LocationIdentity.*; import static com.oracle.graal.compiler.common.GraalOptions.*; import static com.oracle.graal.hotspot.meta.HotSpotForeignCallsProviderImpl.*; import static com.oracle.graal.hotspot.replacements.HotSpotReplacementsUtil.*; import static com.oracle.graal.hotspot.replacements.NewObjectSnippets.*; +import static com.oracle.jvmci.meta.LocationIdentity.*; import java.lang.ref.*; @@ -56,12 +44,15 @@ import com.oracle.graal.nodes.java.*; import com.oracle.graal.nodes.memory.*; import com.oracle.graal.nodes.memory.HeapAccess.BarrierType; +import com.oracle.graal.nodes.memory.address.*; import com.oracle.graal.nodes.spi.*; import com.oracle.graal.nodes.type.*; import com.oracle.graal.replacements.*; import com.oracle.graal.replacements.nodes.*; +import com.oracle.jvmci.code.*; import com.oracle.jvmci.common.*; import com.oracle.jvmci.hotspot.*; +import com.oracle.jvmci.meta.*; /** * HotSpot implementation of {@link LoweringProvider}. @@ -212,9 +203,9 @@ return; } StructuredGraph graph = n.graph(); - LocationNode location = graph.unique(new ConstantLocationNode(KLASS_LAYOUT_HELPER_LOCATION, runtime.getConfig().klassLayoutHelperOffset)); assert !n.getHub().isConstant(); - graph.replaceFloating(n, graph.unique(new FloatingReadNode(n.getHub(), location, null, n.stamp(), n.getGuard(), BarrierType.NONE))); + AddressNode address = createOffsetAddress(graph, n.getHub(), runtime.getConfig().klassLayoutHelperOffset); + graph.replaceFloating(n, graph.unique(new FloatingReadNode(address, KLASS_LAYOUT_HELPER_LOCATION, null, n.stamp(), n.getGuard(), BarrierType.NONE))); } private void lowerHubGetClassNode(HubGetClassNode n, LoweringTool tool) { @@ -223,9 +214,9 @@ } StructuredGraph graph = n.graph(); - LocationNode location = graph.unique(new ConstantLocationNode(CLASS_MIRROR_LOCATION, runtime.getConfig().classMirrorOffset)); assert !n.getHub().isConstant(); - FloatingReadNode read = graph.unique(new FloatingReadNode(n.getHub(), location, null, n.stamp(), n.getGuard(), BarrierType.NONE)); + AddressNode address = createOffsetAddress(graph, n.getHub(), runtime.getConfig().classMirrorOffset); + FloatingReadNode read = graph.unique(new FloatingReadNode(address, CLASS_MIRROR_LOCATION, null, n.stamp(), n.getGuard(), BarrierType.NONE)); graph.replaceFloating(n, read); } @@ -235,9 +226,9 @@ } StructuredGraph graph = n.graph(); - LocationNode location = graph.unique(new ConstantLocationNode(CLASS_KLASS_LOCATION, runtime.getConfig().klassOffset)); assert !n.getValue().isConstant(); - FloatingReadNode read = graph.unique(new FloatingReadNode(n.getValue(), location, null, n.stamp(), n.getGuard(), BarrierType.NONE)); + AddressNode address = createOffsetAddress(graph, n.getValue(), runtime.getConfig().klassOffset); + FloatingReadNode read = graph.unique(new FloatingReadNode(address, CLASS_KLASS_LOCATION, null, n.stamp(), n.getGuard(), BarrierType.NONE)); graph.replaceFloating(n, read); } @@ -266,8 +257,8 @@ // compiled code entry as HotSpot does not guarantee they are final // values. int methodCompiledEntryOffset = runtime.getConfig().methodCompiledEntryOffset; - ReadNode compiledEntry = graph.add(new ReadNode(metaspaceMethod, graph.unique(new ConstantLocationNode(any(), methodCompiledEntryOffset)), StampFactory.forKind(wordKind), - BarrierType.NONE)); + AddressNode address = createOffsetAddress(graph, metaspaceMethod, methodCompiledEntryOffset); + ReadNode compiledEntry = graph.add(new ReadNode(address, any(), StampFactory.forKind(wordKind), BarrierType.NONE)); loweredCallTarget = graph.add(new HotSpotIndirectCallTargetNode(metaspaceMethod, compiledEntry, parameters, invoke.asNode().stamp(), signature, callTarget.targetMethod(), CallingConvention.Type.JavaCall, callTarget.invokeKind())); @@ -318,12 +309,12 @@ @Override protected ValueNode createReadArrayComponentHub(StructuredGraph graph, ValueNode arrayHub, FixedNode anchor) { - LocationNode location = graph.unique(new ConstantLocationNode(OBJ_ARRAY_KLASS_ELEMENT_KLASS_LOCATION, runtime.getConfig().arrayClassElementOffset)); /* * Anchor the read of the element klass to the cfg, because it is only valid when arrayClass * is an object class, which might not be the case in other parts of the compiled method. */ - return graph.unique(new FloatingReadNode(arrayHub, location, null, KlassPointerStamp.klassNonNull(), AbstractBeginNode.prevBegin(anchor))); + AddressNode address = createOffsetAddress(graph, arrayHub, runtime.getConfig().arrayClassElementOffset); + return graph.unique(new FloatingReadNode(address, OBJ_ARRAY_KLASS_ELEMENT_KLASS_LOCATION, null, KlassPointerStamp.klassNonNull(), AbstractBeginNode.prevBegin(anchor))); } @Override @@ -386,8 +377,8 @@ for (OSRLocalNode osrLocal : graph.getNodes(OSRLocalNode.TYPE)) { int size = osrLocal.getKind().getSlotCount(); int offset = localsOffset - (osrLocal.index() + size - 1) * 8; - IndexedLocationNode location = graph.unique(new IndexedLocationNode(any(), offset, ConstantNode.forLong(0, graph), 1)); - ReadNode load = graph.add(new ReadNode(buffer, location, osrLocal.stamp(), BarrierType.NONE)); + AddressNode address = createOffsetAddress(graph, buffer, offset); + ReadNode load = graph.add(new ReadNode(address, any(), osrLocal.stamp(), BarrierType.NONE)); osrLocal.replaceAndDelete(load); graph.addBeforeFixed(migrationEnd, load); } @@ -464,14 +455,14 @@ // We use LocationNode.ANY_LOCATION for the reads that access the vtable // entry as HotSpot does not guarantee that this is a final value. Stamp methodStamp = MethodPointerStamp.method(); - ReadNode metaspaceMethod = graph.add(new ReadNode(hub, graph.unique(new ConstantLocationNode(any(), vtableEntryOffset)), methodStamp, BarrierType.NONE)); + AddressNode address = createOffsetAddress(graph, hub, vtableEntryOffset); + ReadNode metaspaceMethod = graph.add(new ReadNode(address, any(), methodStamp, BarrierType.NONE)); return metaspaceMethod; } @Override protected ValueNode createReadHub(StructuredGraph graph, ValueNode object, GuardingNode guard) { HotSpotVMConfig config = runtime.getConfig(); - LocationNode location = graph.unique(new ConstantLocationNode(HUB_LOCATION, config.hubOffset)); assert !object.isConstant() || object.isNullConstant(); KlassPointerStamp hubStamp = KlassPointerStamp.klassNonNull(); @@ -479,7 +470,8 @@ hubStamp = hubStamp.compressed(config.getKlassEncoding()); } - FloatingReadNode memoryRead = graph.unique(new FloatingReadNode(object, location, null, hubStamp, guard, BarrierType.NONE)); + AddressNode address = createOffsetAddress(graph, object, config.hubOffset); + FloatingReadNode memoryRead = graph.unique(new FloatingReadNode(address, HUB_LOCATION, null, hubStamp, guard, BarrierType.NONE)); if (config.useCompressedClassPointers) { return CompressionNode.uncompress(memoryRead, config.getKlassEncoding()); } else { @@ -489,7 +481,6 @@ private WriteNode createWriteHub(StructuredGraph graph, ValueNode object, ValueNode value) { HotSpotVMConfig config = runtime.getConfig(); - LocationNode location = graph.unique(new ConstantLocationNode(HUB_WRITE_LOCATION, config.hubOffset)); assert !object.isConstant() || object.asConstant().isDefaultForKind(); ValueNode writeValue = value; @@ -497,7 +488,8 @@ writeValue = CompressionNode.compress(value, config.getKlassEncoding()); } - return graph.add(new WriteNode(object, writeValue, location, BarrierType.NONE)); + AddressNode address = createOffsetAddress(graph, object, config.hubOffset); + return graph.add(new WriteNode(address, HUB_WRITE_LOCATION, writeValue, BarrierType.NONE)); } @Override diff -r 9c454c650b29 -r a858c5f56d8a graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotGraphBuilderPlugins.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotGraphBuilderPlugins.java Mon Jun 08 15:57:52 2015 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotGraphBuilderPlugins.java Mon Jun 08 18:47:58 2015 +0200 @@ -22,13 +22,6 @@ */ package com.oracle.graal.hotspot.meta; -import com.oracle.jvmci.code.ForeignCallsProvider; -import com.oracle.jvmci.meta.MetaAccessProvider; -import com.oracle.jvmci.meta.JavaConstant; -import com.oracle.jvmci.meta.ConstantReflectionProvider; -import com.oracle.jvmci.meta.ResolvedJavaMethod; -import com.oracle.jvmci.meta.Kind; - import static com.oracle.graal.hotspot.replacements.HotSpotReplacementsUtil.*; import static com.oracle.graal.hotspot.replacements.SystemSubstitutions.*; import static com.oracle.graal.java.BytecodeParser.Options.*; @@ -48,13 +41,15 @@ import com.oracle.graal.hotspot.replacements.arraycopy.*; import com.oracle.graal.hotspot.word.*; import com.oracle.graal.nodes.*; -import com.oracle.graal.nodes.extended.*; import com.oracle.graal.nodes.memory.HeapAccess.BarrierType; +import com.oracle.graal.nodes.memory.address.*; import com.oracle.graal.nodes.spi.*; import com.oracle.graal.nodes.util.*; import com.oracle.graal.replacements.*; import com.oracle.graal.word.*; +import com.oracle.jvmci.code.*; import com.oracle.jvmci.hotspot.*; +import com.oracle.jvmci.meta.*; import com.oracle.jvmci.options.*; /** @@ -214,9 +209,10 @@ r.register0("currentThread", new InvocationPlugin() { public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, Receiver receiver) { CurrentJavaThreadNode thread = b.add(new CurrentJavaThreadNode(wordTypes.getWordKind())); - ConstantLocationNode location = b.add(new ConstantLocationNode(JAVA_THREAD_THREAD_OBJECT_LOCATION, config.threadObjectOffset)); boolean compressible = false; - ValueNode javaThread = WordOperationPlugin.readOp(b, Kind.Object, thread, location, BarrierType.NONE, compressible); + ValueNode offset = b.add(ConstantNode.forLong(config.threadObjectOffset)); + AddressNode address = b.add(new OffsetAddressNode(thread, offset)); + ValueNode javaThread = WordOperationPlugin.readOp(b, Kind.Object, address, JAVA_THREAD_THREAD_OBJECT_LOCATION, BarrierType.NONE, compressible); boolean exactType = compressible; boolean nonNull = true; b.addPush(Kind.Object, new PiNode(javaThread, metaAccess.lookupJavaType(Thread.class), exactType, nonNull)); diff -r 9c454c650b29 -r a858c5f56d8a 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 Mon Jun 08 15:57:52 2015 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotLoweringProvider.java Mon Jun 08 18:47:58 2015 +0200 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2011, 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 @@ -22,13 +22,12 @@ */ package com.oracle.graal.hotspot.meta; -import com.oracle.jvmci.meta.Kind; import com.oracle.graal.compiler.common.type.*; -import com.oracle.graal.graph.*; import com.oracle.graal.nodes.*; -import com.oracle.graal.nodes.extended.*; +import com.oracle.graal.nodes.memory.address.*; import com.oracle.graal.nodes.spi.*; import com.oracle.jvmci.hotspot.*; +import com.oracle.jvmci.meta.*; /** * HotSpot implementation of {@link LoweringProvider}. @@ -39,7 +38,7 @@ int arrayScalingFactor(Kind kind); - IndexedLocationNode createArrayLocation(Graph graph, Kind elementKind, ValueNode index, boolean initialization); + AddressNode createArrayAddress(StructuredGraph graph, ValueNode array, Kind elementKind, ValueNode index); Stamp loadStamp(Stamp stamp, Kind kind); diff -r 9c454c650b29 -r a858c5f56d8a graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotWordOperationPlugin.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotWordOperationPlugin.java Mon Jun 08 15:57:52 2015 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotWordOperationPlugin.java Mon Jun 08 18:47:58 2015 +0200 @@ -35,10 +35,10 @@ import com.oracle.graal.hotspot.word.HotSpotOperation.HotspotOpcode; import com.oracle.graal.nodes.*; import com.oracle.graal.nodes.calc.*; -import com.oracle.graal.nodes.extended.*; import com.oracle.graal.nodes.java.*; import com.oracle.graal.nodes.memory.HeapAccess.BarrierType; import com.oracle.graal.nodes.memory.*; +import com.oracle.graal.nodes.memory.address.*; import com.oracle.graal.nodes.type.*; import com.oracle.graal.replacements.*; import com.oracle.graal.word.*; @@ -126,13 +126,15 @@ case READ_KLASS_POINTER: assert args.length == 2 || args.length == 3; Stamp readStamp = KlassPointerStamp.klass(); - LocationNode location; + AddressNode address = makeAddress(b, args[0], args[1]); + LocationIdentity location; if (args.length == 2) { - location = makeLocation(b, args[1], any()); + location = any(); } else { - location = makeLocation(b, args[1], args[2]); + assert args[2].isConstant(); + location = snippetReflection.asObject(LocationIdentity.class, args[2].asJavaConstant()); } - ReadNode read = b.add(new ReadNode(args[0], location, readStamp, BarrierType.NONE)); + ReadNode read = b.add(new ReadNode(address, location, readStamp, BarrierType.NONE)); /* * The read must not float outside its block otherwise it may float above an * explicit zero check on its base address. diff -r 9c454c650b29 -r a858c5f56d8a graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/ArrayRangeWriteBarrier.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/ArrayRangeWriteBarrier.java Mon Jun 08 15:57:52 2015 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/ArrayRangeWriteBarrier.java Mon Jun 08 18:47:58 2015 +0200 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 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 @@ -22,23 +22,31 @@ */ package com.oracle.graal.hotspot.nodes; +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.spi.*; @NodeInfo -public abstract class ArrayRangeWriteBarrier extends WriteBarrier { +public abstract class ArrayRangeWriteBarrier extends FixedWithNextNode implements Lowerable { public static final NodeClass TYPE = NodeClass.create(ArrayRangeWriteBarrier.class); + @Input ValueNode object; @Input ValueNode startIndex; @Input ValueNode length; protected ArrayRangeWriteBarrier(NodeClass c, ValueNode object, ValueNode startIndex, ValueNode length) { - super(c, object, null, null, true); + super(c, StampFactory.forVoid()); + this.object = object; this.startIndex = startIndex; this.length = length; } + public ValueNode getObject() { + return object; + } + public ValueNode getStartIndex() { return startIndex; } @@ -46,4 +54,10 @@ public ValueNode getLength() { return length; } + + @Override + public void lower(LoweringTool tool) { + assert graph().getGuardsStage().areFrameStatesAtDeopts(); + tool.getLowerer().lower(this, tool); + } } diff -r 9c454c650b29 -r a858c5f56d8a graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/DirectCompareAndSwapNode.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/DirectCompareAndSwapNode.java Mon Jun 08 15:57:52 2015 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/DirectCompareAndSwapNode.java Mon Jun 08 18:47:58 2015 +0200 @@ -29,41 +29,36 @@ import com.oracle.graal.nodes.*; import com.oracle.graal.nodes.java.*; import com.oracle.graal.nodes.memory.*; +import com.oracle.graal.nodes.memory.address.*; +import com.oracle.graal.nodes.memory.address.AddressNode.Address; import com.oracle.graal.nodes.spi.*; import com.oracle.graal.word.*; /** * A special purpose store node that differs from {@link CompareAndSwapNode} in that it is not a - * {@link StateSplit} and it - * {@linkplain #compareAndSwap(Object, long, Word, Word, LocationIdentity)} returns either the - * expected value or the compared against value instead of a boolean. + * {@link StateSplit} and it {@linkplain #compareAndSwap(Address, Word, Word, LocationIdentity)} + * returns either the expected value or the compared against value instead of a boolean. */ @NodeInfo(allowedUsageTypes = {InputType.Memory}) public final class DirectCompareAndSwapNode extends FixedWithNextNode implements LIRLowerable, MemoryCheckpoint.Single { public static final NodeClass TYPE = NodeClass.create(DirectCompareAndSwapNode.class); - @Input ValueNode object; - @Input ValueNode offset; + @Input(InputType.Association) AddressNode address; @Input ValueNode expectedValue; @Input ValueNode newValue; protected final LocationIdentity locationIdentity; - public DirectCompareAndSwapNode(ValueNode object, ValueNode offset, ValueNode expected, ValueNode newValue, LocationIdentity locationIdentity) { + public DirectCompareAndSwapNode(ValueNode address, ValueNode expected, ValueNode newValue, LocationIdentity locationIdentity) { super(TYPE, expected.stamp()); - this.object = object; - this.offset = offset; + this.address = (AddressNode) address; this.expectedValue = expected; this.newValue = newValue; this.locationIdentity = locationIdentity; } - public ValueNode object() { - return object; - } - - public ValueNode offset() { - return offset; + public AddressNode getAddress() { + return address; } public ValueNode expectedValue() { @@ -85,17 +80,16 @@ } /** - * Compares an expected value with the actual value in a location denoted by an object and a - * given offset. Iff they are same, {@code newValue} is placed into the location and the - * {@code expectedValue} is returned. Otherwise, the actual value is returned. All of the above - * is performed in one atomic hardware transaction. + * Compares an expected value with the actual value in a location denoted by an address. Iff + * they are same, {@code newValue} is placed into the location and the {@code expectedValue} is + * returned. Otherwise, the actual value is returned. All of the above is performed in one + * atomic hardware transaction. * - * @param object the object containing a field to be atomically tested and updated - * @param offset offset from {@code object} of the field + * @param address the address to be atomically tested and updated * @param expectedValue if this value is currently in the field, perform the swap * @param newValue the new value to put into the field * @return either {@code expectedValue} or the actual value */ @NodeIntrinsic - public static native Word compareAndSwap(Object object, long offset, Word expectedValue, Word newValue, @ConstantNodeParameter LocationIdentity locationIdentity); + public static native Word compareAndSwap(Address address, Word expectedValue, Word newValue, @ConstantNodeParameter LocationIdentity locationIdentity); } diff -r 9c454c650b29 -r a858c5f56d8a graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/G1PostWriteBarrier.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/G1PostWriteBarrier.java Mon Jun 08 15:57:52 2015 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/G1PostWriteBarrier.java Mon Jun 08 18:47:58 2015 +0200 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 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 @@ -25,7 +25,7 @@ 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.address.*; @NodeInfo public class G1PostWriteBarrier extends WriteBarrier { @@ -33,12 +33,12 @@ public static final NodeClass TYPE = NodeClass.create(G1PostWriteBarrier.class); protected final boolean alwaysNull; - public G1PostWriteBarrier(ValueNode object, ValueNode value, LocationNode location, boolean precise, boolean alwaysNull) { - this(TYPE, object, value, location, precise, alwaysNull); + public G1PostWriteBarrier(AddressNode address, ValueNode value, boolean precise, boolean alwaysNull) { + this(TYPE, address, value, precise, alwaysNull); } - protected G1PostWriteBarrier(NodeClass c, ValueNode object, ValueNode value, LocationNode location, boolean precise, boolean alwaysNull) { - super(c, object, value, location, precise); + protected G1PostWriteBarrier(NodeClass c, AddressNode address, ValueNode value, boolean precise, boolean alwaysNull) { + super(c, address, value, precise); this.alwaysNull = alwaysNull; } diff -r 9c454c650b29 -r a858c5f56d8a graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/G1PreWriteBarrier.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/G1PreWriteBarrier.java Mon Jun 08 15:57:52 2015 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/G1PreWriteBarrier.java Mon Jun 08 18:47:58 2015 +0200 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 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 @@ -25,7 +25,7 @@ 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.address.*; @NodeInfo public final class G1PreWriteBarrier extends WriteBarrier implements DeoptimizingNode.DeoptBefore { @@ -36,8 +36,8 @@ protected final boolean nullCheck; protected final boolean doLoad; - public G1PreWriteBarrier(ValueNode object, ValueNode expectedObject, LocationNode location, boolean doLoad, boolean nullCheck) { - super(TYPE, object, expectedObject, location, true); + public G1PreWriteBarrier(AddressNode address, ValueNode expectedObject, boolean doLoad, boolean nullCheck) { + super(TYPE, address, expectedObject, true); this.doLoad = doLoad; this.nullCheck = nullCheck; } diff -r 9c454c650b29 -r a858c5f56d8a graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/G1ReferentFieldReadBarrier.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/G1ReferentFieldReadBarrier.java Mon Jun 08 15:57:52 2015 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/G1ReferentFieldReadBarrier.java Mon Jun 08 18:47:58 2015 +0200 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 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 @@ -25,7 +25,7 @@ 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.address.*; /** * The {@code G1ReferentFieldReadBarrier} is added when a read access is performed to the referent @@ -39,8 +39,8 @@ protected final boolean doLoad; - public G1ReferentFieldReadBarrier(ValueNode object, ValueNode expectedObject, LocationNode location, boolean doLoad) { - super(TYPE, object, expectedObject, location, true); + public G1ReferentFieldReadBarrier(AddressNode address, ValueNode expectedObject, boolean doLoad) { + super(TYPE, address, expectedObject, true); this.doLoad = doLoad; } diff -r 9c454c650b29 -r a858c5f56d8a graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/PrefetchAllocateNode.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/PrefetchAllocateNode.java Mon Jun 08 15:57:52 2015 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/PrefetchAllocateNode.java Mon Jun 08 18:47:58 2015 +0200 @@ -28,27 +28,26 @@ import com.oracle.graal.hotspot.*; import com.oracle.graal.nodeinfo.*; import com.oracle.graal.nodes.*; +import com.oracle.graal.nodes.memory.address.*; +import com.oracle.graal.nodes.memory.address.AddressNode.Address; import com.oracle.graal.nodes.spi.*; -import com.oracle.graal.word.*; @NodeInfo public final class PrefetchAllocateNode extends FixedWithNextNode implements LIRLowerable { public static final NodeClass TYPE = NodeClass.create(PrefetchAllocateNode.class); - @Input ValueNode distance; - @Input ValueNode address; + @Input(InputType.Association) AddressNode address; - public PrefetchAllocateNode(ValueNode address, ValueNode distance) { + public PrefetchAllocateNode(ValueNode address) { super(TYPE, StampFactory.forVoid()); - this.address = address; - this.distance = distance; + this.address = (AddressNode) address; } @Override public void generate(NodeLIRBuilderTool gen) { - ((HotSpotNodeLIRBuilder) gen).emitPrefetchAllocate(address, distance); + ((HotSpotLIRGenerator) gen.getLIRGeneratorTool()).emitPrefetchAllocate(gen.operand(address)); } @NodeIntrinsic - public static native void prefetch(Word address, Word distance); + public static native void prefetch(Address address); } diff -r 9c454c650b29 -r a858c5f56d8a graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/SerialWriteBarrier.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/SerialWriteBarrier.java Mon Jun 08 15:57:52 2015 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/SerialWriteBarrier.java Mon Jun 08 18:47:58 2015 +0200 @@ -24,19 +24,18 @@ 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.address.*; @NodeInfo public class SerialWriteBarrier extends WriteBarrier { public static final NodeClass TYPE = NodeClass.create(SerialWriteBarrier.class); - public SerialWriteBarrier(ValueNode object, LocationNode location, boolean precise) { - this(TYPE, object, location, precise); + public SerialWriteBarrier(AddressNode address, boolean precise) { + this(TYPE, address, precise); } - protected SerialWriteBarrier(NodeClass c, ValueNode object, LocationNode location, boolean precise) { - super(c, object, null, location, precise); + protected SerialWriteBarrier(NodeClass c, AddressNode address, boolean precise) { + super(c, address, null, precise); } } diff -r 9c454c650b29 -r a858c5f56d8a graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/WriteBarrier.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/WriteBarrier.java Mon Jun 08 15:57:52 2015 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/nodes/WriteBarrier.java Mon Jun 08 18:47:58 2015 +0200 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 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 @@ -26,23 +26,21 @@ 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.address.*; import com.oracle.graal.nodes.spi.*; @NodeInfo public abstract class WriteBarrier extends FixedWithNextNode implements Lowerable { public static final NodeClass TYPE = NodeClass.create(WriteBarrier.class); - @Input protected ValueNode object; + @Input(InputType.Association) protected AddressNode address; @OptionalInput protected ValueNode value; - @OptionalInput(InputType.Association) protected LocationNode location; protected final boolean precise; - protected WriteBarrier(NodeClass c, ValueNode object, ValueNode value, LocationNode location, boolean precise) { + protected WriteBarrier(NodeClass c, AddressNode address, ValueNode value, boolean precise) { super(c, StampFactory.forVoid()); - this.object = object; + this.address = address; this.value = value; - this.location = location; this.precise = precise; } @@ -50,12 +48,8 @@ return value; } - public ValueNode getObject() { - return object; - } - - public LocationNode getLocation() { - return location; + public AddressNode getAddress() { + return address; } public boolean usePrecise() { diff -r 9c454c650b29 -r a858c5f56d8a graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/phases/LoadJavaMirrorWithKlassPhase.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/phases/LoadJavaMirrorWithKlassPhase.java Mon Jun 08 15:57:52 2015 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/phases/LoadJavaMirrorWithKlassPhase.java Mon Jun 08 18:47:58 2015 +0200 @@ -34,8 +34,8 @@ import com.oracle.graal.hotspot.nodes.*; import com.oracle.graal.hotspot.nodes.type.*; import com.oracle.graal.nodes.*; -import com.oracle.graal.nodes.extended.*; import com.oracle.graal.nodes.memory.*; +import com.oracle.graal.nodes.memory.address.*; import com.oracle.graal.phases.*; import com.oracle.graal.phases.common.*; import com.oracle.graal.phases.tiers.*; @@ -74,8 +74,8 @@ if (type instanceof HotSpotResolvedObjectType) { ConstantNode klass = ConstantNode.forConstant(KlassPointerStamp.klassNonNull(), ((HotSpotResolvedObjectType) type).klass(), metaAccess, graph); - LocationNode location = graph.unique(new ConstantLocationNode(CLASS_MIRROR_LOCATION, classMirrorOffset)); - ValueNode read = graph.unique(new FloatingReadNode(klass, location, null, stamp)); + AddressNode address = graph.unique(new OffsetAddressNode(klass, ConstantNode.forLong(classMirrorOffset, graph))); + ValueNode read = graph.unique(new FloatingReadNode(address, CLASS_MIRROR_LOCATION, null, stamp)); if (((HotSpotObjectConstant) constant).isCompressed()) { return CompressionNode.compress(read, oopEncoding); @@ -102,11 +102,11 @@ throw new JVMCIError("Can't find TYPE field in class"); } - LocationNode location = graph.unique(new ConstantLocationNode(FINAL_LOCATION, typeField.offset())); if (oopEncoding != null) { stamp = NarrowOopStamp.compressed((AbstractObjectStamp) stamp, oopEncoding); } - ValueNode read = graph.unique(new FloatingReadNode(clazz, location, null, stamp)); + AddressNode address = graph.unique(new OffsetAddressNode(clazz, ConstantNode.forLong(typeField.offset(), graph))); + ValueNode read = graph.unique(new FloatingReadNode(address, FINAL_LOCATION, null, stamp)); if (oopEncoding == null || ((HotSpotObjectConstant) constant).isCompressed()) { return read; diff -r 9c454c650b29 -r a858c5f56d8a graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/phases/WriteBarrierAdditionPhase.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/phases/WriteBarrierAdditionPhase.java Mon Jun 08 15:57:52 2015 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/phases/WriteBarrierAdditionPhase.java Mon Jun 08 18:47:58 2015 +0200 @@ -29,6 +29,7 @@ import com.oracle.graal.nodes.java.*; import com.oracle.graal.nodes.memory.*; import com.oracle.graal.nodes.memory.HeapAccess.BarrierType; +import com.oracle.graal.nodes.memory.address.*; import com.oracle.graal.nodes.type.*; import com.oracle.graal.phases.*; import com.oracle.jvmci.common.*; @@ -66,34 +67,33 @@ private void addReadNodeBarriers(ReadNode node, StructuredGraph graph) { if (node.getBarrierType() == BarrierType.PRECISE) { assert config.useG1GC; - G1ReferentFieldReadBarrier barrier = graph.add(new G1ReferentFieldReadBarrier(node.object(), node, node.location(), false)); + G1ReferentFieldReadBarrier barrier = graph.add(new G1ReferentFieldReadBarrier(node.getAddress(), node, false)); graph.addAfterFixed(node, barrier); } else { assert node.getBarrierType() == BarrierType.NONE : "Non precise read barrier has been attached to read node."; } } - protected static void addG1PreWriteBarrier(FixedAccessNode node, ValueNode object, ValueNode value, LocationNode location, boolean doLoad, boolean nullCheck, StructuredGraph graph) { - G1PreWriteBarrier preBarrier = graph.add(new G1PreWriteBarrier(object, value, location, doLoad, nullCheck)); + protected static void addG1PreWriteBarrier(FixedAccessNode node, AddressNode address, ValueNode value, boolean doLoad, boolean nullCheck, StructuredGraph graph) { + G1PreWriteBarrier preBarrier = graph.add(new G1PreWriteBarrier(address, value, doLoad, nullCheck)); preBarrier.setStateBefore(node.stateBefore()); node.setNullCheck(false); node.setStateBefore(null); graph.addBeforeFixed(node, preBarrier); } - protected void addG1PostWriteBarrier(FixedAccessNode node, ValueNode object, ValueNode value, LocationNode location, boolean precise, StructuredGraph graph) { + protected void addG1PostWriteBarrier(FixedAccessNode node, AddressNode address, ValueNode value, boolean precise, StructuredGraph graph) { final boolean alwaysNull = StampTool.isPointerAlwaysNull(value); - graph.addAfterFixed(node, graph.add(new G1PostWriteBarrier(object, value, location, precise, alwaysNull))); + graph.addAfterFixed(node, graph.add(new G1PostWriteBarrier(address, value, precise, alwaysNull))); } - protected void addSerialPostWriteBarrier(FixedAccessNode node, ValueNode object, ValueNode value, LocationNode location, boolean precise, StructuredGraph graph) { + protected void addSerialPostWriteBarrier(FixedAccessNode node, AddressNode address, ValueNode value, boolean precise, StructuredGraph graph) { final boolean alwaysNull = StampTool.isPointerAlwaysNull(value); if (alwaysNull) { // Serial barrier isn't needed for null value return; } - final LocationNode loc = (precise ? location : null); - graph.addAfterFixed(node, graph.add(new SerialWriteBarrier(object, loc, precise))); + graph.addAfterFixed(node, graph.add(new SerialWriteBarrier(address, precise))); } private void addWriteNodeBarriers(WriteNode node, StructuredGraph graph) { @@ -107,11 +107,11 @@ boolean precise = barrierType == BarrierType.PRECISE; if (config.useG1GC) { if (!node.isInitialization()) { - addG1PreWriteBarrier(node, node.object(), null, node.location(), true, node.getNullCheck(), graph); + addG1PreWriteBarrier(node, node.getAddress(), null, true, node.getNullCheck(), graph); } - addG1PostWriteBarrier(node, node.object(), node.value(), node.location(), precise, graph); + addG1PostWriteBarrier(node, node.getAddress(), node.value(), precise, graph); } else { - addSerialPostWriteBarrier(node, node.object(), node.value(), node.location(), precise, graph); + addSerialPostWriteBarrier(node, node.getAddress(), node.value(), precise, graph); } break; default: @@ -129,10 +129,10 @@ case PRECISE: boolean precise = barrierType == BarrierType.PRECISE; if (config.useG1GC) { - addG1PreWriteBarrier(node, node.object(), null, node.location(), true, node.getNullCheck(), graph); - addG1PostWriteBarrier(node, node.object(), node.getNewValue(), node.location(), precise, graph); + addG1PreWriteBarrier(node, node.getAddress(), null, true, node.getNullCheck(), graph); + addG1PostWriteBarrier(node, node.getAddress(), node.getNewValue(), precise, graph); } else { - addSerialPostWriteBarrier(node, node.object(), node.getNewValue(), node.location(), precise, graph); + addSerialPostWriteBarrier(node, node.getAddress(), node.getNewValue(), precise, graph); } break; default: @@ -150,10 +150,10 @@ case PRECISE: boolean precise = barrierType == BarrierType.PRECISE; if (config.useG1GC) { - addG1PreWriteBarrier(node, node.object(), node.getExpectedValue(), node.location(), false, false, graph); - addG1PostWriteBarrier(node, node.object(), node.getNewValue(), node.location(), precise, graph); + addG1PreWriteBarrier(node, node.getAddress(), node.getExpectedValue(), false, false, graph); + addG1PostWriteBarrier(node, node.getAddress(), node.getNewValue(), precise, graph); } else { - addSerialPostWriteBarrier(node, node.object(), node.getNewValue(), node.location(), precise, graph); + addSerialPostWriteBarrier(node, node.getAddress(), node.getNewValue(), precise, graph); } break; default: diff -r 9c454c650b29 -r a858c5f56d8a graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/phases/WriteBarrierVerificationPhase.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/phases/WriteBarrierVerificationPhase.java Mon Jun 08 15:57:52 2015 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/phases/WriteBarrierVerificationPhase.java Mon Jun 08 18:47:58 2015 +0200 @@ -35,6 +35,7 @@ import com.oracle.graal.nodes.java.*; import com.oracle.graal.nodes.memory.*; import com.oracle.graal.nodes.memory.HeapAccess.BarrierType; +import com.oracle.graal.nodes.memory.address.*; import com.oracle.graal.nodes.type.*; import com.oracle.graal.phases.*; import com.oracle.jvmci.common.*; @@ -151,9 +152,11 @@ private static boolean validateBarrier(FixedAccessNode write, WriteBarrier barrier) { assert write instanceof WriteNode || write instanceof LoweredCompareAndSwapNode || write instanceof LoweredAtomicReadAndWriteNode : "Node must be of type requiring a write barrier " + write; - if ((barrier.getObject() == write.object()) && (!barrier.usePrecise() || (barrier.usePrecise() && barrier.getLocation() == write.location()))) { - return true; + if (!barrier.usePrecise()) { + if (barrier.getAddress() instanceof OffsetAddressNode && write.getAddress() instanceof OffsetAddressNode) { + return ((OffsetAddressNode) barrier.getAddress()).getBase() == ((OffsetAddressNode) write.getAddress()).getBase(); + } } - return false; + return barrier.getAddress() == write.getAddress(); } } diff -r 9c454c650b29 -r a858c5f56d8a graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/ClassGetHubNode.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/ClassGetHubNode.java Mon Jun 08 15:57:52 2015 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/ClassGetHubNode.java Mon Jun 08 18:47:58 2015 +0200 @@ -22,11 +22,6 @@ */ package com.oracle.graal.hotspot.replacements; -import com.oracle.jvmci.meta.MetaAccessProvider; -import com.oracle.jvmci.meta.JavaConstant; -import com.oracle.jvmci.meta.ConstantReflectionProvider; -import com.oracle.jvmci.meta.ResolvedJavaType; -import com.oracle.jvmci.meta.Constant; import com.oracle.graal.compiler.common.calc.*; import com.oracle.graal.graph.*; import com.oracle.graal.graph.spi.*; @@ -37,14 +32,16 @@ import com.oracle.graal.nodes.calc.*; import com.oracle.graal.nodes.extended.*; import com.oracle.graal.nodes.memory.*; +import com.oracle.graal.nodes.memory.address.*; import com.oracle.graal.nodes.spi.*; import com.oracle.jvmci.hotspot.*; +import com.oracle.jvmci.meta.*; /** * Read {@code Class::_klass} to get the hub for a {@link java.lang.Class}. This node mostly exists * to replace {@code _klass._java_mirror._klass} with {@code _klass}. The constant folding could be * handled by - * {@link ReadNode#canonicalizeRead(ValueNode, LocationNode, ValueNode, CanonicalizerTool)}. + * {@link ReadNode#canonicalizeRead(ValueNode, AddressNode, LocationIdentity, CanonicalizerTool)}. */ @NodeInfo public final class ClassGetHubNode extends FloatingGuardedNode implements Lowerable, Canonicalizable, ConvertNode { diff -r 9c454c650b29 -r a858c5f56d8a 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 Mon Jun 08 15:57:52 2015 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/MonitorSnippets.java Mon Jun 08 18:47:58 2015 +0200 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 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 @@ -58,6 +58,7 @@ import com.oracle.graal.nodes.debug.*; import com.oracle.graal.nodes.extended.*; import com.oracle.graal.nodes.java.*; +import com.oracle.graal.nodes.memory.address.*; import com.oracle.graal.nodes.spi.*; import com.oracle.graal.nodes.type.*; import com.oracle.graal.phases.common.inlining.*; @@ -180,7 +181,7 @@ Word biasedMark = unbiasedMark.or(thread); trace(trace, " unbiasedMark: 0x%016lx\n", unbiasedMark); trace(trace, " biasedMark: 0x%016lx\n", biasedMark); - if (probability(VERY_FAST_PATH_PROBABILITY, compareAndSwap(object, markOffset(), unbiasedMark, biasedMark, MARK_WORD_LOCATION).equal(unbiasedMark))) { + if (probability(VERY_FAST_PATH_PROBABILITY, compareAndSwap(OffsetAddressNode.address(object, markOffset()), unbiasedMark, biasedMark, MARK_WORD_LOCATION).equal(unbiasedMark))) { // Object is now biased to current thread -> done traceObject(trace, "+lock{bias:acquired}", object, true); lockBiasAcquired.inc(); @@ -200,7 +201,7 @@ // the bias from one thread to another directly in this situation. Word biasedMark = prototypeMarkWord.or(thread); trace(trace, " biasedMark: 0x%016lx\n", biasedMark); - if (probability(VERY_FAST_PATH_PROBABILITY, compareAndSwap(object, markOffset(), mark, biasedMark, MARK_WORD_LOCATION).equal(mark))) { + if (probability(VERY_FAST_PATH_PROBABILITY, compareAndSwap(OffsetAddressNode.address(object, markOffset()), mark, biasedMark, MARK_WORD_LOCATION).equal(mark))) { // Object is now biased to current thread -> done traceObject(trace, "+lock{bias:transfer}", object, true); lockBiasTransfer.inc(); @@ -223,7 +224,7 @@ // that another thread raced us for the privilege of revoking the // bias of this particular object, so it's okay to continue in the // normal locking code. - Word result = compareAndSwap(object, markOffset(), mark, prototypeMarkWord, MARK_WORD_LOCATION); + Word result = compareAndSwap(OffsetAddressNode.address(object, markOffset()), mark, prototypeMarkWord, MARK_WORD_LOCATION); // Fall through to the normal CAS-based lock, because no matter what // the result of the above CAS, some thread must have succeeded in @@ -246,7 +247,7 @@ // Test if the object's mark word is unlocked, and if so, store the // (address of) the lock slot into the object's mark word. - Word currentMark = compareAndSwap(object, markOffset(), unlockedMark, lock, MARK_WORD_LOCATION); + Word currentMark = compareAndSwap(OffsetAddressNode.address(object, markOffset()), unlockedMark, lock, MARK_WORD_LOCATION); if (currentMark.notEqual(unlockedMark)) { trace(trace, " currentMark: 0x%016lx\n", currentMark); // The mark word in the object header was not the same. @@ -337,7 +338,8 @@ // Test if object's mark word is pointing to the displaced mark word, and if so, restore // the displaced mark in the object - if the object's mark word is not pointing to // the displaced mark word, do unlocking via runtime call. - if (probability(VERY_SLOW_PATH_PROBABILITY, DirectCompareAndSwapNode.compareAndSwap(object, markOffset(), lock, displacedMark, MARK_WORD_LOCATION).notEqual(lock))) { + if (probability(VERY_SLOW_PATH_PROBABILITY, + DirectCompareAndSwapNode.compareAndSwap(OffsetAddressNode.address(object, markOffset()), lock, displacedMark, MARK_WORD_LOCATION).notEqual(lock))) { // The object's mark word was not pointing to the displaced header, // we do unlocking via runtime call. traceObject(trace, "-lock{stub}", object, false); diff -r 9c454c650b29 -r a858c5f56d8a graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/NewObjectSnippets.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/NewObjectSnippets.java Mon Jun 08 15:57:52 2015 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/NewObjectSnippets.java Mon Jun 08 18:47:58 2015 +0200 @@ -54,6 +54,7 @@ import com.oracle.graal.nodes.debug.*; import com.oracle.graal.nodes.extended.*; import com.oracle.graal.nodes.java.*; +import com.oracle.graal.nodes.memory.address.*; import com.oracle.graal.nodes.spi.*; import com.oracle.graal.nodes.util.*; import com.oracle.graal.replacements.*; @@ -135,7 +136,7 @@ int distance = config().allocatePrefetchDistance; ExplodeLoopNode.explodeLoop(); for (int i = 0; i < lines; i++) { - PrefetchAllocateNode.prefetch(address, Word.signed(distance)); + PrefetchAllocateNode.prefetch(OffsetAddressNode.address(address, distance)); distance += stepSize; } } diff -r 9c454c650b29 -r a858c5f56d8a graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/WriteBarrierSnippets.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/WriteBarrierSnippets.java Mon Jun 08 15:57:52 2015 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/WriteBarrierSnippets.java Mon Jun 08 18:47:58 2015 +0200 @@ -22,17 +22,11 @@ */ package com.oracle.graal.hotspot.replacements; -import com.oracle.jvmci.code.Register; -import com.oracle.jvmci.code.TargetDescription; -import com.oracle.jvmci.meta.NamedLocationIdentity; -import com.oracle.jvmci.meta.LocationIdentity; -import com.oracle.jvmci.meta.ForeignCallDescriptor; -import com.oracle.jvmci.meta.Kind; -import static com.oracle.jvmci.code.MemoryBarriers.*; import static com.oracle.graal.compiler.common.GraalOptions.*; import static com.oracle.graal.hotspot.replacements.HotSpotReplacementsUtil.*; import static com.oracle.graal.nodes.extended.BranchProbabilityNode.*; import static com.oracle.graal.replacements.SnippetTemplate.*; +import static com.oracle.jvmci.code.MemoryBarriers.*; import com.oracle.graal.compiler.common.*; import com.oracle.graal.graph.Node.ConstantNodeParameter; @@ -43,6 +37,8 @@ import com.oracle.graal.nodes.*; import com.oracle.graal.nodes.extended.*; import com.oracle.graal.nodes.memory.HeapAccess.BarrierType; +import com.oracle.graal.nodes.memory.address.*; +import com.oracle.graal.nodes.memory.address.AddressNode.Address; import com.oracle.graal.nodes.spi.*; import com.oracle.graal.replacements.*; import com.oracle.graal.replacements.Snippet.ConstantParameter; @@ -51,7 +47,9 @@ import com.oracle.graal.replacements.SnippetTemplate.SnippetInfo; import com.oracle.graal.replacements.nodes.*; import com.oracle.graal.word.*; +import com.oracle.jvmci.code.*; import com.oracle.jvmci.hotspot.HotSpotVMConfig.CompressEncoding; +import com.oracle.jvmci.meta.*; public class WriteBarrierSnippets implements Snippets { @@ -72,14 +70,8 @@ public static final LocationIdentity GC_INDEX_LOCATION = NamedLocationIdentity.mutable("GC-Index"); @Snippet - public static void serialWriteBarrier(Object object, Object location, @ConstantParameter boolean usePrecise) { - Object fixedObject = FixedValueAnchorNode.getObject(object); - Pointer oop; - if (usePrecise) { - oop = Word.fromArray(fixedObject, SnippetLocationProxyNode.location(location)); - } else { - oop = Word.fromObject(fixedObject); - } + public static void serialWriteBarrier(Address address) { + Pointer oop = Word.fromAddress(address); serialWriteBarrierCounter.inc(); int cardTableShift = (isImmutableCode() && generatePIC()) ? CardTableShiftNode.cardTableShift() : cardTableShift(); long cardTableAddress = (isImmutableCode() && generatePIC()) ? CardTableAddressNode.cardTableAddress() : cardTableStart(); @@ -114,16 +106,15 @@ } @Snippet - public static void g1PreWriteBarrier(Object object, Object expectedObject, Object location, @ConstantParameter boolean doLoad, @ConstantParameter boolean nullCheck, + public static void g1PreWriteBarrier(Address address, Object object, Object expectedObject, @ConstantParameter boolean doLoad, @ConstantParameter boolean nullCheck, @ConstantParameter Register threadRegister, @ConstantParameter boolean trace) { if (nullCheck) { - NullCheckNode.nullCheck(object); + NullCheckNode.nullCheck(address); } Word thread = registerAsWord(threadRegister); - Object fixedObject = FixedValueAnchorNode.getObject(object); - verifyOop(fixedObject); + verifyOop(object); Object fixedExpectedObject = FixedValueAnchorNode.getObject(expectedObject); - Word field = Word.fromWordBase(Word.fromArray(fixedObject, SnippetLocationProxyNode.location(location))); + Word field = Word.fromWordBase(Word.fromAddress(address)); Word previousOop = Word.fromWordBase(Word.fromObject(fixedExpectedObject)); byte markingValue = thread.readByte(g1SATBQueueMarkingOffset()); Word bufferAddress = thread.readWord(g1SATBQueueBufferOffset()); @@ -132,7 +123,7 @@ int gcCycle = 0; if (trace) { gcCycle = (int) Word.unsigned(HotSpotReplacementsUtil.gcTotalCollectionsAddress()).readLong(0); - log(trace, "[%d] G1-Pre Thread %p Object %p\n", gcCycle, thread.rawValue(), Word.fromObject(fixedObject).rawValue()); + log(trace, "[%d] G1-Pre Thread %p Object %p\n", gcCycle, thread.rawValue(), Word.fromObject(object).rawValue()); log(trace, "[%d] G1-Pre Thread %p Expected Object %p\n", gcCycle, thread.rawValue(), Word.fromObject(fixedExpectedObject).rawValue()); log(trace, "[%d] G1-Pre Thread %p Field %p\n", gcCycle, thread.rawValue(), field.rawValue()); log(trace, "[%d] G1-Pre Thread %p Marking %d\n", gcCycle, thread.rawValue(), markingValue); @@ -170,24 +161,17 @@ } @Snippet - public static void g1PostWriteBarrier(Object object, Object value, Object location, @ConstantParameter boolean usePrecise, @ConstantParameter Register threadRegister, - @ConstantParameter boolean trace) { + public static void g1PostWriteBarrier(Address address, Object object, Object value, @ConstantParameter Register threadRegister, @ConstantParameter boolean trace) { Word thread = registerAsWord(threadRegister); - Object fixedObject = FixedValueAnchorNode.getObject(object); Object fixedValue = FixedValueAnchorNode.getObject(value); - verifyOop(fixedObject); + verifyOop(object); verifyOop(fixedValue); - validateObject(fixedObject, fixedValue); - Word oop; - if (usePrecise) { - oop = Word.fromWordBase(Word.fromArray(fixedObject, SnippetLocationProxyNode.location(location))); - } else { - oop = Word.fromWordBase(Word.fromObject(fixedObject)); - } + validateObject(object, fixedValue); + Word oop = Word.fromWordBase(Word.fromAddress(address)); int gcCycle = 0; if (trace) { gcCycle = (int) Word.unsigned(HotSpotReplacementsUtil.gcTotalCollectionsAddress()).readLong(0); - log(trace, "[%d] G1-Post Thread: %p Object: %p\n", gcCycle, thread.rawValue(), Word.fromObject(fixedObject).rawValue()); + log(trace, "[%d] G1-Post Thread: %p Object: %p\n", gcCycle, thread.rawValue(), Word.fromObject(object).rawValue()); log(trace, "[%d] G1-Post Thread: %p Field: %p\n", gcCycle, thread.rawValue(), oop.rawValue()); } Word writtenValue = Word.fromWordBase(Word.fromObject(fixedValue)); @@ -355,9 +339,7 @@ public void lower(SerialWriteBarrier writeBarrier, LoweringTool tool) { Arguments args = new Arguments(serialWriteBarrier, writeBarrier.graph().getGuardsStage(), tool.getLoweringStage()); - args.add("object", writeBarrier.getObject()); - args.add("location", writeBarrier.getLocation()); - args.addConst("usePrecise", writeBarrier.usePrecise()); + args.add("address", writeBarrier.getAddress()); template(args).instantiate(providers.getMetaAccess(), writeBarrier, DEFAULT_REPLACER, args); } @@ -371,7 +353,13 @@ public void lower(G1PreWriteBarrier writeBarrierPre, HotSpotRegistersProvider registers, LoweringTool tool) { Arguments args = new Arguments(g1PreWriteBarrier, writeBarrierPre.graph().getGuardsStage(), tool.getLoweringStage()); - args.add("object", writeBarrierPre.getObject()); + AddressNode address = writeBarrierPre.getAddress(); + args.add("address", address); + if (address instanceof OffsetAddressNode) { + args.add("object", ((OffsetAddressNode) address).getBase()); + } else { + args.add("object", null); + } ValueNode expected = writeBarrierPre.getExpectedObject(); if (expected != null && expected.stamp() instanceof NarrowOopStamp) { @@ -380,7 +368,6 @@ } args.add("expectedObject", expected); - args.add("location", writeBarrierPre.getLocation()); args.addConst("doLoad", writeBarrierPre.doLoad()); args.addConst("nullCheck", writeBarrierPre.getNullCheck()); args.addConst("threadRegister", registers.getThreadRegister()); @@ -390,7 +377,13 @@ public void lower(G1ReferentFieldReadBarrier readBarrier, HotSpotRegistersProvider registers, LoweringTool tool) { Arguments args = new Arguments(g1ReferentReadBarrier, readBarrier.graph().getGuardsStage(), tool.getLoweringStage()); - args.add("object", readBarrier.getObject()); + AddressNode address = readBarrier.getAddress(); + args.add("address", address); + if (address instanceof OffsetAddressNode) { + args.add("object", ((OffsetAddressNode) address).getBase()); + } else { + args.add("object", null); + } ValueNode expected = readBarrier.getExpectedObject(); if (expected != null && expected.stamp() instanceof NarrowOopStamp) { @@ -399,7 +392,6 @@ } args.add("expectedObject", expected); - args.add("location", readBarrier.getLocation()); args.addConst("doLoad", readBarrier.doLoad()); args.addConst("nullCheck", false); args.addConst("threadRegister", registers.getThreadRegister()); @@ -414,7 +406,13 @@ return; } Arguments args = new Arguments(g1PostWriteBarrier, graph.getGuardsStage(), tool.getLoweringStage()); - args.add("object", writeBarrierPost.getObject()); + AddressNode address = writeBarrierPost.getAddress(); + args.add("address", address); + if (address instanceof OffsetAddressNode) { + args.add("object", ((OffsetAddressNode) address).getBase()); + } else { + args.add("object", null); + } ValueNode value = writeBarrierPost.getValue(); if (value.stamp() instanceof NarrowOopStamp) { @@ -423,8 +421,6 @@ } args.add("value", value); - args.add("location", writeBarrierPost.getLocation()); - args.addConst("usePrecise", writeBarrierPost.usePrecise()); args.addConst("threadRegister", registers.getThreadRegister()); args.addConst("trace", traceBarrier()); template(args).instantiate(providers.getMetaAccess(), writeBarrierPost, DEFAULT_REPLACER, args); diff -r 9c454c650b29 -r a858c5f56d8a graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/arraycopy/ArrayCopyCallNode.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/arraycopy/ArrayCopyCallNode.java Mon Jun 08 15:57:52 2015 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/arraycopy/ArrayCopyCallNode.java Mon Jun 08 18:47:58 2015 +0200 @@ -23,12 +23,6 @@ //JaCoCo Exclude package com.oracle.graal.hotspot.replacements.arraycopy; -import com.oracle.jvmci.meta.NamedLocationIdentity; -import com.oracle.jvmci.meta.JavaConstant; -import com.oracle.jvmci.meta.PrimitiveConstant; -import com.oracle.jvmci.meta.LocationIdentity; -import com.oracle.jvmci.meta.ForeignCallDescriptor; -import com.oracle.jvmci.meta.Kind; import com.oracle.graal.api.runtime.*; import com.oracle.graal.compiler.common.type.*; import com.oracle.graal.graph.*; @@ -41,9 +35,12 @@ import com.oracle.graal.nodes.calc.*; import com.oracle.graal.nodes.extended.*; import com.oracle.graal.nodes.memory.*; +import com.oracle.graal.nodes.memory.address.*; import com.oracle.graal.nodes.spi.*; import com.oracle.graal.runtime.*; +import com.oracle.jvmci.code.*; import com.oracle.jvmci.hotspot.*; +import com.oracle.jvmci.meta.*; @NodeInfo(allowedUsageTypes = {InputType.Memory}) public final class ArrayCopyCallNode extends AbstractMemoryCheckpoint implements Lowerable, MemoryCheckpoint.Single, MemoryAccess, Canonicalizable { @@ -123,9 +120,11 @@ private ValueNode computeBase(ValueNode base, ValueNode pos) { FixedWithNextNode basePtr = graph().add(new GetObjectAddressNode(base)); graph().addBeforeFixed(this, basePtr); - ValueNode loc = graph().unique( - new IndexedLocationNode(getLocationIdentity(), runtime.getJVMCIRuntime().getArrayBaseOffset(elementKind), pos, runtime.getJVMCIRuntime().getArrayIndexScale(elementKind))); - return graph().unique(new ComputeAddressNode(basePtr, loc, StampFactory.forKind(Kind.Long))); + HotSpotJVMCIRuntimeProvider jvmciRuntime = runtime.getJVMCIRuntime(); + int shift = CodeUtil.log2(jvmciRuntime.getArrayIndexScale(elementKind)); + ValueNode scaledIndex = graph().unique(new LeftShiftNode(pos, ConstantNode.forInt(shift, graph()))); + ValueNode offset = graph().unique(new AddNode(scaledIndex, ConstantNode.forInt(jvmciRuntime.getArrayBaseOffset(elementKind), graph()))); + return graph().unique(new OffsetAddressNode(basePtr, offset)); } @Override diff -r 9c454c650b29 -r a858c5f56d8a graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/arraycopy/CheckcastArrayCopyCallNode.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/arraycopy/CheckcastArrayCopyCallNode.java Mon Jun 08 15:57:52 2015 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/arraycopy/CheckcastArrayCopyCallNode.java Mon Jun 08 18:47:58 2015 +0200 @@ -23,9 +23,6 @@ //JaCoCo Exclude package com.oracle.graal.hotspot.replacements.arraycopy; -import com.oracle.jvmci.meta.LocationIdentity; -import com.oracle.jvmci.meta.ForeignCallDescriptor; -import com.oracle.jvmci.meta.Kind; import com.oracle.graal.compiler.common.type.*; import com.oracle.graal.graph.*; import com.oracle.graal.hotspot.*; @@ -36,9 +33,12 @@ import com.oracle.graal.nodes.calc.*; import com.oracle.graal.nodes.extended.*; import com.oracle.graal.nodes.memory.*; +import com.oracle.graal.nodes.memory.address.*; import com.oracle.graal.nodes.spi.*; import com.oracle.graal.word.*; +import com.oracle.jvmci.code.*; import com.oracle.jvmci.hotspot.*; +import com.oracle.jvmci.meta.*; @NodeInfo(allowedUsageTypes = {InputType.Memory, InputType.Value}) public final class CheckcastArrayCopyCallNode extends AbstractMemoryCheckpoint implements Lowerable, MemoryCheckpoint.Single { @@ -97,9 +97,12 @@ private ValueNode computeBase(ValueNode base, ValueNode pos) { FixedWithNextNode basePtr = graph().add(new GetObjectAddressNode(base)); graph().addBeforeFixed(this, basePtr); + HotSpotJVMCIRuntimeProvider jvmciRuntime = runtime.getJVMCIRuntime(); - ValueNode loc = graph().unique(new IndexedLocationNode(getLocationIdentity(), jvmciRuntime.getArrayBaseOffset(Kind.Object), pos, jvmciRuntime.getArrayIndexScale(Kind.Object))); - return graph().unique(new ComputeAddressNode(basePtr, loc, StampFactory.forKind(Kind.Long))); + int shift = CodeUtil.log2(jvmciRuntime.getArrayIndexScale(Kind.Object)); + ValueNode scaledIndex = graph().unique(new LeftShiftNode(pos, ConstantNode.forInt(shift, graph()))); + ValueNode offset = graph().unique(new AddNode(scaledIndex, ConstantNode.forInt(jvmciRuntime.getArrayBaseOffset(Kind.Object), graph()))); + return graph().unique(new OffsetAddressNode(basePtr, offset)); } @Override diff -r 9c454c650b29 -r a858c5f56d8a graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/stubs/NewInstanceStub.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/stubs/NewInstanceStub.java Mon Jun 08 15:57:52 2015 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/stubs/NewInstanceStub.java Mon Jun 08 18:47:58 2015 +0200 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 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 @@ -40,6 +40,7 @@ import com.oracle.graal.hotspot.replacements.*; import com.oracle.graal.hotspot.word.*; import com.oracle.graal.nodes.*; +import com.oracle.graal.nodes.memory.address.*; import com.oracle.graal.replacements.*; import com.oracle.graal.replacements.Snippet.ConstantParameter; import com.oracle.graal.word.*; @@ -246,7 +247,7 @@ return Word.zero(); } - if (compareAndSwap(heapTopAddress, 0, heapTop, newHeapTop, HEAP_TOP_LOCATION).equal(heapTop)) { + if (compareAndSwap(RawAddressNode.address(heapTopAddress), heapTop, newHeapTop, HEAP_TOP_LOCATION).equal(heapTop)) { return heapTop; } } diff -r 9c454c650b29 -r a858c5f56d8a graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/word/MetaspacePointer.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/word/MetaspacePointer.java Mon Jun 08 15:57:52 2015 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/word/MetaspacePointer.java Mon Jun 08 18:47:58 2015 +0200 @@ -22,14 +22,13 @@ */ package com.oracle.graal.hotspot.word; -import com.oracle.jvmci.meta.LocationIdentity; import static com.oracle.graal.hotspot.word.HotSpotOperation.HotspotOpcode.*; -import com.oracle.graal.nodes.extended.*; import com.oracle.graal.nodes.memory.HeapAccess.BarrierType; import com.oracle.graal.word.*; import com.oracle.graal.word.Word.Opcode; import com.oracle.graal.word.Word.Operation; +import com.oracle.jvmci.meta.*; /** * Marker type for a metaspace pointer. @@ -51,7 +50,7 @@ * knows that the highest-order bit of the unsigned value is never used). * * @param offset the signed offset for the memory access - * @param locationIdentity the identity of the read (see {@link LocationNode}) + * @param locationIdentity the identity of the read * @return the result of the memory access */ @Operation(opcode = Opcode.READ_POINTER) @@ -66,7 +65,7 @@ * knows that the highest-order bit of the unsigned value is never used). * * @param offset the signed offset for the memory access - * @param locationIdentity the identity of the read (see {@link LocationNode}) + * @param locationIdentity the identity of the read * @return the result of the memory access */ @Operation(opcode = Opcode.READ_POINTER) @@ -81,7 +80,7 @@ * knows that the highest-order bit of the unsigned value is never used). * * @param offset the signed offset for the memory access - * @param locationIdentity the identity of the read (see {@link LocationNode}) + * @param locationIdentity the identity of the read * @return the result of the memory access */ @Operation(opcode = Opcode.READ_POINTER) @@ -96,7 +95,7 @@ * knows that the highest-order bit of the unsigned value is never used). * * @param offset the signed offset for the memory access - * @param locationIdentity the identity of the read (see {@link LocationNode}) + * @param locationIdentity the identity of the read * @return the result of the memory access */ @Operation(opcode = Opcode.READ_POINTER) @@ -111,7 +110,7 @@ * knows that the highest-order bit of the unsigned value is never used). * * @param offset the signed offset for the memory access - * @param locationIdentity the identity of the read (see {@link LocationNode}) + * @param locationIdentity the identity of the read * @return the result of the memory access */ @Operation(opcode = Opcode.READ_POINTER) @@ -126,7 +125,7 @@ * knows that the highest-order bit of the unsigned value is never used). * * @param offset the signed offset for the memory access - * @param locationIdentity the identity of the read (see {@link LocationNode}) + * @param locationIdentity the identity of the read * @return the result of the memory access */ @Operation(opcode = Opcode.READ_POINTER) @@ -141,7 +140,7 @@ * knows that the highest-order bit of the unsigned value is never used). * * @param offset the signed offset for the memory access - * @param locationIdentity the identity of the read (see {@link LocationNode}) + * @param locationIdentity the identity of the read * @return the result of the memory access */ @Operation(opcode = Opcode.READ_POINTER) @@ -156,7 +155,7 @@ * knows that the highest-order bit of the unsigned value is never used). * * @param offset the signed offset for the memory access - * @param locationIdentity the identity of the read (see {@link LocationNode}) + * @param locationIdentity the identity of the read * @return the result of the memory access */ @Operation(opcode = Opcode.READ_POINTER) @@ -171,7 +170,7 @@ * knows that the highest-order bit of the unsigned value is never used). * * @param offset the signed offset for the memory access - * @param locationIdentity the identity of the read (see {@link LocationNode}) + * @param locationIdentity the identity of the read * @return the result of the memory access */ @Operation(opcode = Opcode.READ_POINTER) @@ -182,7 +181,7 @@ * bytes. * * @param offset the signed offset for the memory access - * @param locationIdentity the identity of the read (see {@link LocationNode}) + * @param locationIdentity the identity of the read * @return the result of the memory access */ @Operation(opcode = Opcode.READ_POINTER) @@ -193,7 +192,7 @@ * bytes. * * @param offset the signed offset for the memory access - * @param locationIdentity the identity of the read (see {@link LocationNode}) + * @param locationIdentity the identity of the read * @return the result of the memory access */ @Operation(opcode = Opcode.READ_POINTER) @@ -204,7 +203,7 @@ * bytes. * * @param offset the signed offset for the memory access - * @param locationIdentity the identity of the read (see {@link LocationNode}) + * @param locationIdentity the identity of the read * @return the result of the memory access */ @Operation(opcode = Opcode.READ_POINTER) @@ -215,7 +214,7 @@ * bytes. * * @param offset the signed offset for the memory access - * @param locationIdentity the identity of the read (see {@link LocationNode}) + * @param locationIdentity the identity of the read * @return the result of the memory access */ @Operation(opcode = Opcode.READ_POINTER) @@ -226,7 +225,7 @@ * bytes. * * @param offset the signed offset for the memory access - * @param locationIdentity the identity of the read (see {@link LocationNode}) + * @param locationIdentity the identity of the read * @return the result of the memory access */ @Operation(opcode = Opcode.READ_POINTER) @@ -237,7 +236,7 @@ * bytes. * * @param offset the signed offset for the memory access - * @param locationIdentity the identity of the read (see {@link LocationNode}) + * @param locationIdentity the identity of the read * @return the result of the memory access */ @Operation(opcode = Opcode.READ_POINTER) @@ -248,7 +247,7 @@ * bytes. * * @param offset the signed offset for the memory access - * @param locationIdentity the identity of the read (see {@link LocationNode}) + * @param locationIdentity the identity of the read * @return the result of the memory access */ @Operation(opcode = Opcode.READ_POINTER) @@ -259,7 +258,7 @@ * bytes. * * @param offset the signed offset for the memory access - * @param locationIdentity the identity of the read (see {@link LocationNode}) + * @param locationIdentity the identity of the read * @return the result of the memory access */ @Operation(opcode = Opcode.READ_POINTER) @@ -270,7 +269,7 @@ * bytes. * * @param offset the signed offset for the memory access - * @param locationIdentity the identity of the read (see {@link LocationNode}) + * @param locationIdentity the identity of the read * @return the result of the memory access */ @Operation(opcode = Opcode.READ_POINTER) @@ -285,7 +284,7 @@ * knows that the highest-order bit of the unsigned value is never used). * * @param offset the signed offset for the memory access - * @param locationIdentity the identity of the write (see {@link LocationNode}) + * @param locationIdentity the identity of the write * @param val the value to be written to memory */ @Operation(opcode = Opcode.WRITE_POINTER) @@ -300,7 +299,7 @@ * knows that the highest-order bit of the unsigned value is never used). * * @param offset the signed offset for the memory access - * @param locationIdentity the identity of the write (see {@link LocationNode}) + * @param locationIdentity the identity of the write * @param val the value to be written to memory */ @Operation(opcode = Opcode.WRITE_POINTER) @@ -315,7 +314,7 @@ * knows that the highest-order bit of the unsigned value is never used). * * @param offset the signed offset for the memory access - * @param locationIdentity the identity of the write (see {@link LocationNode}) + * @param locationIdentity the identity of the write * @param val the value to be written to memory */ @Operation(opcode = Opcode.WRITE_POINTER) @@ -330,7 +329,7 @@ * knows that the highest-order bit of the unsigned value is never used). * * @param offset the signed offset for the memory access - * @param locationIdentity the identity of the write (see {@link LocationNode}) + * @param locationIdentity the identity of the write * @param val the value to be written to memory */ @Operation(opcode = Opcode.WRITE_POINTER) @@ -345,7 +344,7 @@ * knows that the highest-order bit of the unsigned value is never used). * * @param offset the signed offset for the memory access - * @param locationIdentity the identity of the write (see {@link LocationNode}) + * @param locationIdentity the identity of the write * @param val the value to be written to memory */ @Operation(opcode = Opcode.WRITE_POINTER) @@ -360,7 +359,7 @@ * knows that the highest-order bit of the unsigned value is never used). * * @param offset the signed offset for the memory access - * @param locationIdentity the identity of the write (see {@link LocationNode}) + * @param locationIdentity the identity of the write * @param val the value to be written to memory */ @Operation(opcode = Opcode.WRITE_POINTER) @@ -375,7 +374,7 @@ * knows that the highest-order bit of the unsigned value is never used). * * @param offset the signed offset for the memory access - * @param locationIdentity the identity of the write (see {@link LocationNode}) + * @param locationIdentity the identity of the write * @param val the value to be written to memory */ @Operation(opcode = Opcode.WRITE_POINTER) @@ -390,7 +389,7 @@ * knows that the highest-order bit of the unsigned value is never used). * * @param offset the signed offset for the memory access - * @param locationIdentity the identity of the write (see {@link LocationNode}) + * @param locationIdentity the identity of the write * @param val the value to be written to memory */ @Operation(opcode = Opcode.WRITE_POINTER) @@ -405,7 +404,7 @@ * knows that the highest-order bit of the unsigned value is never used). * * @param offset the signed offset for the memory access - * @param locationIdentity the identity of the write (see {@link LocationNode}) + * @param locationIdentity the identity of the write * @param val the value to be written to memory */ @Operation(opcode = Opcode.INITIALIZE) @@ -420,7 +419,7 @@ * knows that the highest-order bit of the unsigned value is never used). * * @param offset the signed offset for the memory access - * @param locationIdentity the identity of the write (see {@link LocationNode}) + * @param locationIdentity the identity of the write * @param val the value to be written to memory */ @Operation(opcode = Opcode.WRITE_POINTER) @@ -431,7 +430,7 @@ * bytes. * * @param offset the signed offset for the memory access - * @param locationIdentity the identity of the write (see {@link LocationNode}) + * @param locationIdentity the identity of the write * @param val the value to be written to memory */ @Operation(opcode = Opcode.WRITE_POINTER) @@ -442,7 +441,7 @@ * bytes. * * @param offset the signed offset for the memory access - * @param locationIdentity the identity of the write (see {@link LocationNode}) + * @param locationIdentity the identity of the write * @param val the value to be written to memory */ @Operation(opcode = Opcode.WRITE_POINTER) @@ -453,7 +452,7 @@ * bytes. * * @param offset the signed offset for the memory access - * @param locationIdentity the identity of the write (see {@link LocationNode}) + * @param locationIdentity the identity of the write * @param val the value to be written to memory */ @Operation(opcode = Opcode.WRITE_POINTER) @@ -464,7 +463,7 @@ * bytes. * * @param offset the signed offset for the memory access - * @param locationIdentity the identity of the write (see {@link LocationNode}) + * @param locationIdentity the identity of the write * @param val the value to be written to memory */ @Operation(opcode = Opcode.WRITE_POINTER) @@ -475,7 +474,7 @@ * bytes. * * @param offset the signed offset for the memory access - * @param locationIdentity the identity of the write (see {@link LocationNode}) + * @param locationIdentity the identity of the write * @param val the value to be written to memory */ @Operation(opcode = Opcode.WRITE_POINTER) @@ -486,7 +485,7 @@ * bytes. * * @param offset the signed offset for the memory access - * @param locationIdentity the identity of the write (see {@link LocationNode}) + * @param locationIdentity the identity of the write * @param val the value to be written to memory */ @Operation(opcode = Opcode.WRITE_POINTER) @@ -497,7 +496,7 @@ * bytes. * * @param offset the signed offset for the memory access - * @param locationIdentity the identity of the write (see {@link LocationNode}) + * @param locationIdentity the identity of the write * @param val the value to be written to memory */ @Operation(opcode = Opcode.WRITE_POINTER) @@ -508,7 +507,7 @@ * bytes. * * @param offset the signed offset for the memory access - * @param locationIdentity the identity of the write (see {@link LocationNode}) + * @param locationIdentity the identity of the write * @param val the value to be written to memory */ @Operation(opcode = Opcode.WRITE_POINTER) @@ -519,7 +518,7 @@ * are in bytes. The memory must be uninitialized or zero prior to this operation. * * @param offset the signed offset for the memory access - * @param locationIdentity the identity of the write (see {@link LocationNode}) + * @param locationIdentity the identity of the write * @param val the value to be written to memory */ @Operation(opcode = Opcode.INITIALIZE) @@ -530,7 +529,7 @@ * bytes. * * @param offset the signed offset for the memory access - * @param locationIdentity the identity of the write (see {@link LocationNode}) + * @param locationIdentity the identity of the write * @param val the value to be written to memory */ @Operation(opcode = Opcode.WRITE_POINTER) diff -r 9c454c650b29 -r a858c5f56d8a graal/com.oracle.graal.lir/src/com/oracle/graal/lir/gen/LIRGeneratorTool.java --- a/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/gen/LIRGeneratorTool.java Mon Jun 08 15:57:52 2015 +0200 +++ b/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/gen/LIRGeneratorTool.java Mon Jun 08 18:47:58 2015 +0200 @@ -142,8 +142,6 @@ */ void emitData(AllocatableValue dst, byte[] data); - Value emitAddress(Value base, long displacement, Value index, int scale); - Variable emitAddress(StackSlotValue slot); void emitMembar(int barriers); diff -r 9c454c650b29 -r a858c5f56d8a graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/AddLocationNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/AddLocationNode.java Mon Jun 08 15:57:52 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,112 +0,0 @@ -/* - * Copyright (c) 2013, 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.extended; - -import com.oracle.graal.compiler.common.type.*; -import com.oracle.graal.graph.*; -import com.oracle.graal.graph.spi.*; -import com.oracle.graal.lir.gen.*; -import com.oracle.graal.nodeinfo.*; -import com.oracle.graal.nodes.*; -import com.oracle.graal.nodes.calc.*; -import com.oracle.graal.nodes.spi.*; -import com.oracle.jvmci.meta.*; - -/** - * Location node that is the sum of two other location nodes. Can represent locations in the form of - * [(base + x) + y] where base is a node and x and y are location nodes. - */ -@NodeInfo(nameTemplate = "&+({p#locationIdentity/s})") -public final class AddLocationNode extends LocationNode implements Canonicalizable.Binary { - - public static final NodeClass TYPE = NodeClass.create(AddLocationNode.class); - @Input(InputType.Association) ValueNode x; - @Input(InputType.Association) ValueNode y; - - public LocationNode getX() { - return (LocationNode) x; - } - - public LocationNode getY() { - return (LocationNode) y; - } - - public AddLocationNode(LocationNode x, LocationNode y) { - super(TYPE, StampFactory.forVoid()); - assert x.getLocationIdentity().equals(y.getLocationIdentity()); - this.x = x; - this.y = y; - } - - @Override - public LocationIdentity getLocationIdentity() { - return getX().getLocationIdentity(); - } - - public LocationNode canonical(CanonicalizerTool tool, LocationNode forX, LocationNode forY) { - if (forX instanceof ConstantLocationNode) { - return canonical((ConstantLocationNode) forX, forY); - } - if (forY instanceof ConstantLocationNode) { - return canonical((ConstantLocationNode) forY, forX); - } - if (forX instanceof IndexedLocationNode && forY instanceof IndexedLocationNode) { - IndexedLocationNode xIdx = (IndexedLocationNode) forX; - IndexedLocationNode yIdx = (IndexedLocationNode) forY; - if (xIdx.getIndexScaling() == yIdx.getIndexScaling()) { - long displacement = xIdx.getDisplacement() + yIdx.getDisplacement(); - ValueNode index = BinaryArithmeticNode.add(xIdx.getIndex(), yIdx.getIndex()); - return new IndexedLocationNode(getLocationIdentity(), displacement, index, xIdx.getIndexScaling()); - } - } - return this; - } - - private LocationNode canonical(ConstantLocationNode constant, LocationNode other) { - if (other instanceof ConstantLocationNode) { - ConstantLocationNode otherConst = (ConstantLocationNode) other; - return new ConstantLocationNode(getLocationIdentity(), otherConst.getDisplacement() + constant.getDisplacement()); - } else if (other instanceof IndexedLocationNode) { - IndexedLocationNode otherIdx = (IndexedLocationNode) other; - return new IndexedLocationNode(getLocationIdentity(), otherIdx.getDisplacement() + constant.getDisplacement(), otherIdx.getIndex(), otherIdx.getIndexScaling()); - } else if (other instanceof AddLocationNode) { - AddLocationNode otherAdd = (AddLocationNode) other; - LocationNode newInner = otherAdd.canonical(constant, otherAdd.getX()); - if (newInner != otherAdd) { - return new AddLocationNode(newInner, otherAdd.getY()); - } - } - return this; - } - - @Override - public Value generateAddress(NodeMappableLIRBuilder builder, LIRGeneratorTool gen, Value base) { - Value xAddr = getX().generateAddress(builder, gen, base); - return getY().generateAddress(builder, gen, xAddr); - } - - @Override - public IntegerStamp getDisplacementStamp() { - return (IntegerStamp) IntegerStamp.OPS.getAdd().foldStamp(getX().getDisplacementStamp(), getY().getDisplacementStamp()); - } -} diff -r 9c454c650b29 -r a858c5f56d8a graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/ComputeAddressNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/ComputeAddressNode.java Mon Jun 08 15:57:52 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,59 +0,0 @@ -/* - * Copyright (c) 2009, 2011, 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.extended; - -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.calc.*; -import com.oracle.graal.nodes.spi.*; -import com.oracle.jvmci.meta.*; - -@NodeInfo -public final class ComputeAddressNode extends FloatingNode implements LIRLowerable { - - public static final NodeClass TYPE = NodeClass.create(ComputeAddressNode.class); - @Input ValueNode object; - @Input(InputType.Association) ValueNode location; - - public ValueNode getObject() { - return object; - } - - public LocationNode getLocation() { - return (LocationNode) location; - } - - public ComputeAddressNode(ValueNode object, ValueNode location, Stamp stamp) { - super(TYPE, stamp); - this.object = object; - this.location = location; - } - - @Override - public void generate(NodeLIRBuilderTool gen) { - Value addr = getLocation().generateAddress(gen, gen.getLIRGeneratorTool(), gen.operand(getObject())); - gen.setResult(this, gen.getLIRGeneratorTool().asAllocatable(addr)); - } -} diff -r 9c454c650b29 -r a858c5f56d8a graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/ConstantLocationNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/ConstantLocationNode.java Mon Jun 08 15:57:52 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,67 +0,0 @@ -/* - * Copyright (c) 2011, 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.extended; - -import com.oracle.graal.compiler.common.type.*; -import com.oracle.graal.graph.*; -import com.oracle.graal.lir.gen.*; -import com.oracle.graal.nodeinfo.*; -import com.oracle.graal.nodes.spi.*; -import com.oracle.jvmci.meta.*; - -/** - * Location node that has a constant displacement. Can represent addresses of the form [base + disp] - * where base is a node and disp is a constant. - */ -@NodeInfo(nameTemplate = "&({p#locationIdentity/s})") -public final class ConstantLocationNode extends LocationNode { - - public static final NodeClass TYPE = NodeClass.create(ConstantLocationNode.class); - protected final LocationIdentity locationIdentity; - protected final long displacement; - - public ConstantLocationNode(LocationIdentity identity, long displacement) { - super(TYPE, StampFactory.forVoid()); - this.locationIdentity = identity; - this.displacement = displacement; - } - - @Override - public LocationIdentity getLocationIdentity() { - return locationIdentity; - } - - public long getDisplacement() { - return displacement; - } - - @Override - public Value generateAddress(NodeMappableLIRBuilder builder, LIRGeneratorTool gen, Value base) { - return gen.emitAddress(base, getDisplacement(), Value.ILLEGAL, 0); - } - - @Override - public IntegerStamp getDisplacementStamp() { - return StampFactory.forInteger(64, displacement, displacement); - } -} diff -r 9c454c650b29 -r a858c5f56d8a graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/IndexedLocationNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/IndexedLocationNode.java Mon Jun 08 15:57:52 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,102 +0,0 @@ -/* - * Copyright (c) 2011, 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.extended; - -import com.oracle.graal.compiler.common.type.*; -import com.oracle.graal.graph.*; -import com.oracle.graal.graph.spi.*; -import com.oracle.graal.lir.gen.*; -import com.oracle.graal.nodeinfo.*; -import com.oracle.graal.nodes.*; -import com.oracle.graal.nodes.spi.*; -import com.oracle.jvmci.code.*; -import com.oracle.jvmci.meta.*; - -/** - * Location node that has a displacement and a scaled index. Can represent locations in the form of - * [base + index * scale + disp] where base and index are nodes and scale and disp are integer - * constants. - */ -@NodeInfo(nameTemplate = "&({p#locationIdentity/s})[{i#index}]") -public final class IndexedLocationNode extends LocationNode implements Canonicalizable { - public static final NodeClass TYPE = NodeClass.create(IndexedLocationNode.class); - - protected final LocationIdentity locationIdentity; - protected final long displacement; - @Input ValueNode index; - protected final int indexScaling; - - /** - * Gets the index or offset of this location. - */ - public ValueNode getIndex() { - return index; - } - - public long getDisplacement() { - return displacement; - } - - /** - * @return Constant that is used to scale the index. - */ - public int getIndexScaling() { - return indexScaling; - } - - public IndexedLocationNode(LocationIdentity identity, long displacement, ValueNode index, int indexScaling) { - super(TYPE, StampFactory.forVoid()); - assert index != null; - assert indexScaling != 0; - this.locationIdentity = identity; - this.index = index; - this.displacement = displacement; - this.indexScaling = indexScaling; - } - - @Override - public LocationIdentity getLocationIdentity() { - return locationIdentity; - } - - @Override - public Node canonical(CanonicalizerTool tool) { - if (index.isConstant()) { - return new ConstantLocationNode(getLocationIdentity(), index.asJavaConstant().asLong() * indexScaling + displacement); - } - return this; - } - - @Override - public IntegerStamp getDisplacementStamp() { - assert indexScaling > 0 && CodeUtil.isPowerOf2(indexScaling); - int scale = CodeUtil.log2(indexScaling); - return (IntegerStamp) IntegerStamp.OPS.getAdd().foldStamp(StampFactory.forInteger(64, displacement, displacement), - IntegerStamp.OPS.getSignExtend().foldStamp(32, 64, IntegerStamp.OPS.getShl().foldStamp(index.stamp(), StampFactory.forInteger(64, scale, scale)))); - } - - @Override - public Value generateAddress(NodeMappableLIRBuilder builder, LIRGeneratorTool gen, Value base) { - return gen.emitAddress(base, displacement, builder.operand(getIndex()), getIndexScaling()); - } -} diff -r 9c454c650b29 -r a858c5f56d8a graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/JavaReadNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/JavaReadNode.java Mon Jun 08 15:57:52 2015 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/JavaReadNode.java Mon Jun 08 18:47:58 2015 +0200 @@ -26,8 +26,8 @@ import com.oracle.graal.graph.*; import com.oracle.graal.graph.spi.*; import com.oracle.graal.nodeinfo.*; -import com.oracle.graal.nodes.*; import com.oracle.graal.nodes.memory.*; +import com.oracle.graal.nodes.memory.address.*; import com.oracle.graal.nodes.spi.*; import com.oracle.jvmci.meta.*; @@ -42,8 +42,8 @@ protected final Kind readKind; protected final boolean compressible; - public JavaReadNode(Kind readKind, ValueNode object, LocationNode location, BarrierType barrierType, boolean compressible) { - super(TYPE, object, location, StampFactory.forKind(readKind), barrierType); + public JavaReadNode(Kind readKind, AddressNode address, LocationIdentity location, BarrierType barrierType, boolean compressible) { + super(TYPE, address, location, StampFactory.forKind(readKind), barrierType); this.readKind = readKind; this.compressible = compressible; } @@ -66,6 +66,6 @@ @Override public Node canonical(CanonicalizerTool tool) { - return ReadNode.canonicalizeRead(this, location(), object(), tool); + return ReadNode.canonicalizeRead(this, getAddress(), getLocationIdentity(), tool); } } diff -r 9c454c650b29 -r a858c5f56d8a graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/JavaWriteNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/JavaWriteNode.java Mon Jun 08 15:57:52 2015 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/JavaWriteNode.java Mon Jun 08 18:47:58 2015 +0200 @@ -26,6 +26,7 @@ import com.oracle.graal.nodeinfo.*; import com.oracle.graal.nodes.*; import com.oracle.graal.nodes.memory.*; +import com.oracle.graal.nodes.memory.address.*; import com.oracle.graal.nodes.spi.*; import com.oracle.jvmci.meta.*; @@ -40,8 +41,8 @@ protected final Kind writeKind; protected final boolean compressible; - public JavaWriteNode(Kind writeKind, ValueNode object, ValueNode value, ValueNode location, BarrierType barrierType, boolean compressible, boolean initialization) { - super(TYPE, object, value, location, barrierType, initialization); + public JavaWriteNode(Kind writeKind, AddressNode address, LocationIdentity location, ValueNode value, BarrierType barrierType, boolean compressible, boolean initialization) { + super(TYPE, address, location, value, barrierType, initialization); this.writeKind = writeKind; this.compressible = compressible; } diff -r 9c454c650b29 -r a858c5f56d8a graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/LocationNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/LocationNode.java Mon Jun 08 15:57:52 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,70 +0,0 @@ -/* - * Copyright (c) 2011, 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.extended; - -import com.oracle.graal.compiler.common.type.*; -import com.oracle.graal.graph.Node.ValueNumberable; -import com.oracle.graal.graph.*; -import com.oracle.graal.lir.gen.*; -import com.oracle.graal.nodeinfo.*; -import com.oracle.graal.nodes.calc.*; -import com.oracle.graal.nodes.spi.*; -import com.oracle.jvmci.meta.*; - -/** - * A location for a memory access in terms of the kind of value accessed and how to access it. All - * locations have the form [base + location], where base is a node and location is defined by - * subclasses of the {@link LocationNode}. - */ -@NodeInfo(allowedUsageTypes = {InputType.Association}) -public abstract class LocationNode extends FloatingNode implements LIRLowerable, ValueNumberable { - - public static final NodeClass TYPE = NodeClass.create(LocationNode.class); - - /** - * Marker interface for locations in snippets. - */ - public interface Location { - } - - protected LocationNode(NodeClass c, Stamp stamp) { - super(c, stamp); - } - - /** - * Returns the identity of the accessed memory location. - */ - public abstract LocationIdentity getLocationIdentity(); - - @Override - public final void generate(NodeLIRBuilderTool generator) { - // nothing to do... - } - - public abstract Value generateAddress(NodeMappableLIRBuilder builder, LIRGeneratorTool gen, Value base); - - /** - * @return the range of the displacement as a 64-bit integer stamp - */ - public abstract IntegerStamp getDisplacementStamp(); -} diff -r 9c454c650b29 -r a858c5f56d8a graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/AbstractNewObjectNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/AbstractNewObjectNode.java Mon Jun 08 15:57:52 2015 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/AbstractNewObjectNode.java Mon Jun 08 18:47:58 2015 +0200 @@ -31,6 +31,7 @@ import com.oracle.graal.nodes.*; import com.oracle.graal.nodes.extended.*; import com.oracle.graal.nodes.memory.*; +import com.oracle.graal.nodes.memory.address.*; import com.oracle.graal.nodes.spi.*; /** @@ -62,20 +63,31 @@ if (((FixedValueAnchorNode) usage).usages().isNotEmpty()) { return; } - } else if (usage instanceof WriteNode) { - if (((WriteNode) usage).object() != this || usage.usages().isNotEmpty()) { - // we would need to fix up the memory graph if the write has usages + } else if (usage instanceof OffsetAddressNode) { + if (((OffsetAddressNode) usage).getBase() != this) { return; } + for (Node access : usage.usages()) { + if (access instanceof WriteNode) { + if (access.usages().isNotEmpty()) { + // we would need to fix up the memory graph if the write has usages + return; + } + } else { + return; + } + } } else { return; } } for (Node usage : usages().distinct().snapshot()) { - List snapshot = usage.inputs().snapshot(); - graph().removeFixed((FixedWithNextNode) usage); - for (Node input : snapshot) { - tool.removeIfUnused(input); + if (usage instanceof OffsetAddressNode) { + for (Node access : usage.usages().snapshot()) { + removeUsage(tool, (FixedWithNextNode) access); + } + } else { + removeUsage(tool, (FixedWithNextNode) usage); } } List snapshot = inputs().snapshot(); @@ -85,6 +97,14 @@ } } + private void removeUsage(SimplifierTool tool, FixedWithNextNode usage) { + List snapshot = usage.inputs().snapshot(); + graph().removeFixed(usage); + for (Node input : snapshot) { + tool.removeIfUnused(input); + } + } + @Override public void lower(LoweringTool tool) { tool.getLowerer().lower(this, tool); diff -r 9c454c650b29 -r a858c5f56d8a graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/AtomicReadAndAddNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/AtomicReadAndAddNode.java Mon Jun 08 15:57:52 2015 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/AtomicReadAndAddNode.java Mon Jun 08 18:47:58 2015 +0200 @@ -28,8 +28,8 @@ 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.memory.address.*; import com.oracle.graal.nodes.spi.*; import com.oracle.jvmci.meta.*; @@ -40,28 +40,18 @@ public final class AtomicReadAndAddNode extends AbstractMemoryCheckpoint implements LIRLowerable, MemoryCheckpoint.Single { public static final NodeClass TYPE = NodeClass.create(AtomicReadAndAddNode.class); - @Input ValueNode object; - @Input ValueNode offset; + @Input(InputType.Association) AddressNode address; @Input ValueNode delta; protected final LocationIdentity locationIdentity; - public AtomicReadAndAddNode(ValueNode object, ValueNode offset, ValueNode delta, LocationIdentity locationIdentity) { + public AtomicReadAndAddNode(AddressNode address, ValueNode delta, LocationIdentity locationIdentity) { super(TYPE, StampFactory.forKind(delta.getKind())); - this.object = object; - this.offset = offset; + this.address = address; this.delta = delta; this.locationIdentity = locationIdentity; } - public ValueNode object() { - return object; - } - - public ValueNode offset() { - return offset; - } - public ValueNode delta() { return delta; } @@ -71,9 +61,7 @@ } public void generate(NodeLIRBuilderTool gen) { - LocationNode location = graph().unique(new IndexedLocationNode(getLocationIdentity(), 0, offset, 1)); - Value address = location.generateAddress(gen, gen.getLIRGeneratorTool(), gen.operand(object())); - Value result = gen.getLIRGeneratorTool().emitAtomicReadAndAdd(address, gen.operand(delta)); + Value result = gen.getLIRGeneratorTool().emitAtomicReadAndAdd(gen.operand(address), gen.operand(delta)); gen.setResult(this, result); } } diff -r 9c454c650b29 -r a858c5f56d8a graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/LoweredAtomicReadAndWriteNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/LoweredAtomicReadAndWriteNode.java Mon Jun 08 15:57:52 2015 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/LoweredAtomicReadAndWriteNode.java Mon Jun 08 18:47:58 2015 +0200 @@ -27,8 +27,8 @@ 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.memory.address.*; import com.oracle.graal.nodes.spi.*; import com.oracle.jvmci.meta.*; @@ -43,8 +43,8 @@ @Input ValueNode newValue; @OptionalInput(InputType.State) FrameState stateAfter; - public LoweredAtomicReadAndWriteNode(ValueNode object, LocationNode location, ValueNode newValue, BarrierType barrierType) { - super(TYPE, object, location, newValue.stamp().unrestricted(), barrierType); + public LoweredAtomicReadAndWriteNode(AddressNode address, LocationIdentity location, ValueNode newValue, BarrierType barrierType) { + super(TYPE, address, location, newValue.stamp().unrestricted(), barrierType); this.newValue = newValue; } @@ -62,13 +62,8 @@ return true; } - public LocationIdentity getLocationIdentity() { - return location().getLocationIdentity(); - } - public void generate(NodeLIRBuilderTool gen) { - Value address = location().generateAddress(gen, gen.getLIRGeneratorTool(), gen.operand(object())); - Value result = gen.getLIRGeneratorTool().emitAtomicReadAndWrite(address, gen.operand(getNewValue())); + Value result = gen.getLIRGeneratorTool().emitAtomicReadAndWrite(gen.operand(getAddress()), gen.operand(getNewValue())); gen.setResult(this, result); } diff -r 9c454c650b29 -r a858c5f56d8a graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/LoweredCompareAndSwapNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/LoweredCompareAndSwapNode.java Mon Jun 08 15:57:52 2015 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/LoweredCompareAndSwapNode.java Mon Jun 08 18:47:58 2015 +0200 @@ -26,8 +26,8 @@ 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.memory.address.*; import com.oracle.graal.nodes.spi.*; import com.oracle.jvmci.meta.*; @@ -64,18 +64,13 @@ return newValue; } - public LoweredCompareAndSwapNode(ValueNode object, LocationNode location, ValueNode expectedValue, ValueNode newValue, BarrierType barrierType) { - super(TYPE, object, location, StampFactory.forKind(Kind.Boolean.getStackKind()), barrierType); + public LoweredCompareAndSwapNode(AddressNode address, LocationIdentity location, ValueNode expectedValue, ValueNode newValue, BarrierType barrierType) { + super(TYPE, address, location, StampFactory.forKind(Kind.Boolean.getStackKind()), barrierType); assert expectedValue.getKind() == newValue.getKind(); this.expectedValue = expectedValue; this.newValue = newValue; } - @Override - public LocationIdentity getLocationIdentity() { - return location().getLocationIdentity(); - } - public boolean canNullCheck() { return false; } @@ -83,8 +78,7 @@ @Override public void generate(NodeLIRBuilderTool gen) { assert getNewValue().stamp().isCompatible(getExpectedValue().stamp()); - Value address = location().generateAddress(gen, gen.getLIRGeneratorTool(), gen.operand(object())); - Value result = gen.getLIRGeneratorTool().emitCompareAndSwap(address, gen.operand(getExpectedValue()), gen.operand(getNewValue()), JavaConstant.INT_1, JavaConstant.INT_0); + Value result = gen.getLIRGeneratorTool().emitCompareAndSwap(gen.operand(getAddress()), gen.operand(getExpectedValue()), gen.operand(getNewValue()), JavaConstant.INT_1, JavaConstant.INT_0); gen.setResult(this, result); } } diff -r 9c454c650b29 -r a858c5f56d8a graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/memory/AbstractWriteNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/memory/AbstractWriteNode.java Mon Jun 08 15:57:52 2015 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/memory/AbstractWriteNode.java Mon Jun 08 18:47:58 2015 +0200 @@ -27,6 +27,7 @@ import com.oracle.graal.nodeinfo.*; import com.oracle.graal.nodes.*; import com.oracle.graal.nodes.extended.*; +import com.oracle.graal.nodes.memory.address.*; import com.oracle.jvmci.meta.*; @NodeInfo(allowedUsageTypes = {InputType.Memory}) @@ -66,18 +67,19 @@ return initialization; } - protected AbstractWriteNode(NodeClass c, ValueNode object, ValueNode value, ValueNode location, BarrierType barrierType) { - this(c, object, value, location, barrierType, false); + protected AbstractWriteNode(NodeClass c, AddressNode address, LocationIdentity location, ValueNode value, BarrierType barrierType) { + this(c, address, location, value, barrierType, false); } - protected AbstractWriteNode(NodeClass c, ValueNode object, ValueNode value, ValueNode location, BarrierType barrierType, boolean initialization) { - super(c, object, location, StampFactory.forVoid(), barrierType); + protected AbstractWriteNode(NodeClass c, AddressNode address, LocationIdentity location, ValueNode value, BarrierType barrierType, boolean initialization) { + super(c, address, location, StampFactory.forVoid(), barrierType); this.value = value; this.initialization = initialization; } - protected AbstractWriteNode(NodeClass c, ValueNode object, ValueNode value, ValueNode location, BarrierType barrierType, GuardingNode guard, boolean initialization) { - super(c, object, location, StampFactory.forVoid(), guard, barrierType, false, null); + protected AbstractWriteNode(NodeClass c, AddressNode address, LocationIdentity location, ValueNode value, BarrierType barrierType, GuardingNode guard, + boolean initialization) { + super(c, address, location, StampFactory.forVoid(), guard, barrierType, false, null); this.value = value; this.initialization = initialization; } @@ -87,11 +89,6 @@ return (type == InputType.Guard && getNullCheck()) ? true : super.isAllowedUsageType(type); } - @Override - public LocationIdentity getLocationIdentity() { - return location().getLocationIdentity(); - } - public MemoryNode getLastLocationAccess() { return (MemoryNode) lastLocationAccess; } diff -r 9c454c650b29 -r a858c5f56d8a graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/memory/Access.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/memory/Access.java Mon Jun 08 15:57:52 2015 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/memory/Access.java Mon Jun 08 18:47:58 2015 +0200 @@ -22,14 +22,15 @@ */ package com.oracle.graal.nodes.memory; -import com.oracle.graal.nodes.*; import com.oracle.graal.nodes.extended.*; +import com.oracle.graal.nodes.memory.address.*; +import com.oracle.jvmci.meta.*; public interface Access extends GuardedNode, HeapAccess { - ValueNode object(); + AddressNode getAddress(); - LocationNode accessLocation(); + LocationIdentity getLocationIdentity(); boolean canNullCheck(); diff -r 9c454c650b29 -r a858c5f56d8a graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/memory/FixedAccessNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/memory/FixedAccessNode.java Mon Jun 08 15:57:52 2015 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/memory/FixedAccessNode.java Mon Jun 08 18:47:58 2015 +0200 @@ -27,36 +27,36 @@ import com.oracle.graal.nodeinfo.*; import com.oracle.graal.nodes.*; import com.oracle.graal.nodes.extended.*; +import com.oracle.graal.nodes.memory.address.*; +import com.oracle.jvmci.meta.*; /** - * Accesses a value at an memory address specified by an {@linkplain #object object} and a - * {@linkplain #accessLocation() location}. The access does not include a null check on the object. + * Accesses a value at an memory address specified by an {@linkplain #address address}. The access + * does not include a null check on the object. */ @NodeInfo public abstract class FixedAccessNode extends DeoptimizingFixedWithNextNode implements Access { public static final NodeClass TYPE = NodeClass.create(FixedAccessNode.class); @OptionalInput(InputType.Guard) protected GuardingNode guard; - @Input protected ValueNode object; - @Input(InputType.Association) protected ValueNode location; + + @Input(InputType.Association) AddressNode address; + protected final LocationIdentity location; + protected boolean nullCheck; protected BarrierType barrierType; - public ValueNode object() { - return object; + public AddressNode getAddress() { + return address; } - protected void setObject(ValueNode x) { - updateUsages(object, x); - object = x; + public void setAddress(AddressNode address) { + updateUsages(this.address, address); + this.address = address; } - public LocationNode location() { - return (LocationNode) location; - } - - public LocationNode accessLocation() { - return (LocationNode) location; + public LocationIdentity getLocationIdentity() { + return location; } public boolean getNullCheck() { @@ -67,18 +67,18 @@ this.nullCheck = check; } - protected FixedAccessNode(NodeClass c, ValueNode object, ValueNode location, Stamp stamp) { - this(c, object, location, stamp, BarrierType.NONE); + protected FixedAccessNode(NodeClass c, AddressNode address, LocationIdentity location, Stamp stamp) { + this(c, address, location, stamp, BarrierType.NONE); } - protected FixedAccessNode(NodeClass c, ValueNode object, ValueNode location, Stamp stamp, BarrierType barrierType) { - this(c, object, location, stamp, null, barrierType, false, null); + protected FixedAccessNode(NodeClass c, AddressNode address, LocationIdentity location, Stamp stamp, BarrierType barrierType) { + this(c, address, location, stamp, null, barrierType, false, null); } - protected FixedAccessNode(NodeClass c, ValueNode object, ValueNode location, Stamp stamp, GuardingNode guard, BarrierType barrierType, boolean nullCheck, + protected FixedAccessNode(NodeClass c, AddressNode address, LocationIdentity location, Stamp stamp, GuardingNode guard, BarrierType barrierType, boolean nullCheck, FrameState stateBefore) { super(c, stamp, stateBefore); - this.object = object; + this.address = address; this.location = location; this.guard = guard; this.barrierType = barrierType; diff -r 9c454c650b29 -r a858c5f56d8a graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/memory/FloatableAccessNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/memory/FloatableAccessNode.java Mon Jun 08 15:57:52 2015 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/memory/FloatableAccessNode.java Mon Jun 08 18:47:58 2015 +0200 @@ -27,6 +27,8 @@ import com.oracle.graal.nodeinfo.*; import com.oracle.graal.nodes.*; import com.oracle.graal.nodes.extended.*; +import com.oracle.graal.nodes.memory.address.*; +import com.oracle.jvmci.meta.*; /** * An {@link FixedAccessNode} that can be converted to a {@link FloatingAccessNode}. @@ -35,17 +37,17 @@ public abstract class FloatableAccessNode extends FixedAccessNode { public static final NodeClass TYPE = NodeClass.create(FloatableAccessNode.class); - protected FloatableAccessNode(NodeClass c, ValueNode object, ValueNode location, Stamp stamp) { - super(c, object, location, stamp); + protected FloatableAccessNode(NodeClass c, AddressNode address, LocationIdentity location, Stamp stamp) { + super(c, address, location, stamp); } - protected FloatableAccessNode(NodeClass c, ValueNode object, ValueNode location, Stamp stamp, GuardingNode guard, BarrierType barrierType) { - super(c, object, location, stamp, guard, barrierType, false, null); + protected FloatableAccessNode(NodeClass c, AddressNode address, LocationIdentity location, Stamp stamp, GuardingNode guard, BarrierType barrierType) { + super(c, address, location, stamp, guard, barrierType, false, null); } - protected FloatableAccessNode(NodeClass c, ValueNode object, ValueNode location, Stamp stamp, GuardingNode guard, BarrierType barrierType, boolean nullCheck, - FrameState stateBefore) { - super(c, object, location, stamp, guard, barrierType, nullCheck, stateBefore); + protected FloatableAccessNode(NodeClass c, AddressNode address, LocationIdentity location, Stamp stamp, GuardingNode guard, BarrierType barrierType, + boolean nullCheck, FrameState stateBefore) { + super(c, address, location, stamp, guard, barrierType, nullCheck, stateBefore); } public abstract FloatingAccessNode asFloatingNode(MemoryNode lastLocationAccess); @@ -62,6 +64,6 @@ * an attached write barrier with pre-semantics can not also float. */ public boolean canFloat() { - return !forceFixed && location().getLocationIdentity().isSingle() && getBarrierType() == BarrierType.NONE; + return !forceFixed && getLocationIdentity().isSingle() && getBarrierType() == BarrierType.NONE; } } diff -r 9c454c650b29 -r a858c5f56d8a graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/memory/FloatingAccessNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/memory/FloatingAccessNode.java Mon Jun 08 15:57:52 2015 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/memory/FloatingAccessNode.java Mon Jun 08 18:47:58 2015 +0200 @@ -27,50 +27,47 @@ import com.oracle.graal.nodeinfo.*; import com.oracle.graal.nodes.*; import com.oracle.graal.nodes.extended.*; +import com.oracle.graal.nodes.memory.address.*; import com.oracle.jvmci.meta.*; @NodeInfo public abstract class FloatingAccessNode extends FloatingGuardedNode implements Access, MemoryAccess { public static final NodeClass TYPE = NodeClass.create(FloatingAccessNode.class); - @Input ValueNode object; - @Input(InputType.Association) LocationNode location; + @Input(InputType.Association) AddressNode address; + protected final LocationIdentity location; + protected BarrierType barrierType; - public ValueNode object() { - return object; - } - - public LocationNode location() { - return location; - } - - public LocationNode accessLocation() { - return location; - } - - public LocationIdentity getLocationIdentity() { - return location.getLocationIdentity(); - } - - protected FloatingAccessNode(NodeClass c, ValueNode object, LocationNode location, Stamp stamp) { + protected FloatingAccessNode(NodeClass c, AddressNode address, LocationIdentity location, Stamp stamp) { super(c, stamp); - this.object = object; + this.address = address; this.location = location; } - protected FloatingAccessNode(NodeClass c, ValueNode object, LocationNode location, Stamp stamp, GuardingNode guard, BarrierType barrierType) { + protected FloatingAccessNode(NodeClass c, AddressNode address, LocationIdentity location, Stamp stamp, GuardingNode guard, BarrierType barrierType) { super(c, stamp, guard); - this.object = object; + this.address = address; this.location = location; this.barrierType = barrierType; } @Override + public AddressNode getAddress() { + return address; + } + + @Override + public LocationIdentity getLocationIdentity() { + return location; + } + + @Override public BarrierType getBarrierType() { return barrierType; } + @Override public boolean canNullCheck() { return true; } diff -r 9c454c650b29 -r a858c5f56d8a graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/memory/FloatingReadNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/memory/FloatingReadNode.java Mon Jun 08 15:57:52 2015 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/memory/FloatingReadNode.java Mon Jun 08 18:47:58 2015 +0200 @@ -28,6 +28,7 @@ import com.oracle.graal.nodeinfo.*; import com.oracle.graal.nodes.*; import com.oracle.graal.nodes.extended.*; +import com.oracle.graal.nodes.memory.address.*; import com.oracle.graal.nodes.spi.*; import com.oracle.jvmci.meta.*; @@ -41,16 +42,16 @@ @OptionalInput(InputType.Memory) MemoryNode lastLocationAccess; - public FloatingReadNode(ValueNode object, LocationNode location, MemoryNode lastLocationAccess, Stamp stamp) { - this(object, location, lastLocationAccess, stamp, null, BarrierType.NONE); + public FloatingReadNode(AddressNode address, LocationIdentity location, MemoryNode lastLocationAccess, Stamp stamp) { + this(address, location, lastLocationAccess, stamp, null, BarrierType.NONE); } - public FloatingReadNode(ValueNode object, LocationNode location, MemoryNode lastLocationAccess, Stamp stamp, GuardingNode guard) { - this(object, location, lastLocationAccess, stamp, guard, BarrierType.NONE); + public FloatingReadNode(AddressNode address, LocationIdentity location, MemoryNode lastLocationAccess, Stamp stamp, GuardingNode guard) { + this(address, location, lastLocationAccess, stamp, guard, BarrierType.NONE); } - public FloatingReadNode(ValueNode object, LocationNode location, MemoryNode lastLocationAccess, Stamp stamp, GuardingNode guard, BarrierType barrierType) { - super(TYPE, object, location, stamp, guard, barrierType); + public FloatingReadNode(AddressNode address, LocationIdentity location, MemoryNode lastLocationAccess, Stamp stamp, GuardingNode guard, BarrierType barrierType) { + super(TYPE, address, location, stamp, guard, barrierType); this.lastLocationAccess = lastLocationAccess; } @@ -65,22 +66,25 @@ @Override public void generate(NodeLIRBuilderTool gen) { - Value address = location().generateAddress(gen, gen.getLIRGeneratorTool(), gen.operand(object())); LIRKind readKind = gen.getLIRGeneratorTool().getLIRKind(stamp()); - gen.setResult(this, gen.getLIRGeneratorTool().emitLoad(readKind, address, null)); + gen.setResult(this, gen.getLIRGeneratorTool().emitLoad(readKind, gen.operand(address), null)); } @Override public Node canonical(CanonicalizerTool tool) { - if (object() instanceof PiNode && ((PiNode) object()).getGuard() == getGuard()) { - return new FloatingReadNode(((PiNode) object()).getOriginalNode(), location(), getLastLocationAccess(), stamp(), getGuard(), getBarrierType()); + if (getAddress() instanceof OffsetAddressNode) { + OffsetAddressNode objAddress = (OffsetAddressNode) getAddress(); + if (objAddress.getBase() instanceof PiNode && ((PiNode) objAddress.getBase()).getGuard() == getGuard()) { + OffsetAddressNode newAddress = new OffsetAddressNode(((PiNode) objAddress.getBase()).getOriginalNode(), objAddress.getOffset()); + return new FloatingReadNode(newAddress, getLocationIdentity(), getLastLocationAccess(), stamp(), getGuard(), getBarrierType()); + } } - return ReadNode.canonicalizeRead(this, location(), object(), tool); + return ReadNode.canonicalizeRead(this, getAddress(), getLocationIdentity(), tool); } @Override public FixedAccessNode asFixedNode() { - return graph().add(new ReadNode(object(), accessLocation(), stamp(), getGuard(), getBarrierType())); + return graph().add(new ReadNode(getAddress(), getLocationIdentity(), stamp(), getGuard(), getBarrierType())); } @Override diff -r 9c454c650b29 -r a858c5f56d8a graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/memory/ReadNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/memory/ReadNode.java Mon Jun 08 15:57:52 2015 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/memory/ReadNode.java Mon Jun 08 18:47:58 2015 +0200 @@ -28,8 +28,8 @@ import com.oracle.graal.nodeinfo.*; import com.oracle.graal.nodes.*; import com.oracle.graal.nodes.extended.*; +import com.oracle.graal.nodes.memory.address.*; import com.oracle.graal.nodes.spi.*; -import com.oracle.graal.nodes.type.*; import com.oracle.graal.nodes.util.*; import com.oracle.jvmci.common.*; import com.oracle.jvmci.meta.*; @@ -38,36 +38,35 @@ * Reads an {@linkplain FixedAccessNode accessed} value. */ @NodeInfo -public final class ReadNode extends FloatableAccessNode implements LIRLowerable, Canonicalizable, PiPushable, Virtualizable, GuardingNode { +public final class ReadNode extends FloatableAccessNode implements LIRLowerable, Canonicalizable, Virtualizable, GuardingNode { public static final NodeClass TYPE = NodeClass.create(ReadNode.class); - public ReadNode(ValueNode object, ValueNode location, Stamp stamp, BarrierType barrierType) { - super(TYPE, object, location, stamp, null, barrierType); + public ReadNode(AddressNode address, LocationIdentity location, Stamp stamp, BarrierType barrierType) { + super(TYPE, address, location, stamp, null, barrierType); } - public ReadNode(ValueNode object, ValueNode location, Stamp stamp, GuardingNode guard, BarrierType barrierType) { - super(TYPE, object, location, stamp, guard, barrierType); + public ReadNode(AddressNode address, LocationIdentity location, Stamp stamp, GuardingNode guard, BarrierType barrierType) { + super(TYPE, address, location, stamp, guard, barrierType); } - public ReadNode(ValueNode object, ValueNode location, Stamp stamp, GuardingNode guard, BarrierType barrierType, boolean nullCheck, FrameState stateBefore) { - super(TYPE, object, location, stamp, guard, barrierType, nullCheck, stateBefore); + public ReadNode(AddressNode address, LocationIdentity location, Stamp stamp, GuardingNode guard, BarrierType barrierType, boolean nullCheck, FrameState stateBefore) { + super(TYPE, address, location, stamp, guard, barrierType, nullCheck, stateBefore); } - public ReadNode(ValueNode object, ValueNode location, ValueNode guard, BarrierType barrierType) { + public ReadNode(AddressNode address, LocationIdentity location, ValueNode guard, BarrierType barrierType) { /* * Used by node intrinsics. Really, you can trust me on that! Since the initial value for * location is a parameter, i.e., a ParameterNode, the constructor cannot use the declared * type LocationNode. */ - super(TYPE, object, location, StampFactory.forNodeIntrinsic(), (GuardingNode) guard, barrierType); + super(TYPE, address, location, StampFactory.forNodeIntrinsic(), (GuardingNode) guard, barrierType); } @Override public void generate(NodeLIRBuilderTool gen) { - Value address = location().generateAddress(gen, gen.getLIRGeneratorTool(), gen.operand(object())); LIRKind readKind = gen.getLIRGeneratorTool().getLIRKind(stamp()); - gen.setResult(this, gen.getLIRGeneratorTool().emitLoad(readKind, address, gen.state(this))); + gen.setResult(this, gen.getLIRGeneratorTool().emitLoad(readKind, gen.operand(address), gen.state(this))); } @Override @@ -81,11 +80,15 @@ return null; } } - if (object() instanceof PiNode && ((PiNode) object()).getGuard() == getGuard()) { - return new ReadNode(((PiNode) object()).getOriginalNode(), location(), stamp(), getGuard(), getBarrierType(), getNullCheck(), stateBefore()); + if (getAddress() instanceof OffsetAddressNode) { + OffsetAddressNode objAddress = (OffsetAddressNode) getAddress(); + if (objAddress.getBase() instanceof PiNode && ((PiNode) objAddress.getBase()).getGuard() == getGuard()) { + OffsetAddressNode newAddress = new OffsetAddressNode(((PiNode) objAddress.getBase()).getOriginalNode(), objAddress.getOffset()); + return new ReadNode(newAddress, getLocationIdentity(), stamp(), getGuard(), getBarrierType(), getNullCheck(), stateBefore()); + } } if (!getNullCheck()) { - return canonicalizeRead(this, location(), object(), tool); + return canonicalizeRead(this, getAddress(), getLocationIdentity(), tool); } else { // if this read is a null check, then replacing it with the value is incorrect for // guard-type usages @@ -95,7 +98,7 @@ @Override public FloatingAccessNode asFloatingNode(MemoryNode lastLocationAccess) { - return graph().unique(new FloatingReadNode(object(), location(), lastLocationAccess, stamp(), getGuard(), getBarrierType())); + return graph().unique(new FloatingReadNode(getAddress(), getLocationIdentity(), lastLocationAccess, stamp(), getGuard(), getBarrierType())); } @Override @@ -103,12 +106,14 @@ return (getNullCheck() && type == InputType.Guard) ? true : super.isAllowedUsageType(type); } - public static ValueNode canonicalizeRead(ValueNode read, LocationNode location, ValueNode object, CanonicalizerTool tool) { + public static ValueNode canonicalizeRead(ValueNode read, AddressNode address, LocationIdentity locationIdentity, CanonicalizerTool tool) { MetaAccessProvider metaAccess = tool.getMetaAccess(); - if (tool.canonicalizeReads()) { - if (metaAccess != null && object != null && object.isConstant() && !object.isNullConstant() && location instanceof ConstantLocationNode) { - long displacement = ((ConstantLocationNode) location).getDisplacement(); - if ((location.getLocationIdentity().isImmutable())) { + if (tool.canonicalizeReads() && address instanceof OffsetAddressNode) { + OffsetAddressNode objAddress = (OffsetAddressNode) address; + ValueNode object = objAddress.getBase(); + if (metaAccess != null && object.isConstant() && !object.isNullConstant() && objAddress.getOffset().isConstant()) { + long displacement = objAddress.getOffset().asJavaConstant().asLong(); + if (locationIdentity.isImmutable()) { Constant constant = read.stamp().readConstant(tool.getConstantReflection().getMemoryAccessProvider(), object.asConstant(), displacement); if (constant != null) { return ConstantNode.forConstant(read.stamp(), constant, metaAccess); @@ -120,7 +125,7 @@ return ConstantNode.forConstant(read.stamp(), constant, metaAccess); } } - if (location.getLocationIdentity().equals(LocationIdentity.ARRAY_LENGTH_LOCATION)) { + if (locationIdentity.equals(LocationIdentity.ARRAY_LENGTH_LOCATION)) { ValueNode length = GraphUtil.arrayLength(object); if (length != null) { // TODO Does this need a PiCastNode to the positive range? @@ -132,36 +137,6 @@ } @Override - public boolean push(PiNode parent) { - if (!(location() instanceof ConstantLocationNode && parent.stamp() instanceof ObjectStamp && parent.object().stamp() instanceof ObjectStamp)) { - return false; - } - - ObjectStamp piStamp = (ObjectStamp) parent.stamp(); - ResolvedJavaType receiverType = piStamp.type(); - if (receiverType == null) { - return false; - } - ConstantLocationNode constantLocationNode = (ConstantLocationNode) location(); - ResolvedJavaField field = receiverType.findInstanceFieldWithOffset(constantLocationNode.getDisplacement(), constantLocationNode.getKind()); - if (field == null) { - // field was not declared by receiverType - return false; - } - - ObjectStamp valueStamp = (ObjectStamp) parent.object().stamp(); - ResolvedJavaType valueType = StampTool.typeOrNull(valueStamp); - if (valueType != null && field.getDeclaringClass().isAssignableFrom(valueType)) { - if (piStamp.nonNull() == valueStamp.nonNull() && piStamp.alwaysNull() == valueStamp.alwaysNull()) { - replaceFirstInput(parent, parent.object()); - return true; - } - } - - return false; - } - - @Override public void virtualize(VirtualizerTool tool) { throw JVMCIError.shouldNotReachHere("unexpected ReadNode before PEA"); } diff -r 9c454c650b29 -r a858c5f56d8a graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/memory/WriteNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/memory/WriteNode.java Mon Jun 08 15:57:52 2015 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/memory/WriteNode.java Mon Jun 08 18:47:58 2015 +0200 @@ -27,7 +27,8 @@ import com.oracle.graal.nodeinfo.*; import com.oracle.graal.nodes.*; import com.oracle.graal.nodes.extended.*; -import com.oracle.graal.nodes.extended.LocationNode.Location; +import com.oracle.graal.nodes.memory.address.*; +import com.oracle.graal.nodes.memory.address.AddressNode.Address; import com.oracle.graal.nodes.spi.*; import com.oracle.jvmci.common.*; import com.oracle.jvmci.meta.*; @@ -40,34 +41,42 @@ public static final NodeClass TYPE = NodeClass.create(WriteNode.class); - public WriteNode(ValueNode object, ValueNode value, ValueNode location, BarrierType barrierType) { - super(TYPE, object, value, location, barrierType); + private WriteNode(ValueNode address, LocationIdentity location, ValueNode value, BarrierType barrierType) { + this((AddressNode) address, location, value, barrierType); } - public WriteNode(ValueNode object, ValueNode value, ValueNode location, BarrierType barrierType, boolean initialization) { - super(TYPE, object, value, location, barrierType, initialization); + public WriteNode(AddressNode address, LocationIdentity location, ValueNode value, BarrierType barrierType) { + super(TYPE, address, location, value, barrierType); } - public WriteNode(ValueNode object, ValueNode value, ValueNode location, BarrierType barrierType, GuardingNode guard, boolean initialization) { - super(TYPE, object, value, location, barrierType, guard, initialization); + public WriteNode(AddressNode address, LocationIdentity location, ValueNode value, BarrierType barrierType, boolean initialization) { + super(TYPE, address, location, value, barrierType, initialization); + } + + public WriteNode(AddressNode address, LocationIdentity location, ValueNode value, BarrierType barrierType, GuardingNode guard, boolean initialization) { + super(TYPE, address, location, value, barrierType, guard, initialization); } @Override public void generate(NodeLIRBuilderTool gen) { - Value address = location().generateAddress(gen, gen.getLIRGeneratorTool(), gen.operand(object())); LIRKind writeKind = gen.getLIRGeneratorTool().getLIRKind(value().stamp()); - gen.getLIRGeneratorTool().emitStore(writeKind, address, gen.operand(value()), gen.state(this)); + gen.getLIRGeneratorTool().emitStore(writeKind, gen.operand(address), gen.operand(value()), gen.state(this)); } @Override public void simplify(SimplifierTool tool) { - if (object() instanceof PiNode && ((PiNode) object()).getGuard() == getGuard()) { - setObject(((PiNode) object()).getOriginalNode()); + if (getAddress() instanceof OffsetAddressNode) { + OffsetAddressNode objAddress = (OffsetAddressNode) getAddress(); + if (objAddress.getBase() instanceof PiNode && ((PiNode) objAddress.getBase()).getGuard() == getGuard()) { + OffsetAddressNode newAddress = graph().unique(new OffsetAddressNode(((PiNode) objAddress.getBase()).getOriginalNode(), objAddress.getOffset())); + setAddress(newAddress); + tool.addToWorkList(newAddress); + } } } @NodeIntrinsic - public static native void writeMemory(Object object, Object value, Location location, @ConstantNodeParameter BarrierType barrierType); + public static native void writeMemory(Address address, @ConstantNodeParameter LocationIdentity location, Object value, @ConstantNodeParameter BarrierType barrierType); @Override public void virtualize(VirtualizerTool tool) { diff -r 9c454c650b29 -r a858c5f56d8a graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/memory/address/AddressNode.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/memory/address/AddressNode.java Mon Jun 08 18:47:58 2015 +0200 @@ -0,0 +1,43 @@ +/* + * Copyright (c) 2015, 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.memory.address; + +import com.oracle.graal.compiler.common.type.*; +import com.oracle.graal.graph.*; +import com.oracle.graal.nodeinfo.*; +import com.oracle.graal.nodes.calc.*; + +/** + * Base class for nodes that deal with addressing calculation. + */ +@NodeInfo(allowedUsageTypes = InputType.Association) +public abstract class AddressNode extends FloatingNode { + public static final NodeClass TYPE = NodeClass.create(AddressNode.class); + + protected AddressNode(NodeClass c) { + super(c, StampFactory.pointer()); + } + + public abstract static class Address extends StructuralInput.Association { + } +} diff -r 9c454c650b29 -r a858c5f56d8a graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/memory/address/OffsetAddressNode.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/memory/address/OffsetAddressNode.java Mon Jun 08 18:47:58 2015 +0200 @@ -0,0 +1,115 @@ +/* + * Copyright (c) 2015, 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.memory.address; + +import com.oracle.graal.compiler.common.type.*; +import com.oracle.graal.graph.*; +import com.oracle.graal.graph.spi.*; +import com.oracle.graal.nodeinfo.*; +import com.oracle.graal.nodes.*; +import com.oracle.graal.nodes.calc.*; +import com.oracle.graal.nodes.spi.*; +import com.oracle.graal.nodes.type.*; +import com.oracle.jvmci.meta.*; + +/** + * Represents an address that is composed of a base and an offset. The base can be either a + * {@link Kind#Object}, a word-sized integer or another pointer. The offset must be a word-sized + * integer. + */ +@NodeInfo(allowedUsageTypes = InputType.Association) +public class OffsetAddressNode extends AddressNode implements Canonicalizable, PiPushable { + public static final NodeClass TYPE = NodeClass.create(OffsetAddressNode.class); + + @Input ValueNode base; + @Input ValueNode offset; + + public OffsetAddressNode(ValueNode base, ValueNode offset) { + super(TYPE); + this.base = base; + this.offset = offset; + } + + public ValueNode getBase() { + return base; + } + + public void setBase(ValueNode base) { + updateUsages(this.base, base); + this.base = base; + } + + public ValueNode getOffset() { + return offset; + } + + public void setOffset(ValueNode offset) { + updateUsages(this.offset, offset); + this.offset = offset; + } + + public Node canonical(CanonicalizerTool tool) { + if (base instanceof RawAddressNode) { + // The RawAddressNode is redundant, just directly use its input as base. + return new OffsetAddressNode(((RawAddressNode) base).getAddress(), offset); + } else if (base instanceof OffsetAddressNode) { + // Rewrite (&base[offset1])[offset2] to base[offset1 + offset2]. + OffsetAddressNode b = (OffsetAddressNode) base; + return new OffsetAddressNode(b.getBase(), BinaryArithmeticNode.add(b.getOffset(), this.getOffset())); + } else { + return this; + } + } + + @Override + public boolean push(PiNode parent) { + if (!(offset.isConstant() && parent.stamp() instanceof ObjectStamp && parent.object().stamp() instanceof ObjectStamp)) { + return false; + } + + ObjectStamp piStamp = (ObjectStamp) parent.stamp(); + ResolvedJavaType receiverType = piStamp.type(); + if (receiverType == null) { + return false; + } + ResolvedJavaField field = receiverType.findInstanceFieldWithOffset(offset.asJavaConstant().asLong(), Kind.Void); + if (field == null) { + // field was not declared by receiverType + return false; + } + + ObjectStamp valueStamp = (ObjectStamp) parent.object().stamp(); + ResolvedJavaType valueType = StampTool.typeOrNull(valueStamp); + if (valueType != null && field.getDeclaringClass().isAssignableFrom(valueType)) { + if (piStamp.nonNull() == valueStamp.nonNull() && piStamp.alwaysNull() == valueStamp.alwaysNull()) { + replaceFirstInput(parent, parent.object()); + return true; + } + } + + return false; + } + + @NodeIntrinsic + public static native Address address(Object base, long offset); +} diff -r 9c454c650b29 -r a858c5f56d8a graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/memory/address/RawAddressNode.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/memory/address/RawAddressNode.java Mon Jun 08 18:47:58 2015 +0200 @@ -0,0 +1,57 @@ +/* + * Copyright (c) 2015, 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.memory.address; + +import com.oracle.graal.graph.*; +import com.oracle.graal.nodeinfo.*; +import com.oracle.graal.nodes.*; + +/** + * Convert a word-sized integer to a raw address. + */ +@NodeInfo(allowedUsageTypes = InputType.Association) +public class RawAddressNode extends AddressNode { + public static final NodeClass TYPE = NodeClass.create(RawAddressNode.class); + + @Input ValueNode address; + + public RawAddressNode(ValueNode address) { + super(TYPE); + this.address = address; + } + + public ValueNode getAddress() { + return address; + } + + public void setAddress(ValueNode address) { + updateUsages(this.address, address); + this.address = address; + } + + @NodeIntrinsic + public static native Address address(long address); + + @NodeIntrinsic + public static native Address address(Object address); +} diff -r 9c454c650b29 -r a858c5f56d8a graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/spi/LoweringProvider.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/spi/LoweringProvider.java Mon Jun 08 15:57:52 2015 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/spi/LoweringProvider.java Mon Jun 08 18:47:58 2015 +0200 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, 2011, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2011, 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 @@ -25,7 +25,7 @@ import com.oracle.graal.compiler.common.type.*; import com.oracle.graal.graph.*; import com.oracle.graal.nodes.*; -import com.oracle.graal.nodes.extended.*; +import com.oracle.graal.nodes.memory.address.*; import com.oracle.jvmci.meta.*; /** @@ -36,14 +36,14 @@ void lower(Node n, LoweringTool tool); /** - * Reconstructs the array index from a location node that was created as a lowering of an + * Reconstructs the array index from an address node that was created as a lowering of an * indexed access to an array. * * @param elementKind the {@link Kind} of the array elements - * @param location a location pointing to an element in an array + * @param address an {@link AddressNode} pointing to an element in an array * @return a node that gives the index of the element */ - ValueNode reconstructArrayIndex(Kind elementKind, LocationNode location); + ValueNode reconstructArrayIndex(Kind elementKind, AddressNode address); /** * Gets the platform specific size of a type in bytes. diff -r 9c454c650b29 -r a858c5f56d8a graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/AddressLoweringPhase.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/AddressLoweringPhase.java Mon Jun 08 18:47:58 2015 +0200 @@ -0,0 +1,63 @@ +/* + * Copyright (c) 2015, 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.phases.common; + +import com.oracle.graal.graph.*; +import com.oracle.graal.nodes.*; +import com.oracle.graal.nodes.memory.address.*; +import com.oracle.graal.phases.*; + +public class AddressLoweringPhase extends Phase { + + public abstract static class AddressLowering { + + public abstract AddressNode lower(ValueNode address); + + public abstract AddressNode lower(ValueNode base, ValueNode offset); + } + + private final AddressLowering lowering; + + public AddressLoweringPhase(AddressLowering lowering) { + this.lowering = lowering; + assert lowering != null; + } + + @Override + protected void run(StructuredGraph graph) { + for (Node node : graph.getNodes()) { + AddressNode lowered; + if (node instanceof RawAddressNode) { + RawAddressNode address = (RawAddressNode) node; + lowered = lowering.lower(address.getAddress()); + } else if (node instanceof OffsetAddressNode) { + OffsetAddressNode address = (OffsetAddressNode) node; + lowered = lowering.lower(address.getBase(), address.getOffset()); + } else { + continue; + } + + node.replaceAndDelete(lowered); + } + } +} diff -r 9c454c650b29 -r a858c5f56d8a graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/FloatingReadPhase.java --- a/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/FloatingReadPhase.java Mon Jun 08 15:57:52 2015 +0200 +++ b/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/FloatingReadPhase.java Mon Jun 08 18:47:58 2015 +0200 @@ -328,7 +328,7 @@ private static void processFloatable(FloatableAccessNode accessNode, MemoryMapImpl state) { StructuredGraph graph = accessNode.graph(); - LocationIdentity locationIdentity = accessNode.location().getLocationIdentity(); + LocationIdentity locationIdentity = accessNode.getLocationIdentity(); if (accessNode.canFloat()) { assert accessNode.getNullCheck() == false; MemoryNode lastLocationAccess = state.getLastLocationAccess(locationIdentity); diff -r 9c454c650b29 -r a858c5f56d8a graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/GuardLoweringPhase.java --- a/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/GuardLoweringPhase.java Mon Jun 08 15:57:52 2015 +0200 +++ b/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/GuardLoweringPhase.java Mon Jun 08 18:47:58 2015 +0200 @@ -22,8 +22,6 @@ */ package com.oracle.graal.phases.common; -import com.oracle.jvmci.meta.JavaConstant; - import static com.oracle.graal.compiler.common.GraalOptions.*; import java.util.*; @@ -35,8 +33,8 @@ import com.oracle.graal.nodes.StructuredGraph.GuardsStage; import com.oracle.graal.nodes.calc.*; import com.oracle.graal.nodes.cfg.*; -import com.oracle.graal.nodes.extended.*; import com.oracle.graal.nodes.memory.*; +import com.oracle.graal.nodes.memory.address.*; import com.oracle.graal.nodes.util.*; import com.oracle.graal.phases.*; import com.oracle.graal.phases.graph.*; @@ -44,6 +42,7 @@ import com.oracle.graal.phases.schedule.SchedulePhase.SchedulingStrategy; import com.oracle.graal.phases.tiers.*; import com.oracle.jvmci.debug.*; +import com.oracle.jvmci.meta.*; /** * This phase lowers {@link GuardNode GuardNodes} into corresponding control-flow structure and @@ -82,16 +81,23 @@ if (node instanceof StateSplit && ((StateSplit) node).stateAfter() != null) { nullGuarded.clear(); } else { - Iterator> it = nullGuarded.entrySet().iterator(); - while (it.hasNext()) { - Entry entry = it.next(); - ValueNode guard = entry.getValue(); - if (guard.usages().contains(node)) { - it.remove(); - } else if (guard instanceof PiNode && guard != node) { - PiNode piNode = (PiNode) guard; - if (piNode.getGuard().asNode().usages().contains(node)) { + /* + * The OffsetAddressNode itself never forces materialization of a null check, even + * if its input is a PiNode. The null check will be folded into the first usage of + * the OffsetAddressNode, so we need to keep it in the nullGuarded map. + */ + if (!(node instanceof OffsetAddressNode)) { + Iterator> it = nullGuarded.entrySet().iterator(); + while (it.hasNext()) { + Entry entry = it.next(); + ValueNode guard = entry.getValue(); + if (guard.usages().contains(node)) { it.remove(); + } else if (guard instanceof PiNode && guard != node) { + PiNode piNode = (PiNode) guard; + if (piNode.getGuard().asNode().usages().contains(node)) { + it.remove(); + } } } } @@ -108,21 +114,21 @@ } private void processAccess(Access access) { - if (access.canNullCheck()) { - ValueNode object = access.object(); - check(access, object); + if (access.canNullCheck() && access.getAddress() instanceof OffsetAddressNode) { + OffsetAddressNode address = (OffsetAddressNode) access.getAddress(); + check(access, address); } } - private void check(Access access, ValueNode object) { - ValueNode guard = nullGuarded.get(object); - if (guard != null && isImplicitNullCheck(access.accessLocation())) { + private void check(Access access, OffsetAddressNode address) { + ValueNode base = address.getBase(); + ValueNode guard = nullGuarded.get(base); + if (guard != null && isImplicitNullCheck(address.getOffset())) { if (guard instanceof PiNode) { PiNode piNode = (PiNode) guard; - assert guard == object; + assert guard == address.getBase(); assert piNode.getGuard() instanceof GuardNode : piNode; - assert access.object() == guard; - access.asNode().replaceFirstInput(piNode, piNode.getOriginalNode()); + address.setBase(piNode.getOriginalNode()); } else { assert guard instanceof GuardNode; } @@ -154,7 +160,7 @@ if (condition.hasNoUsages()) { GraphUtil.killWithUnusedFloatingInputs(condition); } - nullGuarded.remove(object); + nullGuarded.remove(base); } } @@ -166,9 +172,10 @@ } } - private boolean isImplicitNullCheck(LocationNode location) { - if (location instanceof ConstantLocationNode) { - return ((ConstantLocationNode) location).getDisplacement() < implicitNullCheckLimit; + private boolean isImplicitNullCheck(ValueNode offset) { + JavaConstant c = offset.asJavaConstant(); + if (c != null) { + return c.asLong() < implicitNullCheckLimit; } else { return false; } diff -r 9c454c650b29 -r a858c5f56d8a graal/com.oracle.graal.phases/src/com/oracle/graal/phases/schedule/SchedulePhase.java --- a/graal/com.oracle.graal.phases/src/com/oracle/graal/phases/schedule/SchedulePhase.java Mon Jun 08 15:57:52 2015 +0200 +++ b/graal/com.oracle.graal.phases/src/com/oracle/graal/phases/schedule/SchedulePhase.java Mon Jun 08 18:47:58 2015 +0200 @@ -768,9 +768,9 @@ } } else if (n instanceof FloatingReadNode) { FloatingReadNode frn = (FloatingReadNode) n; - buf.format(" // from %s", frn.location().getLocationIdentity()); + buf.format(" // from %s", frn.getLocationIdentity()); buf.format(", lastAccess: %s", frn.getLastLocationAccess()); - buf.format(", object: %s", frn.object()); + buf.format(", address: %s", frn.getAddress()); } else if (n instanceof GuardNode) { buf.format(", anchor: %s", ((GuardNode) n).getAnchor()); } diff -r 9c454c650b29 -r a858c5f56d8a graal/com.oracle.graal.replacements.amd64/src/com/oracle/graal/replacements/amd64/AMD64GraphBuilderPlugins.java --- a/graal/com.oracle.graal.replacements.amd64/src/com/oracle/graal/replacements/amd64/AMD64GraphBuilderPlugins.java Mon Jun 08 15:57:52 2015 +0200 +++ b/graal/com.oracle.graal.replacements.amd64/src/com/oracle/graal/replacements/amd64/AMD64GraphBuilderPlugins.java Mon Jun 08 18:47:58 2015 +0200 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2015, 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 @@ -38,6 +38,7 @@ import com.oracle.graal.graphbuilderconf.InvocationPlugins.Registration; import com.oracle.graal.nodes.*; import com.oracle.graal.nodes.java.*; +import com.oracle.graal.nodes.memory.address.*; import com.oracle.graal.replacements.*; public class AMD64GraphBuilderPlugins { @@ -126,7 +127,8 @@ public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, Receiver unsafe, ValueNode object, ValueNode offset, ValueNode delta) { // Emits a null-check for the otherwise unused receiver unsafe.get(); - b.addPush(kind, new AtomicReadAndAddNode(object, offset, delta, LocationIdentity.any())); + AddressNode address = b.add(new OffsetAddressNode(object, offset)); + b.addPush(kind, new AtomicReadAndAddNode(address, delta, LocationIdentity.any())); return true; } }); diff -r 9c454c650b29 -r a858c5f56d8a graal/com.oracle.graal.replacements.test/src/com/oracle/graal/replacements/test/ObjectAccessTest.java --- a/graal/com.oracle.graal.replacements.test/src/com/oracle/graal/replacements/test/ObjectAccessTest.java Mon Jun 08 15:57:52 2015 +0200 +++ b/graal/com.oracle.graal.replacements.test/src/com/oracle/graal/replacements/test/ObjectAccessTest.java Mon Jun 08 18:47:58 2015 +0200 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 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 @@ -29,6 +29,7 @@ import com.oracle.graal.nodes.StructuredGraph.AllowAssumptions; import com.oracle.graal.nodes.calc.*; import com.oracle.graal.nodes.extended.*; +import com.oracle.graal.nodes.memory.address.*; import com.oracle.graal.replacements.*; import com.oracle.graal.word.*; import com.oracle.jvmci.code.*; @@ -97,19 +98,18 @@ private static void assertRead(StructuredGraph graph, Kind kind, boolean indexConvert, LocationIdentity locationIdentity) { JavaReadNode read = (JavaReadNode) graph.start().next(); Assert.assertEquals(kind.getStackKind(), read.stamp().getStackKind()); - Assert.assertEquals(graph.getParameter(0), read.object()); - IndexedLocationNode location = (IndexedLocationNode) read.location(); - Assert.assertEquals(locationIdentity, location.getLocationIdentity()); - Assert.assertEquals(1, location.getIndexScaling()); + OffsetAddressNode address = (OffsetAddressNode) read.getAddress(); + Assert.assertEquals(graph.getParameter(0), address.getBase()); + Assert.assertEquals(locationIdentity, read.getLocationIdentity()); if (indexConvert) { - SignExtendNode convert = (SignExtendNode) location.getIndex(); + SignExtendNode convert = (SignExtendNode) address.getOffset(); Assert.assertEquals(convert.getInputBits(), 32); Assert.assertEquals(convert.getResultBits(), 64); Assert.assertEquals(graph.getParameter(1), convert.getValue()); } else { - Assert.assertEquals(graph.getParameter(1), location.getIndex()); + Assert.assertEquals(graph.getParameter(1), address.getOffset()); } ReturnNode ret = (ReturnNode) read.next(); @@ -119,20 +119,20 @@ private static void assertWrite(StructuredGraph graph, boolean indexConvert, LocationIdentity locationIdentity) { JavaWriteNode write = (JavaWriteNode) graph.start().next(); Assert.assertEquals(graph.getParameter(2), write.value()); - Assert.assertEquals(graph.getParameter(0), write.object()); + + OffsetAddressNode address = (OffsetAddressNode) write.getAddress(); + Assert.assertEquals(graph.getParameter(0), address.getBase()); Assert.assertEquals(BytecodeFrame.AFTER_BCI, write.stateAfter().bci); - IndexedLocationNode location = (IndexedLocationNode) write.location(); - Assert.assertEquals(locationIdentity, location.getLocationIdentity()); - Assert.assertEquals(1, location.getIndexScaling()); + Assert.assertEquals(locationIdentity, write.getLocationIdentity()); if (indexConvert) { - SignExtendNode convert = (SignExtendNode) location.getIndex(); + SignExtendNode convert = (SignExtendNode) address.getOffset(); Assert.assertEquals(convert.getInputBits(), 32); Assert.assertEquals(convert.getResultBits(), 64); Assert.assertEquals(graph.getParameter(1), convert.getValue()); } else { - Assert.assertEquals(graph.getParameter(1), location.getIndex()); + Assert.assertEquals(graph.getParameter(1), address.getOffset()); } ReturnNode ret = (ReturnNode) write.next(); diff -r 9c454c650b29 -r a858c5f56d8a graal/com.oracle.graal.replacements.test/src/com/oracle/graal/replacements/test/PEGraphDecoderTest.java --- a/graal/com.oracle.graal.replacements.test/src/com/oracle/graal/replacements/test/PEGraphDecoderTest.java Mon Jun 08 15:57:52 2015 +0200 +++ b/graal/com.oracle.graal.replacements.test/src/com/oracle/graal/replacements/test/PEGraphDecoderTest.java Mon Jun 08 18:47:58 2015 +0200 @@ -30,9 +30,9 @@ import com.oracle.graal.graphbuilderconf.InvocationPlugins.Registration; import com.oracle.graal.nodes.*; import com.oracle.graal.nodes.StructuredGraph.AllowAssumptions; -import com.oracle.graal.nodes.extended.*; import com.oracle.graal.nodes.memory.HeapAccess.BarrierType; import com.oracle.graal.nodes.memory.*; +import com.oracle.graal.nodes.memory.address.*; import com.oracle.graal.phases.*; import com.oracle.graal.phases.common.*; import com.oracle.graal.phases.tiers.*; @@ -99,8 +99,8 @@ r.register2("readInt", Object.class, long.class, new InvocationPlugin() { @Override public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, Receiver unused, ValueNode obj, ValueNode offset) { - LocationNode location = b.add(new ConstantLocationNode(LocationIdentity.any(), offset.asJavaConstant().asLong())); - ReadNode read = b.addPush(Kind.Int, new ReadNode(obj, location, StampFactory.forKind(Kind.Int), BarrierType.NONE)); + AddressNode address = b.add(new OffsetAddressNode(obj, offset)); + ReadNode read = b.addPush(Kind.Int, new ReadNode(address, LocationIdentity.any(), StampFactory.forKind(Kind.Int), BarrierType.NONE)); read.setGuard(AbstractBeginNode.prevBegin(read)); return true; } diff -r 9c454c650b29 -r a858c5f56d8a graal/com.oracle.graal.replacements.test/src/com/oracle/graal/replacements/test/PointerTest.java --- a/graal/com.oracle.graal.replacements.test/src/com/oracle/graal/replacements/test/PointerTest.java Mon Jun 08 15:57:52 2015 +0200 +++ b/graal/com.oracle.graal.replacements.test/src/com/oracle/graal/replacements/test/PointerTest.java Mon Jun 08 18:47:58 2015 +0200 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 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 @@ -29,6 +29,7 @@ import com.oracle.graal.nodes.StructuredGraph.AllowAssumptions; import com.oracle.graal.nodes.calc.*; import com.oracle.graal.nodes.extended.*; +import com.oracle.graal.nodes.memory.address.*; import com.oracle.graal.phases.*; import com.oracle.graal.phases.common.*; import com.oracle.graal.phases.tiers.*; @@ -106,21 +107,20 @@ JavaReadNode read = (JavaReadNode) cast.next(); Assert.assertEquals(kind.getStackKind(), read.stamp().getStackKind()); - Assert.assertEquals(cast, read.object()); + OffsetAddressNode address = (OffsetAddressNode) read.getAddress(); + Assert.assertEquals(cast, address.getBase()); Assert.assertEquals(graph.getParameter(0), cast.getInput()); Assert.assertEquals(target.wordKind, cast.stamp().getStackKind()); - IndexedLocationNode location = (IndexedLocationNode) read.location(); - Assert.assertEquals(locationIdentity, location.getLocationIdentity()); - Assert.assertEquals(1, location.getIndexScaling()); + Assert.assertEquals(locationIdentity, read.getLocationIdentity()); if (indexConvert) { - SignExtendNode convert = (SignExtendNode) location.getIndex(); + SignExtendNode convert = (SignExtendNode) address.getOffset(); Assert.assertEquals(convert.getInputBits(), 32); Assert.assertEquals(convert.getResultBits(), 64); Assert.assertEquals(graph.getParameter(1), convert.getValue()); } else { - Assert.assertEquals(graph.getParameter(1), location.getIndex()); + Assert.assertEquals(graph.getParameter(1), address.getOffset()); } ReturnNode ret = (ReturnNode) read.next(); @@ -134,21 +134,20 @@ Assert.assertEquals(graph.getParameter(2), write.value()); Assert.assertEquals(BytecodeFrame.AFTER_BCI, write.stateAfter().bci); - Assert.assertEquals(cast, write.object()); + OffsetAddressNode address = (OffsetAddressNode) write.getAddress(); + Assert.assertEquals(cast, address.getBase()); Assert.assertEquals(graph.getParameter(0), cast.getInput()); Assert.assertEquals(target.wordKind, cast.stamp().getStackKind()); - IndexedLocationNode location = (IndexedLocationNode) write.location(); - Assert.assertEquals(locationIdentity, location.getLocationIdentity()); - Assert.assertEquals(1, location.getIndexScaling()); + Assert.assertEquals(locationIdentity, write.getLocationIdentity()); if (indexConvert) { - SignExtendNode convert = (SignExtendNode) location.getIndex(); + SignExtendNode convert = (SignExtendNode) address.getOffset(); Assert.assertEquals(convert.getInputBits(), 32); Assert.assertEquals(convert.getResultBits(), 64); Assert.assertEquals(graph.getParameter(1), convert.getValue()); } else { - Assert.assertEquals(graph.getParameter(1), location.getIndex()); + Assert.assertEquals(graph.getParameter(1), address.getOffset()); } ReturnNode ret = (ReturnNode) write.next(); diff -r 9c454c650b29 -r a858c5f56d8a 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 Mon Jun 08 15:57:52 2015 +0200 +++ b/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/DefaultJavaLoweringProvider.java Mon Jun 08 18:47:58 2015 +0200 @@ -31,7 +31,6 @@ import java.util.*; import com.oracle.graal.api.replacements.*; -import com.oracle.graal.asm.*; import com.oracle.graal.compiler.common.type.*; import com.oracle.graal.graph.*; import com.oracle.graal.nodes.*; @@ -41,6 +40,7 @@ import com.oracle.graal.nodes.java.*; import com.oracle.graal.nodes.memory.HeapAccess.BarrierType; import com.oracle.graal.nodes.memory.*; +import com.oracle.graal.nodes.memory.address.*; import com.oracle.graal.nodes.spi.*; import com.oracle.graal.nodes.type.*; import com.oracle.graal.nodes.util.*; @@ -127,16 +127,31 @@ GraphUtil.removeFixedWithUnusedInputs(n); } + protected static AddressNode createOffsetAddress(StructuredGraph graph, ValueNode object, long offset) { + ValueNode o = ConstantNode.forLong(offset, graph); + return graph.unique(new OffsetAddressNode(object, o)); + } + + protected AddressNode createFieldAddress(StructuredGraph graph, ValueNode object, ResolvedJavaField field) { + int offset = fieldOffset(field); + if (offset >= 0) { + return createOffsetAddress(graph, object, offset); + } else { + return null; + } + } + protected void lowerLoadFieldNode(LoadFieldNode loadField, LoweringTool tool) { assert loadField.getKind() != Kind.Illegal; StructuredGraph graph = loadField.graph(); ResolvedJavaField field = loadField.field(); ValueNode object = loadField.isStatic() ? staticFieldBase(graph, field) : loadField.object(); Stamp loadStamp = loadStamp(loadField.stamp(), field.getKind()); - ConstantLocationNode location = createFieldLocation(graph, field, false); - assert location != null : "Field that is loaded must not be eliminated: " + field.getDeclaringClass().toJavaName(true) + "." + field.getName(); - ReadNode memoryRead = graph.add(new ReadNode(object, location, loadStamp, fieldLoadBarrierType(field))); + AddressNode address = createFieldAddress(graph, object, field); + assert address != null : "Field that is loaded must not be eliminated: " + field.getDeclaringClass().toJavaName(true) + "." + field.getName(); + + ReadNode memoryRead = graph.add(new ReadNode(address, field.getLocationIdentity(), loadStamp, fieldLoadBarrierType(field))); ValueNode readValue = implicitLoadConvert(graph, field.getKind(), memoryRead); loadField.replaceAtUsages(readValue); graph.replaceFixed(loadField, memoryRead); @@ -156,10 +171,10 @@ ResolvedJavaField field = storeField.field(); ValueNode object = storeField.isStatic() ? staticFieldBase(graph, field) : storeField.object(); ValueNode value = implicitStoreConvert(graph, storeField.field().getKind(), storeField.value()); - ConstantLocationNode location = createFieldLocation(graph, field, false); - assert location != null; + AddressNode address = createFieldAddress(graph, object, field); + assert address != null; - WriteNode memoryWrite = graph.add(new WriteNode(object, value, location, fieldStoreBarrierType(storeField.field()))); + WriteNode memoryWrite = graph.add(new WriteNode(address, field.getLocationIdentity(), value, fieldStoreBarrierType(storeField.field()))); memoryWrite.setStateAfter(storeField.stateAfter()); graph.replaceFixedWithFixed(storeField, memoryWrite); memoryWrite.setGuard(createNullCheck(object, memoryWrite, tool)); @@ -172,13 +187,25 @@ } } + public AddressNode createArrayAddress(StructuredGraph graph, ValueNode array, Kind elementKind, ValueNode index) { + ValueNode longIndex = graph.unique(new SignExtendNode(index, 64)); + + int shift = CodeUtil.log2(arrayScalingFactor(elementKind)); + ValueNode scaledIndex = graph.unique(new LeftShiftNode(longIndex, ConstantNode.forInt(shift, graph))); + + int base = arrayBaseOffset(elementKind); + ValueNode offset = graph.unique(new AddNode(scaledIndex, ConstantNode.forLong(base, graph))); + + return graph.unique(new OffsetAddressNode(array, offset)); + } + protected void lowerLoadIndexedNode(LoadIndexedNode loadIndexed, LoweringTool tool) { StructuredGraph graph = loadIndexed.graph(); Kind elementKind = loadIndexed.elementKind(); - LocationNode location = createArrayLocation(graph, elementKind, loadIndexed.index(), false); Stamp loadStamp = loadStamp(loadIndexed.stamp(), elementKind); - ReadNode memoryRead = graph.add(new ReadNode(loadIndexed.array(), location, loadStamp, BarrierType.NONE)); + AddressNode address = createArrayAddress(graph, loadIndexed.array(), elementKind, loadIndexed.index()); + ReadNode memoryRead = graph.add(new ReadNode(address, NamedLocationIdentity.getArrayLocation(elementKind), loadStamp, BarrierType.NONE)); ValueNode readValue = implicitLoadConvert(graph, elementKind, memoryRead); memoryRead.setGuard(createBoundsCheck(loadIndexed, tool)); @@ -191,7 +218,6 @@ StructuredGraph graph = storeIndexed.graph(); GuardingNode boundsCheck = createBoundsCheck(storeIndexed, tool); Kind elementKind = storeIndexed.elementKind(); - LocationNode location = createArrayLocation(graph, elementKind, storeIndexed.index(), false); ValueNode value = storeIndexed.value(); ValueNode array = storeIndexed.array(); @@ -215,7 +241,9 @@ } } - WriteNode memoryWrite = graph.add(new WriteNode(array, implicitStoreConvert(graph, elementKind, value), location, arrayStoreBarrierType(storeIndexed.elementKind()))); + AddressNode address = createArrayAddress(graph, array, elementKind, storeIndexed.index()); + WriteNode memoryWrite = graph.add(new WriteNode(address, NamedLocationIdentity.getArrayLocation(elementKind), implicitStoreConvert(graph, elementKind, value), + arrayStoreBarrierType(storeIndexed.elementKind()))); memoryWrite.setGuard(boundsCheck); memoryWrite.setStateAfter(storeIndexed.stateAfter()); graph.replaceFixedWithFixed(storeIndexed, memoryWrite); @@ -229,9 +257,9 @@ protected void lowerArrayLengthNode(ArrayLengthNode arrayLengthNode, LoweringTool tool) { StructuredGraph graph = arrayLengthNode.graph(); ValueNode array = arrayLengthNode.array(); - ConstantLocationNode location = graph.unique(new ConstantLocationNode(ARRAY_LENGTH_LOCATION, arrayLengthOffset())); - ReadNode arrayLengthRead = graph.add(new ReadNode(array, location, StampFactory.positiveInt(), BarrierType.NONE)); + AddressNode address = createOffsetAddress(graph, array, arrayLengthOffset()); + ReadNode arrayLengthRead = graph.add(new ReadNode(address, ARRAY_LENGTH_LOCATION, StampFactory.positiveInt(), BarrierType.NONE)); arrayLengthRead.setGuard(createNullCheck(array, arrayLengthNode, tool)); graph.replaceFixedWithFixed(arrayLengthNode, arrayLengthRead); } @@ -261,12 +289,12 @@ protected void lowerCompareAndSwapNode(CompareAndSwapNode cas) { StructuredGraph graph = cas.graph(); Kind valueKind = cas.getValueKind(); - LocationNode location = createLocation(cas.offset(), cas.getLocationIdentity(), valueKind); ValueNode expectedValue = implicitStoreConvert(graph, valueKind, cas.expected()); ValueNode newValue = implicitStoreConvert(graph, valueKind, cas.newValue()); - LoweredCompareAndSwapNode atomicNode = graph.add(new LoweredCompareAndSwapNode(cas.object(), location, expectedValue, newValue, compareAndSwapBarrierType(cas))); + AddressNode address = graph.unique(new OffsetAddressNode(cas.object(), cas.offset())); + LoweredCompareAndSwapNode atomicNode = graph.add(new LoweredCompareAndSwapNode(address, cas.getLocationIdentity(), expectedValue, newValue, compareAndSwapBarrierType(cas))); atomicNode.setStateAfter(cas.stateAfter()); graph.replaceFixedWithFixed(cas, atomicNode); } @@ -274,11 +302,11 @@ protected void lowerAtomicReadAndWriteNode(AtomicReadAndWriteNode n) { StructuredGraph graph = n.graph(); Kind valueKind = n.getValueKind(); - LocationNode location = graph.unique(new IndexedLocationNode(n.getLocationIdentity(), 0, n.offset(), 1)); ValueNode newValue = implicitStoreConvert(graph, valueKind, n.newValue()); - LoweredAtomicReadAndWriteNode memoryRead = graph.add(new LoweredAtomicReadAndWriteNode(n.object(), location, newValue, atomicReadAndWriteBarrierType(n))); + AddressNode address = graph.unique(new OffsetAddressNode(n.object(), n.offset())); + LoweredAtomicReadAndWriteNode memoryRead = graph.add(new LoweredAtomicReadAndWriteNode(address, n.getLocationIdentity(), newValue, atomicReadAndWriteBarrierType(n))); memoryRead.setStateAfter(n.stateAfter()); ValueNode readValue = implicitLoadConvert(graph, valueKind, memoryRead); @@ -301,20 +329,20 @@ } } + protected AddressNode createUnsafeAddress(StructuredGraph graph, ValueNode object, ValueNode offset) { + if (object.isConstant() && object.asConstant().isDefaultForKind()) { + return graph.unique(new RawAddressNode(offset)); + } else { + return graph.unique(new OffsetAddressNode(object, offset)); + } + } + protected ReadNode createUnsafeRead(StructuredGraph graph, UnsafeLoadNode load, GuardingNode guard) { boolean compressible = load.accessKind() == Kind.Object; Kind readKind = load.accessKind(); - ValueNode[] base = null; - ValueNode object = load.object(); - if (object.isConstant() && object.asConstant().isDefaultForKind()) { - base = new ValueNode[1]; - } - LocationNode location = createLocation(load, base); - if (base != null && base[0] != null) { - object = base[0]; - } Stamp loadStamp = loadStamp(load.stamp(), readKind, compressible); - ReadNode memoryRead = graph.add(new ReadNode(object, location, loadStamp, guard, BarrierType.NONE)); + AddressNode address = createUnsafeAddress(graph, load.object(), load.offset()); + ReadNode memoryRead = graph.add(new ReadNode(address, load.getLocationIdentity(), loadStamp, guard, BarrierType.NONE)); if (guard == null) { // An unsafe read must not float otherwise it may float above // a test guaranteeing the read is safe. @@ -327,19 +355,11 @@ protected void lowerUnsafeStoreNode(UnsafeStoreNode store) { StructuredGraph graph = store.graph(); - ValueNode object = store.object(); - ValueNode[] base = null; - if (object.isConstant() && object.asConstant().isDefaultForKind()) { - base = new ValueNode[1]; - } - LocationNode location = createLocation(store, base); - if (base != null && base[0] != null) { - object = base[0]; - } boolean compressible = store.value().getKind() == Kind.Object; Kind valueKind = store.accessKind(); ValueNode value = implicitStoreConvert(graph, valueKind, store.value(), compressible); - WriteNode write = graph.add(new WriteNode(object, value, location, unsafeStoreBarrierType(store))); + AddressNode address = createUnsafeAddress(graph, store.object(), store.offset()); + WriteNode write = graph.add(new WriteNode(address, store.getLocationIdentity(), value, unsafeStoreBarrierType(store))); write.setStateAfter(store.stateAfter()); graph.replaceFixedWithFixed(store, write); } @@ -349,7 +369,7 @@ Kind valueKind = read.getReadKind(); Stamp loadStamp = loadStamp(read.stamp(), valueKind, read.isCompressible()); - ReadNode memoryRead = graph.add(new ReadNode(read.object(), read.location(), loadStamp, read.getBarrierType())); + ReadNode memoryRead = graph.add(new ReadNode(read.getAddress(), read.getLocationIdentity(), loadStamp, read.getBarrierType())); GuardingNode guard = read.getGuard(); ValueNode readValue = implicitLoadConvert(graph, valueKind, memoryRead, read.isCompressible()); if (guard == null) { @@ -368,7 +388,7 @@ Kind valueKind = write.getWriteKind(); ValueNode value = implicitStoreConvert(graph, valueKind, write.value(), write.isCompressible()); - WriteNode memoryWrite = graph.add(new WriteNode(write.object(), value, write.location(), write.getBarrierType(), write.isInitialization())); + WriteNode memoryWrite = graph.add(new WriteNode(write.getAddress(), write.getLocationIdentity(), value, write.getBarrierType(), write.isInitialization())); memoryWrite.setStateAfter(write.stateAfter()); graph.replaceFixedWithFixed(write, memoryWrite); memoryWrite.setGuard(write.getGuard()); @@ -409,21 +429,21 @@ // Truffle requires some leniency in terms of what can be put where: assert valueKind.getStackKind() == entryKind.getStackKind() || (valueKind == Kind.Long || valueKind == Kind.Double || (valueKind == Kind.Int && virtual instanceof VirtualArrayNode)); - ConstantLocationNode location = null; + AddressNode address = null; BarrierType barrierType = null; if (virtual instanceof VirtualInstanceNode) { ResolvedJavaField field = ((VirtualInstanceNode) virtual).field(i); long offset = fieldOffset(field); if (offset >= 0) { - location = graph.unique(new ConstantLocationNode(initLocationIdentity(), offset)); + address = createOffsetAddress(graph, newObject, offset); barrierType = fieldInitializationBarrier(entryKind); } } else { - location = graph.unique(new ConstantLocationNode(initLocationIdentity(), arrayBaseOffset(entryKind) + i * arrayScalingFactor(entryKind))); + address = createOffsetAddress(graph, newObject, arrayBaseOffset(entryKind) + i * arrayScalingFactor(entryKind)); barrierType = arrayInitializationBarrier(entryKind); } - if (location != null) { - WriteNode write = new WriteNode(newObject, implicitStoreConvert(graph, entryKind, value), location, barrierType); + if (address != null) { + WriteNode write = new WriteNode(address, initLocationIdentity(), implicitStoreConvert(graph, entryKind, value), barrierType); graph.addAfterFixed(newObject, graph.add(write)); } } @@ -444,18 +464,18 @@ ValueNode allocValue = allocations[commit.getVirtualObjects().indexOf(value)]; if (!(allocValue.isConstant() && allocValue.asConstant().isDefaultForKind())) { assert virtual.entryKind(i) == Kind.Object && allocValue.getKind() == Kind.Object; - LocationNode location; + AddressNode address; BarrierType barrierType; if (virtual instanceof VirtualInstanceNode) { VirtualInstanceNode virtualInstance = (VirtualInstanceNode) virtual; - location = createFieldLocation(graph, virtualInstance.field(i), true); + address = createFieldAddress(graph, newObject, virtualInstance.field(i)); barrierType = BarrierType.IMPRECISE; } else { - location = createArrayLocation(graph, virtual.entryKind(i), ConstantNode.forInt(i, graph), true); + address = createArrayAddress(graph, newObject, virtual.entryKind(i), ConstantNode.forInt(i, graph)); barrierType = BarrierType.PRECISE; } - if (location != null) { - WriteNode write = new WriteNode(newObject, implicitStoreConvert(graph, Kind.Object, allocValue), location, barrierType); + if (address != null) { + WriteNode write = new WriteNode(address, initLocationIdentity(), implicitStoreConvert(graph, Kind.Object, allocValue), barrierType); graph.addBeforeFixed(commit, graph.add(write)); } } @@ -619,115 +639,14 @@ protected abstract ValueNode createReadArrayComponentHub(StructuredGraph graph, ValueNode arrayHub, FixedNode anchor); - protected ConstantLocationNode createFieldLocation(StructuredGraph graph, ResolvedJavaField field, boolean initialization) { - int offset = fieldOffset(field); - if (offset >= 0) { - LocationIdentity loc = initialization ? initLocationIdentity() : field.getLocationIdentity(); - return graph.unique(new ConstantLocationNode(loc, offset)); - } else { - return null; - } - } - - protected LocationNode createLocation(UnsafeAccessNode access, ValueNode[] base) { - return createLocation(access.offset(), access.getLocationIdentity(), access.accessKind(), base); - } - - protected LocationNode createLocation(ValueNode offsetNode, LocationIdentity locationIdentity, Kind accessKind) { - return createLocation(offsetNode, locationIdentity, accessKind, null); - } - - /** - * Try to unpack the operations in offsetNode into a LocationNode, taking advantage of - * addressing modes if possible. - * - * @param offsetNode the computed offset into the base of the memory operation - * @param locationIdentity - * @param accessKind - * @param base if non-null try to find a value that can be used as the base of the memory - * operation and return it as base[0] - * @return the newly created LocationNode - */ - protected LocationNode createLocation(ValueNode offsetNode, LocationIdentity locationIdentity, Kind accessKind, ValueNode[] base) { - ValueNode offset = offsetNode; - if (offset.isConstant()) { - long offsetValue = offset.asJavaConstant().asLong(); - return offset.graph().unique(new ConstantLocationNode(locationIdentity, offsetValue)); - } - - long displacement = 0; - int indexScaling = 1; - boolean signExtend = false; - if (offset instanceof SignExtendNode) { - SignExtendNode extend = (SignExtendNode) offset; - if (extend.getResultBits() == 64) { - signExtend = true; - offset = extend.getValue(); - } - } - if (offset instanceof AddNode) { - AddNode integerAddNode = (AddNode) offset; - if (integerAddNode.getY() instanceof ConstantNode) { - displacement = integerAddNode.getY().asJavaConstant().asLong(); - offset = integerAddNode.getX(); - } - } - if (base != null && signExtend == false && offset instanceof AddNode) { - /* - * Try to decompose the operation into base plus offset so the base can go into a new - * node. Prefer the unshifted side of an add as the base. - */ - AddNode integerAddNode = (AddNode) offset; - if (integerAddNode.getY() instanceof LeftShiftNode) { - base[0] = integerAddNode.getX(); - offset = integerAddNode.getY(); - } else { - base[0] = integerAddNode.getY(); - offset = integerAddNode.getX(); - } - if (offset instanceof AddNode) { - integerAddNode = (AddNode) offset; - if (integerAddNode.getY() instanceof ConstantNode) { - displacement = integerAddNode.getY().asJavaConstant().asLong(); - offset = integerAddNode.getX(); - } - } - } - if (offset instanceof LeftShiftNode) { - LeftShiftNode leftShiftNode = (LeftShiftNode) offset; - if (leftShiftNode.getY() instanceof ConstantNode) { - long shift = leftShiftNode.getY().asJavaConstant().asLong(); - if (shift >= 1 && shift <= 3) { - if (shift == 1) { - indexScaling = 2; - } else if (shift == 2) { - indexScaling = 4; - } else { - indexScaling = 8; - } - offset = leftShiftNode.getX(); - } - } - } - if (signExtend) { - // If we were using sign extended values before restore the sign extension. - offset = offset.graph().addOrUnique(new SignExtendNode(offset, 64)); - } - return offset.graph().unique(new IndexedLocationNode(locationIdentity, displacement, offset, indexScaling)); - } - - public IndexedLocationNode createArrayLocation(Graph graph, Kind elementKind, ValueNode index, boolean initialization) { - LocationIdentity loc = initialization ? initLocationIdentity() : NamedLocationIdentity.getArrayLocation(elementKind); - return graph.unique(new IndexedLocationNode(loc, arrayBaseOffset(elementKind), index, arrayScalingFactor(elementKind))); - } - protected GuardingNode createBoundsCheck(AccessIndexedNode n, LoweringTool tool) { StructuredGraph graph = n.graph(); ValueNode array = n.array(); ValueNode arrayLength = readArrayLength(array, tool.getConstantReflection()); if (arrayLength == null) { Stamp stamp = StampFactory.positiveInt(); - ReadNode readArrayLength = graph.add(new ReadNode(array, graph.unique(new ConstantLocationNode(ARRAY_LENGTH_LOCATION, arrayLengthOffset())), stamp, BarrierType.NONE)); + AddressNode address = createOffsetAddress(graph, array, arrayLengthOffset()); + ReadNode readArrayLength = graph.add(new ReadNode(address, ARRAY_LENGTH_LOCATION, stamp, BarrierType.NONE)); graph.addBeforeFixed(n, readArrayLength); readArrayLength.setGuard(createNullCheck(array, readArrayLength, tool)); arrayLength = readArrayLength; @@ -755,41 +674,16 @@ } @Override - public ValueNode reconstructArrayIndex(Kind elementKind, LocationNode location) { - assert location.getLocationIdentity().equals(NamedLocationIdentity.getArrayLocation(elementKind)); - - long base; - ValueNode index; - int scale = arrayScalingFactor(elementKind); + public ValueNode reconstructArrayIndex(Kind elementKind, AddressNode address) { + StructuredGraph graph = address.graph(); + ValueNode offset = ((OffsetAddressNode) address).getOffset(); - if (location instanceof ConstantLocationNode) { - base = ((ConstantLocationNode) location).getDisplacement(); - index = null; - } else if (location instanceof IndexedLocationNode) { - IndexedLocationNode indexedLocation = (IndexedLocationNode) location; - assert indexedLocation.getIndexScaling() == scale; - base = indexedLocation.getDisplacement(); - index = indexedLocation.getIndex(); - } else { - throw JVMCIError.shouldNotReachHere(); - } + int base = arrayBaseOffset(elementKind); + ValueNode scaledIndex = graph.unique(new SubNode(offset, ConstantNode.forIntegerStamp(offset.stamp(), base, graph))); - base -= arrayBaseOffset(elementKind); - assert base >= 0 && base % scale == 0; - - base /= scale; - assert NumUtil.isInt(base); - - StructuredGraph graph = location.graph(); - if (index == null) { - return ConstantNode.forInt((int) base, graph); - } else { - if (base == 0) { - return index; - } else { - return BinaryArithmeticNode.add(graph, ConstantNode.forInt((int) base, graph), index); - } - } + int shift = CodeUtil.log2(arrayScalingFactor(elementKind)); + ValueNode ret = graph.unique(new RightShiftNode(scaledIndex, ConstantNode.forInt(shift, graph))); + return IntegerConvertNode.convert(ret, StampFactory.forKind(Kind.Int), graph); } @Override diff -r 9c454c650b29 -r a858c5f56d8a graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/WordOperationPlugin.java --- a/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/WordOperationPlugin.java Mon Jun 08 15:57:52 2015 +0200 +++ b/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/WordOperationPlugin.java Mon Jun 08 18:47:58 2015 +0200 @@ -36,6 +36,7 @@ import com.oracle.graal.nodes.extended.*; import com.oracle.graal.nodes.java.*; import com.oracle.graal.nodes.memory.HeapAccess.BarrierType; +import com.oracle.graal.nodes.memory.address.*; import com.oracle.graal.nodes.type.*; import com.oracle.graal.word.*; import com.oracle.graal.word.Word.Opcode; @@ -205,21 +206,23 @@ case READ_BARRIERED: { assert args.length == 2 || args.length == 3; Kind readKind = wordTypes.asKind(wordMethod.getSignature().getReturnType(wordMethod.getDeclaringClass())); - LocationNode location; + AddressNode address = makeAddress(b, args[0], args[1]); + LocationIdentity location; if (args.length == 2) { - location = makeLocation(b, args[1], any()); + location = any(); } else { - location = makeLocation(b, args[1], args[2]); + assert args[2].isConstant(); + location = snippetReflection.asObject(LocationIdentity.class, args[2].asJavaConstant()); } - b.push(returnKind, readOp(b, readKind, args[0], location, operation.opcode())); + b.push(returnKind, readOp(b, readKind, address, location, operation.opcode())); break; } case READ_HEAP: { assert args.length == 3; Kind readKind = wordTypes.asKind(wordMethod.getSignature().getReturnType(wordMethod.getDeclaringClass())); - LocationNode location = makeLocation(b, args[1], any()); + AddressNode address = makeAddress(b, args[0], args[1]); BarrierType barrierType = snippetReflection.asObject(BarrierType.class, args[2].asJavaConstant()); - b.push(returnKind, readOp(b, readKind, args[0], location, barrierType, true)); + b.push(returnKind, readOp(b, readKind, address, any(), barrierType, true)); break; } case WRITE_POINTER: @@ -228,13 +231,15 @@ case INITIALIZE: { assert args.length == 3 || args.length == 4; Kind writeKind = wordTypes.asKind(wordMethod.getSignature().getParameterType(wordMethod.isStatic() ? 2 : 1, wordMethod.getDeclaringClass())); - LocationNode location; + AddressNode address = makeAddress(b, args[0], args[1]); + LocationIdentity location; if (args.length == 3) { - location = makeLocation(b, args[1], LocationIdentity.any()); + location = any(); } else { - location = makeLocation(b, args[1], args[3]); + assert args[3].isConstant(); + location = snippetReflection.asObject(LocationIdentity.class, args[3].asJavaConstant()); } - writeOp(b, writeKind, args[0], args[2], location, operation.opcode()); + writeOp(b, writeKind, address, location, args[2], operation.opcode()); break; } case ZERO: @@ -268,9 +273,10 @@ b.push(returnKind, objectToWord); break; - case FROM_ARRAY: - assert args.length == 2; - b.addPush(returnKind, new ComputeAddressNode(args[0], args[1], StampFactory.forKind(wordKind))); + case FROM_ADDRESS: + assert args.length == 1; + WordCastNode addressToWord = b.add(WordCastNode.addressToWord(args[0], wordKind)); + b.push(returnKind, addressToWord); break; case TO_OBJECT: @@ -328,41 +334,34 @@ return materialize; } - protected ValueNode readOp(GraphBuilderContext b, Kind readKind, ValueNode base, LocationNode location, Opcode op) { + protected ValueNode readOp(GraphBuilderContext b, Kind readKind, AddressNode address, LocationIdentity location, Opcode op) { assert op == Opcode.READ_POINTER || op == Opcode.READ_OBJECT || op == Opcode.READ_BARRIERED; final BarrierType barrier = (op == Opcode.READ_BARRIERED ? BarrierType.PRECISE : BarrierType.NONE); final boolean compressible = (op == Opcode.READ_OBJECT || op == Opcode.READ_BARRIERED); - return readOp(b, readKind, base, location, barrier, compressible); + return readOp(b, readKind, address, location, barrier, compressible); } - public static ValueNode readOp(GraphBuilderContext b, Kind readKind, ValueNode base, LocationNode location, BarrierType barrierType, boolean compressible) { + public static ValueNode readOp(GraphBuilderContext b, Kind readKind, AddressNode address, LocationIdentity location, BarrierType barrierType, boolean compressible) { /* * A JavaReadNode lowered to a ReadNode that will not float. This means it cannot float * above an explicit zero check on its base address or any other test that ensures the read * is safe. */ - JavaReadNode read = b.add(new JavaReadNode(readKind, base, location, barrierType, compressible)); + JavaReadNode read = b.add(new JavaReadNode(readKind, address, location, barrierType, compressible)); return read; } - protected void writeOp(GraphBuilderContext b, Kind writeKind, ValueNode base, ValueNode value, LocationNode location, Opcode op) { + protected void writeOp(GraphBuilderContext b, Kind writeKind, AddressNode address, LocationIdentity location, ValueNode value, Opcode op) { assert op == Opcode.WRITE_POINTER || op == Opcode.WRITE_OBJECT || op == Opcode.WRITE_BARRIERED || op == Opcode.INITIALIZE; final BarrierType barrier = (op == Opcode.WRITE_BARRIERED ? BarrierType.PRECISE : BarrierType.NONE); final boolean compressible = (op == Opcode.WRITE_OBJECT || op == Opcode.WRITE_BARRIERED); final boolean initialize = (op == Opcode.INITIALIZE); - b.add(new JavaWriteNode(writeKind, base, value, location, barrier, compressible, initialize)); + b.add(new JavaWriteNode(writeKind, address, location, value, barrier, compressible, initialize)); } - public LocationNode makeLocation(GraphBuilderContext b, ValueNode offset, LocationIdentity locationIdentity) { - return b.add(new IndexedLocationNode(locationIdentity, 0, fromSigned(b, offset), 1)); - } - - public LocationNode makeLocation(GraphBuilderContext b, ValueNode offset, ValueNode locationIdentity) { - if (locationIdentity.isConstant()) { - return makeLocation(b, offset, snippetReflection.asObject(LocationIdentity.class, locationIdentity.asJavaConstant())); - } - return b.add(new SnippetLocationNode(snippetReflection, locationIdentity, b.add(ConstantNode.forLong(0)), fromSigned(b, offset), b.add(ConstantNode.forInt(1)))); + public AddressNode makeAddress(GraphBuilderContext b, ValueNode base, ValueNode offset) { + return b.add(new OffsetAddressNode(base, fromSigned(b, offset))); } public ValueNode fromUnsigned(GraphBuilderContext b, ValueNode value) { diff -r 9c454c650b29 -r a858c5f56d8a graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/nodes/DirectObjectStoreNode.java --- a/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/nodes/DirectObjectStoreNode.java Mon Jun 08 15:57:52 2015 +0200 +++ b/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/nodes/DirectObjectStoreNode.java Mon Jun 08 18:47:58 2015 +0200 @@ -26,8 +26,10 @@ import com.oracle.graal.graph.*; import com.oracle.graal.nodeinfo.*; import com.oracle.graal.nodes.*; +import com.oracle.graal.nodes.calc.*; import com.oracle.graal.nodes.extended.*; import com.oracle.graal.nodes.memory.HeapAccess.BarrierType; +import com.oracle.graal.nodes.memory.address.*; import com.oracle.graal.nodes.spi.*; import com.oracle.jvmci.meta.*; @@ -66,8 +68,9 @@ @Override public void lower(LoweringTool tool) { - IndexedLocationNode location = graph().unique(new IndexedLocationNode(locationIdentity, displacement, offset, 1)); - JavaWriteNode write = graph().add(new JavaWriteNode(storeKind, object, value, location, BarrierType.NONE, storeKind == Kind.Object, false)); + ValueNode off = graph().unique(new AddNode(offset, ConstantNode.forIntegerStamp(offset.stamp(), displacement, graph()))); + AddressNode address = graph().unique(new OffsetAddressNode(object, off)); + JavaWriteNode write = graph().add(new JavaWriteNode(storeKind, address, locationIdentity, value, BarrierType.NONE, storeKind == Kind.Object, false)); graph().replaceFixedWithFixed(this, write); tool.getLowerer().lower(write, tool); diff -r 9c454c650b29 -r a858c5f56d8a graal/com.oracle.graal.truffle.hotspot/src/com/oracle/graal/truffle/hotspot/nfi/NativeCallStubGraphBuilder.java --- a/graal/com.oracle.graal.truffle.hotspot/src/com/oracle/graal/truffle/hotspot/nfi/NativeCallStubGraphBuilder.java Mon Jun 08 15:57:52 2015 +0200 +++ b/graal/com.oracle.graal.truffle.hotspot/src/com/oracle/graal/truffle/hotspot/nfi/NativeCallStubGraphBuilder.java Mon Jun 08 18:47:58 2015 +0200 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2014, 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 @@ -22,13 +22,6 @@ */ package com.oracle.graal.truffle.hotspot.nfi; -import com.oracle.jvmci.meta.ResolvedJavaType; -import com.oracle.jvmci.meta.ResolvedJavaMethod; -import com.oracle.jvmci.meta.ResolvedJavaField; -import com.oracle.jvmci.meta.NamedLocationIdentity; -import com.oracle.jvmci.meta.LocationIdentity; -import com.oracle.jvmci.meta.Kind; -import com.oracle.jvmci.meta.JavaConstant; import static com.oracle.graal.hotspot.HotSpotGraalRuntime.*; import java.util.*; @@ -39,9 +32,12 @@ import com.oracle.graal.nodes.StructuredGraph.AllowAssumptions; import com.oracle.graal.nodes.extended.*; import com.oracle.graal.nodes.java.*; +import com.oracle.graal.nodes.memory.address.*; import com.oracle.graal.nodes.virtual.*; +import com.oracle.graal.word.nodes.*; import com.oracle.jvmci.common.*; import com.oracle.jvmci.hotspot.*; +import com.oracle.jvmci.meta.*; /** * Utility creating a graph for a stub used to call a native function. @@ -122,15 +118,13 @@ if (kind == Kind.Object) { // array value Kind arrayElementKind = getElementKind(type); - LocationIdentity locationIdentity = NamedLocationIdentity.getArrayLocation(arrayElementKind); HotSpotJVMCIRuntimeProvider jvmciRuntime = runtime().getJVMCIRuntime(); int displacement = jvmciRuntime.getArrayBaseOffset(arrayElementKind); - ConstantNode index = ConstantNode.forInt(0, g); - int indexScaling = jvmciRuntime.getArrayIndexScale(arrayElementKind); - IndexedLocationNode locationNode = g.unique(new IndexedLocationNode(locationIdentity, displacement, index, indexScaling)); - Stamp wordStamp = StampFactory.forKind(providers.getWordTypes().getWordKind()); - ComputeAddressNode arrayAddress = g.unique(new ComputeAddressNode(boxedElement, locationNode, wordStamp)); - args.add(arrayAddress); + AddressNode arrayAddress = g.unique(new OffsetAddressNode(boxedElement, ConstantNode.forLong(displacement, g))); + WordCastNode cast = g.add(WordCastNode.addressToWord(arrayAddress, providers.getWordTypes().getWordKind())); + last.setNext(cast); + last = cast; + args.add(cast); } else { // boxed primitive value try { diff -r 9c454c650b29 -r a858c5f56d8a graal/com.oracle.graal.truffle.test/src/com/oracle/graal/truffle/test/ConditionAnchoringTest.java --- a/graal/com.oracle.graal.truffle.test/src/com/oracle/graal/truffle/test/ConditionAnchoringTest.java Mon Jun 08 15:57:52 2015 +0200 +++ b/graal/com.oracle.graal.truffle.test/src/com/oracle/graal/truffle/test/ConditionAnchoringTest.java Mon Jun 08 18:47:58 2015 +0200 @@ -126,7 +126,7 @@ DominatorConditionalEliminationPhase conditionalElimination = new DominatorConditionalEliminationPhase(false); conditionalElimination.apply(graph); - floatingReads = graph.getNodes().filter(FloatingReadNode.class).filter(n -> ((FloatingReadNode) n).location().getLocationIdentity() instanceof ObjectLocationIdentity); + floatingReads = graph.getNodes().filter(FloatingReadNode.class).filter(n -> ((FloatingReadNode) n).getLocationIdentity() instanceof ObjectLocationIdentity); conditionAnchors = graph.getNodes().filter(ConditionAnchorNode.class); assertThat(floatingReads, hasCount(1)); assertThat(conditionAnchors, isEmpty()); diff -r 9c454c650b29 -r a858c5f56d8a graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/ReadEliminationBlockState.java --- a/graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/ReadEliminationBlockState.java Mon Jun 08 15:57:52 2015 +0200 +++ b/graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/ReadEliminationBlockState.java Mon Jun 08 18:47:58 2015 +0200 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2011, 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 @@ -27,7 +27,6 @@ import com.oracle.graal.compiler.common.*; import com.oracle.graal.nodes.*; -import com.oracle.graal.nodes.extended.*; public class ReadEliminationBlockState extends EffectsBlockState { @@ -111,20 +110,38 @@ } } - static class ReadCacheEntry extends CacheEntry { + static class ReadCacheEntry extends CacheEntry { + + private final LocationIdentity location; - public ReadCacheEntry(ValueNode object, LocationNode identity) { - super(object, identity); + public ReadCacheEntry(ValueNode object, ValueNode offset, LocationIdentity location) { + super(object, offset); + this.location = location; } @Override - public CacheEntry duplicateWithObject(ValueNode newObject) { - return new ReadCacheEntry(newObject, identity); + public CacheEntry duplicateWithObject(ValueNode newObject) { + return new ReadCacheEntry(newObject, identity, location); } @Override public boolean conflicts(LocationIdentity other) { - return identity.getLocationIdentity().equals(other); + return location.equals(other); + } + + @Override + public boolean equals(Object obj) { + if (!(obj instanceof ReadCacheEntry)) { + return false; + } + + ReadCacheEntry other = (ReadCacheEntry) obj; + return this.location.equals(other.location) && super.equals(other); + } + + @Override + public int hashCode() { + return location.hashCode() * 23 + super.hashCode(); } } diff -r 9c454c650b29 -r a858c5f56d8a graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/ReadEliminationClosure.java --- a/graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/ReadEliminationClosure.java Mon Jun 08 15:57:52 2015 +0200 +++ b/graal/com.oracle.graal.virtual/src/com/oracle/graal/virtual/phases/ea/ReadEliminationClosure.java Mon Jun 08 18:47:58 2015 +0200 @@ -36,6 +36,7 @@ import com.oracle.graal.nodes.extended.*; import com.oracle.graal.nodes.java.*; import com.oracle.graal.nodes.memory.*; +import com.oracle.graal.nodes.memory.address.*; import com.oracle.graal.nodes.util.*; import com.oracle.graal.virtual.phases.ea.ReadEliminationBlockState.CacheEntry; import com.oracle.graal.virtual.phases.ea.ReadEliminationBlockState.LoadCacheEntry; @@ -86,40 +87,41 @@ } } else if (node instanceof ReadNode) { ReadNode read = (ReadNode) node; - if (read.location() instanceof ConstantLocationNode) { - ValueNode object = GraphUtil.unproxify(read.object()); - ReadCacheEntry identifier = new ReadCacheEntry(object, read.location()); - ValueNode cachedValue = state.getCacheEntry(identifier); - if (cachedValue != null && read.stamp().isCompatible(cachedValue.stamp())) { - // Anchor guard if it is not fixed and different from cachedValue's guard - if (read.getGuard() != null && !(read.getGuard() instanceof FixedNode)) { - if (!(cachedValue instanceof GuardedNode) || ((GuardedNode) cachedValue).getGuard() != read.getGuard()) { - effects.addFixedNodeBefore(new ValueAnchorNode((ValueNode) read.getGuard()), read); + if (read.getAddress() instanceof OffsetAddressNode) { + OffsetAddressNode address = (OffsetAddressNode) read.getAddress(); + if (address.getOffset().isConstant()) { + ValueNode object = GraphUtil.unproxify(address.getBase()); + ReadCacheEntry identifier = new ReadCacheEntry(object, address.getOffset(), read.getLocationIdentity()); + ValueNode cachedValue = state.getCacheEntry(identifier); + if (cachedValue != null && read.stamp().isCompatible(cachedValue.stamp())) { + // Anchor guard if it is not fixed and different from cachedValue's guard + if (read.getGuard() != null && !(read.getGuard() instanceof FixedNode)) { + if (!(cachedValue instanceof GuardedNode) || ((GuardedNode) cachedValue).getGuard() != read.getGuard()) { + effects.addFixedNodeBefore(new ValueAnchorNode((ValueNode) read.getGuard()), read); + } } } - effects.replaceAtUsages(read, cachedValue); - addScalarAlias(read, cachedValue); - deleted = true; - } else { - state.addCacheEntry(identifier, read); } } } else if (node instanceof WriteNode) { WriteNode write = (WriteNode) node; - if (write.location() instanceof ConstantLocationNode) { - ValueNode object = GraphUtil.unproxify(write.object()); - ReadCacheEntry identifier = new ReadCacheEntry(object, write.location()); - ValueNode cachedValue = state.getCacheEntry(identifier); + if (write.getAddress() instanceof OffsetAddressNode) { + OffsetAddressNode address = (OffsetAddressNode) write.getAddress(); + if (address.getOffset().isConstant()) { + ValueNode object = GraphUtil.unproxify(address.getBase()); + ReadCacheEntry identifier = new ReadCacheEntry(object, address.getOffset(), write.getLocationIdentity()); + ValueNode cachedValue = state.getCacheEntry(identifier); - ValueNode value = getScalarAlias(write.value()); - if (GraphUtil.unproxify(value) == GraphUtil.unproxify(cachedValue)) { - effects.deleteNode(write); - deleted = true; + ValueNode value = getScalarAlias(write.value()); + if (GraphUtil.unproxify(value) == GraphUtil.unproxify(cachedValue)) { + effects.deleteNode(write); + deleted = true; + } + processIdentity(state, write.getLocationIdentity()); + state.addCacheEntry(identifier, value); + } else { + processIdentity(state, write.getLocationIdentity()); } - processIdentity(state, write.location().getLocationIdentity()); - state.addCacheEntry(identifier, value); - } else { - processIdentity(state, write.location().getLocationIdentity()); } } else if (node instanceof UnsafeAccessNode) { if (node instanceof UnsafeLoadNode) { diff -r 9c454c650b29 -r a858c5f56d8a graal/com.oracle.graal.word/src/com/oracle/graal/word/BarrieredAccess.java --- a/graal/com.oracle.graal.word/src/com/oracle/graal/word/BarrieredAccess.java Mon Jun 08 15:57:52 2015 +0200 +++ b/graal/com.oracle.graal.word/src/com/oracle/graal/word/BarrieredAccess.java Mon Jun 08 18:47:58 2015 +0200 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2014, 2014, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2014, 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 @@ -22,10 +22,9 @@ */ package com.oracle.graal.word; -import com.oracle.jvmci.meta.LocationIdentity; -import com.oracle.graal.nodes.extended.*; import com.oracle.graal.word.Word.Opcode; import com.oracle.graal.word.Word.Operation; +import com.oracle.jvmci.meta.*; /** * Medium-level memory access for Objects. Similarly to the readXxx and writeXxx methods defined for @@ -44,7 +43,7 @@ * * @param object the base object for the memory access * @param offset the signed offset for the memory access - * @param locationIdentity the identity of the read (see {@link LocationNode}) + * @param locationIdentity the identity of the read * @return the result of the memory access */ @Operation(opcode = Opcode.READ_BARRIERED) @@ -59,7 +58,7 @@ * * @param object the base object for the memory access * @param offset the signed offset for the memory access - * @param locationIdentity the identity of the read (see {@link LocationNode}) + * @param locationIdentity the identity of the read * @return the result of the memory access */ @Operation(opcode = Opcode.READ_BARRIERED) @@ -74,7 +73,7 @@ * * @param object the base object for the memory access * @param offset the signed offset for the memory access - * @param locationIdentity the identity of the read (see {@link LocationNode}) + * @param locationIdentity the identity of the read * @return the result of the memory access */ @Operation(opcode = Opcode.READ_BARRIERED) @@ -89,7 +88,7 @@ * * @param object the base object for the memory access * @param offset the signed offset for the memory access - * @param locationIdentity the identity of the read (see {@link LocationNode}) + * @param locationIdentity the identity of the read * @return the result of the memory access */ @Operation(opcode = Opcode.READ_BARRIERED) @@ -104,7 +103,7 @@ * * @param object the base object for the memory access * @param offset the signed offset for the memory access - * @param locationIdentity the identity of the read (see {@link LocationNode}) + * @param locationIdentity the identity of the read * @return the result of the memory access */ @Operation(opcode = Opcode.READ_BARRIERED) @@ -119,7 +118,7 @@ * * @param object the base object for the memory access * @param offset the signed offset for the memory access - * @param locationIdentity the identity of the read (see {@link LocationNode}) + * @param locationIdentity the identity of the read * @return the result of the memory access */ @Operation(opcode = Opcode.READ_BARRIERED) @@ -134,7 +133,7 @@ * * @param object the base object for the memory access * @param offset the signed offset for the memory access - * @param locationIdentity the identity of the read (see {@link LocationNode}) + * @param locationIdentity the identity of the read * @return the result of the memory access */ @Operation(opcode = Opcode.READ_BARRIERED) @@ -149,7 +148,7 @@ * * @param object the base object for the memory access * @param offset the signed offset for the memory access - * @param locationIdentity the identity of the read (see {@link LocationNode}) + * @param locationIdentity the identity of the read * @return the result of the memory access */ @Operation(opcode = Opcode.READ_BARRIERED) @@ -164,7 +163,7 @@ * * @param object the base object for the memory access * @param offset the signed offset for the memory access - * @param locationIdentity the identity of the read (see {@link LocationNode}) + * @param locationIdentity the identity of the read * @return the result of the memory access */ @Operation(opcode = Opcode.READ_BARRIERED) @@ -175,7 +174,7 @@ * * @param object the base object for the memory access * @param offset the signed offset for the memory access - * @param locationIdentity the identity of the read (see {@link LocationNode}) + * @param locationIdentity the identity of the read * @return the result of the memory access */ @Operation(opcode = Opcode.READ_BARRIERED) @@ -186,7 +185,7 @@ * * @param object the base object for the memory access * @param offset the signed offset for the memory access - * @param locationIdentity the identity of the read (see {@link LocationNode}) + * @param locationIdentity the identity of the read * @return the result of the memory access */ @Operation(opcode = Opcode.READ_BARRIERED) @@ -197,7 +196,7 @@ * * @param object the base object for the memory access * @param offset the signed offset for the memory access - * @param locationIdentity the identity of the read (see {@link LocationNode}) + * @param locationIdentity the identity of the read * @return the result of the memory access */ @Operation(opcode = Opcode.READ_BARRIERED) @@ -208,7 +207,7 @@ * * @param object the base object for the memory access * @param offset the signed offset for the memory access - * @param locationIdentity the identity of the read (see {@link LocationNode}) + * @param locationIdentity the identity of the read * @return the result of the memory access */ @Operation(opcode = Opcode.READ_BARRIERED) @@ -219,7 +218,7 @@ * * @param object the base object for the memory access * @param offset the signed offset for the memory access - * @param locationIdentity the identity of the read (see {@link LocationNode}) + * @param locationIdentity the identity of the read * @return the result of the memory access */ @Operation(opcode = Opcode.READ_BARRIERED) @@ -230,7 +229,7 @@ * * @param object the base object for the memory access * @param offset the signed offset for the memory access - * @param locationIdentity the identity of the read (see {@link LocationNode}) + * @param locationIdentity the identity of the read * @return the result of the memory access */ @Operation(opcode = Opcode.READ_BARRIERED) @@ -241,7 +240,7 @@ * * @param object the base object for the memory access * @param offset the signed offset for the memory access - * @param locationIdentity the identity of the read (see {@link LocationNode}) + * @param locationIdentity the identity of the read * @return the result of the memory access */ @Operation(opcode = Opcode.READ_BARRIERED) @@ -252,7 +251,7 @@ * * @param object the base object for the memory access * @param offset the signed offset for the memory access - * @param locationIdentity the identity of the read (see {@link LocationNode}) + * @param locationIdentity the identity of the read * @return the result of the memory access */ @Operation(opcode = Opcode.READ_BARRIERED) @@ -263,7 +262,7 @@ * * @param object the base object for the memory access * @param offset the signed offset for the memory access - * @param locationIdentity the identity of the read (see {@link LocationNode}) + * @param locationIdentity the identity of the read * @return the result of the memory access */ @Operation(opcode = Opcode.READ_BARRIERED) @@ -278,7 +277,7 @@ * * @param object the base object for the memory access * @param offset the signed offset for the memory access - * @param locationIdentity the identity of the write (see {@link LocationNode}) + * @param locationIdentity the identity of the write * @param val the value to be written to memory */ @Operation(opcode = Opcode.WRITE_BARRIERED) @@ -293,7 +292,7 @@ * * @param object the base object for the memory access * @param offset the signed offset for the memory access - * @param locationIdentity the identity of the write (see {@link LocationNode}) + * @param locationIdentity the identity of the write * @param val the value to be written to memory */ @Operation(opcode = Opcode.WRITE_BARRIERED) @@ -308,7 +307,7 @@ * * @param object the base object for the memory access * @param offset the signed offset for the memory access - * @param locationIdentity the identity of the write (see {@link LocationNode}) + * @param locationIdentity the identity of the write * @param val the value to be written to memory */ @Operation(opcode = Opcode.WRITE_BARRIERED) @@ -323,7 +322,7 @@ * * @param object the base object for the memory access * @param offset the signed offset for the memory access - * @param locationIdentity the identity of the write (see {@link LocationNode}) + * @param locationIdentity the identity of the write * @param val the value to be written to memory */ @Operation(opcode = Opcode.WRITE_BARRIERED) @@ -338,7 +337,7 @@ * * @param object the base object for the memory access * @param offset the signed offset for the memory access - * @param locationIdentity the identity of the write (see {@link LocationNode}) + * @param locationIdentity the identity of the write * @param val the value to be written to memory */ @Operation(opcode = Opcode.WRITE_BARRIERED) @@ -353,7 +352,7 @@ * * @param object the base object for the memory access * @param offset the signed offset for the memory access - * @param locationIdentity the identity of the write (see {@link LocationNode}) + * @param locationIdentity the identity of the write * @param val the value to be written to memory */ @Operation(opcode = Opcode.WRITE_BARRIERED) @@ -368,7 +367,7 @@ * * @param object the base object for the memory access * @param offset the signed offset for the memory access - * @param locationIdentity the identity of the write (see {@link LocationNode}) + * @param locationIdentity the identity of the write * @param val the value to be written to memory */ @Operation(opcode = Opcode.WRITE_BARRIERED) @@ -383,7 +382,7 @@ * * @param object the base object for the memory access * @param offset the signed offset for the memory access - * @param locationIdentity the identity of the write (see {@link LocationNode}) + * @param locationIdentity the identity of the write * @param val the value to be written to memory */ @Operation(opcode = Opcode.WRITE_BARRIERED) @@ -398,7 +397,7 @@ * * @param object the base object for the memory access * @param offset the signed offset for the memory access - * @param locationIdentity the identity of the write (see {@link LocationNode}) + * @param locationIdentity the identity of the write * @param val the value to be written to memory */ @Operation(opcode = Opcode.WRITE_BARRIERED) @@ -409,7 +408,7 @@ * * @param object the base object for the memory access * @param offset the signed offset for the memory access - * @param locationIdentity the identity of the write (see {@link LocationNode}) + * @param locationIdentity the identity of the write * @param val the value to be written to memory */ @Operation(opcode = Opcode.WRITE_BARRIERED) @@ -420,7 +419,7 @@ * * @param object the base object for the memory access * @param offset the signed offset for the memory access - * @param locationIdentity the identity of the write (see {@link LocationNode}) + * @param locationIdentity the identity of the write * @param val the value to be written to memory */ @Operation(opcode = Opcode.WRITE_BARRIERED) @@ -431,7 +430,7 @@ * * @param object the base object for the memory access * @param offset the signed offset for the memory access - * @param locationIdentity the identity of the write (see {@link LocationNode}) + * @param locationIdentity the identity of the write * @param val the value to be written to memory */ @Operation(opcode = Opcode.WRITE_BARRIERED) @@ -442,7 +441,7 @@ * * @param object the base object for the memory access * @param offset the signed offset for the memory access - * @param locationIdentity the identity of the write (see {@link LocationNode}) + * @param locationIdentity the identity of the write * @param val the value to be written to memory */ @Operation(opcode = Opcode.WRITE_BARRIERED) @@ -453,7 +452,7 @@ * * @param object the base object for the memory access * @param offset the signed offset for the memory access - * @param locationIdentity the identity of the write (see {@link LocationNode}) + * @param locationIdentity the identity of the write * @param val the value to be written to memory */ @Operation(opcode = Opcode.WRITE_BARRIERED) @@ -464,7 +463,7 @@ * * @param object the base object for the memory access * @param offset the signed offset for the memory access - * @param locationIdentity the identity of the write (see {@link LocationNode}) + * @param locationIdentity the identity of the write * @param val the value to be written to memory */ @Operation(opcode = Opcode.WRITE_BARRIERED) @@ -475,7 +474,7 @@ * * @param object the base object for the memory access * @param offset the signed offset for the memory access - * @param locationIdentity the identity of the write (see {@link LocationNode}) + * @param locationIdentity the identity of the write * @param val the value to be written to memory */ @Operation(opcode = Opcode.WRITE_BARRIERED) @@ -486,7 +485,7 @@ * * @param object the base object for the memory access * @param offset the signed offset for the memory access - * @param locationIdentity the identity of the write (see {@link LocationNode}) + * @param locationIdentity the identity of the write * @param val the value to be written to memory */ @Operation(opcode = Opcode.WRITE_BARRIERED) @@ -497,7 +496,7 @@ * * @param object the base object for the memory access * @param offset the signed offset for the memory access - * @param locationIdentity the identity of the write (see {@link LocationNode}) + * @param locationIdentity the identity of the write * @param val the value to be written to memory */ @Operation(opcode = Opcode.WRITE_BARRIERED) diff -r 9c454c650b29 -r a858c5f56d8a graal/com.oracle.graal.word/src/com/oracle/graal/word/ObjectAccess.java --- a/graal/com.oracle.graal.word/src/com/oracle/graal/word/ObjectAccess.java Mon Jun 08 15:57:52 2015 +0200 +++ b/graal/com.oracle.graal.word/src/com/oracle/graal/word/ObjectAccess.java Mon Jun 08 18:47:58 2015 +0200 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013, 2013, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2013, 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 @@ -22,10 +22,9 @@ */ package com.oracle.graal.word; -import com.oracle.jvmci.meta.LocationIdentity; -import com.oracle.graal.nodes.extended.*; import com.oracle.graal.word.Word.Opcode; import com.oracle.graal.word.Word.Operation; +import com.oracle.jvmci.meta.*; /** * Low-level memory access for Objects. Similarly to the readXxx and writeXxx methods defined for @@ -44,7 +43,7 @@ * * @param object the base object for the memory access * @param offset the signed offset for the memory access - * @param locationIdentity the identity of the read (see {@link LocationNode}) + * @param locationIdentity the identity of the read * @return the result of the memory access */ @Operation(opcode = Opcode.READ_OBJECT) @@ -59,7 +58,7 @@ * * @param object the base object for the memory access * @param offset the signed offset for the memory access - * @param locationIdentity the identity of the read (see {@link LocationNode}) + * @param locationIdentity the identity of the read * @return the result of the memory access */ @Operation(opcode = Opcode.READ_OBJECT) @@ -74,7 +73,7 @@ * * @param object the base object for the memory access * @param offset the signed offset for the memory access - * @param locationIdentity the identity of the read (see {@link LocationNode}) + * @param locationIdentity the identity of the read * @return the result of the memory access */ @Operation(opcode = Opcode.READ_OBJECT) @@ -89,7 +88,7 @@ * * @param object the base object for the memory access * @param offset the signed offset for the memory access - * @param locationIdentity the identity of the read (see {@link LocationNode}) + * @param locationIdentity the identity of the read * @return the result of the memory access */ @Operation(opcode = Opcode.READ_OBJECT) @@ -104,7 +103,7 @@ * * @param object the base object for the memory access * @param offset the signed offset for the memory access - * @param locationIdentity the identity of the read (see {@link LocationNode}) + * @param locationIdentity the identity of the read * @return the result of the memory access */ @Operation(opcode = Opcode.READ_OBJECT) @@ -119,7 +118,7 @@ * * @param object the base object for the memory access * @param offset the signed offset for the memory access - * @param locationIdentity the identity of the read (see {@link LocationNode}) + * @param locationIdentity the identity of the read * @return the result of the memory access */ @Operation(opcode = Opcode.READ_OBJECT) @@ -134,7 +133,7 @@ * * @param object the base object for the memory access * @param offset the signed offset for the memory access - * @param locationIdentity the identity of the read (see {@link LocationNode}) + * @param locationIdentity the identity of the read * @return the result of the memory access */ @Operation(opcode = Opcode.READ_OBJECT) @@ -149,7 +148,7 @@ * * @param object the base object for the memory access * @param offset the signed offset for the memory access - * @param locationIdentity the identity of the read (see {@link LocationNode}) + * @param locationIdentity the identity of the read * @return the result of the memory access */ @Operation(opcode = Opcode.READ_OBJECT) @@ -164,7 +163,7 @@ * * @param object the base object for the memory access * @param offset the signed offset for the memory access - * @param locationIdentity the identity of the read (see {@link LocationNode}) + * @param locationIdentity the identity of the read * @return the result of the memory access */ @Operation(opcode = Opcode.READ_OBJECT) @@ -175,7 +174,7 @@ * * @param object the base object for the memory access * @param offset the signed offset for the memory access - * @param locationIdentity the identity of the read (see {@link LocationNode}) + * @param locationIdentity the identity of the read * @return the result of the memory access */ @Operation(opcode = Opcode.READ_OBJECT) @@ -186,7 +185,7 @@ * * @param object the base object for the memory access * @param offset the signed offset for the memory access - * @param locationIdentity the identity of the read (see {@link LocationNode}) + * @param locationIdentity the identity of the read * @return the result of the memory access */ @Operation(opcode = Opcode.READ_OBJECT) @@ -197,7 +196,7 @@ * * @param object the base object for the memory access * @param offset the signed offset for the memory access - * @param locationIdentity the identity of the read (see {@link LocationNode}) + * @param locationIdentity the identity of the read * @return the result of the memory access */ @Operation(opcode = Opcode.READ_OBJECT) @@ -208,7 +207,7 @@ * * @param object the base object for the memory access * @param offset the signed offset for the memory access - * @param locationIdentity the identity of the read (see {@link LocationNode}) + * @param locationIdentity the identity of the read * @return the result of the memory access */ @Operation(opcode = Opcode.READ_OBJECT) @@ -219,7 +218,7 @@ * * @param object the base object for the memory access * @param offset the signed offset for the memory access - * @param locationIdentity the identity of the read (see {@link LocationNode}) + * @param locationIdentity the identity of the read * @return the result of the memory access */ @Operation(opcode = Opcode.READ_OBJECT) @@ -230,7 +229,7 @@ * * @param object the base object for the memory access * @param offset the signed offset for the memory access - * @param locationIdentity the identity of the read (see {@link LocationNode}) + * @param locationIdentity the identity of the read * @return the result of the memory access */ @Operation(opcode = Opcode.READ_OBJECT) @@ -241,7 +240,7 @@ * * @param object the base object for the memory access * @param offset the signed offset for the memory access - * @param locationIdentity the identity of the read (see {@link LocationNode}) + * @param locationIdentity the identity of the read * @return the result of the memory access */ @Operation(opcode = Opcode.READ_OBJECT) @@ -252,7 +251,7 @@ * * @param object the base object for the memory access * @param offset the signed offset for the memory access - * @param locationIdentity the identity of the read (see {@link LocationNode}) + * @param locationIdentity the identity of the read * @return the result of the memory access */ @Operation(opcode = Opcode.READ_OBJECT) @@ -263,7 +262,7 @@ * * @param object the base object for the memory access * @param offset the signed offset for the memory access - * @param locationIdentity the identity of the read (see {@link LocationNode}) + * @param locationIdentity the identity of the read * @return the result of the memory access */ @Operation(opcode = Opcode.READ_OBJECT) @@ -278,7 +277,7 @@ * * @param object the base object for the memory access * @param offset the signed offset for the memory access - * @param locationIdentity the identity of the write (see {@link LocationNode}) + * @param locationIdentity the identity of the write * @param val the value to be written to memory */ @Operation(opcode = Opcode.WRITE_OBJECT) @@ -293,7 +292,7 @@ * * @param object the base object for the memory access * @param offset the signed offset for the memory access - * @param locationIdentity the identity of the write (see {@link LocationNode}) + * @param locationIdentity the identity of the write * @param val the value to be written to memory */ @Operation(opcode = Opcode.WRITE_OBJECT) @@ -308,7 +307,7 @@ * * @param object the base object for the memory access * @param offset the signed offset for the memory access - * @param locationIdentity the identity of the write (see {@link LocationNode}) + * @param locationIdentity the identity of the write * @param val the value to be written to memory */ @Operation(opcode = Opcode.WRITE_OBJECT) @@ -323,7 +322,7 @@ * * @param object the base object for the memory access * @param offset the signed offset for the memory access - * @param locationIdentity the identity of the write (see {@link LocationNode}) + * @param locationIdentity the identity of the write * @param val the value to be written to memory */ @Operation(opcode = Opcode.WRITE_OBJECT) @@ -338,7 +337,7 @@ * * @param object the base object for the memory access * @param offset the signed offset for the memory access - * @param locationIdentity the identity of the write (see {@link LocationNode}) + * @param locationIdentity the identity of the write * @param val the value to be written to memory */ @Operation(opcode = Opcode.WRITE_OBJECT) @@ -353,7 +352,7 @@ * * @param object the base object for the memory access * @param offset the signed offset for the memory access - * @param locationIdentity the identity of the write (see {@link LocationNode}) + * @param locationIdentity the identity of the write * @param val the value to be written to memory */ @Operation(opcode = Opcode.WRITE_OBJECT) @@ -368,7 +367,7 @@ * * @param object the base object for the memory access * @param offset the signed offset for the memory access - * @param locationIdentity the identity of the write (see {@link LocationNode}) + * @param locationIdentity the identity of the write * @param val the value to be written to memory */ @Operation(opcode = Opcode.WRITE_OBJECT) @@ -383,7 +382,7 @@ * * @param object the base object for the memory access * @param offset the signed offset for the memory access - * @param locationIdentity the identity of the write (see {@link LocationNode}) + * @param locationIdentity the identity of the write * @param val the value to be written to memory */ @Operation(opcode = Opcode.WRITE_OBJECT) @@ -398,7 +397,7 @@ * * @param object the base object for the memory access * @param offset the signed offset for the memory access - * @param locationIdentity the identity of the write (see {@link LocationNode}) + * @param locationIdentity the identity of the write * @param val the value to be written to memory */ @Operation(opcode = Opcode.WRITE_OBJECT) @@ -409,7 +408,7 @@ * * @param object the base object for the memory access * @param offset the signed offset for the memory access - * @param locationIdentity the identity of the write (see {@link LocationNode}) + * @param locationIdentity the identity of the write * @param val the value to be written to memory */ @Operation(opcode = Opcode.WRITE_OBJECT) @@ -420,7 +419,7 @@ * * @param object the base object for the memory access * @param offset the signed offset for the memory access - * @param locationIdentity the identity of the write (see {@link LocationNode}) + * @param locationIdentity the identity of the write * @param val the value to be written to memory */ @Operation(opcode = Opcode.WRITE_OBJECT) @@ -431,7 +430,7 @@ * * @param object the base object for the memory access * @param offset the signed offset for the memory access - * @param locationIdentity the identity of the write (see {@link LocationNode}) + * @param locationIdentity the identity of the write * @param val the value to be written to memory */ @Operation(opcode = Opcode.WRITE_OBJECT) @@ -442,7 +441,7 @@ * * @param object the base object for the memory access * @param offset the signed offset for the memory access - * @param locationIdentity the identity of the write (see {@link LocationNode}) + * @param locationIdentity the identity of the write * @param val the value to be written to memory */ @Operation(opcode = Opcode.WRITE_OBJECT) @@ -453,7 +452,7 @@ * * @param object the base object for the memory access * @param offset the signed offset for the memory access - * @param locationIdentity the identity of the write (see {@link LocationNode}) + * @param locationIdentity the identity of the write * @param val the value to be written to memory */ @Operation(opcode = Opcode.WRITE_OBJECT) @@ -464,7 +463,7 @@ * * @param object the base object for the memory access * @param offset the signed offset for the memory access - * @param locationIdentity the identity of the write (see {@link LocationNode}) + * @param locationIdentity the identity of the write * @param val the value to be written to memory */ @Operation(opcode = Opcode.WRITE_OBJECT) @@ -475,7 +474,7 @@ * * @param object the base object for the memory access * @param offset the signed offset for the memory access - * @param locationIdentity the identity of the write (see {@link LocationNode}) + * @param locationIdentity the identity of the write * @param val the value to be written to memory */ @Operation(opcode = Opcode.WRITE_OBJECT) @@ -486,7 +485,7 @@ * * @param object the base object for the memory access * @param offset the signed offset for the memory access - * @param locationIdentity the identity of the write (see {@link LocationNode}) + * @param locationIdentity the identity of the write * @param val the value to be written to memory */ @Operation(opcode = Opcode.WRITE_OBJECT) @@ -497,7 +496,7 @@ * * @param object the base object for the memory access * @param offset the signed offset for the memory access - * @param locationIdentity the identity of the write (see {@link LocationNode}) + * @param locationIdentity the identity of the write * @param val the value to be written to memory */ @Operation(opcode = Opcode.WRITE_OBJECT) diff -r 9c454c650b29 -r a858c5f56d8a graal/com.oracle.graal.word/src/com/oracle/graal/word/Pointer.java --- a/graal/com.oracle.graal.word/src/com/oracle/graal/word/Pointer.java Mon Jun 08 15:57:52 2015 +0200 +++ b/graal/com.oracle.graal.word/src/com/oracle/graal/word/Pointer.java Mon Jun 08 18:47:58 2015 +0200 @@ -22,9 +22,8 @@ */ package com.oracle.graal.word; -import com.oracle.jvmci.meta.LocationIdentity; -import com.oracle.graal.nodes.extended.*; import com.oracle.graal.nodes.memory.HeapAccess.BarrierType; +import com.oracle.jvmci.meta.*; /** * Lowest-level memory access of native C memory. These methods access the raw memory without any @@ -55,7 +54,7 @@ * knows that the highest-order bit of the unsigned value is never used). * * @param offset the signed offset for the memory access - * @param locationIdentity the identity of the read (see {@link LocationNode}) + * @param locationIdentity the identity of the read * @return the result of the memory access */ byte readByte(WordBase offset, LocationIdentity locationIdentity); @@ -69,7 +68,7 @@ * knows that the highest-order bit of the unsigned value is never used). * * @param offset the signed offset for the memory access - * @param locationIdentity the identity of the read (see {@link LocationNode}) + * @param locationIdentity the identity of the read * @return the result of the memory access */ char readChar(WordBase offset, LocationIdentity locationIdentity); @@ -83,7 +82,7 @@ * knows that the highest-order bit of the unsigned value is never used). * * @param offset the signed offset for the memory access - * @param locationIdentity the identity of the read (see {@link LocationNode}) + * @param locationIdentity the identity of the read * @return the result of the memory access */ short readShort(WordBase offset, LocationIdentity locationIdentity); @@ -97,7 +96,7 @@ * knows that the highest-order bit of the unsigned value is never used). * * @param offset the signed offset for the memory access - * @param locationIdentity the identity of the read (see {@link LocationNode}) + * @param locationIdentity the identity of the read * @return the result of the memory access */ int readInt(WordBase offset, LocationIdentity locationIdentity); @@ -111,7 +110,7 @@ * knows that the highest-order bit of the unsigned value is never used). * * @param offset the signed offset for the memory access - * @param locationIdentity the identity of the read (see {@link LocationNode}) + * @param locationIdentity the identity of the read * @return the result of the memory access */ long readLong(WordBase offset, LocationIdentity locationIdentity); @@ -125,7 +124,7 @@ * knows that the highest-order bit of the unsigned value is never used). * * @param offset the signed offset for the memory access - * @param locationIdentity the identity of the read (see {@link LocationNode}) + * @param locationIdentity the identity of the read * @return the result of the memory access */ float readFloat(WordBase offset, LocationIdentity locationIdentity); @@ -139,7 +138,7 @@ * knows that the highest-order bit of the unsigned value is never used). * * @param offset the signed offset for the memory access - * @param locationIdentity the identity of the read (see {@link LocationNode}) + * @param locationIdentity the identity of the read * @return the result of the memory access */ double readDouble(WordBase offset, LocationIdentity locationIdentity); @@ -153,7 +152,7 @@ * knows that the highest-order bit of the unsigned value is never used). * * @param offset the signed offset for the memory access - * @param locationIdentity the identity of the read (see {@link LocationNode}) + * @param locationIdentity the identity of the read * @return the result of the memory access */ Word readWord(WordBase offset, LocationIdentity locationIdentity); @@ -167,7 +166,7 @@ * knows that the highest-order bit of the unsigned value is never used). * * @param offset the signed offset for the memory access - * @param locationIdentity the identity of the read (see {@link LocationNode}) + * @param locationIdentity the identity of the read * @return the result of the memory access */ Object readObject(WordBase offset, LocationIdentity locationIdentity); @@ -177,7 +176,7 @@ * bytes. * * @param offset the signed offset for the memory access - * @param locationIdentity the identity of the read (see {@link LocationNode}) + * @param locationIdentity the identity of the read * @return the result of the memory access */ byte readByte(int offset, LocationIdentity locationIdentity); @@ -187,7 +186,7 @@ * bytes. * * @param offset the signed offset for the memory access - * @param locationIdentity the identity of the read (see {@link LocationNode}) + * @param locationIdentity the identity of the read * @return the result of the memory access */ char readChar(int offset, LocationIdentity locationIdentity); @@ -197,7 +196,7 @@ * bytes. * * @param offset the signed offset for the memory access - * @param locationIdentity the identity of the read (see {@link LocationNode}) + * @param locationIdentity the identity of the read * @return the result of the memory access */ short readShort(int offset, LocationIdentity locationIdentity); @@ -207,7 +206,7 @@ * bytes. * * @param offset the signed offset for the memory access - * @param locationIdentity the identity of the read (see {@link LocationNode}) + * @param locationIdentity the identity of the read * @return the result of the memory access */ int readInt(int offset, LocationIdentity locationIdentity); @@ -217,7 +216,7 @@ * bytes. * * @param offset the signed offset for the memory access - * @param locationIdentity the identity of the read (see {@link LocationNode}) + * @param locationIdentity the identity of the read * @return the result of the memory access */ long readLong(int offset, LocationIdentity locationIdentity); @@ -227,7 +226,7 @@ * bytes. * * @param offset the signed offset for the memory access - * @param locationIdentity the identity of the read (see {@link LocationNode}) + * @param locationIdentity the identity of the read * @return the result of the memory access */ float readFloat(int offset, LocationIdentity locationIdentity); @@ -237,7 +236,7 @@ * bytes. * * @param offset the signed offset for the memory access - * @param locationIdentity the identity of the read (see {@link LocationNode}) + * @param locationIdentity the identity of the read * @return the result of the memory access */ double readDouble(int offset, LocationIdentity locationIdentity); @@ -247,7 +246,7 @@ * bytes. * * @param offset the signed offset for the memory access - * @param locationIdentity the identity of the read (see {@link LocationNode}) + * @param locationIdentity the identity of the read * @return the result of the memory access */ Word readWord(int offset, LocationIdentity locationIdentity); @@ -257,7 +256,7 @@ * bytes. * * @param offset the signed offset for the memory access - * @param locationIdentity the identity of the read (see {@link LocationNode}) + * @param locationIdentity the identity of the read * @return the result of the memory access */ Object readObject(int offset, LocationIdentity locationIdentity); @@ -271,7 +270,7 @@ * knows that the highest-order bit of the unsigned value is never used). * * @param offset the signed offset for the memory access - * @param locationIdentity the identity of the write (see {@link LocationNode}) + * @param locationIdentity the identity of the write * @param val the value to be written to memory */ void writeByte(WordBase offset, byte val, LocationIdentity locationIdentity); @@ -285,7 +284,7 @@ * knows that the highest-order bit of the unsigned value is never used). * * @param offset the signed offset for the memory access - * @param locationIdentity the identity of the write (see {@link LocationNode}) + * @param locationIdentity the identity of the write * @param val the value to be written to memory */ void writeChar(WordBase offset, char val, LocationIdentity locationIdentity); @@ -299,7 +298,7 @@ * knows that the highest-order bit of the unsigned value is never used). * * @param offset the signed offset for the memory access - * @param locationIdentity the identity of the write (see {@link LocationNode}) + * @param locationIdentity the identity of the write * @param val the value to be written to memory */ void writeShort(WordBase offset, short val, LocationIdentity locationIdentity); @@ -313,7 +312,7 @@ * knows that the highest-order bit of the unsigned value is never used). * * @param offset the signed offset for the memory access - * @param locationIdentity the identity of the write (see {@link LocationNode}) + * @param locationIdentity the identity of the write * @param val the value to be written to memory */ void writeInt(WordBase offset, int val, LocationIdentity locationIdentity); @@ -327,7 +326,7 @@ * knows that the highest-order bit of the unsigned value is never used). * * @param offset the signed offset for the memory access - * @param locationIdentity the identity of the write (see {@link LocationNode}) + * @param locationIdentity the identity of the write * @param val the value to be written to memory */ void writeLong(WordBase offset, long val, LocationIdentity locationIdentity); @@ -341,7 +340,7 @@ * knows that the highest-order bit of the unsigned value is never used). * * @param offset the signed offset for the memory access - * @param locationIdentity the identity of the write (see {@link LocationNode}) + * @param locationIdentity the identity of the write * @param val the value to be written to memory */ void writeFloat(WordBase offset, float val, LocationIdentity locationIdentity); @@ -355,7 +354,7 @@ * knows that the highest-order bit of the unsigned value is never used). * * @param offset the signed offset for the memory access - * @param locationIdentity the identity of the write (see {@link LocationNode}) + * @param locationIdentity the identity of the write * @param val the value to be written to memory */ void writeDouble(WordBase offset, double val, LocationIdentity locationIdentity); @@ -369,7 +368,7 @@ * knows that the highest-order bit of the unsigned value is never used). * * @param offset the signed offset for the memory access - * @param locationIdentity the identity of the write (see {@link LocationNode}) + * @param locationIdentity the identity of the write * @param val the value to be written to memory */ void writeWord(WordBase offset, WordBase val, LocationIdentity locationIdentity); @@ -383,7 +382,7 @@ * knows that the highest-order bit of the unsigned value is never used). * * @param offset the signed offset for the memory access - * @param locationIdentity the identity of the write (see {@link LocationNode}) + * @param locationIdentity the identity of the write * @param val the value to be written to memory */ void initializeLong(WordBase offset, long val, LocationIdentity locationIdentity); @@ -397,7 +396,7 @@ * knows that the highest-order bit of the unsigned value is never used). * * @param offset the signed offset for the memory access - * @param locationIdentity the identity of the write (see {@link LocationNode}) + * @param locationIdentity the identity of the write * @param val the value to be written to memory */ void writeObject(WordBase offset, Object val, LocationIdentity locationIdentity); @@ -407,7 +406,7 @@ * bytes. * * @param offset the signed offset for the memory access - * @param locationIdentity the identity of the write (see {@link LocationNode}) + * @param locationIdentity the identity of the write * @param val the value to be written to memory */ void writeByte(int offset, byte val, LocationIdentity locationIdentity); @@ -417,7 +416,7 @@ * bytes. * * @param offset the signed offset for the memory access - * @param locationIdentity the identity of the write (see {@link LocationNode}) + * @param locationIdentity the identity of the write * @param val the value to be written to memory */ void writeChar(int offset, char val, LocationIdentity locationIdentity); @@ -427,7 +426,7 @@ * bytes. * * @param offset the signed offset for the memory access - * @param locationIdentity the identity of the write (see {@link LocationNode}) + * @param locationIdentity the identity of the write * @param val the value to be written to memory */ void writeShort(int offset, short val, LocationIdentity locationIdentity); @@ -437,7 +436,7 @@ * bytes. * * @param offset the signed offset for the memory access - * @param locationIdentity the identity of the write (see {@link LocationNode}) + * @param locationIdentity the identity of the write * @param val the value to be written to memory */ void writeInt(int offset, int val, LocationIdentity locationIdentity); @@ -447,7 +446,7 @@ * bytes. * * @param offset the signed offset for the memory access - * @param locationIdentity the identity of the write (see {@link LocationNode}) + * @param locationIdentity the identity of the write * @param val the value to be written to memory */ void writeLong(int offset, long val, LocationIdentity locationIdentity); @@ -457,7 +456,7 @@ * bytes. * * @param offset the signed offset for the memory access - * @param locationIdentity the identity of the write (see {@link LocationNode}) + * @param locationIdentity the identity of the write * @param val the value to be written to memory */ void writeFloat(int offset, float val, LocationIdentity locationIdentity); @@ -467,7 +466,7 @@ * bytes. * * @param offset the signed offset for the memory access - * @param locationIdentity the identity of the write (see {@link LocationNode}) + * @param locationIdentity the identity of the write * @param val the value to be written to memory */ void writeDouble(int offset, double val, LocationIdentity locationIdentity); @@ -477,7 +476,7 @@ * bytes. * * @param offset the signed offset for the memory access - * @param locationIdentity the identity of the write (see {@link LocationNode}) + * @param locationIdentity the identity of the write * @param val the value to be written to memory */ void writeWord(int offset, WordBase val, LocationIdentity locationIdentity); @@ -487,7 +486,7 @@ * are in bytes. The memory must be uninitialized or zero prior to this operation. * * @param offset the signed offset for the memory access - * @param locationIdentity the identity of the write (see {@link LocationNode}) + * @param locationIdentity the identity of the write * @param val the value to be written to memory */ void initializeLong(int offset, long val, LocationIdentity locationIdentity); @@ -497,7 +496,7 @@ * bytes. * * @param offset the signed offset for the memory access - * @param locationIdentity the identity of the write (see {@link LocationNode}) + * @param locationIdentity the identity of the write * @param val the value to be written to memory */ void writeObject(int offset, Object val, LocationIdentity locationIdentity); diff -r 9c454c650b29 -r a858c5f56d8a graal/com.oracle.graal.word/src/com/oracle/graal/word/Word.java --- a/graal/com.oracle.graal.word/src/com/oracle/graal/word/Word.java Mon Jun 08 15:57:52 2015 +0200 +++ b/graal/com.oracle.graal.word/src/com/oracle/graal/word/Word.java Mon Jun 08 18:47:58 2015 +0200 @@ -22,8 +22,6 @@ */ package com.oracle.graal.word; -import com.oracle.jvmci.code.UnsignedMath; -import com.oracle.jvmci.meta.LocationIdentity; import static com.oracle.jvmci.common.UnsafeAccess.*; import java.lang.annotation.*; @@ -32,7 +30,10 @@ import com.oracle.graal.nodes.*; import com.oracle.graal.nodes.calc.*; import com.oracle.graal.nodes.memory.HeapAccess.BarrierType; +import com.oracle.graal.nodes.memory.address.AddressNode.Address; +import com.oracle.jvmci.code.*; import com.oracle.jvmci.common.*; +import com.oracle.jvmci.meta.*; public abstract class Word implements Signed, Unsigned, Pointer { @@ -73,7 +74,7 @@ FROM_SIGNED, FROM_OBJECT, FROM_WORDBASE, - FROM_ARRAY, + FROM_ADDRESS, TO_OBJECT, TO_RAW_VALUE, } @@ -177,8 +178,8 @@ @Operation(opcode = Opcode.FROM_OBJECT) public static native Pointer fromObject(Object val); - @Operation(opcode = Opcode.FROM_ARRAY) - public static native Pointer fromArray(Object oop, Object location); + @Operation(opcode = Opcode.FROM_ADDRESS) + public static native Pointer fromAddress(Address address); @Override @Operation(opcode = Opcode.TO_OBJECT) diff -r 9c454c650b29 -r a858c5f56d8a graal/com.oracle.graal.word/src/com/oracle/graal/word/nodes/SnippetLocationNode.java --- a/graal/com.oracle.graal.word/src/com/oracle/graal/word/nodes/SnippetLocationNode.java Mon Jun 08 15:57:52 2015 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,113 +0,0 @@ -/* - * Copyright (c) 2013, 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.word.nodes; - -import com.oracle.jvmci.meta.Value; -import com.oracle.jvmci.meta.LocationIdentity; -import static com.oracle.jvmci.meta.LocationIdentity.*; -import com.oracle.graal.api.replacements.*; -import com.oracle.graal.compiler.common.type.*; -import com.oracle.graal.graph.*; -import com.oracle.graal.graph.spi.*; -import com.oracle.graal.lir.gen.*; -import com.oracle.graal.nodeinfo.*; -import com.oracle.graal.nodes.*; -import com.oracle.graal.nodes.extended.*; -import com.oracle.graal.nodes.spi.*; -import com.oracle.jvmci.common.*; - -/** - * Location node that can be used inside a snippet without having the elements (including the - * location identity and kind) as a snippet constant. Can represent locations in the form of [base + - * index * scale + disp]. When the location is created, all elements (base, index, scale, disp) are - * nodes. Both scale and disp must eventually canonicalize to {@link ConstantNode constants} so that - * this node can be canonicalized to a {@link IndexedLocationNode} or {@link ConstantLocationNode}. - */ -@NodeInfo -public final class SnippetLocationNode extends LocationNode implements Canonicalizable { - public static final NodeClass TYPE = NodeClass.create(SnippetLocationNode.class); - - protected final SnippetReflectionProvider snippetReflection; - - @Input(InputType.Association) ValueNode locationIdentity; - @Input ValueNode displacement; - @Input ValueNode index; - @Input ValueNode indexScaling; - - public SnippetLocationNode(@InjectedNodeParameter SnippetReflectionProvider snippetReflection, ValueNode locationIdentity, ValueNode displacement) { - this(snippetReflection, locationIdentity, displacement, null, null); - } - - public SnippetLocationNode(@InjectedNodeParameter SnippetReflectionProvider snippetReflection, ValueNode locationIdentity, ValueNode displacement, ValueNode index, ValueNode indexScaling) { - super(TYPE, StampFactory.object()); - this.snippetReflection = snippetReflection; - this.locationIdentity = locationIdentity; - this.displacement = displacement; - this.index = index; - this.indexScaling = indexScaling; - } - - @Override - public LocationIdentity getLocationIdentity() { - if (locationIdentity.isConstant()) { - LocationIdentity identity = snippetReflection.asObject(LocationIdentity.class, locationIdentity.asJavaConstant()); - return identity; - } - // We do not know our actual location identity yet, so be conservative. - return any(); - } - - @Override - public Node canonical(CanonicalizerTool tool) { - if (locationIdentity.isConstant() && displacement.isConstant() && (indexScaling == null || indexScaling.isConstant())) { - LocationIdentity constLocation = snippetReflection.asObject(LocationIdentity.class, locationIdentity.asJavaConstant()); - long constDisplacement = displacement.asJavaConstant().asLong(); - int constIndexScaling = indexScaling == null ? 0 : indexScaling.asJavaConstant().asInt(); - - if (index == null || constIndexScaling == 0) { - return graph().unique(new ConstantLocationNode(constLocation, constDisplacement)); - } else if (index.isConstant()) { - return graph().unique(new ConstantLocationNode(constLocation, index.asJavaConstant().asLong() * constIndexScaling + constDisplacement)); - } else { - return graph().unique(new IndexedLocationNode(constLocation, constDisplacement, index, constIndexScaling)); - } - } - return this; - } - - @Override - public Value generateAddress(NodeMappableLIRBuilder builder, LIRGeneratorTool gen, Value base) { - throw new JVMCIError("locationIdentity must be a constant so that this node can be canonicalized: " + locationIdentity); - } - - @Override - public IntegerStamp getDisplacementStamp() { - throw JVMCIError.shouldNotReachHere(); - } - - @NodeIntrinsic - public static native Location constantLocation(LocationIdentity identity, long displacement); - - @NodeIntrinsic - public static native Location indexedLocation(LocationIdentity identity, long displacement, int index, int indexScaling); -} diff -r 9c454c650b29 -r a858c5f56d8a graal/com.oracle.graal.word/src/com/oracle/graal/word/nodes/WordCastNode.java --- a/graal/com.oracle.graal.word/src/com/oracle/graal/word/nodes/WordCastNode.java Mon Jun 08 15:57:52 2015 +0200 +++ b/graal/com.oracle.graal.word/src/com/oracle/graal/word/nodes/WordCastNode.java Mon Jun 08 18:47:58 2015 +0200 @@ -56,6 +56,11 @@ return new WordCastNode(StampFactory.forKind(wordKind), input); } + public static WordCastNode addressToWord(ValueNode input, Kind wordKind) { + assert input.stamp() instanceof AbstractPointerStamp; + return new WordCastNode(StampFactory.forKind(wordKind), input); + } + public WordCastNode(Stamp stamp, ValueNode input) { super(TYPE, stamp); this.input = input;