use of org.graalvm.compiler.nodes.memory.ReadNode in project graal by oracle.
the class ConditionAnchoringTest method test.
public void test(String name, int ids) {
StructuredGraph graph = parseEager(name, AllowAssumptions.YES);
NodeIterable<RawLoadNode> unsafeNodes = graph.getNodes().filter(RawLoadNode.class);
assertThat(unsafeNodes, hasCount(1));
// lower unsafe load
PhaseContext context = new PhaseContext(getProviders());
LoweringPhase lowering = new LoweringPhase(new CanonicalizerPhase(), StandardLoweringStage.HIGH_TIER);
lowering.apply(graph, context);
unsafeNodes = graph.getNodes().filter(RawLoadNode.class);
NodeIterable<ConditionAnchorNode> conditionAnchors = graph.getNodes().filter(ConditionAnchorNode.class);
NodeIterable<ReadNode> reads = graph.getNodes().filter(ReadNode.class);
assertThat(unsafeNodes, isEmpty());
assertThat(conditionAnchors, hasCount(1));
// 2 * ids id reads, 1 'field' access
assertThat(reads, hasCount(2 * ids + 1));
// float reads and canonicalize to give a chance to conditions to GVN
FloatingReadPhase floatingReadPhase = new FloatingReadPhase();
floatingReadPhase.apply(graph);
CanonicalizerPhase canonicalizerPhase = new CanonicalizerPhase();
canonicalizerPhase.apply(graph, context);
NodeIterable<FloatingReadNode> floatingReads = graph.getNodes().filter(FloatingReadNode.class);
// 1 id read, 1 'field' access
assertThat(floatingReads, hasCount(ids + 1));
new ConditionalEliminationPhase(false).apply(graph, context);
floatingReads = graph.getNodes().filter(FloatingReadNode.class).filter(n -> ((FloatingReadNode) n).getLocationIdentity() instanceof ObjectLocationIdentity);
conditionAnchors = graph.getNodes().filter(ConditionAnchorNode.class);
assertThat(floatingReads, hasCount(1));
assertThat(conditionAnchors, isEmpty());
FloatingReadNode readNode = floatingReads.first();
assertThat(readNode.getGuard(), instanceOf(BeginNode.class));
assertThat(readNode.getGuard().asNode().predecessor(), instanceOf(IfNode.class));
}
use of org.graalvm.compiler.nodes.memory.ReadNode in project graal by oracle.
the class AddressLoweringByUsePhase method run.
@Override
protected void run(StructuredGraph graph) {
// first replace address nodes hanging off known usages
for (Node node : graph.getNodes()) {
AddressNode address;
AddressNode lowered;
if (node instanceof ReadNode) {
ReadNode readNode = (ReadNode) node;
Stamp stamp = readNode.stamp(NodeView.DEFAULT);
address = readNode.getAddress();
lowered = lowering.lower(readNode, stamp, address);
} else if (node instanceof JavaReadNode) {
JavaReadNode javaReadNode = (JavaReadNode) node;
Stamp stamp = javaReadNode.stamp(NodeView.DEFAULT);
address = javaReadNode.getAddress();
lowered = lowering.lower(javaReadNode, stamp, address);
} else if (node instanceof FloatingReadNode) {
FloatingReadNode floatingReadNode = (FloatingReadNode) node;
Stamp stamp = floatingReadNode.stamp(NodeView.DEFAULT);
address = floatingReadNode.getAddress();
lowered = lowering.lower(floatingReadNode, stamp, address);
} else if (node instanceof AbstractWriteNode) {
AbstractWriteNode abstractWriteNode = (AbstractWriteNode) node;
Stamp stamp = abstractWriteNode.value().stamp(NodeView.DEFAULT);
address = abstractWriteNode.getAddress();
lowered = lowering.lower(abstractWriteNode, stamp, address);
} else if (node instanceof PrefetchAllocateNode) {
PrefetchAllocateNode prefetchAllocateNode = (PrefetchAllocateNode) node;
Stamp stamp = StampFactory.forKind(JavaKind.Object);
address = (AddressNode) prefetchAllocateNode.inputs().first();
lowered = lowering.lower(prefetchAllocateNode, stamp, address);
} else {
continue;
}
// in which case we want to use it not delete it!
if (lowered != address) {
// replace original with lowered at this usage only
// n.b. lowered is added unique so repeat lowerings will elide
node.replaceFirstInput(address, lowered);
// if that was the last reference we can kill the old (dead) node
if (address.hasNoUsages()) {
GraphUtil.killWithUnusedFloatingInputs(address);
}
}
}
// now replace any remaining unlowered address nodes
for (Node node : graph.getNodes()) {
AddressNode lowered;
if (node instanceof OffsetAddressNode) {
AddressNode address = (AddressNode) node;
lowered = lowering.lower(address);
} else {
continue;
}
// will always be a new AddresNode
node.replaceAtUsages(lowered);
GraphUtil.killWithUnusedFloatingInputs(node);
}
}
use of org.graalvm.compiler.nodes.memory.ReadNode in project graal by oracle.
the class DefaultHotSpotLoweringProvider method createReadVirtualMethod.
private ReadNode createReadVirtualMethod(StructuredGraph graph, ValueNode hub, int vtableEntryOffset) {
assert vtableEntryOffset > 0;
// We use LocationNode.ANY_LOCATION for the reads that access the vtable
// entry as HotSpot does not guarantee that this is a final value.
Stamp methodStamp = MethodPointerStamp.methodNonNull();
AddressNode address = createOffsetAddress(graph, hub, vtableEntryOffset);
ReadNode metaspaceMethod = graph.add(new ReadNode(address, any(), methodStamp, BarrierType.NONE));
return metaspaceMethod;
}
use of org.graalvm.compiler.nodes.memory.ReadNode in project graal by oracle.
the class DefaultHotSpotLoweringProvider method lowerOSRStartNode.
private void lowerOSRStartNode(OSRStartNode osrStart) {
StructuredGraph graph = osrStart.graph();
if (graph.getGuardsStage() == StructuredGraph.GuardsStage.FIXED_DEOPTS) {
StartNode newStart = graph.add(new StartNode());
ParameterNode buffer = graph.addWithoutUnique(new ParameterNode(0, StampPair.createSingle(StampFactory.forKind(runtime.getTarget().wordJavaKind))));
ForeignCallNode migrationEnd = graph.add(new ForeignCallNode(foreignCalls, OSR_MIGRATION_END, buffer));
migrationEnd.setStateAfter(osrStart.stateAfter());
newStart.setNext(migrationEnd);
FixedNode next = osrStart.next();
osrStart.setNext(null);
migrationEnd.setNext(next);
graph.setStart(newStart);
final int wordSize = target.wordSize;
// @formatter:off
// taken from c2 locals_addr = osr_buf + (max_locals-1)*wordSize)
// @formatter:on
int localsOffset = (graph.method().getMaxLocals() - 1) * wordSize;
for (OSRLocalNode osrLocal : graph.getNodes(OSRLocalNode.TYPE)) {
int size = osrLocal.getStackKind().getSlotCount();
int offset = localsOffset - (osrLocal.index() + size - 1) * wordSize;
AddressNode address = createOffsetAddress(graph, buffer, offset);
ReadNode load = graph.add(new ReadNode(address, any(), osrLocal.stamp(NodeView.DEFAULT), BarrierType.NONE));
osrLocal.replaceAndDelete(load);
graph.addBeforeFixed(migrationEnd, load);
}
// @formatter:off
// taken from c2 monitors_addr = osr_buf + (max_locals+mcnt*2-1)*wordSize);
// @formatter:on
final int lockCount = osrStart.stateAfter().locksSize();
final int locksOffset = (graph.method().getMaxLocals() + lockCount * 2 - 1) * wordSize;
// buffer
for (OSRMonitorEnterNode osrMonitorEnter : graph.getNodes(OSRMonitorEnterNode.TYPE)) {
MonitorIdNode monitorID = osrMonitorEnter.getMonitorId();
OSRLockNode lock = (OSRLockNode) osrMonitorEnter.object();
final int index = lock.index();
final int offsetDisplacedHeader = locksOffset - ((index * 2) + 1) * wordSize;
final int offsetLockObject = locksOffset - index * 2 * wordSize;
// load the displaced mark from the osr buffer
AddressNode addressDisplacedHeader = createOffsetAddress(graph, buffer, offsetDisplacedHeader);
ReadNode loadDisplacedHeader = graph.add(new ReadNode(addressDisplacedHeader, any(), lock.stamp(NodeView.DEFAULT), BarrierType.NONE));
graph.addBeforeFixed(migrationEnd, loadDisplacedHeader);
// we need to initialize the stack slot for the lock
BeginLockScopeNode beginLockScope = graph.add(new BeginLockScopeNode(lock.getStackKind(), monitorID.getLockDepth()));
graph.addBeforeFixed(migrationEnd, beginLockScope);
// write the displaced mark to the correct stack slot
AddressNode addressDisplacedMark = createOffsetAddress(graph, beginLockScope, runtime.getVMConfig().basicLockDisplacedHeaderOffset);
WriteNode writeStackSlot = graph.add(new WriteNode(addressDisplacedMark, DISPLACED_MARK_WORD_LOCATION, loadDisplacedHeader, BarrierType.NONE));
graph.addBeforeFixed(migrationEnd, writeStackSlot);
// load the lock object from the osr buffer
AddressNode addressLockObject = createOffsetAddress(graph, buffer, offsetLockObject);
ReadNode loadObject = graph.add(new ReadNode(addressLockObject, any(), lock.stamp(NodeView.DEFAULT), BarrierType.NONE));
lock.replaceAndDelete(loadObject);
graph.addBeforeFixed(migrationEnd, loadObject);
}
osrStart.replaceAtUsagesAndDelete(newStart);
}
}
use of org.graalvm.compiler.nodes.memory.ReadNode in project graal by oracle.
the class HotSpotGraphBuilderPlugins method registerThreadPlugins.
private static void registerThreadPlugins(InvocationPlugins plugins, MetaAccessProvider metaAccess, WordTypes wordTypes, GraalHotSpotVMConfig config, BytecodeProvider bytecodeProvider) {
Registration r = new Registration(plugins, Thread.class, bytecodeProvider);
r.register0("currentThread", new InvocationPlugin() {
@Override
public boolean apply(GraphBuilderContext b, ResolvedJavaMethod targetMethod, Receiver receiver) {
CurrentJavaThreadNode thread = b.add(new CurrentJavaThreadNode(wordTypes.getWordKind()));
ValueNode offset = b.add(ConstantNode.forLong(config.threadObjectOffset));
AddressNode address = b.add(new OffsetAddressNode(thread, offset));
// JavaThread::_threadObj is never compressed
ObjectStamp stamp = StampFactory.objectNonNull(TypeReference.create(b.getAssumptions(), metaAccess.lookupJavaType(Thread.class)));
b.addPush(JavaKind.Object, new ReadNode(address, JAVA_THREAD_THREAD_OBJECT_LOCATION, stamp, BarrierType.NONE));
return true;
}
});
r.registerMethodSubstitution(ThreadSubstitutions.class, "isInterrupted", Receiver.class, boolean.class);
}
Aggregations