Search in sources :

Example 1 with Pair

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;
}
Also used : BranchInstruction(org.apache.bcel.generic.BranchInstruction) InstructionHandle(org.apache.bcel.generic.InstructionHandle) CallString(com.jopdesign.common.code.CallString) Pair(com.jopdesign.common.graphutils.Pair)

Example 2 with Pair

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);
}
Also used : MONITORENTER(org.apache.bcel.generic.MONITORENTER) InstructionHandle(org.apache.bcel.generic.InstructionHandle) MONITOREXIT(org.apache.bcel.generic.MONITOREXIT) HashSet(java.util.HashSet) CFGEdge(com.jopdesign.common.code.ControlFlowGraph.CFGEdge) Pair(com.jopdesign.common.graphutils.Pair) CFGNode(com.jopdesign.common.code.ControlFlowGraph.CFGNode) Stack(java.util.Stack) ContextCFG(com.jopdesign.common.code.SuperGraph.ContextCFG) SuperGraphEdge(com.jopdesign.common.code.SuperGraph.SuperGraphEdge)

Example 3 with Pair

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;
}
Also used : MethodInfo(com.jopdesign.common.MethodInfo) List(java.util.List) LinkedHashMap(java.util.LinkedHashMap) Pair(com.jopdesign.common.graphutils.Pair)

Example 4 with Pair

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();
    }
}
Also used : PrintStream(java.io.PrintStream) UnsupportedEncodingException(java.io.UnsupportedEncodingException) ByteArrayOutputStream(java.io.ByteArrayOutputStream) InstructionHandle(org.apache.bcel.generic.InstructionHandle) ContextMap(com.jopdesign.dfa.framework.ContextMap) ValueMapping(com.jopdesign.dfa.analyses.ValueMapping) CallString(com.jopdesign.common.code.CallString) AnalysisResultSerialization(com.jopdesign.dfa.framework.AnalysisResultSerialization) Pair(com.jopdesign.common.graphutils.Pair)

Example 5 with Pair

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);
        }
    }
}
Also used : FlowEdge(com.jopdesign.dfa.framework.FlowEdge) SerializedFlowEdge(com.jopdesign.dfa.framework.FlowEdge.SerializedFlowEdge) LinkedHashSet(java.util.LinkedHashSet) Context(com.jopdesign.dfa.framework.Context) Set(java.util.Set) LinkedHashSet(java.util.LinkedHashSet) InstructionHandle(org.apache.bcel.generic.InstructionHandle) ContextMap(com.jopdesign.dfa.framework.ContextMap) CallString(com.jopdesign.common.code.CallString) LinkedHashMap(java.util.LinkedHashMap) Map(java.util.Map) LinkedHashMap(java.util.LinkedHashMap) ContextMap(com.jopdesign.dfa.framework.ContextMap) Pair(com.jopdesign.common.graphutils.Pair)

Aggregations

Pair (com.jopdesign.common.graphutils.Pair)5 InstructionHandle (org.apache.bcel.generic.InstructionHandle)4 CallString (com.jopdesign.common.code.CallString)3 ContextMap (com.jopdesign.dfa.framework.ContextMap)2 LinkedHashMap (java.util.LinkedHashMap)2 MethodInfo (com.jopdesign.common.MethodInfo)1 CFGEdge (com.jopdesign.common.code.ControlFlowGraph.CFGEdge)1 CFGNode (com.jopdesign.common.code.ControlFlowGraph.CFGNode)1 ContextCFG (com.jopdesign.common.code.SuperGraph.ContextCFG)1 SuperGraphEdge (com.jopdesign.common.code.SuperGraph.SuperGraphEdge)1 ValueMapping (com.jopdesign.dfa.analyses.ValueMapping)1 AnalysisResultSerialization (com.jopdesign.dfa.framework.AnalysisResultSerialization)1 Context (com.jopdesign.dfa.framework.Context)1 FlowEdge (com.jopdesign.dfa.framework.FlowEdge)1 SerializedFlowEdge (com.jopdesign.dfa.framework.FlowEdge.SerializedFlowEdge)1 ByteArrayOutputStream (java.io.ByteArrayOutputStream)1 PrintStream (java.io.PrintStream)1 UnsupportedEncodingException (java.io.UnsupportedEncodingException)1 HashSet (java.util.HashSet)1 LinkedHashSet (java.util.LinkedHashSet)1