Search in sources :

Example 11 with ExceptionalUnitGraph

use of soot.toolkits.graph.ExceptionalUnitGraph in project soot by Sable.

the class SmartLocalDefsPool method getSmartLocalDefsFor.

/**
 * This method returns a fresh instance of a {@link SmartLocalDefs} analysis, based
 * on a freshly created {@link ExceptionalUnitGraph} for b, with standard parameters.
 * If the body b's modification count has not changed since the last time such an analysis
 * was requested for b, then the previously created analysis is returned instead.
 * @see Body#getModificationCount()
 */
public SmartLocalDefs getSmartLocalDefsFor(Body b) {
    Pair<Long, SmartLocalDefs> modCountAndSLD = pool.get(b);
    if (modCountAndSLD != null && modCountAndSLD.o1.longValue() == b.getModificationCount()) {
        return modCountAndSLD.o2;
    } else {
        ExceptionalUnitGraph g = new ExceptionalUnitGraph(b);
        SmartLocalDefs newSLD = new SmartLocalDefs(g, new SimpleLiveLocals(g));
        pool.put(b, new Pair<Long, SmartLocalDefs>(b.getModificationCount(), newSLD));
        return newSLD;
    }
}
Also used : ExceptionalUnitGraph(soot.toolkits.graph.ExceptionalUnitGraph)

Example 12 with ExceptionalUnitGraph

use of soot.toolkits.graph.ExceptionalUnitGraph in project soot by Sable.

the class StringGroupPair method unsplitAssignColorsToLocals.

/**
 * Provides a coloring for the locals of <code>unitBody</code>, attempting
 * to not split locals assigned the same name in the original Jimple.
 */
public static void unsplitAssignColorsToLocals(Body unitBody, Map<Local, Object> localToGroup, Map<Local, Integer> localToColor, Map<Object, Integer> groupToColorCount) {
    // To understand why a pedantic throw analysis is required, see comment
    // in assignColorsToLocals method
    ExceptionalUnitGraph unitGraph = new ExceptionalUnitGraph(unitBody, PedanticThrowAnalysis.v(), Options.v().omit_excepting_unit_edges());
    LiveLocals liveLocals;
    liveLocals = new SimpleLiveLocals(unitGraph);
    UnitInterferenceGraph intGraph = new UnitInterferenceGraph(unitBody, localToGroup, liveLocals, unitGraph);
    Map<Local, String> localToOriginalName = new HashMap<Local, String>();
    // Map each local variable to its original name
    {
        for (Local local : intGraph.getLocals()) {
            int signIndex;
            signIndex = local.getName().indexOf("#");
            if (signIndex != -1) {
                localToOriginalName.put(local, local.getName().substring(0, signIndex));
            } else
                localToOriginalName.put(local, local.getName());
        }
    }
    Map<StringGroupPair, List<Integer>> originalNameAndGroupToColors = new HashMap<StringGroupPair, List<Integer>>();
    // maps an original name to the colors being used for it
    // Assign a color for each local.
    {
        int[] freeColors = new int[10];
        for (Local local : intGraph.getLocals()) {
            if (localToColor.containsKey(local)) {
                // Already assigned, probably a parameter
                continue;
            }
            Object group = localToGroup.get(local);
            int colorCount = groupToColorCount.get(group).intValue();
            if (freeColors.length < colorCount)
                freeColors = new int[Math.max(freeColors.length * 2, colorCount)];
            // Set all colors to free.
            {
                for (int i = 0; i < colorCount; i++) freeColors[i] = 1;
            }
            // Remove unavailable colors for this local
            {
                Local[] interferences = intGraph.getInterferencesOf(local);
                if (interferences != null)
                    for (Local element : interferences) {
                        if (localToColor.containsKey(element)) {
                            int usedColor = localToColor.get(element).intValue();
                            freeColors[usedColor] = 0;
                        }
                    }
            }
            // Assign a color to this local.
            {
                String originalName = localToOriginalName.get(local);
                List<Integer> originalNameColors = originalNameAndGroupToColors.get(new StringGroupPair(originalName, group));
                if (originalNameColors == null) {
                    originalNameColors = new ArrayList<Integer>();
                    originalNameAndGroupToColors.put(new StringGroupPair(originalName, group), originalNameColors);
                }
                boolean found = false;
                int assignedColor = 0;
                // Check if the colors assigned to this
                // original name is already free
                {
                    Iterator<Integer> colorIt = originalNameColors.iterator();
                    while (colorIt.hasNext()) {
                        Integer color = colorIt.next();
                        if (freeColors[color.intValue()] == 1) {
                            found = true;
                            assignedColor = color.intValue();
                        }
                    }
                }
                if (!found) {
                    assignedColor = colorCount++;
                    groupToColorCount.put(group, new Integer(colorCount));
                    originalNameColors.add(new Integer(assignedColor));
                }
                localToColor.put(local, new Integer(assignedColor));
            }
        }
    }
}
Also used : HashMap(java.util.HashMap) Local(soot.Local) ExceptionalUnitGraph(soot.toolkits.graph.ExceptionalUnitGraph) Iterator(java.util.Iterator) ArrayList(java.util.ArrayList) List(java.util.List)

