예제 #1
0
  /**
   * Traverse the statements in the given body, looking for aggregation possibilities; that is,
   * given a def d and a use u, d has no other uses, u has no other defs, collapse d and u.
   *
   * <p>option: only-stack-locals; if this is true, only aggregate variables starting with $
   */
  protected void internalTransform(Body b, String phaseName, Map<String, String> options) {
    StmtBody body = (StmtBody) b;
    boolean onlyStackVars = PhaseOptions.getBoolean(options, "only-stack-locals");

    int aggregateCount = 1;

    if (Options.v().time()) Timers.v().aggregationTimer.start();
    boolean changed = false;

    Map<ValueBox, Zone> boxToZone =
        new HashMap<ValueBox, Zone>(body.getUnits().size() * 2 + 1, 0.7f);

    // Determine the zone of every box
    {
      Zonation zonation = new Zonation(body);

      for (Unit u : body.getUnits()) {
        Zone zone = zonation.getZoneOf(u);

        for (ValueBox box : u.getUseBoxes()) {
          boxToZone.put(box, zone);
        }

        for (ValueBox box : u.getDefBoxes()) {
          boxToZone.put(box, zone);
        }
      }
    }

    do {
      if (Options.v().verbose())
        G.v()
            .out
            .println(
                "["
                    + body.getMethod().getName()
                    + "] Aggregating iteration "
                    + aggregateCount
                    + "...");

      // body.printTo(new java.io.PrintWriter(G.v().out, true));

      changed = internalAggregate(body, boxToZone, onlyStackVars);

      aggregateCount++;
    } while (changed);

    if (Options.v().time()) Timers.v().aggregationTimer.end();
  }
예제 #2
0
  /**
   * Constructs a BriefUnitGraph given a Body instance.
   *
   * @param body The underlying body we want to make a graph for.
   */
  public BriefUnitGraph(Body body) {
    super(body);
    int size = unitChain.size();

    if (Options.v().time()) Timers.v().graphTimer.start();

    unitToSuccs = new HashMap(size * 2 + 1, 0.7f);
    unitToPreds = new HashMap(size * 2 + 1, 0.7f);
    buildUnexceptionalEdges(unitToSuccs, unitToPreds);
    makeMappedListsUnmodifiable(unitToSuccs);
    makeMappedListsUnmodifiable(unitToPreds);

    buildHeadsAndTails();

    if (Options.v().time()) Timers.v().graphTimer.end();
  }
예제 #3
0
  // This method is deprecated. Use soot.util.JasminOutputStream instead.
  public void writeXXXDeprecated(SootClass cl, String outputDir) {
    String outputDirWithSep = "";

    if (!outputDir.equals("")) outputDirWithSep = outputDir + fileSeparator;

    try {
      File tempFile = new File(outputDirWithSep + cl.getName() + ".jasmin");

      FileOutputStream streamOut = new FileOutputStream(tempFile);

      PrintWriter writerOut = new PrintWriter(new EscapedWriter(new OutputStreamWriter(streamOut)));

      if (cl.containsBafBody()) new soot.baf.JasminClass(cl).print(writerOut);
      else new soot.jimple.JasminClass(cl).print(writerOut);

      writerOut.close();

      if (Options.v().time()) Timers.v().assembleJasminTimer.start();

      // Invoke jasmin
      {
        String[] args;

        if (outputDir.equals("")) {
          args = new String[1];

          args[0] = cl.getName() + ".jasmin";
        } else {
          args = new String[3];

          args[0] = "-d";
          args[1] = outputDir;
          args[2] = outputDirWithSep + cl.getName() + ".jasmin";
        }

        jasmin.Main.main(args);
      }

      tempFile.delete();

      if (Options.v().time()) Timers.v().assembleJasminTimer.end();

    } catch (IOException e) {
      throw new RuntimeException("Could not produce new classfile! (" + e + ")");
    }
  }
