# HG changeset patch # User Christos Kotselidis # Date 1372359835 -7200 # Node ID c636b4399ffa66e7d45d9edb185aa85d60cd18f9 # Parent 35783fbfcf28c22cc4845d65c5f991b81a759b9b# Parent 97caf20971ed169ccd5ac6f716094090fae6f156 Merge diff -r 97caf20971ed -r c636b4399ffa 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 Thu Jun 27 18:21:13 2013 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotRuntime.java Thu Jun 27 21:03:55 2013 +0200 @@ -618,7 +618,7 @@ } else if (n instanceof UnsafeLoadNode) { UnsafeLoadNode load = (UnsafeLoadNode) n; assert load.kind() != Kind.Illegal; - lowerUnsafeLoad(load); + lowerUnsafeLoad(load, tool); } else if (n instanceof UnsafeStoreNode) { UnsafeStoreNode store = (UnsafeStoreNode) n; IndexedLocationNode location = IndexedLocationNode.create(ANY_LOCATION, store.accessKind(), store.displacement(), store.offset(), graph, 1); @@ -783,6 +783,10 @@ writeBarrierSnippets.lower((SerialWriteBarrier) n, tool); } else if (n instanceof SerialArrayRangeWriteBarrier) { writeBarrierSnippets.lower((SerialArrayRangeWriteBarrier) n, tool); + } else if (n instanceof G1ArrayRangePreWriteBarrier) { + writeBarrierSnippets.lower((G1ArrayRangePreWriteBarrier) n, tool); + } else if (n instanceof G1ArrayRangePostWriteBarrier) { + writeBarrierSnippets.lower((G1ArrayRangePostWriteBarrier) n, tool); } else if (n instanceof NewMultiArrayNode) { if (tool.getLoweringType() == LoweringType.AFTER_GUARDS) { newObjectSnippets.lower((NewMultiArrayNode) n); @@ -851,17 +855,18 @@ * * * - * TODO (ck): Replace the code below with a snippet. + * TODO (ck): Replace the code below with a snippet, properly fix the issue with the unsafe + * loads generated by the array copy intrinsics (robust assertions). * */ - private void lowerUnsafeLoad(UnsafeLoadNode load) { + private void lowerUnsafeLoad(UnsafeLoadNode load, LoweringTool tool) { StructuredGraph graph = load.graph(); boolean compress = (!load.object().isNullConstant() && load.accessKind() == Kind.Object); if (config().useG1GC && load.object().kind() == Kind.Object && load.accessKind() == Kind.Object && !load.object().objectStamp().alwaysNull() && load.object().objectStamp().type() != null && - !(load.object().objectStamp().type().isArray())) { + !(load.object().objectStamp().type().isArray()) && tool.getLoweringType() != LoweringType.AFTER_GUARDS) { IndexedLocationNode location = IndexedLocationNode.create(ANY_LOCATION, load.accessKind(), load.displacement(), load.offset(), graph, 1); // Calculate offset+displacement - IntegerAddNode addNode = graph.add(new IntegerAddNode(Kind.Long, load.offset(), ConstantNode.forInt(load.displacement(), graph))); + IntegerAddNode addNode = graph.add(new IntegerAddNode(Kind.Long, load.offset(), ConstantNode.forLong(load.displacement(), graph))); // Compare previous result with referent offset (16) CompareNode offsetCondition = CompareNode.createCompareNode(Condition.EQ, addNode, ConstantNode.forLong(referentOffset(), graph)); // Instance of unsafe load is java.lang.ref.Reference diff -r 97caf20971ed -r c636b4399ffa 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 Thu Jun 27 18:21:13 2013 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/phases/WriteBarrierAdditionPhase.java Thu Jun 27 21:03:55 2013 +0200 @@ -22,8 +22,8 @@ */ package com.oracle.graal.hotspot.phases; -import com.oracle.graal.graph.*; -import com.oracle.graal.hotspot.replacements.*; +import static com.oracle.graal.hotspot.replacements.HotSpotReplacementsUtil.*; + import com.oracle.graal.nodes.*; import com.oracle.graal.nodes.HeapAccess.WriteBarrierType; import com.oracle.graal.nodes.extended.*; @@ -55,7 +55,7 @@ private static void addReadNodeBarriers(ReadNode node, StructuredGraph graph) { if (node.getWriteBarrierType() == WriteBarrierType.PRECISE) { - assert HotSpotReplacementsUtil.useG1GC(); + assert useG1GC(); graph.addAfterFixed(node, graph.add(new G1PreWriteBarrier(node.object(), node, node.location(), false))); } else { assert node.getWriteBarrierType() == WriteBarrierType.NONE : "Non precise write barrier has been attached to read node."; @@ -65,14 +65,14 @@ private static void addWriteNodeBarriers(WriteNode node, StructuredGraph graph) { WriteBarrierType barrierType = node.getWriteBarrierType(); if (barrierType == WriteBarrierType.PRECISE) { - if (HotSpotReplacementsUtil.useG1GC()) { + if (useG1GC()) { graph.addBeforeFixed(node, graph.add(new G1PreWriteBarrier(node.object(), null, node.location(), true))); graph.addAfterFixed(node, graph.add(new G1PostWriteBarrier(node.object(), node.value(), node.location(), true))); } else { graph.addAfterFixed(node, graph.add(new SerialWriteBarrier(node.object(), node.location(), true))); } } else if (barrierType == WriteBarrierType.IMPRECISE) { - if (HotSpotReplacementsUtil.useG1GC()) { + if (useG1GC()) { graph.addBeforeFixed(node, graph.add(new G1PreWriteBarrier(node.object(), null, node.location(), true))); graph.addAfterFixed(node, graph.add(new G1PostWriteBarrier(node.object(), node.value(), node.location(), false))); } else { @@ -87,14 +87,14 @@ private static void addCASBarriers(CompareAndSwapNode node, StructuredGraph graph) { WriteBarrierType barrierType = node.getWriteBarrierType(); if (barrierType == WriteBarrierType.PRECISE) { - if (HotSpotReplacementsUtil.useG1GC()) { + if (useG1GC()) { graph.addBeforeFixed(node, graph.add(new G1PreWriteBarrier(node.object(), node.expected(), node.getLocation(), false))); graph.addAfterFixed(node, graph.add(new G1PostWriteBarrier(node.object(), node.newValue(), node.getLocation(), true))); } else { graph.addAfterFixed(node, graph.add(new SerialWriteBarrier(node.object(), node.getLocation(), true))); } } else if (barrierType == WriteBarrierType.IMPRECISE) { - if (HotSpotReplacementsUtil.useG1GC()) { + if (useG1GC()) { graph.addBeforeFixed(node, graph.add(new G1PreWriteBarrier(node.object(), node.expected(), node.getLocation(), false))); graph.addAfterFixed(node, graph.add(new G1PostWriteBarrier(node.object(), node.newValue(), node.getLocation(), false))); } else { @@ -106,8 +106,11 @@ } private static void addArrayRangeBarriers(ArrayRangeWriteNode node, StructuredGraph graph) { - if (HotSpotReplacementsUtil.useG1GC()) { - throw new GraalInternalError("G1 does not yet support barriers for ArrayCopy Intrinsics. Run with -G:-IntrinsifyArrayCopy"); + if (useG1GC()) { + G1ArrayRangePreWriteBarrier g1ArrayRangePreWriteBarrier = graph.add(new G1ArrayRangePreWriteBarrier(node.getArray(), node.getIndex(), node.getLength())); + G1ArrayRangePostWriteBarrier g1ArrayRangePostWriteBarrier = graph.add(new G1ArrayRangePostWriteBarrier(node.getArray(), node.getIndex(), node.getLength())); + graph.addBeforeFixed(node, g1ArrayRangePreWriteBarrier); + graph.addAfterFixed(node, g1ArrayRangePostWriteBarrier); } else { SerialArrayRangeWriteBarrier serialArrayRangeWriteBarrier = graph.add(new SerialArrayRangeWriteBarrier(node.getArray(), node.getIndex(), node.getLength())); graph.addAfterFixed(node, serialArrayRangeWriteBarrier); diff -r 97caf20971ed -r c636b4399ffa 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 Thu Jun 27 18:21:13 2013 +0200 +++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/WriteBarrierSnippets.java Thu Jun 27 21:03:55 2013 +0200 @@ -111,7 +111,7 @@ // If the previous value has to be loaded (before the write), the load is issued. // The load is always issued except the cases of CAS and referent field. if (doLoad) { - previousOop = (Word) Word.fromObject(UnsafeLoadNode.load(field, 0, 0, Kind.Object)); + previousOop = (Word) Word.fromObject(field.readObjectCompressed(0)); } // If the previous value is null the barrier should not be issued. if (previousOop.notEqual(0)) { @@ -187,6 +187,79 @@ } } + @Snippet + public static void g1ArrayRangePreWriteBarrier(Object object, int startIndex, int length) { + Object dest = FixedValueAnchorNode.getObject(object); + Word thread = thread(); + byte markingValue = thread.readByte(g1SATBQueueMarkingOffset()); + Word bufferAddress = thread.readWord(g1SATBQueueBufferOffset()); + Word indexAddress = thread.add(g1SATBQueueIndexOffset()); + Word indexValue = indexAddress.readWord(0); + + // If the concurrent marker is not enabled return. + if (markingValue == (byte) 0) { + return; + } + Word oop; + final int scale = arrayIndexScale(Kind.Object); + int header = arrayBaseOffset(Kind.Object); + + for (int i = startIndex; i < length; i++) { + Word address = (Word) Word.fromObject(dest).add(header).add(Word.unsigned(i * (long) scale)); + oop = (Word) Word.fromObject(address.readObjectCompressed(0)); + if (oop.notEqual(0)) { + if (indexValue.notEqual(0)) { + Word nextIndex = indexValue.subtract(wordSize()); + Word logAddress = bufferAddress.add(nextIndex); + // Log the object to be marked as well as update the SATB's buffer next index. + logAddress.writeWord(0, oop); + indexAddress.writeWord(0, nextIndex); + } else { + g1PreBarrierStub(G1WBPRECALL, oop.toObject()); + } + } + } + } + + @Snippet + public static void g1ArrayRangePostWriteBarrier(Object object, int startIndex, int length) { + Object dest = FixedValueAnchorNode.getObject(object); + Word thread = thread(); + Word bufferAddress = thread.readWord(g1CardQueueBufferOffset()); + Word indexAddress = thread.add(g1CardQueueIndexOffset()); + Word indexValue = thread.readWord(g1CardQueueIndexOffset()); + + int cardShift = cardTableShift(); + long cardStart = cardTableStart(); + final int scale = arrayIndexScale(Kind.Object); + int header = arrayBaseOffset(Kind.Object); + long dstAddr = GetObjectAddressNode.get(dest); + long start = (dstAddr + header + (long) startIndex * scale) >>> cardShift; + long end = (dstAddr + header + ((long) startIndex + length - 1) * scale) >>> cardShift; + long count = end - start + 1; + + while (count-- > 0) { + Word cardAddress = Word.unsigned((start + cardStart) + count); + byte cardByte = cardAddress.readByte(0); + // If the card is already dirty, (hence already enqueued) skip the insertion. + if (cardByte != (byte) 0) { + cardAddress.writeByte(0, (byte) 0); + // If the thread local card queue is full, issue a native call which will + // initialize a new one and add the card entry. + if (indexValue.notEqual(0)) { + Word nextIndex = indexValue.subtract(wordSize()); + Word logAddress = bufferAddress.add(nextIndex); + // Log the object to be scanned as well as update + // the card queue's next index. + logAddress.writeWord(0, cardAddress); + indexAddress.writeWord(0, nextIndex); + } else { + g1PostBarrierStub(G1WBPOSTCALL, cardAddress); + } + } + } + } + public static final ForeignCallDescriptor G1WBPRECALL = new ForeignCallDescriptor("write_barrier_pre", void.class, Object.class); @NodeIntrinsic(ForeignCallNode.class) @@ -203,6 +276,8 @@ private final SnippetInfo serialArrayRangeWriteBarrier = snippet(WriteBarrierSnippets.class, "serialArrayRangeWriteBarrier"); private final SnippetInfo g1PreWriteBarrier = snippet(WriteBarrierSnippets.class, "g1PreWriteBarrier"); private final SnippetInfo g1PostWriteBarrier = snippet(WriteBarrierSnippets.class, "g1PostWriteBarrier"); + private final SnippetInfo g1ArrayRangePreWriteBarrier = snippet(WriteBarrierSnippets.class, "g1ArrayRangePreWriteBarrier"); + private final SnippetInfo g1ArrayRangePostWriteBarrier = snippet(WriteBarrierSnippets.class, "g1ArrayRangePostWriteBarrier"); public Templates(CodeCacheProvider runtime, Replacements replacements, TargetDescription target) { super(runtime, replacements, target); @@ -241,5 +316,21 @@ args.addConst("usePrecise", writeBarrierPost.usePrecise()); template(args).instantiate(runtime, writeBarrierPost, DEFAULT_REPLACER, args); } + + public void lower(G1ArrayRangePreWriteBarrier arrayRangeWriteBarrier, @SuppressWarnings("unused") LoweringTool tool) { + Arguments args = new Arguments(g1ArrayRangePreWriteBarrier); + args.add("object", arrayRangeWriteBarrier.getObject()); + args.add("startIndex", arrayRangeWriteBarrier.getStartIndex()); + args.add("length", arrayRangeWriteBarrier.getLength()); + template(args).instantiate(runtime, arrayRangeWriteBarrier, DEFAULT_REPLACER, args); + } + + public void lower(G1ArrayRangePostWriteBarrier arrayRangeWriteBarrier, @SuppressWarnings("unused") LoweringTool tool) { + Arguments args = new Arguments(g1ArrayRangePostWriteBarrier); + args.add("object", arrayRangeWriteBarrier.getObject()); + args.add("startIndex", arrayRangeWriteBarrier.getStartIndex()); + args.add("length", arrayRangeWriteBarrier.getLength()); + template(args).instantiate(runtime, arrayRangeWriteBarrier, DEFAULT_REPLACER, args); + } } } diff -r 97caf20971ed -r c636b4399ffa graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/ArrayRangeWriteBarrier.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/ArrayRangeWriteBarrier.java Thu Jun 27 21:03:55 2013 +0200 @@ -0,0 +1,43 @@ +/* + * 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; + +public abstract class ArrayRangeWriteBarrier extends WriteBarrier { + + @Input private ValueNode startIndex; + @Input private ValueNode length; + + public ValueNode getStartIndex() { + return startIndex; + } + + public ValueNode getLength() { + return length; + } + + public ArrayRangeWriteBarrier(ValueNode object, ValueNode startIndex, ValueNode length) { + super(object, null, true); + this.startIndex = startIndex; + this.length = length; + } +} diff -r 97caf20971ed -r c636b4399ffa graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/G1ArrayRangePostWriteBarrier.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/G1ArrayRangePostWriteBarrier.java Thu Jun 27 21:03:55 2013 +0200 @@ -0,0 +1,30 @@ +/* + * 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; + +public final class G1ArrayRangePostWriteBarrier extends ArrayRangeWriteBarrier { + + public G1ArrayRangePostWriteBarrier(ValueNode object, ValueNode startIndex, ValueNode length) { + super(object, startIndex, length); + } +} diff -r 97caf20971ed -r c636b4399ffa graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/G1ArrayRangePreWriteBarrier.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/G1ArrayRangePreWriteBarrier.java Thu Jun 27 21:03:55 2013 +0200 @@ -0,0 +1,30 @@ +/* + * 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; + +public final class G1ArrayRangePreWriteBarrier extends ArrayRangeWriteBarrier { + + public G1ArrayRangePreWriteBarrier(ValueNode object, ValueNode startIndex, ValueNode length) { + super(object, startIndex, length); + } +} diff -r 97caf20971ed -r c636b4399ffa graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/SerialArrayRangeWriteBarrier.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/SerialArrayRangeWriteBarrier.java Thu Jun 27 18:21:13 2013 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/SerialArrayRangeWriteBarrier.java Thu Jun 27 21:03:55 2013 +0200 @@ -22,37 +22,9 @@ */ package com.oracle.graal.nodes; -import com.oracle.graal.nodes.spi.*; -import com.oracle.graal.nodes.type.*; - -public final class SerialArrayRangeWriteBarrier extends FixedWithNextNode implements Lowerable { - - @Input private ValueNode object; - @Input private ValueNode startIndex; - @Input private ValueNode length; - - public ValueNode getObject() { - return object; - } - - public ValueNode getStartIndex() { - return startIndex; - } - - public ValueNode getLength() { - return length; - } +public final class SerialArrayRangeWriteBarrier extends ArrayRangeWriteBarrier { public SerialArrayRangeWriteBarrier(ValueNode object, ValueNode startIndex, ValueNode length) { - super(StampFactory.forVoid()); - this.object = object; - this.startIndex = startIndex; - this.length = length; - + super(object, startIndex, length); } - - public void lower(LoweringTool generator, LoweringType loweringType) { - generator.getRuntime().lower(this, generator); - } - } diff -r 97caf20971ed -r c636b4399ffa 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 Thu Jun 27 18:21:13 2013 +0200 +++ b/graal/com.oracle.graal.word/src/com/oracle/graal/word/Pointer.java Thu Jun 27 21:03:55 2013 +0200 @@ -586,6 +586,19 @@ Object readObject(WordBase offset); /** + * Reads the memory at address {@code (this + offset)} and uncompresses it. Both the base + * address and offset are in bytes. + *