Example 13 with ExceptionalUnitGraph

use of soot.toolkits.graph.ExceptionalUnitGraph in project soot by Sable.

the class XMLPrinter method printStatementsInBody.

/**
 * Prints the given <code>JimpleBody</code> to the specified <code>PrintWriter</code>.
 */
private void printStatementsInBody(Body body, java.io.PrintWriter out) {
    LabeledUnitPrinter up = new NormalUnitPrinter(body);
    Map<Unit, String> stmtToName = up.labels();
    Chain<Unit> units = body.getUnits();
    // UnitGraph unitGraph = new soot.toolkits.graph.BriefUnitGraph( body );
    ExceptionalUnitGraph exceptionalUnitGraph = new soot.toolkits.graph.ExceptionalUnitGraph(body);
    // include any analysis which will be used in the xml output
    LiveLocals sll = new SimpleLiveLocals(exceptionalUnitGraph);
    // iterate through each statement
    String cleanMethodName = cleanMethod(body.getMethod().getName());
    Iterator<Unit> unitIt = units.iterator();
    Unit currentStmt = null;
    String currentLabel = "default";
    long statementCount = 0;
    long labelCount = 0;
    long labelID = 0;
    // lists
    Vector<String> useList = new Vector<String>();
    Vector<Vector<Long>> useDataList = new Vector<Vector<Long>>();
    Vector<String> defList = new Vector<String>();
    Vector<Vector<Long>> defDataList = new Vector<Vector<Long>>();
    Vector<Vector<String>> paramData = new Vector<Vector<String>>();
    Vector<XMLLabel> xmlLabelsList = new Vector<XMLLabel>();
    long maxStmtCount = 0;
    /*
        // for invokes, add a list of potential targets
        if (!Scene.v().hasActiveInvokeGraph()) {
            InvokeGraphBuilder.v().transform("jil.igb");
        }

        // build an invoke graph based on class hiearchy analysis
        InvokeGraph igCHA = Scene.v().getActiveInvokeGraph();

        // build an invoke graph based on variable type analysis
        InvokeGraph igVTA = Scene.v().getActiveInvokeGraph();
        try {
            VariableTypeAnalysis vta = null;
            int VTApasses = 1;
            //Options.getInt( PackManager.v().getPhaseOptions( "jil.igb" ), "VTA-passes" );
            for (int i = 0; i < VTApasses; i++) {
                vta = new VariableTypeAnalysis(igVTA);
                vta.trimActiveInvokeGraph();
                igVTA.refreshReachableMethods();
            }
        } catch (RuntimeException re) {
            // this will fail if the --analyze-context flag is not specified
            // logger.debug(""+ "JIL VTA FAILED: " + re );
            igVTA = null;
        }
        */
    // add method node
    XMLNode methodNode = xmlNode.addChild("method", new String[] { "name", "returntype", "class" }, new String[] { cleanMethodName, body.getMethod().getReturnType().toString(), body.getMethod().getDeclaringClass().getName().toString() });
    String declarationStr = body.getMethod().getDeclaration().toString().trim();
    methodNode.addChild("declaration", toCDATA(declarationStr), new String[] { "length" }, new String[] { declarationStr.length() + "" });
    // create references to parameters, locals, labels, stmts nodes
    XMLNode parametersNode = methodNode.addChild("parameters", new String[] { "method" }, new String[] { cleanMethodName });
    XMLNode localsNode = methodNode.addChild("locals");
    XMLNode labelsNode = methodNode.addChild("labels");
    XMLNode stmtsNode = methodNode.addChild("statements");
    // create default label
    XMLLabel xmlLabel = new XMLLabel(labelCount, cleanMethodName, currentLabel);
    labelsNode.addChild("label", new String[] { "id", "name", "method" }, new String[] { (labelCount++) + "", currentLabel, cleanMethodName });
    // for each statement...
    while (unitIt.hasNext()) {
        currentStmt = (Unit) unitIt.next();
        // new label
        if (stmtToName.containsKey(currentStmt)) {
            currentLabel = stmtToName.get(currentStmt).toString();
            // fill in the stmt count for the previous label
            // index = xmlLabels.indexOf( "%s" );
            // if( index != -1 )
            // xmlLabels = xmlLabels.substring( 0, index ) + ( labelID ) + xmlLabels.substring( index + 2 );
            // index = xmlLabels.indexOf( "%d" );
            // if( index != -1 )
            // xmlLabels = xmlLabels.substring( 0, index ) + new Float( ( new Float( labelID ).floatValue() / new Float( units.size() ).intValue() ) * 100.0 ).intValue() + xmlLabels.substring( index + 2 );
            xmlLabel.stmtCount = labelID;
            xmlLabel.stmtPercentage = new Float((new Float(labelID).floatValue() / new Float(units.size()).intValue()) * 100.0).longValue();
            if (xmlLabel.stmtPercentage > maxStmtCount)
                maxStmtCount = xmlLabel.stmtPercentage;
            xmlLabelsList.addElement(xmlLabel);
            // xmlLabel.clear();
            xmlLabel = new XMLLabel(labelCount, cleanMethodName, currentLabel);
            labelsNode.addChild("label", new String[] { "id", "name", "method" }, new String[] { labelCount + "", currentLabel, cleanMethodName });
            labelCount++;
            labelID = 0;
        }
        // examine each statement
        XMLNode stmtNode = stmtsNode.addChild("statement", new String[] { "id", "label", "method", "labelid" }, new String[] { statementCount + "", currentLabel, cleanMethodName, labelID + "" });
        XMLNode sootstmtNode = stmtNode.addChild("soot_statement", new String[] { "branches", "fallsthrough" }, new String[] { boolToString(currentStmt.branches()), boolToString(currentStmt.fallsThrough()) });
        // uses for each statement
        int j = 0;
        Iterator<ValueBox> boxIt = currentStmt.getUseBoxes().iterator();
        while (boxIt.hasNext()) {
            ValueBox box = (ValueBox) boxIt.next();
            if (box.getValue() instanceof Local) {
                String local = cleanLocal(((Local) box.getValue()).toString());
                sootstmtNode.addChild("uses", new String[] { "id", "local", "method" }, new String[] { j + "", local, cleanMethodName });
                j++;
                Vector<Long> tempVector = null;
                int useIndex = useList.indexOf(local);
                if (useIndex == -1) {
                    useDataList.addElement(tempVector);
                    useList.addElement(local);
                    useIndex = useList.indexOf(local);
                }
                if (useDataList.size() > useIndex) {
                    tempVector = useDataList.elementAt(useIndex);
                    if (tempVector == null) {
                        tempVector = new Vector<Long>();
                    }
                    tempVector.addElement(new Long(statementCount));
                    useDataList.setElementAt(tempVector, useIndex);
                }
            }
        }
        // defines for each statement
        j = 0;
        boxIt = currentStmt.getDefBoxes().iterator();
        while (boxIt.hasNext()) {
            ValueBox box = (ValueBox) boxIt.next();
            if (box.getValue() instanceof Local) {
                String local = cleanLocal(((Local) box.getValue()).toString());
                sootstmtNode.addChild("defines", new String[] { "id", "local", "method" }, new String[] { j + "", local, cleanMethodName });
                j++;
                Vector<Long> tempVector = null;
                int defIndex = defList.indexOf(local);
                if (defIndex == -1) {
                    defDataList.addElement(tempVector);
                    defList.addElement(local);
                    defIndex = defList.indexOf(local);
                }
                if (defDataList.size() > defIndex) {
                    tempVector = defDataList.elementAt(defIndex);
                    if (tempVector == null) {
                        tempVector = new Vector<Long>();
                    }
                    tempVector.addElement(new Long(statementCount));
                    defDataList.setElementAt(tempVector, defIndex);
                }
            }
        }
        /*
            // for invokes, add a list of potential targets
            if (stmtCurrentStmt.containsInvokeExpr()) {
                // default analysis is CHA
                if (igCHA != null) {
                    try {
                        List targets = igCHA.getTargetsOf(stmtCurrentStmt);
                        XMLNode CHAinvoketargetsNode =
                            sootstmtNode.addChild(
                                "invoketargets",
                                new String[] { "analysis", "count" },
                                new String[] { "CHA", targets.size() + "" });
                        for (int i = 0; i < targets.size(); i++) {
                            SootMethod meth = (SootMethod) targets.get(i);
                            CHAinvoketargetsNode.addChild(
                                "target",
                                new String[] { "id", "class", "method" },
                                new String[] {
                                    i + "",
                                    meth.getDeclaringClass().getFullName(),
                                    cleanMethod(meth.getName())});
                        }
                    } catch (RuntimeException re) {
                        //logger.debug(""+ "XML: " + re + " (" + stmtCurrentStmt + ")" );
                    }
                }

                // now try VTA, which will only work if the -a or --analyze-context switch is specified
                if (igVTA != null) {
                    InvokeExpr ie =
                        (InvokeExpr) stmtCurrentStmt.getInvokeExpr();
                    if (!(ie instanceof StaticInvokeExpr)
                        && !(ie instanceof SpecialInvokeExpr)) {
                        try {
                            List targets = igVTA.getTargetsOf(stmtCurrentStmt);
                            XMLNode VTAinvoketargetsNode =
                                sootstmtNode.addChild(
                                    "invoketargets",
                                    new String[] { "analysis", "count" },
                                    new String[] {
                                        "VTA",
                                        targets.size() + "" });
                            for (int i = 0; i < targets.size(); i++) {
                                SootMethod meth = (SootMethod) targets.get(i);
                                VTAinvoketargetsNode.addChild(
                                    "target",
                                    new String[] { "id", "class", "method" },
                                    new String[] {
                                        i + "",
                                        meth.getDeclaringClass().getFullName(),
                                        cleanMethod(meth.getName())});
                            }
                        } catch (RuntimeException re) {
                            //logger.debug(""+ "XML: " + re + " (" + stmtCurrentStmt + ")" );
                        }
                    }
                }
            }
            */
        // simple live locals
        List<Local> liveLocalsIn = sll.getLiveLocalsBefore(currentStmt);
        List<Local> liveLocalsOut = sll.getLiveLocalsAfter(currentStmt);
        XMLNode livevarsNode = sootstmtNode.addChild("livevariables", new String[] { "incount", "outcount" }, new String[] { liveLocalsIn.size() + "", liveLocalsOut.size() + "" });
        for (int i = 0; i < liveLocalsIn.size(); i++) {
            livevarsNode.addChild("in", new String[] { "id", "local", "method" }, new String[] { i + "", cleanLocal(liveLocalsIn.get(i).toString()), cleanMethodName });
        }
        for (int i = 0; i < liveLocalsOut.size(); i++) {
            livevarsNode.addChild("out", new String[] { "id", "local", "method" }, new String[] { i + "", cleanLocal(liveLocalsOut.get(i).toString()), cleanMethodName });
        }
        // parameters
        for (int i = 0; i < body.getMethod().getParameterTypes().size(); i++) {
            Vector<String> tempVec = new Vector<String>();
            paramData.addElement(tempVec);
        }
        // parse any info from the statement code
        currentStmt.toString(up);
        String jimpleStr = up.toString().trim();
        if (currentStmt instanceof soot.jimple.IdentityStmt && jimpleStr.indexOf("@parameter") != -1) {
            // this line is a use of a parameter
            String tempStr = jimpleStr.substring(jimpleStr.indexOf("@parameter") + 10);
            if (tempStr.indexOf(":") != -1)
                tempStr = tempStr.substring(0, tempStr.indexOf(":")).trim();
            if (tempStr.indexOf(" ") != -1)
                tempStr = tempStr.substring(0, tempStr.indexOf(" ")).trim();
            int paramIndex = new Integer(tempStr).intValue();
            Vector<String> tempVec = paramData.elementAt(paramIndex);
            if (tempVec != null)
                tempVec.addElement(Long.toString(statementCount));
            paramData.setElementAt(tempVec, paramIndex);
        }
        // add plain jimple representation of each statement
        sootstmtNode.addChild("jimple", toCDATA(jimpleStr), new String[] { "length" }, new String[] { (jimpleStr.length() + 1) + "" });
        // increment statement counters
        labelID++;
        statementCount++;
    }
    // add count to statments
    stmtsNode.addAttribute("count", statementCount + "");
    // method parameters
    parametersNode.addAttribute("count", body.getMethod().getParameterCount() + "");
    for (int i = 0; i < body.getMethod().getParameterTypes().size(); i++) {
        XMLNode paramNode = parametersNode.addChild("parameter", new String[] { "id", "type", "method", "name" }, new String[] { i + "", body.getMethod().getParameterTypes().get(i).toString(), cleanMethodName, "_parameter" + i });
        XMLNode sootparamNode = paramNode.addChild("soot_parameter");
        Vector<String> tempVec = paramData.elementAt(i);
        for (int k = 0; k < tempVec.size(); k++) {
            sootparamNode.addChild("use", new String[] { "id", "line", "method" }, new String[] { k + "", String.valueOf(tempVec.elementAt(k)) + "", cleanMethodName });
        }
        sootparamNode.addAttribute("uses", tempVec.size() + "");
    }
    /*		
                index = xmlLabels.indexOf( "%s" );
        if( index != -1 )
                    xmlLabels = xmlLabels.substring( 0, index ) + ( labelID ) + xmlLabels.substring( index + 2 );
        index = xmlLabels.indexOf( "%d" );
        if( index != -1 )			
                    xmlLabels = xmlLabels.substring( 0, index ) + new Float( ( new Float( labelID ).floatValue() / new Float( units.size() ).floatValue() ) * 100.0 ).intValue() + xmlLabels.substring( index + 2 );
        */
    xmlLabel.stmtCount = labelID;
    xmlLabel.stmtPercentage = new Float((new Float(labelID).floatValue() / new Float(units.size()).floatValue()) * 100.0).longValue();
    if (xmlLabel.stmtPercentage > maxStmtCount)
        maxStmtCount = xmlLabel.stmtPercentage;
    xmlLabelsList.addElement(xmlLabel);
    // print out locals
    Collection<Local> locals = body.getLocals();
    Iterator<Local> localsIterator = locals.iterator();
    Vector<String> localTypes = new Vector<String>();
    Vector<Vector<XMLNode>> typedLocals = new Vector<Vector<XMLNode>>();
    Vector<Integer> typeCounts = new Vector<Integer>();
    int j = 0;
    int currentType = 0;
    while (localsIterator.hasNext()) {
        int useCount = 0;
        int defineCount = 0;
        Local localData = (Local) localsIterator.next();
        String local = cleanLocal((String) localData.toString());
        String localType = localData.getType().toString();
        // collect the local types
        if (!localTypes.contains(localType)) {
            localTypes.addElement(localType);
            typedLocals.addElement(new Vector<XMLNode>());
            typeCounts.addElement(new Integer(0));
        }
        // create a reference to the local node
        XMLNode localNode = new XMLNode("local", "", new String[] { "id", "method", "name", "type" }, new String[] { j + "", cleanMethodName, local, localType });
        XMLNode sootlocalNode = localNode.addChild("soot_local");
        currentType = 0;
        for (int k = 0; k < localTypes.size(); k++) {
            if (localType.equalsIgnoreCase(localTypes.elementAt(k))) {
                currentType = k;
                Integer tempInt = new Integer(typeCounts.elementAt(k).intValue() + 1);
                typeCounts.setElementAt(tempInt, k);
                break;
            }
        }
        // add all uses to this local
        for (int k = 0; k < useList.size(); k++) {
            String query = useList.elementAt(k);
            if (query.equalsIgnoreCase(local)) {
                Vector<Long> tempVector = useDataList.elementAt(useList.indexOf(local));
                for (int i = 0; i < tempVector.size(); i++) {
                    sootlocalNode.addChild("use", new String[] { "id", "line", "method" }, new String[] { i + "", ((Long) tempVector.elementAt(i)).toString(), cleanMethodName });
                }
                useCount = tempVector.size();
                break;
            }
        }
        // add all definitions to this local
        for (int k = 0; k < defList.size(); k++) {
            String query = (defList.elementAt(k));
            if (query.equalsIgnoreCase(local)) {
                Vector<Long> tempVector = defDataList.elementAt(defList.indexOf(local));
                for (int i = 0; i < tempVector.size(); i++) {
                    sootlocalNode.addChild("definition", new String[] { "id", "line", "method" }, new String[] { i + "", ((Long) tempVector.elementAt(i)).toString(), cleanMethodName });
                }
                defineCount = tempVector.size();
                break;
            }
        }
        // add number of uses and defines to this local
        sootlocalNode.addAttribute("uses", useCount + "");
        sootlocalNode.addAttribute("defines", defineCount + "");
        // create a list of locals sorted by type
        Vector<XMLNode> list = typedLocals.elementAt(currentType);
        list.addElement(localNode);
        typedLocals.setElementAt(list, currentType);
        // add local to locals node
        localsNode.addChild((XMLNode) localNode.clone());
        j++;
    }
    // add count to the locals node
    localsNode.addAttribute("count", locals.size() + "");
    // add types node to locals node, and each type with each local per type
    XMLNode typesNode = localsNode.addChild("types", new String[] { "count" }, new String[] { localTypes.size() + "" });
    for (int i = 0; i < localTypes.size(); i++) {
        String type = localTypes.elementAt(i);
        XMLNode typeNode = typesNode.addChild("type", new String[] { "id", "type", "count" }, new String[] { i + "", type, typeCounts.elementAt(i) + "" });
        Vector<XMLNode> list = typedLocals.elementAt(i);
        for (j = 0; j < list.size(); j++) {
            typeNode.addChild(list.elementAt(j));
        }
    }
    // add count attribute to labels node, and stmtcount, and stmtpercentage attributes to each label node
    labelsNode.addAttribute("count", labelCount + "");
    XMLNode current = labelsNode.child;
    for (int i = 0; i < xmlLabelsList.size(); i++) {
        XMLLabel tempLabel = xmlLabelsList.elementAt(i);
        tempLabel.stmtPercentage = new Float((new Float(tempLabel.stmtPercentage).floatValue() / new Float(maxStmtCount).floatValue()) * 100.0).longValue();
        if (current != null) {
            current.addAttribute("stmtcount", tempLabel.stmtCount + "");
            current.addAttribute("stmtpercentage", tempLabel.stmtPercentage + "");
            current = current.next;
        }
    }
    // Print out exceptions
    statementCount = 0;
    XMLNode exceptionsNode = methodNode.addChild("exceptions");
    Iterator<Trap> trapIt = body.getTraps().iterator();
    if (trapIt.hasNext()) {
        while (trapIt.hasNext()) {
            Trap trap = trapIt.next();
            // catch java.io.IOException from label0 to label1 with label2;
            XMLNode catchNode = exceptionsNode.addChild("exception", new String[] { "id", "method", "type" }, new String[] { (statementCount++) + "", cleanMethodName, Scene.v().quotedNameOf(trap.getException().getName()) });
            catchNode.addChild("begin", new String[] { "label" }, new String[] { stmtToName.get(trap.getBeginUnit()).toString() });
            catchNode.addChild("end", new String[] { "label" }, new String[] { stmtToName.get(trap.getEndUnit()).toString() });
            catchNode.addChild("handler", new String[] { "label" }, new String[] { stmtToName.get(trap.getHandlerUnit()).toString() });
        }
    }
    exceptionsNode.addAttribute("count", exceptionsNode.getNumberOfChildren() + "");
    return;
}
Also used : LabeledUnitPrinter(soot.LabeledUnitPrinter) Unit(soot.Unit) ExceptionalUnitGraph(soot.toolkits.graph.ExceptionalUnitGraph) SimpleLiveLocals(soot.toolkits.scalar.SimpleLiveLocals) Vector(java.util.Vector) NormalUnitPrinter(soot.NormalUnitPrinter) Local(soot.Local) Trap(soot.Trap) SimpleLiveLocals(soot.toolkits.scalar.SimpleLiveLocals) LiveLocals(soot.toolkits.scalar.LiveLocals) ValueBox(soot.ValueBox)

