use of org.graalvm.compiler.nodes.virtual.VirtualObjectNode in project graal by oracle.
the class PartialEscapeClosure method processNodeInputs.
/**
* This replaces all inputs that point to virtual or materialized values with the actual value,
* materializing if necessary. Also takes care of frame states, adding the necessary
* {@link VirtualObjectState}.
*/
private void processNodeInputs(ValueNode node, FixedNode insertBefore, BlockT state, GraphEffectList effects) {
VirtualUtil.trace(node.getOptions(), debug, "processing nodewithstate: %s", node);
for (Node input : node.inputs()) {
if (input instanceof ValueNode) {
ValueNode alias = getAlias((ValueNode) input);
if (alias instanceof VirtualObjectNode) {
int id = ((VirtualObjectNode) alias).getObjectId();
ensureMaterialized(state, id, insertBefore, effects, COUNTER_MATERIALIZATIONS_UNHANDLED);
effects.replaceFirstInput(node, input, state.getObjectState(id).getMaterializedValue());
VirtualUtil.trace(node.getOptions(), debug, "replacing input %s at %s", input, node);
}
}
}
if (node instanceof NodeWithState) {
processNodeWithState((NodeWithState) node, state, effects);
}
}
use of org.graalvm.compiler.nodes.virtual.VirtualObjectNode in project graal by oracle.
the class PartialEscapeClosure method collectReferencedVirtualObjects.
private void collectReferencedVirtualObjects(BlockT state, EconomicSet<VirtualObjectNode> virtual) {
Iterator<VirtualObjectNode> iterator = virtual.iterator();
while (iterator.hasNext()) {
VirtualObjectNode object = iterator.next();
int id = object.getObjectId();
if (id != -1) {
ObjectState objState = state.getObjectStateOptional(id);
if (objState != null && objState.isVirtual()) {
for (ValueNode entry : objState.getEntries()) {
if (entry instanceof VirtualObjectNode) {
VirtualObjectNode entryVirtual = (VirtualObjectNode) entry;
if (!virtual.contains(entryVirtual)) {
virtual.add(entryVirtual);
}
}
}
}
}
}
}
use of org.graalvm.compiler.nodes.virtual.VirtualObjectNode in project graal by oracle.
the class VirtualizerToolImpl method createVirtualObject.
@Override
public void createVirtualObject(VirtualObjectNode virtualObject, ValueNode[] entryState, List<MonitorIdNode> locks, boolean ensureVirtualized) {
VirtualUtil.trace(options, debug, "{{%s}} ", current);
if (!virtualObject.isAlive()) {
effects.addFloatingNode(virtualObject, "newVirtualObject");
}
for (int i = 0; i < entryState.length; i++) {
ValueNode entry = entryState[i];
entryState[i] = entry instanceof VirtualObjectNode ? entry : closure.getAliasAndResolve(state, entry);
}
int id = virtualObject.getObjectId();
if (id == -1) {
id = closure.virtualObjects.size();
closure.virtualObjects.add(virtualObject);
virtualObject.setObjectId(id);
}
state.addObject(id, new ObjectState(entryState, locks, ensureVirtualized));
closure.addVirtualAlias(virtualObject, virtualObject);
PartialEscapeClosure.COUNTER_ALLOCATION_REMOVED.increment(debug);
effects.addVirtualizationDelta(1);
}
use of org.graalvm.compiler.nodes.virtual.VirtualObjectNode in project graal by oracle.
the class LoopFragment method computeNodes.
protected static void computeNodes(NodeBitMap nodes, Graph graph, Iterable<AbstractBeginNode> blocks, Iterable<AbstractBeginNode> earlyExits) {
for (AbstractBeginNode b : blocks) {
if (b.isDeleted()) {
continue;
}
for (Node n : b.getBlockNodes()) {
if (n instanceof Invoke) {
nodes.mark(((Invoke) n).callTarget());
}
if (n instanceof NodeWithState) {
NodeWithState withState = (NodeWithState) n;
withState.states().forEach(state -> state.applyToVirtual(node -> nodes.mark(node)));
}
if (n instanceof AbstractMergeNode) {
// if a merge is in the loop, all of its phis are also in the loop
for (PhiNode phi : ((AbstractMergeNode) n).phis()) {
nodes.mark(phi);
}
}
nodes.mark(n);
}
}
for (AbstractBeginNode earlyExit : earlyExits) {
if (earlyExit.isDeleted()) {
continue;
}
nodes.mark(earlyExit);
if (earlyExit instanceof LoopExitNode) {
LoopExitNode loopExit = (LoopExitNode) earlyExit;
FrameState stateAfter = loopExit.stateAfter();
if (stateAfter != null) {
stateAfter.applyToVirtual(node -> nodes.mark(node));
}
for (ProxyNode proxy : loopExit.proxies()) {
nodes.mark(proxy);
}
}
}
final NodeBitMap nonLoopNodes = graph.createNodeBitMap();
Deque<WorkListEntry> worklist = new ArrayDeque<>();
for (AbstractBeginNode b : blocks) {
if (b.isDeleted()) {
continue;
}
for (Node n : b.getBlockNodes()) {
if (n instanceof CommitAllocationNode) {
for (VirtualObjectNode obj : ((CommitAllocationNode) n).getVirtualObjects()) {
markFloating(worklist, obj, nodes, nonLoopNodes);
}
}
if (n instanceof MonitorEnterNode) {
markFloating(worklist, ((MonitorEnterNode) n).getMonitorId(), nodes, nonLoopNodes);
}
if (n instanceof AbstractMergeNode) {
/*
* Since we already marked all phi nodes as being in the loop to break cycles,
* we also have to iterate over their usages here.
*/
for (PhiNode phi : ((AbstractMergeNode) n).phis()) {
for (Node usage : phi.usages()) {
markFloating(worklist, usage, nodes, nonLoopNodes);
}
}
}
for (Node usage : n.usages()) {
markFloating(worklist, usage, nodes, nonLoopNodes);
}
}
}
}
use of org.graalvm.compiler.nodes.virtual.VirtualObjectNode in project graal by oracle.
the class DefaultJavaLoweringProvider method lowerCommitAllocationNode.
@SuppressWarnings("try")
protected void lowerCommitAllocationNode(CommitAllocationNode commit, LoweringTool tool) {
StructuredGraph graph = commit.graph();
if (graph.getGuardsStage() == StructuredGraph.GuardsStage.FIXED_DEOPTS) {
List<AbstractNewObjectNode> recursiveLowerings = new ArrayList<>();
ValueNode[] allocations = new ValueNode[commit.getVirtualObjects().size()];
BitSet omittedValues = new BitSet();
int valuePos = 0;
for (int objIndex = 0; objIndex < commit.getVirtualObjects().size(); objIndex++) {
VirtualObjectNode virtual = commit.getVirtualObjects().get(objIndex);
int entryCount = virtual.entryCount();
AbstractNewObjectNode newObject;
try (DebugCloseable nsp = virtual.withNodeSourcePosition()) {
if (virtual instanceof VirtualInstanceNode) {
newObject = graph.add(createNewInstanceFromVirtual(virtual));
} else {
newObject = graph.add(createNewArrayFromVirtual(virtual, ConstantNode.forInt(entryCount, graph)));
}
}
recursiveLowerings.add(newObject);
graph.addBeforeFixed(commit, newObject);
allocations[objIndex] = newObject;
for (int i = 0; i < entryCount; i++) {
ValueNode value = commit.getValues().get(valuePos);
if (value instanceof VirtualObjectNode) {
value = allocations[commit.getVirtualObjects().indexOf(value)];
}
if (value == null) {
omittedValues.set(valuePos);
} else if (!(value.isConstant() && value.asConstant().isDefaultForKind())) {
// Constant.illegal is always the defaultForKind, so it is skipped
JavaKind valueKind = value.getStackKind();
JavaKind entryKind = virtual.entryKind(i);
// Truffle requires some leniency in terms of what can be put where:
assert valueKind.getStackKind() == entryKind.getStackKind() || (valueKind == JavaKind.Long || valueKind == JavaKind.Double || (valueKind == JavaKind.Int && virtual instanceof VirtualArrayNode));
AddressNode address = null;
BarrierType barrierType = null;
if (virtual instanceof VirtualInstanceNode) {
ResolvedJavaField field = ((VirtualInstanceNode) virtual).field(i);
long offset = fieldOffset(field);
if (offset >= 0) {
address = createOffsetAddress(graph, newObject, offset);
barrierType = fieldInitializationBarrier(entryKind);
}
} else {
address = createOffsetAddress(graph, newObject, arrayBaseOffset(entryKind) + i * arrayScalingFactor(entryKind));
barrierType = arrayInitializationBarrier(entryKind);
}
if (address != null) {
WriteNode write = new WriteNode(address, LocationIdentity.init(), implicitStoreConvert(graph, entryKind, value), barrierType);
graph.addAfterFixed(newObject, graph.add(write));
}
}
valuePos++;
}
}
valuePos = 0;
for (int objIndex = 0; objIndex < commit.getVirtualObjects().size(); objIndex++) {
VirtualObjectNode virtual = commit.getVirtualObjects().get(objIndex);
int entryCount = virtual.entryCount();
ValueNode newObject = allocations[objIndex];
for (int i = 0; i < entryCount; i++) {
if (omittedValues.get(valuePos)) {
ValueNode value = commit.getValues().get(valuePos);
assert value instanceof VirtualObjectNode;
ValueNode allocValue = allocations[commit.getVirtualObjects().indexOf(value)];
if (!(allocValue.isConstant() && allocValue.asConstant().isDefaultForKind())) {
assert virtual.entryKind(i) == JavaKind.Object && allocValue.getStackKind() == JavaKind.Object;
AddressNode address;
BarrierType barrierType;
if (virtual instanceof VirtualInstanceNode) {
VirtualInstanceNode virtualInstance = (VirtualInstanceNode) virtual;
address = createFieldAddress(graph, newObject, virtualInstance.field(i));
barrierType = BarrierType.IMPRECISE;
} else {
address = createArrayAddress(graph, newObject, virtual.entryKind(i), ConstantNode.forInt(i, graph));
barrierType = BarrierType.PRECISE;
}
if (address != null) {
WriteNode write = new WriteNode(address, LocationIdentity.init(), implicitStoreConvert(graph, JavaKind.Object, allocValue), barrierType);
graph.addBeforeFixed(commit, graph.add(write));
}
}
}
valuePos++;
}
}
finishAllocatedObjects(tool, commit, allocations);
graph.removeFixed(commit);
for (AbstractNewObjectNode recursiveLowering : recursiveLowerings) {
recursiveLowering.lower(tool);
}
}
}
Aggregations