# HG changeset patch # User Thomas Wuerthinger # Date 1309961715 -7200 # Node ID 8044bdfaab06c7e9d77032467d55315e992bfb4f # Parent 7f2bf8fe68041c0bc47c0884c97da577ac517c31 Lowering of array accesses. diff -r 7f2bf8fe6804 -r 8044bdfaab06 graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/GraalOptions.java --- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/GraalOptions.java Wed Jul 06 13:28:51 2011 +0200 +++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/GraalOptions.java Wed Jul 06 16:15:15 2011 +0200 @@ -153,6 +153,7 @@ public static boolean CommentedAssembly = ____; public static boolean PrintLIRWithAssembly = ____; + public static boolean OptReadElimination = ____; public static boolean OptGVN = ____; public static boolean OptCanonicalizer = true; public static boolean OptLoops = ____; diff -r 7f2bf8fe6804 -r 8044bdfaab06 graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/gen/LIRGenerator.java --- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/gen/LIRGenerator.java Wed Jul 06 13:28:51 2011 +0200 +++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/gen/LIRGenerator.java Wed Jul 06 16:15:15 2011 +0200 @@ -484,6 +484,8 @@ emitCompare((Compare) node, trueSuccessor, falseSuccessor); } else if (node instanceof InstanceOf) { emitInstanceOf((TypeCheck) node, trueSuccessor, falseSuccessor, info); + } else if (node instanceof Constant) { + emitConstantBranch(((Constant) node).asConstant().asBoolean(), trueSuccessor, falseSuccessor, info); } else { throw Util.unimplemented(node.toString()); } @@ -498,6 +500,21 @@ instr.setFalseSuccessor(falseSuccessor); } + + public void emitConstantBranch(boolean value, LIRBlock trueSuccessorBlock, LIRBlock falseSuccessorBlock, LIRDebugInfo info) { + if (value) { + emitConstantBranch(trueSuccessorBlock, info); + } else { + emitConstantBranch(falseSuccessorBlock, info); + } + } + + private void emitConstantBranch(LIRBlock block, LIRDebugInfo info) { + if (block != null) { + lir.jump(block); + } + } + public void emitCompare(Compare compare, LIRBlock trueSuccessorBlock, LIRBlock falseSuccessorBlock) { CiKind kind = compare.x().kind; @@ -761,13 +778,17 @@ FrameState state = lastState; assert state != null : "deoptimize instruction always needs a state"; - if (deoptimizationStubs == null) { - deoptimizationStubs = new ArrayList(); + if (comp instanceof Constant && comp.asConstant().asBoolean()) { + // Nothing to emit. + } else { + if (deoptimizationStubs == null) { + deoptimizationStubs = new ArrayList(); + } + + DeoptimizationStub stub = new DeoptimizationStub(DeoptAction.InvalidateReprofile, state); + deoptimizationStubs.add(stub); + emitBooleanBranch(comp, null, new LIRBlock(stub.label, stub.info), stub.info); } - DeoptimizationStub stub = new DeoptimizationStub(DeoptAction.InvalidateReprofile, state); - deoptimizationStubs.add(stub); - - emitBooleanBranch(comp, null, new LIRBlock(stub.label, stub.info), stub.info); } } diff -r 7f2bf8fe6804 -r 8044bdfaab06 graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/graph/IR.java --- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/graph/IR.java Wed Jul 06 13:28:51 2011 +0200 +++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/graph/IR.java Wed Jul 06 16:15:15 2011 +0200 @@ -111,13 +111,15 @@ new GlobalValueNumberingPhase().apply(graph); } + new LoweringPhase(compilation.runtime).apply(graph); if (GraalOptions.Lower) { - new LoweringPhase(compilation.runtime).apply(graph); new MemoryPhase().apply(graph); if (GraalOptions.OptGVN) { new GlobalValueNumberingPhase().apply(graph); } - new ReadEliminationPhase().apply(graph); + if (GraalOptions.OptReadElimination) { + new ReadEliminationPhase().apply(graph); + } } IdentifyBlocksPhase schedule = new IdentifyBlocksPhase(true); diff -r 7f2bf8fe6804 -r 8044bdfaab06 graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/CheckCast.java --- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/CheckCast.java Wed Jul 06 13:28:51 2011 +0200 +++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/CheckCast.java Wed Jul 06 16:15:15 2011 +0200 @@ -42,7 +42,7 @@ * @param object the instruction producing the object * @param graph */ - public CheckCast(Constant targetClassInstruction, Value object, Graph graph) { + public CheckCast(Value targetClassInstruction, Value object, Graph graph) { super(targetClassInstruction, object, CiKind.Object, INPUT_COUNT, SUCCESSOR_COUNT, graph); } diff -r 7f2bf8fe6804 -r 8044bdfaab06 graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/GuardNode.java --- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/GuardNode.java Wed Jul 06 13:28:51 2011 +0200 +++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/GuardNode.java Wed Jul 06 16:15:15 2011 +0200 @@ -55,8 +55,9 @@ inputs().set(super.inputCount() + INPUT_NODE, n); } - public GuardNode(Graph graph) { + public GuardNode(BooleanNode node, Graph graph) { super(CiKind.Illegal, INPUT_COUNT, SUCCESSOR_COUNT, graph); + setNode(node); } @Override @@ -71,7 +72,7 @@ @Override public Node copy(Graph into) { - return new GuardNode(into); + return new GuardNode(null, into); } @SuppressWarnings("unchecked") diff -r 7f2bf8fe6804 -r 8044bdfaab06 graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/LoadIndexed.java --- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/LoadIndexed.java Wed Jul 06 13:28:51 2011 +0200 +++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/LoadIndexed.java Wed Jul 06 16:15:15 2011 +0200 @@ -23,6 +23,8 @@ package com.oracle.max.graal.compiler.ir; import com.oracle.max.graal.compiler.debug.*; +import com.oracle.max.graal.compiler.phases.*; +import com.oracle.max.graal.compiler.phases.LoweringPhase.LoweringOp; import com.oracle.max.graal.graph.*; import com.sun.cri.ci.*; import com.sun.cri.ri.*; @@ -85,6 +87,16 @@ return false; } + + @SuppressWarnings("unchecked") + @Override + public T lookup(Class clazz) { + if (clazz == LoweringOp.class) { + return (T) LoweringPhase.DELEGATE_TO_RUNTIME; + } + return super.lookup(clazz); + } + @Override public Node copy(Graph into) { LoadIndexed x = new LoadIndexed(null, null, null, elementKind(), into); diff -r 7f2bf8fe6804 -r 8044bdfaab06 graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/StoreIndexed.java --- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/StoreIndexed.java Wed Jul 06 13:28:51 2011 +0200 +++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/StoreIndexed.java Wed Jul 06 16:15:15 2011 +0200 @@ -23,6 +23,8 @@ package com.oracle.max.graal.compiler.ir; import com.oracle.max.graal.compiler.debug.*; +import com.oracle.max.graal.compiler.phases.*; +import com.oracle.max.graal.compiler.phases.LoweringPhase.*; import com.oracle.max.graal.graph.*; import com.sun.cri.ci.*; @@ -82,6 +84,15 @@ out.print(array()).print('[').print(index()).print("] := ").print(value()).print(" (").print(kind.typeChar).print(')'); } + @SuppressWarnings("unchecked") + @Override + public T lookup(Class clazz) { + if (clazz == LoweringOp.class) { + return (T) LoweringPhase.DELEGATE_TO_RUNTIME; + } + return super.lookup(clazz); + } + @Override public Node copy(Graph into) { StoreIndexed x = new StoreIndexed(null, null, null, elementKind(), null, into); diff -r 7f2bf8fe6804 -r 8044bdfaab06 graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/TypeCheck.java --- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/TypeCheck.java Wed Jul 06 13:28:51 2011 +0200 +++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/ir/TypeCheck.java Wed Jul 06 16:15:15 2011 +0200 @@ -61,11 +61,11 @@ /** * The instruction that loads the target class object that is used by this checkcast. */ - public Constant targetClassInstruction() { - return (Constant) inputs().get(super.inputCount() + INPUT_TARGET_CLASS_INSTRUCTION); + public Value targetClassInstruction() { + return (Value) inputs().get(super.inputCount() + INPUT_TARGET_CLASS_INSTRUCTION); } - private void setTargetClassInstruction(Constant n) { + private void setTargetClassInstruction(Value n) { inputs().set(super.inputCount() + INPUT_TARGET_CLASS_INSTRUCTION, n); } @@ -75,7 +75,7 @@ * @return the target class */ public RiType targetClass() { - return (RiType) targetClassInstruction().asConstant().asObject(); + return targetClassInstruction() instanceof Constant ? (RiType) targetClassInstruction().asConstant().asObject() : null; } /** @@ -87,7 +87,7 @@ * @param successorCount * @param graph */ - public TypeCheck(Constant targetClassInstruction, Value object, CiKind kind, int inputCount, int successorCount, Graph graph) { + public TypeCheck(Value targetClassInstruction, Value object, CiKind kind, int inputCount, int successorCount, Graph graph) { super(kind, inputCount + INPUT_COUNT, successorCount + SUCCESSOR_COUNT, graph); setObject(object); setTargetClassInstruction(targetClassInstruction); diff -r 7f2bf8fe6804 -r 8044bdfaab06 graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/phases/LoweringPhase.java --- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/phases/LoweringPhase.java Wed Jul 06 13:28:51 2011 +0200 +++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/phases/LoweringPhase.java Wed Jul 06 16:15:15 2011 +0200 @@ -57,11 +57,13 @@ } private void process(final Block b) { + + final Node anchor = b.javaBlock().createAnchor(); final CiLoweringTool loweringTool = new CiLoweringTool() { @Override public Node getGuardAnchor() { - return b.createAnchor(); + return anchor; } @Override @@ -72,19 +74,13 @@ @Override public Node createGuard(Node condition) { Anchor anchor = (Anchor) getGuardAnchor(); - for (GuardNode guard : anchor.happensAfterGuards()) { - if (guard.node().valueEqual(condition)) { - condition.delete(); - return guard; - } - } - GuardNode newGuard = new GuardNode(anchor.graph()); + GuardNode newGuard = new GuardNode((BooleanNode) condition, anchor.graph()); newGuard.setAnchor(anchor); - newGuard.setNode((BooleanNode) condition); return newGuard; } }; + // Lower the instructions of this block. for (final Node n : b.getInstructions()) { if (n instanceof FixedNode) { diff -r 7f2bf8fe6804 -r 8044bdfaab06 graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/phases/MemoryPhase.java --- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/phases/MemoryPhase.java Wed Jul 06 13:28:51 2011 +0200 +++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/phases/MemoryPhase.java Wed Jul 06 16:15:15 2011 +0200 @@ -315,6 +315,8 @@ LoopBegin begin = end.loopBegin(); Block beginBlock = nodeMap.get(begin); MemoryMap memoryMap = memoryMaps[beginBlock.blockID()]; + assert memoryMap != null : beginBlock.name(); + assert memoryMap.getLoopEntryMap() != null; memoryMap.getLoopEntryMap().resetMergeOperationCount(); memoryMap.getLoopEntryMap().mergeWith(map, beginBlock); Node loopCheckPoint = memoryMap.getLoopCheckPoint(); diff -r 7f2bf8fe6804 -r 8044bdfaab06 graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/schedule/Block.java --- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/schedule/Block.java Wed Jul 06 13:28:51 2011 +0200 +++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/schedule/Block.java Wed Jul 06 16:15:15 2011 +0200 @@ -246,4 +246,8 @@ } } } + + public String name() { + return "B" + blockID; + } } diff -r 7f2bf8fe6804 -r 8044bdfaab06 graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/target/amd64/AMD64LIRAssembler.java --- a/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/target/amd64/AMD64LIRAssembler.java Wed Jul 06 13:28:51 2011 +0200 +++ b/graal/com.oracle.max.graal.compiler/src/com/oracle/max/graal/compiler/target/amd64/AMD64LIRAssembler.java Wed Jul 06 16:15:15 2011 +0200 @@ -1300,11 +1300,11 @@ default : throw Util.shouldNotReachHere(); } } else { - throw Util.shouldNotReachHere(); + throw Util.shouldNotReachHere("opr1=" + opr1.toString() + " opr2=" + opr2); } } else { - throw Util.shouldNotReachHere(opr1.toString() + " opr2 = " + opr2); + throw Util.shouldNotReachHere("opr1=" + opr1.toString() + " opr2=" + opr2); } // Checkstyle: on } diff -r 7f2bf8fe6804 -r 8044bdfaab06 graal/com.oracle.max.graal.runtime/src/com/oracle/max/graal/runtime/HotSpotRuntime.java --- a/graal/com.oracle.max.graal.runtime/src/com/oracle/max/graal/runtime/HotSpotRuntime.java Wed Jul 06 13:28:51 2011 +0200 +++ b/graal/com.oracle.max.graal.runtime/src/com/oracle/max/graal/runtime/HotSpotRuntime.java Wed Jul 06 16:15:15 2011 +0200 @@ -26,6 +26,7 @@ import java.lang.reflect.*; import java.util.*; +import com.oracle.max.graal.compiler.*; import com.oracle.max.graal.compiler.graph.*; import com.oracle.max.graal.compiler.ir.*; import com.oracle.max.graal.compiler.value.*; @@ -36,6 +37,7 @@ import com.sun.cri.ci.CiTargetMethod.DataPatch; import com.sun.cri.ci.CiTargetMethod.Safepoint; import com.sun.cri.ri.*; +import com.sun.cri.ri.RiType.Representation; import com.sun.max.asm.dis.*; import com.sun.max.lang.*; @@ -246,6 +248,10 @@ @Override public void lower(Node n, CiLoweringTool tool) { + if (!GraalOptions.Lower) { + return; + } + if (n instanceof LoadField) { LoadField field = (LoadField) n; if (field.isVolatile()) { @@ -277,9 +283,70 @@ memoryWrite.setNext(field.next()); } field.replaceAndDelete(memoryWrite); + } else if (n instanceof LoadIndexed) { + LoadIndexed loadIndexed = (LoadIndexed) n; + Graph graph = loadIndexed.graph(); + GuardNode boundsCheck = createBoundsCheck(loadIndexed, tool); + + CiKind elementKind = loadIndexed.elementKind(); + LocationNode arrayLocation = createArrayLocation(graph, elementKind); + arrayLocation.setIndex(loadIndexed.index()); + ReadNode memoryRead = new ReadNode(elementKind.stackKind(), loadIndexed.array(), arrayLocation, graph); + memoryRead.setGuard(boundsCheck); + memoryRead.setNext(loadIndexed.next()); + loadIndexed.replaceAndDelete(memoryRead); + } else if (n instanceof StoreIndexed) { + StoreIndexed storeIndexed = (StoreIndexed) n; + Graph graph = storeIndexed.graph(); + Anchor anchor = new Anchor(graph); + GuardNode boundsCheck = createBoundsCheck(storeIndexed, tool); + anchor.inputs().add(boundsCheck); + + + CiKind elementKind = storeIndexed.elementKind(); + LocationNode arrayLocation = createArrayLocation(graph, elementKind); + arrayLocation.setIndex(storeIndexed.index()); + Value value = storeIndexed.value(); + if (elementKind == CiKind.Object) { + // Store check! + if (storeIndexed.array().exactType() != null) { + RiType elementType = storeIndexed.array().exactType().componentType(); + if (elementType.superType() != null) { + Constant type = new Constant(elementType.getEncoding(Representation.ObjectHub), graph); + value = new CheckCast(type, value, graph); + } else { + assert elementType.name().equals("Ljava/lang/Object;") : elementType.name(); + } + } else { + ReadNode arrayKlass = new ReadNode(CiKind.Object, storeIndexed.array(), LocationNode.create(LocationNode.FINAL_LOCATION, CiKind.Object, config.hubOffset, graph), graph); + ReadNode arrayElementKlass = new ReadNode(CiKind.Object, arrayKlass, LocationNode.create(LocationNode.FINAL_LOCATION, CiKind.Object, config.arrayClassElementOffset, graph), graph); + value = new CheckCast(arrayElementKlass, value, graph); + } + } + WriteNode memoryWrite = new WriteNode(elementKind.stackKind(), storeIndexed.array(), value, arrayLocation, graph); + memoryWrite.setGuard(boundsCheck); + memoryWrite.setStateAfter(storeIndexed.stateAfter()); + anchor.setNext(memoryWrite); + if (elementKind == CiKind.Object && !value.isNullConstant()) { + ArrayWriteBarrier writeBarrier = new ArrayWriteBarrier(storeIndexed.array(), arrayLocation, graph); + memoryWrite.setNext(writeBarrier); + writeBarrier.setNext(storeIndexed.next()); + } else { + memoryWrite.setNext(storeIndexed.next()); + } + storeIndexed.replaceAtPredecessors(anchor); + storeIndexed.delete(); } } + private LocationNode createArrayLocation(Graph graph, CiKind elementKind) { + return LocationNode.create(LocationNode.getArrayLocation(elementKind), elementKind, config.getArrayOffset(elementKind), graph); + } + + private GuardNode createBoundsCheck(AccessIndexed n, CiLoweringTool tool) { + return (GuardNode) tool.createGuard(new Compare(n.index(), Condition.BT, n.length(), n.graph())); + } + @Override public Graph intrinsicGraph(RiMethod method, List parameters) { if (!intrinsicGraphs.containsKey(method)) { diff -r 7f2bf8fe6804 -r 8044bdfaab06 graal/com.oracle.max.graal.runtime/src/com/oracle/max/graal/runtime/HotSpotXirGenerator.java --- a/graal/com.oracle.max.graal.runtime/src/com/oracle/max/graal/runtime/HotSpotXirGenerator.java Wed Jul 06 13:28:51 2011 +0200 +++ b/graal/com.oracle.max.graal.runtime/src/com/oracle/max/graal/runtime/HotSpotXirGenerator.java Wed Jul 06 16:15:15 2011 +0200 @@ -1179,7 +1179,6 @@ @Override public XirSnippet genCheckCast(XirSite site, XirArgument receiver, XirArgument hub, RiType type) { - assert type.isResolved(); return new XirSnippet(checkCastTemplates.get(site), receiver, hub); } diff -r 7f2bf8fe6804 -r 8044bdfaab06 graal/com.oracle.max.graal.runtime/src/com/oracle/max/graal/runtime/nodes/ArrayWriteBarrier.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.max.graal.runtime/src/com/oracle/max/graal/runtime/nodes/ArrayWriteBarrier.java Wed Jul 06 16:15:15 2011 +0200 @@ -0,0 +1,99 @@ +/* + * Copyright (c) 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.max.graal.runtime.nodes; + +import com.oracle.max.graal.compiler.debug.*; +import com.oracle.max.graal.compiler.gen.*; +import com.oracle.max.graal.compiler.ir.*; +import com.oracle.max.graal.graph.*; +import com.sun.cri.ci.*; + + +public final class ArrayWriteBarrier extends WriteBarrier { + private static final int INPUT_COUNT = 2; + private static final int INPUT_OBJECT = 0; + private static final int INPUT_LOCATION = 1; + + private static final int SUCCESSOR_COUNT = 0; + + @Override + protected int inputCount() { + return super.inputCount() + INPUT_COUNT; + } + + /** + * The instruction that produces the object tested against null. + */ + public Value object() { + return (Value) inputs().get(super.inputCount() + INPUT_OBJECT); + } + + public void setObject(Value n) { + inputs().set(super.inputCount() + INPUT_OBJECT, n); + } + + /** + * The instruction that produces the object tested against null. + */ + public LocationNode location() { + return (LocationNode) inputs().get(super.inputCount() + INPUT_LOCATION); + } + + public void setLocation(LocationNode n) { + inputs().set(super.inputCount() + INPUT_LOCATION, n); + } + + public ArrayWriteBarrier(Value object, LocationNode index, Graph graph) { + super(INPUT_COUNT, SUCCESSOR_COUNT, graph); + this.setObject(object); + this.setLocation(index); + } + + + @SuppressWarnings("unchecked") + @Override + public T lookup(Class clazz) { + if (clazz == LIRGenerator.LIRGeneratorOp.class) { + return (T) new LIRGenerator.LIRGeneratorOp() { + @Override + public void generate(Node n, LIRGenerator generator) { + assert n == ArrayWriteBarrier.this; + CiVariable temp = generator.newVariable(CiKind.Word); + generator.lir().lea(location().createAddress(generator, object()), temp); + ArrayWriteBarrier.this.generateBarrier(temp, generator); + } + }; + } + return super.lookup(clazz); + } + + @Override + public void print(LogStream out) { + out.print("field write barrier ").print(object()); + } + + @Override + public Node copy(Graph into) { + return new ArrayWriteBarrier(null, null, into); + } +} diff -r 7f2bf8fe6804 -r 8044bdfaab06 graal/com.oracle.max.graal.runtime/src/com/oracle/max/graal/runtime/nodes/FieldWriteBarrier.java --- a/graal/com.oracle.max.graal.runtime/src/com/oracle/max/graal/runtime/nodes/FieldWriteBarrier.java Wed Jul 06 13:28:51 2011 +0200 +++ b/graal/com.oracle.max.graal.runtime/src/com/oracle/max/graal/runtime/nodes/FieldWriteBarrier.java Wed Jul 06 16:15:15 2011 +0200 @@ -25,13 +25,11 @@ import com.oracle.max.graal.compiler.debug.*; import com.oracle.max.graal.compiler.gen.*; import com.oracle.max.graal.compiler.ir.*; -import com.oracle.max.graal.compiler.lir.*; import com.oracle.max.graal.graph.*; -import com.oracle.max.graal.runtime.*; import com.sun.cri.ci.*; -public final class FieldWriteBarrier extends FixedNodeWithNext { +public final class FieldWriteBarrier extends WriteBarrier { private static final int INPUT_COUNT = 1; private static final int INPUT_OBJECT = 0; @@ -54,7 +52,7 @@ } public FieldWriteBarrier(Value object, Graph graph) { - super(CiKind.Illegal, INPUT_COUNT, SUCCESSOR_COUNT, graph); + super(INPUT_COUNT, SUCCESSOR_COUNT, graph); this.setObject(object); } @@ -68,18 +66,8 @@ public void generate(Node n, LIRGenerator generator) { assert n == FieldWriteBarrier.this; CiVariable temp = generator.newVariable(CiKind.Word); - HotSpotVMConfig config = CompilerImpl.getInstance().getConfig(); generator.lir().move(generator.makeOperand(object()), temp); - generator.lir().unsignedShiftRight(temp, CiConstant.forInt(config.cardtableShift), temp, CiValue.IllegalValue); - - long startAddress = config.cardtableStartAddress; - int displacement = 0; - if (((int) startAddress) == startAddress) { - displacement = (int) startAddress; - } else { - generator.lir().add(temp, CiConstant.forLong(config.cardtableStartAddress), temp); - } - generator.lir().move(CiConstant.FALSE, new CiAddress(CiKind.Boolean, temp, displacement), (LIRDebugInfo) null); + FieldWriteBarrier.this.generateBarrier(temp, generator); } }; } diff -r 7f2bf8fe6804 -r 8044bdfaab06 graal/com.oracle.max.graal.runtime/src/com/oracle/max/graal/runtime/nodes/WriteBarrier.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.max.graal.runtime/src/com/oracle/max/graal/runtime/nodes/WriteBarrier.java Wed Jul 06 16:15:15 2011 +0200 @@ -0,0 +1,55 @@ +/* + * Copyright (c) 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.max.graal.runtime.nodes; + +import com.oracle.max.graal.compiler.gen.*; +import com.oracle.max.graal.compiler.ir.*; +import com.oracle.max.graal.compiler.lir.*; +import com.oracle.max.graal.graph.*; +import com.oracle.max.graal.runtime.*; +import com.sun.cri.ci.*; + + +public abstract class WriteBarrier extends FixedNodeWithNext { + private static final int INPUT_COUNT = 0; + private static final int SUCCESSOR_COUNT = 0; + + public WriteBarrier(int inputCount, int successorCount, Graph graph) { + super(CiKind.Illegal, inputCount + INPUT_COUNT, successorCount + SUCCESSOR_COUNT, graph); + } + + + protected void generateBarrier(CiValue temp, LIRGenerator generator) { + HotSpotVMConfig config = CompilerImpl.getInstance().getConfig(); + generator.lir().unsignedShiftRight(temp, CiConstant.forInt(config.cardtableShift), temp, CiValue.IllegalValue); + + long startAddress = config.cardtableStartAddress; + int displacement = 0; + if (((int) startAddress) == startAddress) { + displacement = (int) startAddress; + } else { + generator.lir().add(temp, CiConstant.forLong(config.cardtableStartAddress), temp); + } + generator.lir().move(CiConstant.FALSE, new CiAddress(CiKind.Boolean, temp, displacement), (LIRDebugInfo) null); + } +}