Example 14 with ExceptionalUnitGraph

use of soot.toolkits.graph.ExceptionalUnitGraph in project soot by Sable.

the class LocalSplitter method internalTransform.

@Override
protected void internalTransform(Body body, String phaseName, Map<String, String> options) {
    if (Options.v().verbose())
        logger.debug("[" + body.getMethod().getName() + "] Splitting locals...");
    if (Options.v().time())
        Timers.v().splitTimer.start();
    if (Options.v().time())
        Timers.v().splitPhase1Timer.start();
    if (throwAnalysis == null)
        throwAnalysis = Scene.v().getDefaultThrowAnalysis();
    if (omitExceptingUnitEdges == false)
        omitExceptingUnitEdges = Options.v().omit_excepting_unit_edges();
    // Pack the locals for efficiency
    final LocalBitSetPacker localPacker = new LocalBitSetPacker(body);
    localPacker.pack();
    // Go through the definitions, building the webs
    ExceptionalUnitGraph graph = new ExceptionalUnitGraph(body, throwAnalysis, omitExceptingUnitEdges);
    // run in panic mode on first split (maybe change this depending on the input
    // source)
    final LocalDefs defs = LocalDefs.Factory.newLocalDefs(graph, true);
    final LocalUses uses = LocalUses.Factory.newLocalUses(graph, defs);
    if (Options.v().time())
        Timers.v().splitPhase1Timer.end();
    if (Options.v().time())
        Timers.v().splitPhase2Timer.start();
    Set<Unit> visited = new HashSet<Unit>();
    // Collect the set of locals that we need to split^
    BitSet localsToSplit = new BitSet(localPacker.getLocalCount());
    {
        BitSet localsVisited = new BitSet(localPacker.getLocalCount());
        for (Unit s : body.getUnits()) {
            if (s.getDefBoxes().isEmpty())
                continue;
            if (!(s.getDefBoxes().get(0).getValue() instanceof Local))
                continue;
            // If we see a local the second time, we know that we must split it
            Local l = (Local) s.getDefBoxes().get(0).getValue();
            if (localsVisited.get(l.getNumber()))
                localsToSplit.set(l.getNumber());
            localsVisited.set(l.getNumber());
        }
    }
    int w = 0;
    for (Unit s : body.getUnits()) {
        if (s.getDefBoxes().isEmpty())
            continue;
        if (s.getDefBoxes().size() > 1)
            throw new RuntimeException("stmt with more than 1 defbox!");
        if (!(s.getDefBoxes().get(0).getValue() instanceof Local))
            continue;
        // we don't want to visit a node twice
        if (visited.remove(s))
            continue;
        // always reassign locals to avoid "use before definition" bugs!
        // unfortunately this creates a lot of new locals, so it's important
        // to remove them afterwards
        Local oldLocal = (Local) s.getDefBoxes().get(0).getValue();
        if (!localsToSplit.get(oldLocal.getNumber()))
            continue;
        Local newLocal = (Local) oldLocal.clone();
        // renaming should not be done here
        newLocal.setName(newLocal.getName() + '#' + ++w);
        body.getLocals().add(newLocal);
        Deque<Unit> queue = new ArrayDeque<Unit>();
        queue.addFirst(s);
        do {
            final Unit head = queue.removeFirst();
            if (visited.add(head)) {
                for (UnitValueBoxPair use : uses.getUsesOf(head)) {
                    ValueBox vb = use.valueBox;
                    Value v = vb.getValue();
                    if (v == newLocal)
                        continue;
                    // should always be true - but who knows ...
                    if (v instanceof Local) {
                        Local l = (Local) v;
                        queue.addAll(defs.getDefsOfAt(l, use.unit));
                        vb.setValue(newLocal);
                    }
                }
                for (ValueBox vb : head.getDefBoxes()) {
                    Value v = vb.getValue();
                    if (v instanceof Local) {
                        vb.setValue(newLocal);
                    }
                }
            }
        } while (!queue.isEmpty());
        // keep the set small
        visited.remove(s);
    }
    // Restore the original local numbering
    localPacker.unpack();
    if (Options.v().time())
        Timers.v().splitPhase2Timer.end();
    if (Options.v().time())
        Timers.v().splitTimer.end();
}
Also used : BitSet(java.util.BitSet) Local(soot.Local) Unit(soot.Unit) ArrayDeque(java.util.ArrayDeque) ExceptionalUnitGraph(soot.toolkits.graph.ExceptionalUnitGraph) ValueBox(soot.ValueBox) Value(soot.Value) LocalBitSetPacker(soot.util.LocalBitSetPacker) HashSet(java.util.HashSet)

