# HG changeset patch # User Christos Kotselidis # Date 1365802185 -7200 # Node ID 2cae919cd3af0ad6cbeb44e7b4f4083cfedcb5b4 # Parent 1c77db9ba06409cd97ca5037bb53886d136b92c9 Introduce enumeration for the different write barrier types diff -r 1c77db9ba064 -r 2cae919cd3af graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotRuntime.java --- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotRuntime.java Wed Apr 10 16:25:47 2013 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotRuntime.java Fri Apr 12 23:29:45 2013 +0200 @@ -64,6 +64,7 @@ import com.oracle.graal.nodes.*; import com.oracle.graal.nodes.calc.*; import com.oracle.graal.nodes.extended.*; +import com.oracle.graal.nodes.extended.WriteNode.WriteBarrierType; import com.oracle.graal.nodes.java.*; import com.oracle.graal.nodes.java.MethodCallTargetNode.InvokeKind; import com.oracle.graal.nodes.spi.*; @@ -573,16 +574,14 @@ HotSpotResolvedJavaField field = (HotSpotResolvedJavaField) storeField.field(); ValueNode object = storeField.isStatic() ? ConstantNode.forObject(field.getDeclaringClass().mirror(), this, graph) : storeField.object(); LocationNode location = LocationNode.create(field, field.getKind(), field.offset(), graph); - WriteNode memoryWrite = graph.add(new WriteNode(object, storeField.value(), location, false)); + WriteBarrierType barrierType = getFieldStoreBarrier(storeField); + WriteNode memoryWrite = graph.add(new WriteNode(object, storeField.value(), location, barrierType)); memoryWrite.dependencies().add(tool.createNullCheckGuard(object)); memoryWrite.setStateAfter(storeField.stateAfter()); graph.replaceFixedWithFixed(storeField, memoryWrite); FixedWithNextNode last = memoryWrite; FixedWithNextNode first = memoryWrite; - if (field.getKind() == Kind.Object && !memoryWrite.value().objectStamp().alwaysNull()) { - memoryWrite.setWriteBarrier(); - } if (storeField.isVolatile()) { MembarNode preMembar = graph.add(new MembarNode(JMM_PRE_VOLATILE_WRITE)); graph.addBeforeFixed(first, preMembar); @@ -592,13 +591,7 @@ } else if (n instanceof CompareAndSwapNode) { // Separate out GC barrier semantics CompareAndSwapNode cas = (CompareAndSwapNode) n; - ValueNode expected = cas.expected(); - if (expected.kind() == Kind.Object && !cas.newValue().objectStamp().alwaysNull()) { - ResolvedJavaType type = cas.object().objectStamp().type(); - final boolean precise = (type != null && type.isArray() && !MetaUtil.isJavaLangObject(type)); - cas.setWriteBarrier(); - cas.setPreciseWriteBarrier(precise); - } + cas.setWriteBarrierType(getCompareAndSwapBarrier(cas)); } else if (n instanceof LoadIndexedNode) { LoadIndexedNode loadIndexed = (LoadIndexedNode) n; ValueNode boundsCheck = createBoundsCheck(loadIndexed, tool); @@ -634,14 +627,12 @@ value = checkcast; } } - WriteNode memoryWrite = graph.add(new WriteNode(array, value, arrayLocation, true)); + WriteBarrierType barrierType = getArrayStoreBarrier(storeIndexed); + WriteNode memoryWrite = graph.add(new WriteNode(array, value, arrayLocation, barrierType)); memoryWrite.dependencies().add(boundsCheck); memoryWrite.setStateAfter(storeIndexed.stateAfter()); graph.replaceFixedWithFixed(storeIndexed, memoryWrite); - if (elementKind == Kind.Object && !value.objectStamp().alwaysNull()) { - memoryWrite.setWriteBarrier(); - } } else if (n instanceof UnsafeLoadNode) { UnsafeLoadNode load = (UnsafeLoadNode) n; assert load.kind() != Kind.Illegal; @@ -655,14 +646,11 @@ UnsafeStoreNode store = (UnsafeStoreNode) n; IndexedLocationNode location = IndexedLocationNode.create(LocationNode.ANY_LOCATION, store.accessKind(), store.displacement(), store.offset(), graph, 1); ValueNode object = store.object(); - ResolvedJavaType type = object.objectStamp().type(); - final boolean precise = (type != null && type.isArray() && !MetaUtil.isJavaLangObject(type)); - WriteNode write = graph.add(new WriteNode(object, store.value(), location, precise)); + WriteBarrierType barrierType = getUnsafeStoreBarrier(store); + WriteNode write = graph.add(new WriteNode(object, store.value(), location, barrierType)); write.setStateAfter(store.stateAfter()); graph.replaceFixedWithFixed(store, write); - if (write.value().kind() == Kind.Object && !write.value().objectStamp().alwaysNull()) { - write.setWriteBarrier(); - } + } else if (n instanceof LoadHubNode) { LoadHubNode loadHub = (LoadHubNode) n; assert loadHub.kind() == wordKind; @@ -722,6 +710,48 @@ } } + private static WriteBarrierType getFieldStoreBarrier(StoreFieldNode storeField) { + WriteBarrierType barrierType = WriteBarrierType.NONE; + if (storeField.field().getKind() == Kind.Object && !storeField.value().objectStamp().alwaysNull()) { + barrierType = WriteBarrierType.IMPRECISE; + } + return barrierType; + } + + private static WriteBarrierType getArrayStoreBarrier(StoreIndexedNode store) { + WriteBarrierType barrierType = WriteBarrierType.NONE; + if (store.elementKind() == Kind.Object && !store.value().objectStamp().alwaysNull()) { + barrierType = WriteBarrierType.PRECISE; + } + return barrierType; + } + + private static WriteBarrierType getUnsafeStoreBarrier(UnsafeStoreNode store) { + WriteBarrierType barrierType = WriteBarrierType.NONE; + if (store.value().kind() == Kind.Object && !store.value().objectStamp().alwaysNull()) { + ResolvedJavaType type = store.object().objectStamp().type(); + if ((type != null && type.isArray() && !MetaUtil.isJavaLangObject(type))) { + barrierType = WriteBarrierType.PRECISE; + } else { + barrierType = WriteBarrierType.IMPRECISE; + } + } + return barrierType; + } + + private static WriteBarrierType getCompareAndSwapBarrier(CompareAndSwapNode cas) { + WriteBarrierType barrierType = WriteBarrierType.NONE; + if (cas.expected().kind() == Kind.Object && !cas.newValue().objectStamp().alwaysNull()) { + ResolvedJavaType type = cas.object().objectStamp().type(); + if ((type != null && type.isArray() && !MetaUtil.isJavaLangObject(type))) { + barrierType = WriteBarrierType.PRECISE; + } else { + barrierType = WriteBarrierType.IMPRECISE; + } + } + return barrierType; + } + private IndexedLocationNode createArrayLocation(Graph graph, Kind elementKind, ValueNode index) { int scale = this.graalRuntime.getTarget().sizeInBytes(elementKind); return IndexedLocationNode.create(LocationNode.getArrayLocation(elementKind), elementKind, getArrayBaseOffset(elementKind), index, graph, scale); diff -r 1c77db9ba064 -r 2cae919cd3af 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 Wed Apr 10 16:25:47 2013 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/phases/WriteBarrierAdditionPhase.java Fri Apr 12 23:29:45 2013 +0200 @@ -24,6 +24,7 @@ import com.oracle.graal.nodes.*; import com.oracle.graal.nodes.extended.*; +import com.oracle.graal.nodes.extended.WriteNode.WriteBarrierType; import com.oracle.graal.nodes.java.*; import com.oracle.graal.phases.*; @@ -46,16 +47,27 @@ } private static void addWriteNodeBarriers(WriteNode node, StructuredGraph graph) { - if (node.needsWriteBarrier()) { - graph.addAfterFixed(node, graph.add(new SerialWriteBarrier(node.object(), node.location(), node.usePreciseWriteBarriers()))); + WriteBarrierType barrierType = node.getWriteBarrierType(); + if (barrierType == WriteBarrierType.PRECISE) { + graph.addAfterFixed(node, graph.add(new SerialWriteBarrier(node.object(), node.location(), true))); + } else if (barrierType == WriteBarrierType.IMPRECISE) { + graph.addAfterFixed(node, graph.add(new SerialWriteBarrier(node.object(), node.location(), false))); + } else { + assert barrierType == WriteBarrierType.NONE; } } private static void addCASBarriers(CompareAndSwapNode node, StructuredGraph graph) { - if (node.needsWriteBarrier()) { + WriteBarrierType barrierType = node.getWriteBarrierType(); + if (barrierType == WriteBarrierType.PRECISE) { LocationNode location = IndexedLocationNode.create(LocationNode.ANY_LOCATION, node.expected().kind(), node.displacement(), node.offset(), graph, 1); - graph.addAfterFixed(node, graph.add(new SerialWriteBarrier(node.object(), location, node.usePreciseWriteBarriers()))); + graph.addAfterFixed(node, graph.add(new SerialWriteBarrier(node.object(), location, true))); + } else if (barrierType == WriteBarrierType.IMPRECISE) { + LocationNode location = IndexedLocationNode.create(LocationNode.ANY_LOCATION, node.expected().kind(), node.displacement(), node.offset(), graph, 1); + graph.addAfterFixed(node, graph.add(new SerialWriteBarrier(node.object(), location, false))); + } else { + assert barrierType == WriteBarrierType.NONE; } } diff -r 1c77db9ba064 -r 2cae919cd3af graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/WriteNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/WriteNode.java Wed Apr 10 16:25:47 2013 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/extended/WriteNode.java Fri Apr 12 23:29:45 2013 +0200 @@ -34,13 +34,25 @@ @Input private ValueNode value; @Input(notDataflow = true) private FrameState stateAfter; + private final WriteBarrierType barrierType; /* - * The field below instructs the snippet to use the address of the object or the effective - * address of the object element of an array when calculating the card offset. + * The types of write barriers attached to stores. */ - private final boolean usePreciseWriteBarriers; - private boolean needsWriteBarrier; + public enum WriteBarrierType { + /* + * Primitive stores which do not necessitate write barriers. + */ + NONE, + /* + * Array object stores which necessitate precise write barriers. + */ + PRECISE, + /* + * Field object stores which necessitate imprecise write barriers. + */ + IMPRECISE + } public FrameState stateAfter() { return stateAfter; @@ -60,22 +72,14 @@ return value; } - public boolean usePreciseWriteBarriers() { - return usePreciseWriteBarriers; - } - - public boolean needsWriteBarrier() { - return needsWriteBarrier; + public WriteBarrierType getWriteBarrierType() { + return barrierType; } - public void setWriteBarrier() { - this.needsWriteBarrier = true; - } - - public WriteNode(ValueNode object, ValueNode value, ValueNode location, boolean usePreciseWriteBarriers) { + public WriteNode(ValueNode object, ValueNode value, ValueNode location, WriteBarrierType barrierType) { super(object, location, StampFactory.forVoid()); this.value = value; - this.usePreciseWriteBarriers = usePreciseWriteBarriers; + this.barrierType = barrierType; } @Override diff -r 1c77db9ba064 -r 2cae919cd3af graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/CompareAndSwapNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/CompareAndSwapNode.java Wed Apr 10 16:25:47 2013 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/CompareAndSwapNode.java Fri Apr 12 23:29:45 2013 +0200 @@ -28,6 +28,7 @@ import com.oracle.graal.graph.*; import com.oracle.graal.nodes.*; import com.oracle.graal.nodes.extended.*; +import com.oracle.graal.nodes.extended.WriteNode.*; import com.oracle.graal.nodes.spi.*; import com.oracle.graal.nodes.type.*; @@ -42,12 +43,7 @@ @Input private ValueNode expected; @Input private ValueNode newValue; private final int displacement; - /* - * The field below instructs the snippet to use the address of the object or the effective - * address of the object element of an array when calculating the card offset. - */ - private boolean usePreciseWriteBarriers; - private boolean needsWriteBarrier; + private WriteBarrierType barrierType; public ValueNode object() { return object; @@ -69,20 +65,12 @@ return displacement; } - public boolean usePreciseWriteBarriers() { - return usePreciseWriteBarriers; + public WriteBarrierType getWriteBarrierType() { + return barrierType; } - public boolean needsWriteBarrier() { - return needsWriteBarrier; - } - - public void setWriteBarrier() { - this.needsWriteBarrier = true; - } - - public void setPreciseWriteBarrier(boolean precise) { - this.usePreciseWriteBarriers = precise; + public void setWriteBarrierType(WriteBarrierType type) { + this.barrierType = type; } public CompareAndSwapNode(ValueNode object, int displacement, ValueNode offset, ValueNode expected, ValueNode newValue) { @@ -93,7 +81,7 @@ this.expected = expected; this.newValue = newValue; this.displacement = displacement; - this.usePreciseWriteBarriers = false; + this.barrierType = WriteBarrierType.NONE; } @Override diff -r 1c77db9ba064 -r 2cae919cd3af 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 Wed Apr 10 16:25:47 2013 +0200 +++ b/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/nodes/DirectObjectStoreNode.java Fri Apr 12 23:29:45 2013 +0200 @@ -24,6 +24,7 @@ import com.oracle.graal.nodes.*; import com.oracle.graal.nodes.extended.*; +import com.oracle.graal.nodes.extended.WriteNode.*; import com.oracle.graal.nodes.spi.*; import com.oracle.graal.nodes.type.*; import com.oracle.graal.word.*; @@ -63,7 +64,7 @@ public void lower(LoweringTool tool) { StructuredGraph graph = (StructuredGraph) this.graph(); IndexedLocationNode location = IndexedLocationNode.create(LocationNode.ANY_LOCATION, value.kind(), displacement, offset, graph, 1); - WriteNode write = graph.add(new WriteNode(object, value, location, false)); + WriteNode write = graph.add(new WriteNode(object, value, location, WriteBarrierType.NONE)); graph.replaceFixedWithFixed(this, write); } } diff -r 1c77db9ba064 -r 2cae919cd3af graal/com.oracle.graal.word/src/com/oracle/graal/word/phases/WordTypeRewriterPhase.java --- a/graal/com.oracle.graal.word/src/com/oracle/graal/word/phases/WordTypeRewriterPhase.java Wed Apr 10 16:25:47 2013 +0200 +++ b/graal/com.oracle.graal.word/src/com/oracle/graal/word/phases/WordTypeRewriterPhase.java Fri Apr 12 23:29:45 2013 +0200 @@ -29,6 +29,7 @@ import com.oracle.graal.nodes.*; import com.oracle.graal.nodes.calc.*; import com.oracle.graal.nodes.extended.*; +import com.oracle.graal.nodes.extended.WriteNode.*; import com.oracle.graal.nodes.java.*; import com.oracle.graal.nodes.type.*; import com.oracle.graal.nodes.util.*; @@ -277,7 +278,7 @@ private static ValueNode writeOp(StructuredGraph graph, ValueNode base, ValueNode offset, ValueNode value, Invoke invoke, Kind writeKind, Object locationIdentity) { IndexedLocationNode location = IndexedLocationNode.create(locationIdentity, writeKind, 0, offset, graph, 1); - WriteNode write = graph.add(new WriteNode(base, value, location, false)); + WriteNode write = graph.add(new WriteNode(base, value, location, WriteBarrierType.NONE)); write.setStateAfter(invoke.stateAfter()); graph.addBeforeFixed(invoke.node(), write); return write;