예제 #4
0
  /**
   * Computes the analysis given a UnitGraph computed from a method body. It is recommended that a
   * ExceptionalUnitGraph (or similar) be provided for correct results in the case of exceptional
   * control flow.
   *
   * @param g a graph on which to compute the analysis.
   * @see ExceptionalUnitGraph
   */
  public SimpleLiveLocals(UnitGraph graph) {
    if (Options.v().time()) Timers.v().liveTimer.start();

    if (Options.v().verbose())
      G.v()
          .out
          .println(
              "["
                  + graph.getBody().getMethod().getName()
                  + "]     Constructing SimpleLiveLocals...");

    SimpleLiveLocalsAnalysis analysis = new SimpleLiveLocalsAnalysis(graph);

    if (Options.v().time()) Timers.v().livePostTimer.start();

    // Build unitToLocals map
    {
      unitToLocalsAfter = new HashMap<Unit, List>(graph.size() * 2 + 1, 0.7f);
      unitToLocalsBefore = new HashMap<Unit, List>(graph.size() * 2 + 1, 0.7f);

      Iterator unitIt = graph.iterator();

      while (unitIt.hasNext()) {
        Unit s = (Unit) unitIt.next();

        FlowSet set = (FlowSet) analysis.getFlowBefore(s);
        unitToLocalsBefore.put(s, Collections.unmodifiableList(set.toList()));

        set = (FlowSet) analysis.getFlowAfter(s);
        unitToLocalsAfter.put(s, Collections.unmodifiableList(set.toList()));
      }
    }

    if (Options.v().time()) Timers.v().livePostTimer.end();

    if (Options.v().time()) Timers.v().liveTimer.end();
  }
예제 #5
0
  SimpleLiveLocalsAnalysis(UnitGraph g) {
    super(g);

    if (Options.v().time()) Timers.v().liveSetupTimer.start();

    emptySet = new ArraySparseSet();

    // Create kill sets.
    {
      unitToKillSet = new HashMap<Unit, FlowSet>(g.size() * 2 + 1, 0.7f);

      Iterator unitIt = g.iterator();

      while (unitIt.hasNext()) {
        Unit s = (Unit) unitIt.next();

        FlowSet killSet = emptySet.clone();

        Iterator boxIt = s.getDefBoxes().iterator();

        while (boxIt.hasNext()) {
          ValueBox box = (ValueBox) boxIt.next();

          if (box.getValue() instanceof Local) killSet.add(box.getValue(), killSet);
        }

        unitToKillSet.put(s, killSet);
      }
    }

    // Create generate sets
    {
      unitToGenerateSet = new HashMap<Unit, FlowSet>(g.size() * 2 + 1, 0.7f);

      Iterator unitIt = g.iterator();

      while (unitIt.hasNext()) {
        Unit s = (Unit) unitIt.next();

        FlowSet genSet = emptySet.clone();

        Iterator boxIt = s.getUseBoxes().iterator();

        while (boxIt.hasNext()) {
          ValueBox box = (ValueBox) boxIt.next();

          if (box.getValue() instanceof Local) genSet.add(box.getValue(), genSet);
        }

        unitToGenerateSet.put(s, genSet);
      }
    }

    if (Options.v().time()) Timers.v().liveSetupTimer.end();

    if (Options.v().time()) Timers.v().liveAnalysisTimer.start();

    doAnalysis();

    if (Options.v().time()) Timers.v().liveAnalysisTimer.end();
  }
