src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/phases/WriteBarrierVerificationPhase.java
Index Unified diffs Context diffs Sdiffs Patch New Old Previous File Next File hotspot Cdiff src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/phases/WriteBarrierVerificationPhase.java

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

Print this page

        

*** 31,55 **** import org.graalvm.compiler.hotspot.GraalHotSpotVMConfig; import org.graalvm.compiler.hotspot.nodes.ArrayRangeWriteBarrier; import org.graalvm.compiler.hotspot.nodes.G1PostWriteBarrier; import org.graalvm.compiler.hotspot.nodes.ObjectWriteBarrier; import org.graalvm.compiler.hotspot.nodes.SerialWriteBarrier; import org.graalvm.compiler.nodes.DeoptimizingNode; import org.graalvm.compiler.nodes.FixedWithNextNode; import org.graalvm.compiler.nodes.LoopBeginNode; import org.graalvm.compiler.nodes.StructuredGraph; import org.graalvm.compiler.nodes.ValueNode; import org.graalvm.compiler.nodes.extended.ArrayRangeWriteNode; import org.graalvm.compiler.nodes.java.LoweredAtomicReadAndWriteNode; ! import org.graalvm.compiler.nodes.java.LoweredCompareAndSwapNode; import org.graalvm.compiler.nodes.memory.FixedAccessNode; import org.graalvm.compiler.nodes.memory.HeapAccess; 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.OffsetAddressNode; import org.graalvm.compiler.nodes.type.StampTool; import org.graalvm.compiler.phases.Phase; /** * Verification phase that checks if, for every write, at least one write barrier is present at all * paths leading to the previous safepoint. For every write, necessitating a write barrier, a --- 31,57 ---- import org.graalvm.compiler.hotspot.GraalHotSpotVMConfig; import org.graalvm.compiler.hotspot.nodes.ArrayRangeWriteBarrier; import org.graalvm.compiler.hotspot.nodes.G1PostWriteBarrier; import org.graalvm.compiler.hotspot.nodes.ObjectWriteBarrier; import org.graalvm.compiler.hotspot.nodes.SerialWriteBarrier; + import org.graalvm.compiler.nodeinfo.Verbosity; import org.graalvm.compiler.nodes.DeoptimizingNode; import org.graalvm.compiler.nodes.FixedWithNextNode; import org.graalvm.compiler.nodes.LoopBeginNode; import org.graalvm.compiler.nodes.StructuredGraph; import org.graalvm.compiler.nodes.ValueNode; import org.graalvm.compiler.nodes.extended.ArrayRangeWriteNode; import org.graalvm.compiler.nodes.java.LoweredAtomicReadAndWriteNode; ! import org.graalvm.compiler.nodes.java.LogicCompareAndSwapNode; import org.graalvm.compiler.nodes.memory.FixedAccessNode; import org.graalvm.compiler.nodes.memory.HeapAccess; 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.OffsetAddressNode; import org.graalvm.compiler.nodes.type.StampTool; + import org.graalvm.compiler.nodes.util.GraphUtil; import org.graalvm.compiler.phases.Phase; /** * Verification phase that checks if, for every write, at least one write barrier is present at all * paths leading to the previous safepoint. For every write, necessitating a write barrier, a
*** 71,80 **** --- 73,88 ---- } private void processWrites(StructuredGraph graph) { for (Node node : graph.getNodes()) { if (isObjectWrite(node) || isObjectArrayRangeWrite(node)) { + if (node instanceof WriteNode) { + WriteNode writeNode = (WriteNode) node; + if (StampTool.isPointerAlwaysNull(writeNode.value())) { + continue; + } + } validateWrite(node); } } }
*** 90,100 **** expandFrontier(frontier, write); Iterator<Node> iterator = frontier.iterator(); while (iterator.hasNext()) { Node currentNode = iterator.next(); if (isSafepoint(currentNode)) { ! throw new AssertionError("Write barrier must be present " + write); } if (useG1GC()) { if (!(currentNode instanceof G1PostWriteBarrier) || (!validateBarrier((FixedAccessNode) write, (ObjectWriteBarrier) currentNode))) { expandFrontier(frontier, currentNode); } --- 98,108 ---- expandFrontier(frontier, write); Iterator<Node> iterator = frontier.iterator(); while (iterator.hasNext()) { Node currentNode = iterator.next(); if (isSafepoint(currentNode)) { ! throw new AssertionError("Write barrier must be present " + write.toString(Verbosity.All) + " / " + write.inputs()); } if (useG1GC()) { if (!(currentNode instanceof G1PostWriteBarrier) || (!validateBarrier((FixedAccessNode) write, (ObjectWriteBarrier) currentNode))) { expandFrontier(frontier, currentNode); }
*** 112,122 **** } private boolean hasAttachedBarrier(FixedWithNextNode node) { final Node next = node.next(); final Node previous = node.predecessor(); ! final boolean validatePreBarrier = useG1GC() && (isObjectWrite(node) || !((ArrayRangeWriteNode) node).isInitialization()); if (isObjectWrite(node)) { return (isObjectBarrier(node, next) || StampTool.isPointerAlwaysNull(getValueWritten(node))) && (!validatePreBarrier || isObjectBarrier(node, previous)); } else if (isObjectArrayRangeWrite(node)) { return (isArrayBarrier(node, next) || StampTool.isPointerAlwaysNull(getValueWritten(node))) && (!validatePreBarrier || isArrayBarrier(node, previous)); } else { --- 120,136 ---- } private boolean hasAttachedBarrier(FixedWithNextNode node) { final Node next = node.next(); final Node previous = node.predecessor(); ! boolean validatePreBarrier = useG1GC() && (isObjectWrite(node) || !((ArrayRangeWriteNode) node).isInitialization()); ! if (node instanceof WriteNode) { ! WriteNode writeNode = (WriteNode) node; ! if (writeNode.getLocationIdentity().isInit()) { ! validatePreBarrier = false; ! } ! } if (isObjectWrite(node)) { return (isObjectBarrier(node, next) || StampTool.isPointerAlwaysNull(getValueWritten(node))) && (!validatePreBarrier || isObjectBarrier(node, previous)); } else if (isObjectArrayRangeWrite(node)) { return (isArrayBarrier(node, next) || StampTool.isPointerAlwaysNull(getValueWritten(node))) && (!validatePreBarrier || isArrayBarrier(node, previous)); } else {
*** 148,157 **** --- 162,175 ---- } } } private static boolean isSafepoint(Node node) { + if (node instanceof FixedAccessNode) { + // Implicit null checks on reads or writes do not count. + return false; + } /* * LoopBegin nodes are also treated as safepoints since a bottom-up analysis is performed * and loop safepoints are placed before LoopEnd nodes. Possible elimination of write * barriers inside loops, derived from writes outside loops, can not be permitted. */
*** 159,182 **** } private static ValueNode getValueWritten(FixedWithNextNode write) { if (write instanceof WriteNode) { return ((WriteNode) write).value(); ! } else if (write instanceof LoweredCompareAndSwapNode) { ! return ((LoweredCompareAndSwapNode) write).getNewValue(); } else if (write instanceof LoweredAtomicReadAndWriteNode) { return ((LoweredAtomicReadAndWriteNode) write).getNewValue(); } else { throw GraalError.shouldNotReachHere(String.format("unexpected write node %s", write)); } } private static boolean validateBarrier(FixedAccessNode write, ObjectWriteBarrier barrier) { ! assert write instanceof WriteNode || write instanceof LoweredCompareAndSwapNode || write instanceof LoweredAtomicReadAndWriteNode : "Node must be of type requiring a write barrier " + write; if (!barrier.usePrecise()) { if (barrier.getAddress() instanceof OffsetAddressNode && write.getAddress() instanceof OffsetAddressNode) { ! return ((OffsetAddressNode) barrier.getAddress()).getBase() == ((OffsetAddressNode) write.getAddress()).getBase(); } } return barrier.getAddress() == write.getAddress(); } } --- 177,200 ---- } private static ValueNode getValueWritten(FixedWithNextNode write) { if (write instanceof WriteNode) { return ((WriteNode) write).value(); ! } else if (write instanceof LogicCompareAndSwapNode) { ! return ((LogicCompareAndSwapNode) write).getNewValue(); } else if (write instanceof LoweredAtomicReadAndWriteNode) { return ((LoweredAtomicReadAndWriteNode) write).getNewValue(); } else { throw GraalError.shouldNotReachHere(String.format("unexpected write node %s", write)); } } private static boolean validateBarrier(FixedAccessNode write, ObjectWriteBarrier barrier) { ! assert write instanceof WriteNode || write instanceof LogicCompareAndSwapNode || write instanceof LoweredAtomicReadAndWriteNode : "Node must be of type requiring a write barrier " + write; if (!barrier.usePrecise()) { if (barrier.getAddress() instanceof OffsetAddressNode && write.getAddress() instanceof OffsetAddressNode) { ! return GraphUtil.unproxify(((OffsetAddressNode) barrier.getAddress()).getBase()) == GraphUtil.unproxify(((OffsetAddressNode) write.getAddress()).getBase()); } } return barrier.getAddress() == write.getAddress(); } }
src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.hotspot/src/org/graalvm/compiler/hotspot/phases/WriteBarrierVerificationPhase.java
Index Unified diffs Context diffs Sdiffs Patch New Old Previous File Next File