package org.graalvm.compiler.phases.common.instrumentation;
import static org.graalvm.compiler.core.common.CompilationIdentifier.INVALID_COMPILATION_ID;
import java.util.Collections;
import java.util.Map;
import org.graalvm.compiler.core.common.type.StampPair;
import org.graalvm.compiler.debug.Debug;
import org.graalvm.compiler.debug.GraalError;
import org.graalvm.compiler.graph.Node;
import org.graalvm.compiler.graph.NodeBitMap;
import org.graalvm.compiler.graph.NodeFlood;
import org.graalvm.compiler.graph.Position;
import org.graalvm.compiler.nodeinfo.InputType;
import org.graalvm.compiler.nodes.AbstractEndNode;
import org.graalvm.compiler.nodes.AbstractLocalNode;
import org.graalvm.compiler.nodes.FixedNode;
import org.graalvm.compiler.nodes.FrameState;
import org.graalvm.compiler.nodes.LoopEndNode;
import org.graalvm.compiler.nodes.ParameterNode;
import org.graalvm.compiler.nodes.ReturnNode;
import org.graalvm.compiler.nodes.StructuredGraph;
import org.graalvm.compiler.nodes.StructuredGraph.AllowAssumptions;
import org.graalvm.compiler.nodes.ValueNode;
import org.graalvm.compiler.nodes.calc.FloatingNode;
import org.graalvm.compiler.nodes.debug.instrumentation.InstrumentationBeginNode;
import org.graalvm.compiler.nodes.debug.instrumentation.InstrumentationEndNode;
import org.graalvm.compiler.nodes.debug.instrumentation.InstrumentationNode;
import org.graalvm.compiler.nodes.util.GraphUtil;
import org.graalvm.compiler.nodes.virtual.EscapeObjectState;
import org.graalvm.compiler.phases.BasePhase;
import org.graalvm.compiler.phases.common.DeadCodeEliminationPhase;
import org.graalvm.compiler.phases.tiers.HighTierContext;
public class extends BasePhase<HighTierContext> {
@Override
protected void (StructuredGraph graph, HighTierContext context) {
for (InstrumentationBeginNode begin : graph.getNodes().filter(InstrumentationBeginNode.class)) {
Instrumentation instrumentation = new Instrumentation(begin);
if (begin.isAnchored() || begin.getTarget() != null) {
InstrumentationNode instrumentationNode = graph.addWithoutUnique(new InstrumentationNode(begin.getTarget(), begin.isAnchored()));
graph.addBeforeFixed(begin, instrumentationNode);
FrameState currentState = begin.stateAfter();
FrameState newState = graph.addWithoutUnique(new FrameState(currentState.outerFrameState(), currentState.getCode(), currentState.bci, 0, 0,
0, currentState.rethrowException(), currentState.duringCall(), null,
Collections.<EscapeObjectState> emptyList()));
instrumentationNode.setStateBefore(newState);
StructuredGraph instrumentationGraph = instrumentation.genInstrumentationGraph(graph, instrumentationNode);
new DeadCodeEliminationPhase().apply(instrumentationGraph, false);
instrumentationNode.setInstrumentationGraph(instrumentationGraph);
Debug.dump(Debug.INFO_LOG_LEVEL, instrumentationGraph, "After extracted instrumentation at %s", instrumentation);
}
instrumentation.unlink();
}
}
private static class {
private InstrumentationBeginNode ;
private InstrumentationEndNode ;
private NodeBitMap ;
(InstrumentationBeginNode begin) {
this.begin = begin;
NodeFlood cfgFlood = begin.graph().createNodeFlood();
cfgFlood.add(begin.next());
for (Node current : cfgFlood) {
if (current instanceof InstrumentationEndNode) {
this.end = (InstrumentationEndNode) current;
} else if (current instanceof LoopEndNode) {
} else if (current instanceof AbstractEndNode) {
cfgFlood.add(((AbstractEndNode) current).merge());
} else {
cfgFlood.addAll(current.successors());
}
}
if (this.end == null) {
throw GraalError.shouldNotReachHere("could not find invocation to instrumentationEnd()");
}
NodeBitMap cfgNodes = cfgFlood.getVisited();
NodeFlood dfgFlood = begin.graph().createNodeFlood();
dfgFlood.addAll(cfgNodes);
dfgFlood.add(begin.stateAfter());
for (Node current : dfgFlood) {
for (Position pos : current.inputPositions()) {
Node input = pos.get(current);
if (pos.getInputType() == InputType.Value) {
if (current instanceof FrameState) {
continue;
}
if (!(input instanceof FloatingNode)) {
continue;
}
if (input instanceof AbstractLocalNode) {
continue;
}
if (shouldIncludeValueInput((FloatingNode) input, cfgNodes)) {
dfgFlood.add(input);
}
} else {
dfgFlood.add(input);
}
}
}
this.nodes = dfgFlood.getVisited();
}
StructuredGraph (StructuredGraph oldGraph, InstrumentationNode instrumentationNode) {
StructuredGraph instrumentationGraph = new StructuredGraph(AllowAssumptions.YES, INVALID_COMPILATION_ID);
Map<Node, Node> replacements = Node.newMap();
int index = 0;
for (Node current : nodes) {
for (Node input : current.inputs()) {
if (input instanceof ValueNode) {
ValueNode valueNode = (ValueNode) input;
if (!nodes.isMarked(input) && !replacements.containsKey(input)) {
ParameterNode parameter = new ParameterNode(index++, StampPair.createSingle(valueNode.stamp()));
instrumentationGraph.addWithoutUnique(parameter);
instrumentationNode.addWeakDependency(valueNode);
replacements.put(input, parameter);
}
}
}
}
replacements = instrumentationGraph.addDuplicates(nodes, oldGraph, nodes.count(), replacements);
instrumentationGraph.start().setNext((FixedNode) replacements.get(begin.next()));
instrumentationGraph.start().setStateAfter((FrameState) replacements.get(begin.stateAfter()));
replacements.get(end).replaceAtPredecessor(instrumentationGraph.addWithoutUnique(new ReturnNode(null)));
return instrumentationGraph;
}
private static boolean (FloatingNode node, NodeBitMap cfgNodes) {
for (Position pos : node.inputPositions()) {
if (pos.getInputType() == InputType.Value) {
continue;
}
Node input = pos.get(node);
if (input instanceof FixedNode && !cfgNodes.isMarked(input)) {
return false;
}
}
return true;
}
void () {
FixedNode next = end.next();
end.setNext(null);
begin.replaceAtPredecessor(next);
GraphUtil.killCFG(begin);
}
}
@Override
public boolean () {
return false;
}
}