예제 #6
0
  protected void doAnalysis() {
    LinkedList<Object> changedUnits = new LinkedList<Object>();
    HashSet<Object> changedUnitsSet = new HashSet<Object>();

    int numNodes = graph.size();
    int numComputations = 0;

    // Set initial values and nodes to visit.

    createWorkList(changedUnits, changedUnitsSet);

    // testWorkList(changedUnits);

    // Set initial values for entry points
    {
      Iterator it = graph.getHeads().iterator();

      while (it.hasNext()) {
        Object s = it.next();

        // unitToBeforeFlow.put(s, entryInitialFlow());
        nodes.add(s);
        valueBefore.add(entryInitialFlow());
      }
    }

    // Perform fixed point flow analysis
    {
      Object previousAfterFlow = newInitialFlow();

      while (!changedUnits.isEmpty()) {
        Object beforeFlow;
        Object afterFlow;

        Object s = changedUnits.removeFirst();
        Tag tag = (Tag) ((JPegStmt) s).getTags().get(0);
        // System.out.println("===unit is: "+tag+" "+s);
        changedUnitsSet.remove(s);

        // copy(unitToAfterFlow.get(s), previousAfterFlow);
        // add for debug april 6
        int pos = nodes.indexOf(s);
        copy(valueAfter.elementAt(pos), previousAfterFlow);
        // end add for debug april
        // Compute and store beforeFlow
        {
          List preds = graph.getPredsOf(s);

          // beforeFlow = unitToBeforeFlow.get(s);

          beforeFlow = valueBefore.elementAt(pos);

          if (preds.size() == 1) {
            // copy(unitToAfterFlow.get(preds.get(0)), beforeFlow);
            copy(valueAfter.elementAt(nodes.indexOf(preds.get(0))), beforeFlow);
          } else if (preds.size() != 0) {
            Iterator predIt = preds.iterator();
            Object obj = predIt.next();

            // copy(unitToAfterFlow.get(obj), beforeFlow);
            copy(valueAfter.elementAt(nodes.indexOf(obj)), beforeFlow);

            while (predIt.hasNext()) {
              JPegStmt stmt = (JPegStmt) predIt.next();
              if (stmt.equals(obj)) {
                // System.out.println("!!!same object!!!");
                continue;
              }
              Tag tag1 = (Tag) stmt.getTags().get(0);
              // System.out.println("pred: "+tag1+" "+stmt);

              // Object otherBranchFlow = unitToAfterFlow.get(stmt);
              if (nodes.indexOf(stmt) >= 0) // RLH
              {
                Object otherBranchFlow = valueAfter.elementAt(nodes.indexOf(stmt));

                merge(beforeFlow, otherBranchFlow, beforeFlow);
              }
            }
          }
        }

        // Compute afterFlow and store it.
        {
          // afterFlow = unitToAfterFlow.get(s);
          afterFlow = valueAfter.elementAt(nodes.indexOf(s));
          flowThrough(beforeFlow, s, afterFlow);

          // unitToAfterFlow.put(s, afterFlow);
          valueAfter.set(nodes.indexOf(s), afterFlow);
          // System.out.println("update afterFlow nodes: "+s);
          // System.out.println("afterFlow: "+afterFlow);
          // ((MonitorSet)unitToAfterFlow.get(s)).test();

          numComputations++;
        }

        // Update queue appropriately

        if (!afterFlow.equals(previousAfterFlow)) {

          Iterator succIt = graph.getSuccsOf(s).iterator();

          while (succIt.hasNext()) {
            Object succ = succIt.next();

            if (!changedUnitsSet.contains(succ)) {
              changedUnits.addLast(succ);
              changedUnitsSet.add(succ);
              /*if (succ instanceof JPegStmt){
              Tag tag1 = (Tag)((JPegStmt)succ).getTags().get(0);

              System.out.println("add to worklist: "+tag1+" "+succ);
              }
              else
              System.out.println("add to worklist: "+succ);
              */
            }
          }
        }
      }
    }

    // G.v().out.println(graph.getBody().getMethod().getSignature() + " numNodes: " + numNodes +
    //    " numComputations: " + numComputations + " avg: " + Main.truncatedOf((double)
    // numComputations / numNodes, 2));

    Timers.v().totalFlowNodes += numNodes;
    Timers.v().totalFlowComputations += numComputations;
  }