Example 15 with ExceptionalUnitGraph

use of soot.toolkits.graph.ExceptionalUnitGraph in project soot by Sable.

the class RunVeryBusyAnalysis method main.

public static void main(String[] args) {
    args = new String[] { "testers.VeryBusyClass" };
    if (args.length == 0) {
        System.out.println("Usage: java RunVeryBusyAnalysis class_to_analyse");
        System.exit(0);
    }
    String sep = File.separator;
    String pathSep = File.pathSeparator;
    String path = System.getProperty("java.home") + sep + "lib" + sep + "rt.jar";
    path += pathSep + "." + sep + "tutorial" + sep + "guide" + sep + "examples" + sep + "analysis_framework" + sep + "src";
    Options.v().set_soot_classpath(path);
    SootClass sClass = Scene.v().loadClassAndSupport(args[0]);
    sClass.setApplicationClass();
    Scene.v().loadNecessaryClasses();
    for (SootMethod m : sClass.getMethods()) {
        Body b = m.retrieveActiveBody();
        System.out.println("=======================================");
        System.out.println(m.toString());
        UnitGraph graph = new ExceptionalUnitGraph(b);
        VeryBusyExpressions vbe = new SimpleVeryBusyExpressions(graph);
        for (Unit u : graph) {
            List<AbstractBinopExpr> before = vbe.getBusyExpressionsBefore(u);
            List<AbstractBinopExpr> after = vbe.getBusyExpressionsAfter(u);
            UnitPrinter up = new NormalUnitPrinter(b);
            up.setIndent("");
            System.out.println("---------------------------------------");
            u.toString(up);
            System.out.println(up.output());
            System.out.print("Busy in: {");
            sep = "";
            for (AbstractBinopExpr e : before) {
                System.out.print(sep);
                System.out.print(e.toString());
                sep = ", ";
            }
            System.out.println("}");
            System.out.print("Busy out: {");
            sep = "";
            for (AbstractBinopExpr e : after) {
                System.out.print(sep);
                System.out.print(e.toString());
                sep = ", ";
            }
            System.out.println("}");
            System.out.println("---------------------------------------");
        }
        System.out.println("=======================================");
    }
}
Also used : NormalUnitPrinter(soot.NormalUnitPrinter) SimpleVeryBusyExpressions(dk.brics.soot.analyses.SimpleVeryBusyExpressions) SootClass(soot.SootClass) Unit(soot.Unit) SimpleVeryBusyExpressions(dk.brics.soot.analyses.SimpleVeryBusyExpressions) VeryBusyExpressions(dk.brics.soot.analyses.VeryBusyExpressions) ExceptionalUnitGraph(soot.toolkits.graph.ExceptionalUnitGraph) ExceptionalUnitGraph(soot.toolkits.graph.ExceptionalUnitGraph) UnitGraph(soot.toolkits.graph.UnitGraph) NormalUnitPrinter(soot.NormalUnitPrinter) UnitPrinter(soot.UnitPrinter) SootMethod(soot.SootMethod) Body(soot.Body)

Aggregations

ExceptionalUnitGraph (soot.toolkits.graph.ExceptionalUnitGraph)22 Unit (soot.Unit)14 Local (soot.Local)10 List (java.util.List)8 ArrayList (java.util.ArrayList)7 Value (soot.Value)7 Stmt (soot.jimple.Stmt)6 ValueBox (soot.ValueBox)5 AssignStmt (soot.jimple.AssignStmt)5 Trap (soot.Trap)4 DefinitionStmt (soot.jimple.DefinitionStmt)4 HashMap (java.util.HashMap)3 HashSet (java.util.HashSet)3 Iterator (java.util.Iterator)3 NullConstant (soot.jimple.NullConstant)3 UnitGraph (soot.toolkits.graph.UnitGraph)3 LocalDefs (soot.toolkits.scalar.LocalDefs)3 BitSet (java.util.BitSet)2 Body (soot.Body)2 NormalUnitPrinter (soot.NormalUnitPrinter)2