< prev index next >

src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/phases/WriteBarrierAdditionPhase.java

Print this page

        

*** 23,202 **** package org.graalvm.compiler.hotspot.phases; import org.graalvm.compiler.debug.DebugCloseable; - import org.graalvm.compiler.debug.GraalError; import org.graalvm.compiler.graph.Node; import org.graalvm.compiler.hotspot.GraalHotSpotVMConfig; ! import org.graalvm.compiler.hotspot.nodes.G1ArrayRangePostWriteBarrier; ! import org.graalvm.compiler.hotspot.nodes.G1ArrayRangePreWriteBarrier; ! import org.graalvm.compiler.hotspot.nodes.G1PostWriteBarrier; ! import org.graalvm.compiler.hotspot.nodes.G1PreWriteBarrier; ! import org.graalvm.compiler.hotspot.nodes.G1ReferentFieldReadBarrier; ! import org.graalvm.compiler.hotspot.nodes.SerialArrayRangeWriteBarrier; ! import org.graalvm.compiler.hotspot.nodes.SerialWriteBarrier; import org.graalvm.compiler.nodes.StructuredGraph; - import org.graalvm.compiler.nodes.ValueNode; import org.graalvm.compiler.nodes.extended.ArrayRangeWrite; import org.graalvm.compiler.nodes.java.AbstractCompareAndSwapNode; import org.graalvm.compiler.nodes.java.LoweredAtomicReadAndWriteNode; - import org.graalvm.compiler.nodes.memory.FixedAccessNode; - import org.graalvm.compiler.nodes.memory.HeapAccess.BarrierType; import org.graalvm.compiler.nodes.memory.ReadNode; import org.graalvm.compiler.nodes.memory.WriteNode; - import org.graalvm.compiler.nodes.memory.address.AddressNode; - import org.graalvm.compiler.nodes.type.StampTool; import org.graalvm.compiler.phases.Phase; public class WriteBarrierAdditionPhase extends Phase { ! private GraalHotSpotVMConfig config; public WriteBarrierAdditionPhase(GraalHotSpotVMConfig config) { ! this.config = config; } @SuppressWarnings("try") @Override protected void run(StructuredGraph graph) { for (Node n : graph.getNodes()) { try (DebugCloseable scope = n.graph().withNodeSourcePosition(n)) { if (n instanceof ReadNode) { ! addReadNodeBarriers((ReadNode) n, graph); } else if (n instanceof WriteNode) { ! addWriteNodeBarriers((WriteNode) n, graph); } else if (n instanceof LoweredAtomicReadAndWriteNode) { LoweredAtomicReadAndWriteNode loweredAtomicReadAndWriteNode = (LoweredAtomicReadAndWriteNode) n; ! addAtomicReadWriteNodeBarriers(loweredAtomicReadAndWriteNode, graph); } else if (n instanceof AbstractCompareAndSwapNode) { ! addCASBarriers((AbstractCompareAndSwapNode) n, graph); } else if (n instanceof ArrayRangeWrite) { ArrayRangeWrite node = (ArrayRangeWrite) n; if (node.writesObjectArray()) { ! addArrayRangeBarriers(node, graph); } } } } } ! private void addReadNodeBarriers(ReadNode node, StructuredGraph graph) { ! if (node.getBarrierType() == BarrierType.PRECISE) { ! assert config.useG1GC; ! 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, 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, AddressNode address, ValueNode value, boolean precise, StructuredGraph graph) { ! final boolean alwaysNull = StampTool.isPointerAlwaysNull(value); ! graph.addAfterFixed(node, graph.add(new G1PostWriteBarrier(address, value, precise, alwaysNull))); ! } ! ! 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; ! } ! graph.addAfterFixed(node, graph.add(new SerialWriteBarrier(address, precise))); ! } ! ! private void addWriteNodeBarriers(WriteNode node, StructuredGraph graph) { ! BarrierType barrierType = node.getBarrierType(); ! switch (barrierType) { ! case NONE: ! // nothing to do ! break; ! case IMPRECISE: ! case PRECISE: ! boolean precise = barrierType == BarrierType.PRECISE; ! if (config.useG1GC) { ! if (!node.getLocationIdentity().isInit()) { ! // The pre barrier does nothing if the value being read is null, so it can ! // be explicitly skipped when this is an initializing store. ! addG1PreWriteBarrier(node, node.getAddress(), null, true, node.getNullCheck(), graph); ! } ! addG1PostWriteBarrier(node, node.getAddress(), node.value(), precise, graph); ! } else { ! addSerialPostWriteBarrier(node, node.getAddress(), node.value(), precise, graph); ! } ! break; ! default: ! throw new GraalError("unexpected barrier type: " + barrierType); ! } ! } ! ! private void addAtomicReadWriteNodeBarriers(LoweredAtomicReadAndWriteNode node, StructuredGraph graph) { ! BarrierType barrierType = node.getBarrierType(); ! switch (barrierType) { ! case NONE: ! // nothing to do ! break; ! case IMPRECISE: ! case PRECISE: ! boolean precise = barrierType == BarrierType.PRECISE; ! if (config.useG1GC) { ! addG1PreWriteBarrier(node, node.getAddress(), null, true, node.getNullCheck(), graph); ! addG1PostWriteBarrier(node, node.getAddress(), node.getNewValue(), precise, graph); ! } else { ! addSerialPostWriteBarrier(node, node.getAddress(), node.getNewValue(), precise, graph); ! } ! break; ! default: ! throw new GraalError("unexpected barrier type: " + barrierType); ! } ! } ! ! private void addCASBarriers(AbstractCompareAndSwapNode node, StructuredGraph graph) { ! BarrierType barrierType = node.getBarrierType(); ! switch (barrierType) { ! case NONE: ! // nothing to do ! break; ! case IMPRECISE: ! case PRECISE: ! boolean precise = barrierType == BarrierType.PRECISE; ! if (config.useG1GC) { ! addG1PreWriteBarrier(node, node.getAddress(), node.getExpectedValue(), false, false, graph); ! addG1PostWriteBarrier(node, node.getAddress(), node.getNewValue(), precise, graph); ! } else { ! addSerialPostWriteBarrier(node, node.getAddress(), node.getNewValue(), precise, graph); ! } ! break; ! default: ! throw new GraalError("unexpected barrier type: " + barrierType); ! } } ! private void addArrayRangeBarriers(ArrayRangeWrite write, StructuredGraph graph) { if (config.useG1GC) { ! if (!write.isInitialization()) { ! // The pre barrier does nothing if the value being read is null, so it can ! // be explicitly skipped when this is an initializing store. ! G1ArrayRangePreWriteBarrier g1ArrayRangePreWriteBarrier = graph.add(new G1ArrayRangePreWriteBarrier(write.getAddress(), write.getLength(), write.getElementStride())); ! graph.addBeforeFixed(write.asNode(), g1ArrayRangePreWriteBarrier); ! } ! G1ArrayRangePostWriteBarrier g1ArrayRangePostWriteBarrier = graph.add(new G1ArrayRangePostWriteBarrier(write.getAddress(), write.getLength(), write.getElementStride())); ! graph.addAfterFixed(write.asNode(), g1ArrayRangePostWriteBarrier); } else { ! SerialArrayRangeWriteBarrier serialArrayRangeWriteBarrier = graph.add(new SerialArrayRangeWriteBarrier(write.getAddress(), write.getLength(), write.getElementStride())); ! graph.addAfterFixed(write.asNode(), serialArrayRangeWriteBarrier); } } ! @Override ! public boolean checkContract() { ! return false; } } --- 23,93 ---- package org.graalvm.compiler.hotspot.phases; import org.graalvm.compiler.debug.DebugCloseable; import org.graalvm.compiler.graph.Node; import org.graalvm.compiler.hotspot.GraalHotSpotVMConfig; ! import org.graalvm.compiler.hotspot.gc.g1.G1BarrierSet; ! import org.graalvm.compiler.hotspot.gc.shared.BarrierSet; ! import org.graalvm.compiler.hotspot.gc.shared.CardTableBarrierSet; import org.graalvm.compiler.nodes.StructuredGraph; import org.graalvm.compiler.nodes.extended.ArrayRangeWrite; import org.graalvm.compiler.nodes.java.AbstractCompareAndSwapNode; import org.graalvm.compiler.nodes.java.LoweredAtomicReadAndWriteNode; import org.graalvm.compiler.nodes.memory.ReadNode; import org.graalvm.compiler.nodes.memory.WriteNode; import org.graalvm.compiler.phases.Phase; public class WriteBarrierAdditionPhase extends Phase { ! private BarrierSet barrierSet; public WriteBarrierAdditionPhase(GraalHotSpotVMConfig config) { ! this.barrierSet = createBarrierSet(config); } @SuppressWarnings("try") @Override protected void run(StructuredGraph graph) { for (Node n : graph.getNodes()) { try (DebugCloseable scope = n.graph().withNodeSourcePosition(n)) { if (n instanceof ReadNode) { ! barrierSet.addReadNodeBarriers((ReadNode) n, graph); } else if (n instanceof WriteNode) { ! barrierSet.addWriteNodeBarriers((WriteNode) n, graph); } else if (n instanceof LoweredAtomicReadAndWriteNode) { LoweredAtomicReadAndWriteNode loweredAtomicReadAndWriteNode = (LoweredAtomicReadAndWriteNode) n; ! barrierSet.addAtomicReadWriteNodeBarriers(loweredAtomicReadAndWriteNode, graph); } else if (n instanceof AbstractCompareAndSwapNode) { ! barrierSet.addCASBarriers((AbstractCompareAndSwapNode) n, graph); } else if (n instanceof ArrayRangeWrite) { ArrayRangeWrite node = (ArrayRangeWrite) n; if (node.writesObjectArray()) { ! barrierSet.addArrayRangeBarriers(node, graph); } } } } } ! @Override ! public boolean checkContract() { ! return false; } ! private BarrierSet createBarrierSet(GraalHotSpotVMConfig config) { if (config.useG1GC) { ! return createG1BarrierSet(); } else { ! return createCardTableBarrierSet(); } } ! protected BarrierSet createCardTableBarrierSet() { ! return new CardTableBarrierSet(); ! } ! ! protected BarrierSet createG1BarrierSet() { ! return new G1BarrierSet(); } }
< prev index next >