+ * The offset is always treated as a {@link Signed} value. However, the static type is + * {@link WordBase} to avoid the frequent casts to of {@link Unsigned} values (where the caller + * knows that the highest-order bit of the unsigned value is never used). + * + * @param offset the signed offset for the memory access + * @return the result of the memory access + */ + Object readObjectCompressed(WordBase offset); + + /** * Reads the memory at address {@code (this + offset)}. Both the base address and offset are in * bytes. * @@ -667,6 +680,15 @@ Object readObject(int offset); /** + * Reads the memory at address {@code (this + offset)} and decompressed it. Both the base + * address and offset are in bytes. + * + * @param offset the signed offset for the memory access + * @return the result of the memory access + */ + Object readObjectCompressed(int offset); + + /** * Writes the memory at address {@code (this + offset)}. Both the base address and offset are in * bytes. *

diff -r 97caf20971ed -r c636b4399ffa 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 Thu Jun 27 18:21:13 2013 +0200 +++ b/graal/com.oracle.graal.word/src/com/oracle/graal/word/Word.java Thu Jun 27 21:03:55 2013 +0200 @@ -59,6 +59,7 @@ COMPARISON, NOT, READ, + READ_COMPRESSED, WRITE, ZERO, FROM_UNSIGNED, @@ -867,6 +868,10 @@ public native Object readObject(WordBase offset); @Override + @Operation(opcode = Opcode.READ_COMPRESSED) + public native Object readObjectCompressed(WordBase offset); + + @Override @Operation(opcode = Opcode.READ) public byte readByte(int offset) { return readByte(signed(offset)); @@ -921,6 +926,12 @@ } @Override + @Operation(opcode = Opcode.READ_COMPRESSED) + public Object readObjectCompressed(int offset) { + return readObjectCompressed(signed(offset)); + } + + @Override @Operation(opcode = Opcode.WRITE) public void writeByte(WordBase offset, byte val) { unsafe.putByte(add((Word) offset).unbox(), val); diff -r 97caf20971ed -r c636b4399ffa 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 Thu Jun 27 18:21:13 2013 +0200 +++ b/graal/com.oracle.graal.word/src/com/oracle/graal/word/phases/WordTypeRewriterPhase.java Thu Jun 27 21:03:55 2013 +0200 @@ -169,7 +169,19 @@ } else { location = makeLocation(graph, arguments.get(1), readKind, arguments.get(2)); } - replace(invoke, readOp(graph, arguments.get(0), invoke, location)); + replace(invoke, readOp(graph, arguments.get(0), invoke, location, false)); + break; + } + case READ_COMPRESSED: { + assert arguments.size() == 2 || arguments.size() == 3; + Kind readKind = asKind(callTargetNode.returnType()); + LocationNode location; + if (arguments.size() == 2) { + location = makeLocation(graph, arguments.get(1), readKind, ANY_LOCATION); + } else { + location = makeLocation(graph, arguments.get(1), readKind, arguments.get(2)); + } + replace(invoke, readOp(graph, arguments.get(0), invoke, location, true)); break; } case WRITE: { @@ -309,8 +321,8 @@ return IndexedLocationNode.create(locationIdentity, readKind, 0, offset, graph, 1); } - private static ValueNode readOp(StructuredGraph graph, ValueNode base, Invoke invoke, LocationNode location) { - ReadNode read = graph.add(new ReadNode(base, location, invoke.asNode().stamp(), WriteBarrierType.NONE, false)); + private static ValueNode readOp(StructuredGraph graph, ValueNode base, Invoke invoke, LocationNode location, boolean compress) { + ReadNode read = graph.add(new ReadNode(base, location, invoke.asNode().stamp(), WriteBarrierType.NONE, compress)); graph.addBeforeFixed(invoke.asNode(), read); // The read must not float outside its block otherwise it may float above an explicit zero // check on its base address