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