use of org.graalvm.compiler.graph.Node in project graal by oracle.
the class DefaultJavaLoweringProvider method finishAllocatedObjects.
public void finishAllocatedObjects(LoweringTool tool, CommitAllocationNode commit, ValueNode[] allocations) {
StructuredGraph graph = commit.graph();
for (int objIndex = 0; objIndex < commit.getVirtualObjects().size(); objIndex++) {
FixedValueAnchorNode anchor = graph.add(new FixedValueAnchorNode(allocations[objIndex]));
allocations[objIndex] = anchor;
graph.addBeforeFixed(commit, anchor);
}
/*
* Note that the FrameState that is assigned to these MonitorEnterNodes isn't the correct
* state. It will be the state from before the allocation occurred instead of a valid state
* after the locking is performed. In practice this should be fine since these are newly
* allocated objects. The bytecodes themselves permit allocating an object, doing a
* monitorenter and then dropping all references to the object which would produce the same
* state, though that would normally produce an IllegalMonitorStateException. In HotSpot
* some form of fast path locking should always occur so the FrameState should never
* actually be used.
*/
ArrayList<MonitorEnterNode> enters = null;
for (int objIndex = 0; objIndex < commit.getVirtualObjects().size(); objIndex++) {
List<MonitorIdNode> locks = commit.getLocks(objIndex);
if (locks.size() > 1) {
// Ensure that the lock operations are performed in lock depth order
ArrayList<MonitorIdNode> newList = new ArrayList<>(locks);
newList.sort((a, b) -> Integer.compare(a.getLockDepth(), b.getLockDepth()));
locks = newList;
}
int lastDepth = -1;
for (MonitorIdNode monitorId : locks) {
assert lastDepth < monitorId.getLockDepth();
lastDepth = monitorId.getLockDepth();
MonitorEnterNode enter = graph.add(new MonitorEnterNode(allocations[objIndex], monitorId));
graph.addBeforeFixed(commit, enter);
if (enters == null) {
enters = new ArrayList<>();
}
enters.add(enter);
}
}
for (Node usage : commit.usages().snapshot()) {
if (usage instanceof AllocatedObjectNode) {
AllocatedObjectNode addObject = (AllocatedObjectNode) usage;
int index = commit.getVirtualObjects().indexOf(addObject.getVirtualObject());
addObject.replaceAtUsagesAndDelete(allocations[index]);
} else {
assert enters != null;
commit.replaceAtUsages(InputType.Memory, enters.get(enters.size() - 1));
}
}
if (enters != null) {
for (MonitorEnterNode enter : enters) {
enter.lower(tool);
}
}
assert commit.hasNoUsages();
insertAllocationBarrier(commit, graph);
}
use of org.graalvm.compiler.graph.Node in project graal by oracle.
the class PEGraphDecoder method canonicalizeFixedNode.
@SuppressWarnings("try")
@Override
protected Node canonicalizeFixedNode(MethodScope s, Node node) {
PEMethodScope methodScope = (PEMethodScope) s;
Node replacedNode = node;
if (nodePlugins != null && nodePlugins.length > 0) {
if (node instanceof LoadFieldNode) {
LoadFieldNode loadFieldNode = (LoadFieldNode) node;
PEAppendGraphBuilderContext graphBuilderContext = new PEAppendGraphBuilderContext(methodScope, loadFieldNode);
ResolvedJavaField field = loadFieldNode.field();
if (loadFieldNode.isStatic()) {
for (NodePlugin nodePlugin : nodePlugins) {
if (nodePlugin.handleLoadStaticField(graphBuilderContext, field)) {
replacedNode = graphBuilderContext.pushedNode;
break;
}
}
} else {
ValueNode object = loadFieldNode.object();
for (NodePlugin nodePlugin : nodePlugins) {
if (nodePlugin.handleLoadField(graphBuilderContext, object, field)) {
replacedNode = graphBuilderContext.pushedNode;
break;
}
}
}
} else if (node instanceof StoreFieldNode) {
StoreFieldNode storeFieldNode = (StoreFieldNode) node;
PEAppendGraphBuilderContext graphBuilderContext = new PEAppendGraphBuilderContext(methodScope, storeFieldNode);
ResolvedJavaField field = storeFieldNode.field();
if (storeFieldNode.isStatic()) {
ValueNode value = storeFieldNode.value();
for (NodePlugin nodePlugin : nodePlugins) {
if (nodePlugin.handleStoreStaticField(graphBuilderContext, field, value)) {
replacedNode = graphBuilderContext.pushedNode;
break;
}
}
} else {
ValueNode object = storeFieldNode.object();
ValueNode value = storeFieldNode.value();
for (NodePlugin nodePlugin : nodePlugins) {
if (nodePlugin.handleStoreField(graphBuilderContext, object, field, value)) {
replacedNode = graphBuilderContext.pushedNode;
break;
}
}
}
} else if (node instanceof LoadIndexedNode) {
LoadIndexedNode loadIndexedNode = (LoadIndexedNode) node;
PEAppendGraphBuilderContext graphBuilderContext = new PEAppendGraphBuilderContext(methodScope, loadIndexedNode);
ValueNode array = loadIndexedNode.array();
ValueNode index = loadIndexedNode.index();
for (NodePlugin nodePlugin : nodePlugins) {
if (nodePlugin.handleLoadIndexed(graphBuilderContext, array, index, loadIndexedNode.elementKind())) {
replacedNode = graphBuilderContext.pushedNode;
break;
}
}
} else if (node instanceof StoreIndexedNode) {
StoreIndexedNode storeIndexedNode = (StoreIndexedNode) node;
PEAppendGraphBuilderContext graphBuilderContext = new PEAppendGraphBuilderContext(methodScope, storeIndexedNode);
ValueNode array = storeIndexedNode.array();
ValueNode index = storeIndexedNode.index();
ValueNode value = storeIndexedNode.value();
for (NodePlugin nodePlugin : nodePlugins) {
if (nodePlugin.handleStoreIndexed(graphBuilderContext, array, index, storeIndexedNode.elementKind(), value)) {
replacedNode = graphBuilderContext.pushedNode;
break;
}
}
} else if (node instanceof NewInstanceNode) {
NewInstanceNode newInstanceNode = (NewInstanceNode) node;
PEAppendGraphBuilderContext graphBuilderContext = new PEAppendGraphBuilderContext(methodScope, newInstanceNode);
ResolvedJavaType type = newInstanceNode.instanceClass();
for (NodePlugin nodePlugin : nodePlugins) {
if (nodePlugin.handleNewInstance(graphBuilderContext, type)) {
replacedNode = graphBuilderContext.pushedNode;
break;
}
}
} else if (node instanceof NewArrayNode) {
NewArrayNode newArrayNode = (NewArrayNode) node;
PEAppendGraphBuilderContext graphBuilderContext = new PEAppendGraphBuilderContext(methodScope, newArrayNode);
ResolvedJavaType elementType = newArrayNode.elementType();
ValueNode length = newArrayNode.length();
for (NodePlugin nodePlugin : nodePlugins) {
if (nodePlugin.handleNewArray(graphBuilderContext, elementType, length)) {
replacedNode = graphBuilderContext.pushedNode;
break;
}
}
} else if (node instanceof NewMultiArrayNode) {
NewMultiArrayNode newArrayNode = (NewMultiArrayNode) node;
PEAppendGraphBuilderContext graphBuilderContext = new PEAppendGraphBuilderContext(methodScope, newArrayNode);
ResolvedJavaType elementType = newArrayNode.type();
ValueNode[] dimensions = newArrayNode.dimensions().toArray(new ValueNode[0]);
for (NodePlugin nodePlugin : nodePlugins) {
if (nodePlugin.handleNewMultiArray(graphBuilderContext, elementType, dimensions)) {
replacedNode = graphBuilderContext.pushedNode;
break;
}
}
}
}
return super.canonicalizeFixedNode(methodScope, replacedNode);
}
use of org.graalvm.compiler.graph.Node in project graal by oracle.
the class IntegerExactFoldTest method testFolding.
@Test
public void testFolding() {
StructuredGraph graph = prepareGraph();
IntegerStamp a = StampFactory.forInteger(bits, lowerBoundA, upperBoundA);
IntegerStamp b = StampFactory.forInteger(bits, lowerBoundB, upperBoundB);
List<ParameterNode> params = graph.getNodes(ParameterNode.TYPE).snapshot();
params.get(0).replaceAtMatchingUsages(graph.addOrUnique(new PiNode(params.get(0), a)), x -> x instanceof IntegerExactArithmeticNode);
params.get(1).replaceAtMatchingUsages(graph.addOrUnique(new PiNode(params.get(1), b)), x -> x instanceof IntegerExactArithmeticNode);
Node originalNode = graph.getNodes().filter(x -> x instanceof IntegerExactArithmeticNode).first();
assertNotNull("original node must be in the graph", originalNode);
new CanonicalizerPhase().apply(graph, getDefaultHighTierContext());
ValueNode node = findNode(graph);
boolean overflowExpected = node instanceof IntegerExactArithmeticNode;
IntegerStamp resultStamp = (IntegerStamp) node.stamp(NodeView.DEFAULT);
operation.verifyOverflow(lowerBoundA, upperBoundA, lowerBoundB, upperBoundB, bits, overflowExpected, resultStamp);
}
use of org.graalvm.compiler.graph.Node in project graal by oracle.
the class VerifyVirtualizableUsage method verifyVirtualizableEffectArguments.
private static void verifyVirtualizableEffectArguments(ResolvedJavaType constantNodeType, ResolvedJavaMethod caller, ResolvedJavaMethod callee, int bciCaller, NodeInputList<? extends Node> arguments, int startIdx) {
/*
* Virtualizable.virtualize should never apply effects on the graph during the execution of
* the call as the handling of loops during pea might be speculative and does not hold. We
* should only allow nodes changing the graph that do no harm like constants.
*/
int i = 0;
for (Node arg : arguments) {
if (i >= startIdx) {
Stamp argStamp = ((ValueNode) arg).stamp(NodeView.DEFAULT);
if (argStamp instanceof ObjectStamp) {
ObjectStamp objectStamp = (ObjectStamp) argStamp;
ResolvedJavaType argStampType = objectStamp.type();
if (!(argStampType.equals(constantNodeType))) {
StackTraceElement e = caller.asStackTraceElement(bciCaller);
throw new VerificationError("%s:Parameter %d in call to %s (which has effects on the graph) is not a " + "constant and thus not safe to apply during speculative virtualization.", e, i, callee.format("%H.%n(%p)"));
}
}
}
i++;
}
}
use of org.graalvm.compiler.graph.Node in project graal by oracle.
the class BinaryGraphPrinter method blockNodes.
@Override
public List<Node> blockNodes(GraphInfo info, Block block) {
List<Node> nodes = info.blockToNodes.get(block);
if (nodes == null) {
return null;
}
List<Node> extraNodes = new LinkedList<>();
for (Node node : nodes) {
findExtraNodes(node, extraNodes);
}
extraNodes.removeAll(nodes);
extraNodes.addAll(0, nodes);
return extraNodes;
}
Aggregations