use of com.jopdesign.common.graphutils.Pair in project jop by jop-devel.
the class LoopBounds method getBound.
public int getBound(InstructionHandle instr, CallString csSuffix) {
ContextMap<CallString, Pair<ValueMapping, ValueMapping>> r = bounds.get(instr);
if (r == null) {
// no bound at this point
return -1;
}
// merge bound for all contexts
int maxValue = -1;
for (CallString callString : r.keySet()) {
if (!callString.hasSuffix(csSuffix))
continue;
Pair<ValueMapping, ValueMapping> bounds = r.get(callString);
ValueMapping first = bounds.first();
ValueMapping second = bounds.second();
if (first == null || second == null) {
return -1;
}
InstructionHandle target = ((BranchInstruction) instr.getInstruction()).getTarget();
if (scopes.get(target) != null) {
if (scopes.get(target).get(callString) <= first.defscope || scopes.get(target).get(callString) <= second.defscope) {
return -1;
}
}
if (scopes.get(instr).get(callString) <= first.defscope || scopes.get(instr).get(callString) <= second.defscope) {
return -1;
}
// if (first.softinc || second.softinc) {
// return -1;
// }
int val = ValueMapping.computeBound(first, second);
if (val < 0) {
// no bound for some context
return -1;
} else {
// compute the maximum
maxValue = Math.max(maxValue, val);
}
}
return maxValue;
}
use of com.jopdesign.common.graphutils.Pair in project jop by jop-devel.
the class Segment method synchronizedSegment.
/**
* Create an interprocedural segment for a synchronized block. Currently we do
* not split basic blocks here, so either you are happy with basic block granularity,
* or you split the basic block while loading.
* @param targetBlock The block containing the monitorenter instruction
* @param monitorEnter The monitor enter instruction
* @param callString The context for the method
* @param cfgProvider A control flow graph provider
* @param callStringLength Length of the callstrings
* @param infeasibles Information about infeasible edges (null if no information available)
*
* @return a segment representing executions of the synchronized block
*/
public static Segment synchronizedSegment(ContextCFG ccfg, CFGNode entryNode, InstructionHandle monitorEnter, CFGProvider cfgProvider, int callStringLength, InfeasibleEdgeProvider infeasibles) {
if (infeasibles == null) {
infeasibles = InfeasibleEdgeProvider.NO_INFEASIBLES;
}
ControlFlowGraph cfg = ccfg.getCfg();
SuperGraph superGraph = new SuperGraph(cfgProvider, cfg, ccfg.getCallString(), callStringLength, infeasibles);
ContextCFG rootMethod = superGraph.getRootNode();
/* lift entry edges */
Set<SuperGraphEdge> entryEdges = Iterators.addAll(new HashSet<SuperGraphEdge>(), superGraph.liftCFGEdges(rootMethod, cfg.incomingEdgesOf(entryNode)));
/* find exit blocks (might also be in the same block) */
/* monitorenter followed bei monitorexit in same block => segment only contains this block */
Set<CFGEdge> monitorExitEdges = new HashSet<CFGEdge>();
CFGNode currentNode = entryNode;
int currentNestingLevel = 1;
Iterator<InstructionHandle> insIter = currentNode.getBasicBlock().getInstructions().iterator();
while (insIter.hasNext()) {
if (insIter.next() == monitorEnter)
break;
}
Stack<Pair<CFGNode, Integer>> todo = new Stack<Pair<CFGNode, Integer>>();
Set<CFGNode> visited = new HashSet<CFGNode>();
do {
boolean isExit = false;
while (insIter.hasNext()) {
InstructionHandle ih = insIter.next();
if (ih.getInstruction() instanceof MONITOREXIT) {
/* blocks outgoing edges terminate segment */
currentNestingLevel--;
if (currentNestingLevel == 0) {
isExit = true;
// If monitorexit is not implemented in Java, the outgoing edges of the
// basic block that contains monitorexit end the synchronized block.
// In order to avoid imprecision, it is advisable that monitorexit is the
// last statement in the basic block.
// We also handle the case when monitorexit is implemented in Java. In this case,
// currentNode will be a SpecialInvokeNode, urrentNode's only
// successor will be the corresponding ReturnNode, and the outgoing edges of
// the ReturnNode are the exit edges for the synchronized segment.
CFGNode onlySuccessor = Iterators.fromSingleton(cfg.getSuccessors(currentNode));
if (onlySuccessor != null && onlySuccessor instanceof ControlFlowGraph.ReturnNode) {
Iterators.addAll(monitorExitEdges, cfg.outgoingEdgesOf(onlySuccessor));
} else {
Iterators.addAll(monitorExitEdges, cfg.outgoingEdgesOf(currentNode));
}
break;
}
} else if (ih.getInstruction() instanceof MONITORENTER) {
currentNestingLevel++;
}
}
if (!isExit) {
for (CFGNode node : cfg.getSuccessors(currentNode)) {
todo.add(new Pair<CFGNode, Integer>(node, currentNestingLevel));
}
}
currentNode = null;
while (!todo.isEmpty()) {
Pair<CFGNode, Integer> nextPair = todo.pop();
CFGNode nextNode = nextPair.first();
if (!visited.contains(nextNode)) {
visited.add(nextNode);
if (cfg.outgoingEdgesOf(nextNode).isEmpty()) {
throw new AssertionError("Found monitor-exit free path from monitorenter to the end of a function. In: " + cfg);
} else if (nextNode.getBasicBlock() == null) {
for (CFGNode node : cfg.getSuccessors(nextNode)) {
todo.add(new Pair<CFGNode, Integer>(node, nextPair.second()));
}
} else {
currentNode = nextNode;
currentNestingLevel = nextPair.second();
insIter = currentNode.getBasicBlock().getInstructions().iterator();
break;
}
}
}
} while (currentNode != null);
Set<SuperGraphEdge> exitEdges = Iterators.addAll(new HashSet<SuperGraphEdge>(), superGraph.liftCFGEdges(rootMethod, monitorExitEdges));
return new Segment(superGraph, entryEdges, exitEdges);
}
use of com.jopdesign.common.graphutils.Pair in project jop by jop-devel.
the class SuperGraph method getCallSites.
/**
* @return return all callsite invoke/return superedge pairs, grouped by the invoked method
*/
public Map<MethodInfo, List<Pair<SuperInvokeEdge, SuperReturnEdge>>> getCallSites() {
Map<MethodInfo, List<Pair<SuperInvokeEdge, SuperReturnEdge>>> iMap = new LinkedHashMap<MethodInfo, List<Pair<SuperInvokeEdge, SuperReturnEdge>>>();
for (ContextCFG node : superGraph.vertexSet()) {
List<Pair<SuperInvokeEdge, SuperReturnEdge>> callSites = getCallSitesInvoking(node);
MethodInfo invoked = node.getCfg().getMethodInfo();
if (iMap.containsKey(invoked)) {
callSites.addAll(iMap.get(invoked));
}
iMap.put(invoked, callSites);
}
return iMap;
}
use of com.jopdesign.common.graphutils.Pair in project jop by jop-devel.
the class DFATool method dumpDFA.
public String dumpDFA(MethodInfo method) {
if (getLoopBounds() == null)
return "n/a";
if (method.isAbstract()) {
return "n/a";
}
ByteArrayOutputStream baos = new ByteArrayOutputStream();
PrintStream os = new PrintStream(baos);
Map<InstructionHandle, ContextMap<CallString, Pair<ValueMapping, ValueMapping>>> results = getLoopBounds().getResult();
if (results == null)
return "n/a";
AnalysisResultSerialization<Pair<ValueMapping, ValueMapping>> printer = new AnalysisResultSerialization<Pair<ValueMapping, ValueMapping>>();
for (Entry<InstructionHandle, ContextMap<CallString, Pair<ValueMapping, ValueMapping>>> ihEntry : results.entrySet()) {
for (Entry<CallString, Pair<ValueMapping, ValueMapping>> csEntry : ihEntry.getValue().entrySet()) {
if (ihEntry.getValue().getContext().getMethodInfo().equals(method)) {
printer.addResult(method, ihEntry.getKey().getPosition(), csEntry.getKey(), csEntry.getValue());
}
}
}
printer.dump(os);
try {
return baos.toString("UTF-8");
} catch (UnsupportedEncodingException e) {
return baos.toString();
}
}
use of com.jopdesign.common.graphutils.Pair in project jop by jop-devel.
the class LoopBounds method copyResults.
@Override
public void copyResults(MethodInfo newContainer, Map<InstructionHandle, InstructionHandle> newHandles) {
for (Map.Entry<InstructionHandle, InstructionHandle> entry : newHandles.entrySet()) {
InstructionHandle oldHandle = entry.getKey();
InstructionHandle newHandle = entry.getValue();
if (newHandle == null)
continue;
// TODO support updating the callstrings too
// TODO this does NOT update stackPtr,.. in the new context!
ContextMap<CallString, Pair<ValueMapping, ValueMapping>> value = bounds.get(oldHandle);
if (value != null)
bounds.put(newHandle, value.copy(newContainer));
ContextMap<CallString, Interval> value1 = arrayIndices.get(oldHandle);
if (value1 != null)
arrayIndices.put(newHandle, value1.copy(newContainer));
ContextMap<CallString, Integer> value2 = scopes.get(oldHandle);
if (value2 != null)
scopes.put(newHandle, value2.copy(newContainer));
ContextMap<CallString, Interval[]> value3 = sizes.get(oldHandle);
if (value3 != null)
sizes.put(newHandle, value3.copy(newContainer));
ContextMap<CallString, Set<FlowEdge>> old = infeasibles.get(oldHandle);
if (old != null) {
Map<CallString, Set<FlowEdge>> map = new LinkedHashMap<CallString, Set<FlowEdge>>(old.size());
for (CallString cs : old.keySet()) {
Set<FlowEdge> newSet = new LinkedHashSet<FlowEdge>();
for (FlowEdge edge : old.get(cs)) {
InstructionHandle newHead = newHandles.get(edge.getHead());
InstructionHandle newTail = newHandles.get(edge.getTail());
if (newHead != null && newTail != null) {
Context ctx = new Context(edge.getContext());
ctx.setMethodInfo(newContainer);
newSet.add(new FlowEdge(newTail, newHead, edge.getType(), ctx));
}
}
map.put(cs, newSet);
}
Context c = old.getContext();
c.setMethodInfo(newContainer);
ContextMap<CallString, Set<FlowEdge>> edges = new ContextMap<CallString, Set<FlowEdge>>(c, map);
infeasibles.put(newHandle, edges);
}
}
}
Aggregations