use of org.graalvm.compiler.hotspot.nodes.SerialWriteBarrier in project graal by oracle.
the class WriteBarrierAdditionTest method testHelper.
@SuppressWarnings("try")
private void testHelper(final String snippetName, final int expectedBarriers) throws Exception, SecurityException {
ResolvedJavaMethod snippet = getResolvedJavaMethod(snippetName);
DebugContext debug = getDebugContext();
try (DebugContext.Scope s = debug.scope("WriteBarrierAdditionTest", snippet)) {
StructuredGraph graph = parseEager(snippet, AllowAssumptions.NO, debug);
HighTierContext highContext = getDefaultHighTierContext();
MidTierContext midContext = new MidTierContext(getProviders(), getTargetProvider(), OptimisticOptimizations.ALL, graph.getProfilingInfo());
new InliningPhase(new InlineEverythingPolicy(), new CanonicalizerPhase()).apply(graph, highContext);
new CanonicalizerPhase().apply(graph, highContext);
new LoweringPhase(new CanonicalizerPhase(), LoweringTool.StandardLoweringStage.HIGH_TIER).apply(graph, highContext);
new GuardLoweringPhase().apply(graph, midContext);
new LoweringPhase(new CanonicalizerPhase(), LoweringTool.StandardLoweringStage.MID_TIER).apply(graph, midContext);
new WriteBarrierAdditionPhase(config).apply(graph);
debug.dump(DebugContext.BASIC_LEVEL, graph, "After Write Barrier Addition");
int barriers = 0;
if (config.useG1GC) {
barriers = graph.getNodes().filter(G1ReferentFieldReadBarrier.class).count() + graph.getNodes().filter(G1PreWriteBarrier.class).count() + graph.getNodes().filter(G1PostWriteBarrier.class).count();
} else {
barriers = graph.getNodes().filter(SerialWriteBarrier.class).count();
}
if (expectedBarriers != barriers) {
Assert.assertEquals(getScheduledGraphString(graph), expectedBarriers, barriers);
}
for (WriteNode write : graph.getNodes().filter(WriteNode.class)) {
if (config.useG1GC) {
if (write.getBarrierType() != BarrierType.NONE) {
Assert.assertEquals(1, write.successors().count());
Assert.assertTrue(write.next() instanceof G1PostWriteBarrier);
Assert.assertTrue(write.predecessor() instanceof G1PreWriteBarrier);
}
} else {
if (write.getBarrierType() != BarrierType.NONE) {
Assert.assertEquals(1, write.successors().count());
Assert.assertTrue(write.next() instanceof SerialWriteBarrier);
}
}
}
for (ReadNode read : graph.getNodes().filter(ReadNode.class)) {
if (read.getBarrierType() != BarrierType.NONE) {
Assert.assertTrue(read.getAddress() instanceof OffsetAddressNode);
JavaConstant constDisp = ((OffsetAddressNode) read.getAddress()).getOffset().asJavaConstant();
Assert.assertNotNull(constDisp);
Assert.assertEquals(referentOffset, constDisp.asLong());
Assert.assertTrue(config.useG1GC);
Assert.assertEquals(BarrierType.PRECISE, read.getBarrierType());
Assert.assertTrue(read.next() instanceof G1ReferentFieldReadBarrier);
}
}
} catch (Throwable e) {
throw debug.handle(e);
}
}
use of org.graalvm.compiler.hotspot.nodes.SerialWriteBarrier in project graal by oracle.
the class WriteBarrierVerificationTest method testPredicate.
@SuppressWarnings("try")
private void testPredicate(final String snippet, final GraphPredicate expectedBarriers, final int... removedBarrierIndices) {
DebugContext debug = getDebugContext();
try (DebugCloseable d = debug.disableIntercept();
DebugContext.Scope s = debug.scope("WriteBarrierVerificationTest", new DebugDumpScope(snippet))) {
final StructuredGraph graph = parseEager(snippet, AllowAssumptions.YES, debug);
HighTierContext highTierContext = getDefaultHighTierContext();
new InliningPhase(new CanonicalizerPhase()).apply(graph, highTierContext);
MidTierContext midTierContext = new MidTierContext(getProviders(), getTargetProvider(), OptimisticOptimizations.ALL, graph.getProfilingInfo());
new LoweringPhase(new CanonicalizerPhase(), LoweringTool.StandardLoweringStage.HIGH_TIER).apply(graph, highTierContext);
new GuardLoweringPhase().apply(graph, midTierContext);
new LoopSafepointInsertionPhase().apply(graph);
new LoweringPhase(new CanonicalizerPhase(), LoweringTool.StandardLoweringStage.MID_TIER).apply(graph, highTierContext);
new WriteBarrierAdditionPhase(config).apply(graph);
int barriers = 0;
// First, the total number of expected barriers is checked.
if (config.useG1GC) {
barriers = graph.getNodes().filter(G1PreWriteBarrier.class).count() + graph.getNodes().filter(G1PostWriteBarrier.class).count() + graph.getNodes().filter(G1ArrayRangePreWriteBarrier.class).count() + graph.getNodes().filter(G1ArrayRangePostWriteBarrier.class).count();
Assert.assertTrue(expectedBarriers.apply(graph) * 2 == barriers);
} else {
barriers = graph.getNodes().filter(SerialWriteBarrier.class).count() + graph.getNodes().filter(SerialArrayRangeWriteBarrier.class).count();
Assert.assertTrue(expectedBarriers.apply(graph) == barriers);
}
ResolvedJavaField barrierIndexField = getMetaAccess().lookupJavaField(WriteBarrierVerificationTest.class.getDeclaredField("barrierIndex"));
LocationIdentity barrierIdentity = new FieldLocationIdentity(barrierIndexField);
// Iterate over all write nodes and remove barriers according to input indices.
NodeIteratorClosure<Boolean> closure = new NodeIteratorClosure<Boolean>() {
@Override
protected Boolean processNode(FixedNode node, Boolean currentState) {
if (node instanceof WriteNode) {
WriteNode write = (WriteNode) node;
LocationIdentity obj = write.getLocationIdentity();
if (obj.equals(barrierIdentity)) {
/*
* A "barrierIndex" variable was found and is checked against the input
* barrier array.
*/
if (eliminateBarrier(write.value().asJavaConstant().asInt(), removedBarrierIndices)) {
return true;
}
}
} else if (node instanceof SerialWriteBarrier || node instanceof G1PostWriteBarrier) {
// Remove flagged write barriers.
if (currentState) {
graph.removeFixed(((FixedWithNextNode) node));
return false;
}
}
return currentState;
}
private boolean eliminateBarrier(int index, int[] map) {
for (int i = 0; i < map.length; i++) {
if (map[i] == index) {
return true;
}
}
return false;
}
@Override
protected EconomicMap<LoopExitNode, Boolean> processLoop(LoopBeginNode loop, Boolean initialState) {
return ReentrantNodeIterator.processLoop(this, loop, initialState).exitStates;
}
@Override
protected Boolean merge(AbstractMergeNode merge, List<Boolean> states) {
return false;
}
@Override
protected Boolean afterSplit(AbstractBeginNode node, Boolean oldState) {
return false;
}
};
try (Scope disabled = debug.disable()) {
ReentrantNodeIterator.apply(closure, graph.start(), false);
new WriteBarrierVerificationPhase(config).apply(graph);
} catch (AssertionError error) {
/*
* Catch assertion, test for expected one and re-throw in order to validate unit
* test.
*/
Assert.assertTrue(error.getMessage().contains("Write barrier must be present"));
throw error;
}
} catch (Throwable e) {
throw debug.handle(e);
}
}
use of org.graalvm.compiler.hotspot.nodes.SerialWriteBarrier in project graal by oracle.
the class DefaultHotSpotLoweringProvider method lower.
@Override
public void lower(Node n, LoweringTool tool) {
StructuredGraph graph = (StructuredGraph) n.graph();
if (n instanceof Invoke) {
lowerInvoke((Invoke) n, tool, graph);
} else if (n instanceof LoadMethodNode) {
lowerLoadMethodNode((LoadMethodNode) n);
} else if (n instanceof GetClassNode) {
lowerGetClassNode((GetClassNode) n, tool, graph);
} else if (n instanceof StoreHubNode) {
lowerStoreHubNode((StoreHubNode) n, graph);
} else if (n instanceof OSRStartNode) {
lowerOSRStartNode((OSRStartNode) n);
} else if (n instanceof BytecodeExceptionNode) {
lowerBytecodeExceptionNode((BytecodeExceptionNode) n);
} else if (n instanceof InstanceOfNode) {
InstanceOfNode instanceOfNode = (InstanceOfNode) n;
if (graph.getGuardsStage().areDeoptsFixed()) {
instanceofSnippets.lower(instanceOfNode, tool);
} else {
if (instanceOfNode.allowsNull()) {
ValueNode object = instanceOfNode.getValue();
LogicNode newTypeCheck = graph.addOrUniqueWithInputs(InstanceOfNode.create(instanceOfNode.type(), object, instanceOfNode.profile(), instanceOfNode.getAnchor()));
LogicNode newNode = LogicNode.or(graph.unique(IsNullNode.create(object)), newTypeCheck, GraalDirectives.UNLIKELY_PROBABILITY);
instanceOfNode.replaceAndDelete(newNode);
}
}
} else if (n instanceof InstanceOfDynamicNode) {
InstanceOfDynamicNode instanceOfDynamicNode = (InstanceOfDynamicNode) n;
if (graph.getGuardsStage().areDeoptsFixed()) {
instanceofSnippets.lower(instanceOfDynamicNode, tool);
} else {
ValueNode mirror = instanceOfDynamicNode.getMirrorOrHub();
if (mirror.stamp(NodeView.DEFAULT).getStackKind() == JavaKind.Object) {
ClassGetHubNode classGetHub = graph.unique(new ClassGetHubNode(mirror));
instanceOfDynamicNode.setMirror(classGetHub);
}
if (instanceOfDynamicNode.allowsNull()) {
ValueNode object = instanceOfDynamicNode.getObject();
LogicNode newTypeCheck = graph.addOrUniqueWithInputs(InstanceOfDynamicNode.create(graph.getAssumptions(), tool.getConstantReflection(), instanceOfDynamicNode.getMirrorOrHub(), object, false));
LogicNode newNode = LogicNode.or(graph.unique(IsNullNode.create(object)), newTypeCheck, GraalDirectives.UNLIKELY_PROBABILITY);
instanceOfDynamicNode.replaceAndDelete(newNode);
}
}
} else if (n instanceof ClassIsAssignableFromNode) {
if (graph.getGuardsStage().areDeoptsFixed()) {
instanceofSnippets.lower((ClassIsAssignableFromNode) n, tool);
}
} else if (n instanceof NewInstanceNode) {
if (graph.getGuardsStage().areFrameStatesAtDeopts()) {
newObjectSnippets.lower((NewInstanceNode) n, registers, tool);
}
} else if (n instanceof DynamicNewInstanceNode) {
DynamicNewInstanceNode newInstanceNode = (DynamicNewInstanceNode) n;
if (newInstanceNode.getClassClass() == null) {
JavaConstant classClassMirror = constantReflection.forObject(Class.class);
ConstantNode classClass = ConstantNode.forConstant(classClassMirror, tool.getMetaAccess(), graph);
newInstanceNode.setClassClass(classClass);
}
if (graph.getGuardsStage().areFrameStatesAtDeopts()) {
newObjectSnippets.lower(newInstanceNode, registers, tool);
}
} else if (n instanceof NewArrayNode) {
if (graph.getGuardsStage().areFrameStatesAtDeopts()) {
newObjectSnippets.lower((NewArrayNode) n, registers, tool);
}
} else if (n instanceof DynamicNewArrayNode) {
DynamicNewArrayNode dynamicNewArrayNode = (DynamicNewArrayNode) n;
if (dynamicNewArrayNode.getVoidClass() == null) {
JavaConstant voidClassMirror = constantReflection.forObject(void.class);
ConstantNode voidClass = ConstantNode.forConstant(voidClassMirror, tool.getMetaAccess(), graph);
dynamicNewArrayNode.setVoidClass(voidClass);
}
if (graph.getGuardsStage().areFrameStatesAtDeopts()) {
newObjectSnippets.lower(dynamicNewArrayNode, registers, tool);
}
} else if (n instanceof VerifyHeapNode) {
if (graph.getGuardsStage().areFrameStatesAtDeopts()) {
newObjectSnippets.lower((VerifyHeapNode) n, registers, tool);
}
} else if (n instanceof RawMonitorEnterNode) {
if (graph.getGuardsStage().areFrameStatesAtDeopts()) {
monitorSnippets.lower((RawMonitorEnterNode) n, registers, tool);
}
} else if (n instanceof MonitorExitNode) {
if (graph.getGuardsStage().areFrameStatesAtDeopts()) {
monitorSnippets.lower((MonitorExitNode) n, registers, tool);
}
} else if (n instanceof ArrayCopyNode) {
arraycopySnippets.lower((ArrayCopyNode) n, tool);
} else if (n instanceof ArrayCopyWithSlowPathNode) {
arraycopySnippets.lower((ArrayCopyWithSlowPathNode) n, tool);
} else if (n instanceof G1PreWriteBarrier) {
writeBarrierSnippets.lower((G1PreWriteBarrier) n, registers, tool);
} else if (n instanceof G1PostWriteBarrier) {
writeBarrierSnippets.lower((G1PostWriteBarrier) n, registers, tool);
} else if (n instanceof G1ReferentFieldReadBarrier) {
writeBarrierSnippets.lower((G1ReferentFieldReadBarrier) n, registers, tool);
} else if (n instanceof SerialWriteBarrier) {
writeBarrierSnippets.lower((SerialWriteBarrier) n, tool);
} else if (n instanceof SerialArrayRangeWriteBarrier) {
writeBarrierSnippets.lower((SerialArrayRangeWriteBarrier) n, tool);
} else if (n instanceof G1ArrayRangePreWriteBarrier) {
writeBarrierSnippets.lower((G1ArrayRangePreWriteBarrier) n, registers, tool);
} else if (n instanceof G1ArrayRangePostWriteBarrier) {
writeBarrierSnippets.lower((G1ArrayRangePostWriteBarrier) n, registers, tool);
} else if (n instanceof NewMultiArrayNode) {
if (graph.getGuardsStage().areFrameStatesAtDeopts()) {
newObjectSnippets.lower((NewMultiArrayNode) n, tool);
}
} else if (n instanceof LoadExceptionObjectNode) {
exceptionObjectSnippets.lower((LoadExceptionObjectNode) n, registers, tool);
} else if (n instanceof AssertionNode) {
assertionSnippets.lower((AssertionNode) n, tool);
} else if (n instanceof StringToBytesNode) {
if (graph.getGuardsStage().areDeoptsFixed()) {
stringToBytesSnippets.lower((StringToBytesNode) n, tool);
}
} else if (n instanceof IntegerDivRemNode) {
// Nothing to do for division nodes. The HotSpot signal handler catches divisions by
// zero and the MIN_VALUE / -1 cases.
} else if (n instanceof AbstractDeoptimizeNode || n instanceof UnwindNode || n instanceof RemNode || n instanceof SafepointNode) {
/* No lowering, we generate LIR directly for these nodes. */
} else if (n instanceof ClassGetHubNode) {
lowerClassGetHubNode((ClassGetHubNode) n, tool);
} else if (n instanceof HubGetClassNode) {
lowerHubGetClassNode((HubGetClassNode) n, tool);
} else if (n instanceof KlassLayoutHelperNode) {
lowerKlassLayoutHelperNode((KlassLayoutHelperNode) n, tool);
} else if (n instanceof ComputeObjectAddressNode) {
if (graph.getGuardsStage().areFrameStatesAtDeopts()) {
lowerComputeObjectAddressNode((ComputeObjectAddressNode) n);
}
} else if (n instanceof IdentityHashCodeNode) {
hashCodeSnippets.lower((IdentityHashCodeNode) n, tool);
} else if (n instanceof ResolveDynamicConstantNode) {
if (graph.getGuardsStage().areFrameStatesAtDeopts()) {
resolveConstantSnippets.lower((ResolveDynamicConstantNode) n, tool);
}
} else if (n instanceof ResolveConstantNode) {
if (graph.getGuardsStage().areFrameStatesAtDeopts()) {
resolveConstantSnippets.lower((ResolveConstantNode) n, tool);
}
} else if (n instanceof ResolveMethodAndLoadCountersNode) {
if (graph.getGuardsStage().areFrameStatesAtDeopts()) {
resolveConstantSnippets.lower((ResolveMethodAndLoadCountersNode) n, tool);
}
} else if (n instanceof InitializeKlassNode) {
if (graph.getGuardsStage().areFrameStatesAtDeopts()) {
resolveConstantSnippets.lower((InitializeKlassNode) n, tool);
}
} else if (n instanceof ProfileNode) {
profileSnippets.lower((ProfileNode) n, tool);
} else {
super.lower(n, tool);
}
}
use of org.graalvm.compiler.hotspot.nodes.SerialWriteBarrier in project graal by oracle.
the class WriteBarrierVerificationPhase method validateWrite.
private void validateWrite(Node write) {
/*
* The currently validated write is checked in order to discover if it has an appropriate
* attached write barrier.
*/
if (hasAttachedBarrier((FixedWithNextNode) write)) {
return;
}
NodeFlood frontier = write.graph().createNodeFlood();
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);
}
} else {
if (!(currentNode instanceof SerialWriteBarrier) || (!validateBarrier((FixedAccessNode) write, (ObjectWriteBarrier) currentNode)) || ((currentNode instanceof SerialWriteBarrier) && !validateBarrier((FixedAccessNode) write, (ObjectWriteBarrier) currentNode))) {
expandFrontier(frontier, currentNode);
}
}
}
}
Aggregations