Beispiel #1
0
  private boolean removeBeginNode() {
    List heads = getHeads();
    if (heads.size() != 1) {
      // System.out.println("heads: "+heads);
      // System.out.println("Error: the size of heads is not equal to 1!");
      return false;
      //	    System.exit(1);
    } else {
      JPegStmt head = (JPegStmt) heads.get(0);
      // System.out.println("test head: "+head);
      if (!head.getName().equals("begin")) {
        System.err.println("Error: the head is not begin node!");
        System.exit(1);
      }
      // remove begin node from heads list
      heads.remove(0);
      // set the preds list of the succs of head to a new list and put succs of head into heads
      Iterator succOfHeadIt = getSuccsOf(head).iterator();
      while (succOfHeadIt.hasNext()) {

        JPegStmt succOfHead = (JPegStmt) succOfHeadIt.next();

        unitToPreds.put(succOfHead, new ArrayList());
        // put succs of head into heads
        heads.add(succOfHead);
      }
      // remove begin node from inlinee Peg
      if (!mainPegChain.remove(head)) {
        System.err.println("fail to remove begin node in from mainPegChain!");
        System.exit(1);
      }
      if (!allNodes.contains(head)) {
        System.err.println("fail to find begin node in FlowSet allNodes!");
        System.exit(1);
      } else {
        allNodes.remove(head);
      }

      // remove begin node from unitToSuccs
      if (unitToSuccs.containsKey(head)) {
        unitToSuccs.remove(head);
      }
    }

    return true;
  }
  /**
   * This method pushes all newExpr down to be the stmt directly before every invoke of the init
   * only if they are in the types list
   */
  public void internalTransform(Body b, String phaseName, Map options) {
    JimpleBody body = (JimpleBody) b;

    if (Options.v().verbose())
      G.v().out.println("[" + body.getMethod().getName() + "] Folding Jimple constructors...");

    Chain units = body.getUnits();
    List<Unit> stmtList = new ArrayList<Unit>();
    stmtList.addAll(units);

    Iterator<Unit> it = stmtList.iterator();
    Iterator<Unit> nextStmtIt = stmtList.iterator();
    // start ahead one
    nextStmtIt.next();

    SmartLocalDefs localDefs = SmartLocalDefsPool.v().getSmartLocalDefsFor(body);
    UnitGraph graph = localDefs.getGraph();
    LocalUses localUses = new SimpleLocalUses(graph, localDefs);

    /* fold in NewExpr's with specialinvoke's */
    while (it.hasNext()) {
      Stmt s = (Stmt) it.next();

      if (!(s instanceof AssignStmt)) continue;

      /* this should be generalized to ArrayRefs */
      // only deal with stmts that are an local = newExpr
      Value lhs = ((AssignStmt) s).getLeftOp();
      if (!(lhs instanceof Local)) continue;

      Value rhs = ((AssignStmt) s).getRightOp();
      if (!(rhs instanceof NewExpr)) continue;

      // check if very next statement is invoke -->
      // this indicates there is no control flow between
      // new and invoke and should do nothing
      if (nextStmtIt.hasNext()) {
        Stmt next = (Stmt) nextStmtIt.next();
        if (next instanceof InvokeStmt) {
          InvokeStmt invoke = (InvokeStmt) next;

          if (invoke.getInvokeExpr() instanceof SpecialInvokeExpr) {
            SpecialInvokeExpr invokeExpr = (SpecialInvokeExpr) invoke.getInvokeExpr();
            if (invokeExpr.getBase() == lhs) {
              break;
            }
          }
        }
      }

      // check if new is in the types list - only process these
      if (!types.contains(((NewExpr) rhs).getType())) continue;

      List lu = localUses.getUsesOf(s);
      Iterator luIter = lu.iterator();
      boolean MadeNewInvokeExpr = false;

      while (luIter.hasNext()) {
        Unit use = ((UnitValueBoxPair) (luIter.next())).unit;
        if (!(use instanceof InvokeStmt)) continue;
        InvokeStmt is = (InvokeStmt) use;
        if (!(is.getInvokeExpr() instanceof SpecialInvokeExpr)
            || lhs != ((SpecialInvokeExpr) is.getInvokeExpr()).getBase()) continue;

        // make a new one here
        AssignStmt constructStmt =
            Jimple.v()
                .newAssignStmt(((DefinitionStmt) s).getLeftOp(), ((DefinitionStmt) s).getRightOp());
        constructStmt.setRightOp(Jimple.v().newNewExpr(((NewExpr) rhs).getBaseType()));
        MadeNewInvokeExpr = true;

        // redirect jumps
        use.redirectJumpsToThisTo(constructStmt);
        // insert new one here
        units.insertBefore(constructStmt, use);

        constructStmt.addTag(s.getTag("SourceLnPosTag"));
      }
      if (MadeNewInvokeExpr) {
        units.remove(s);
      }
    }
  }
Beispiel #3
0
  protected void buildSuccsForInlining(JPegStmt stmt, Chain chain, PegGraph inlinee) {
    // System.out.println("entering buildSuccsForInlining...");
    Tag tag = (Tag) stmt.getTags().get(0);
    // System.out.println("stmt is: "+tag+" "+stmt);
    /*connect heads of inlinee with the preds of invokeStmt and
     * delete stmt from the succs list from the preds
     */

    Iterator predIt = getPredsOf(stmt).iterator();
    // System.out.println("preds list: "+getPredsOf(stmt));
    // System.out.println("preds size: "+getPredsOf(stmt).size());
    Iterator headsIt = inlinee.getHeads().iterator();
    {
      // System.out.println("heads: "+inlinee.getHeads());
      while (predIt.hasNext()) {
        JPegStmt pred = (JPegStmt) predIt.next();
        // System.out.println("pred: "+pred);
        List succList = (List) getSuccsOf(pred);
        // System.out.println("succList of pred: "+succList);
        int pos = succList.indexOf(stmt);
        // System.out.println("remove : "+stmt + " from succList: \n"+succList+ "\n of pred" );
        // remove invokeStmt
        succList.remove(pos);

        while (headsIt.hasNext()) {
          succList.add(headsIt.next());
        }
        unitToSuccs.put(pred, succList);
      }

      {
        while (headsIt.hasNext()) {
          Object head = headsIt.next();
          List predsOfHeads = new ArrayList();
          predsOfHeads.addAll(getPredsOf(head));
          unitToPreds.put(head, predsOfHeads);
        }
      }
      /*
      {
      predIt = getPredsOf(stmt).iterator();
      while (predIt.hasNext()){
      JPegStmt s = (JPegStmt)predIt.next();
      if (unitToSuccs.containsKey(s)){
      Iterator succIt = ((List) unitToSuccs.get(s)).iterator();
      while(succIt.hasNext()){

      //Object successor =  succIt.next();
       JPegStmt successor = (JPegStmt)succIt.next();
       List predList = (List) unitToPreds.get(successor);
       if (predList != null) {
       try {
       predList.add(s);

       } catch(NullPointerException e) {
       System.out.println(s + "successor: " + successor);
       throw e;
       }
       }
       }
       }
       }




       }*/

    }

    /*connect tails of inlinee with the succ of invokeStmt and
     * delete stmt from the
     */

    Iterator tailsIt = inlinee.getTails().iterator();
    {
      // System.out.println("tails: "+inlinee.getTails());
      while (tailsIt.hasNext()) {
        Iterator succIt = getSuccsOf(stmt).iterator();
        JPegStmt tail = (JPegStmt) tailsIt.next();
        List succList = null;
        if (unitToSuccs.containsKey(tail)) {
          // System.out.println("error: unitToSucc containsKey: "+tail);
          succList = (List) getSuccsOf(tail);
          // System.out.println("succList: "+succList);
        } else {

          succList = new ArrayList();
        }
        while (succIt.hasNext()) {
          JPegStmt succ = (JPegStmt) succIt.next();
          succList.add(succ);
          // System.out.println("succ: "+succ);
          // remove stmt from the preds list of the succs of itself.
          List predListOfSucc = getPredsOf(succ);
          if (predListOfSucc == null) {
            System.err.println("Error: predListOfSucc is null!");
            System.exit(1);
          } else {
            if (predListOfSucc.size() != 0) {

              int pos = predListOfSucc.indexOf(stmt);
              if (pos > 0 || pos == 0) {

                //	System.out.println("remove stmt: "+stmt+" from the preds list"+predListOfSucc+"
                // of the succ");
                predListOfSucc.remove(pos);
              }

              //		System.out.println("remove(from PRED): ");
            }
          }
          unitToPreds.put(succ, predListOfSucc);
        }
        unitToSuccs.put(tail, succList);
        // System.out.println("put: "+tail);
        // System.out.println("succList: "+succList+ "into unitToSucc");

      }
    }

    // add Nov 1
    {
      tailsIt = inlinee.getTails().iterator();
      while (tailsIt.hasNext()) {
        JPegStmt s = (JPegStmt) tailsIt.next();
        if (unitToSuccs.containsKey(s)) {
          Iterator succIt = unitToSuccs.get(s).iterator();
          while (succIt.hasNext()) {

            // Object successor =  succIt.next();
            JPegStmt successor = (JPegStmt) succIt.next();
            List<JPegStmt> predList = unitToPreds.get(successor);
            if (predList != null && !predList.contains(s)) {
              try {
                predList.add(s);
                /*
                Tag tag = (Tag)successor.getTags().get(0);
                System.out.println("add "+s+" to predlist of "+tag+" "+successor);
                */
              } catch (NullPointerException e) {
                System.out.println(s + "successor: " + successor);
                throw e;
              }
            }
          }
        }
      }
    }
    // end add Nov 1

    // System.out.println("stmt: "+stmt);
    // remove stmt from allNodes and mainPegChain
    // System.out.println("mainPegChain contains stmt: "+mainPegChain.contains(stmt));
    //		testPegChain();

    if (!allNodes.contains(stmt)) {
      System.err.println("fail to find begin node in  allNodes!");
      System.exit(1);
    } else {
      allNodes.remove(stmt);
      // System.out.println("remove from allNode: "+stmt);
    }

    if (!chain.contains(stmt)) {
      System.err.println("Error! Chain does not contains stmt (extending point)!");
      System.exit(1);

    } else {
      if (!chain.remove(stmt)) {
        System.err.println("fail to remove invoke stmt in from Chain!");
        System.exit(1);
      }
    }
    /*
    if (!mainPegChain.contains(stmt)){
    boolean find = false;
    //System.out.println("main chain does not contain AFTER");
     Set maps = startToThread.entrySet();
     for(Iterator iter=maps.iterator(); iter.hasNext();){
     Map.Entry entry = (Map.Entry)iter.next();
     Object startNode = entry.getKey();
     Iterator runIt  = ((List)entry.getValue()).iterator();
     while (runIt.hasNext()){
     Chain chain=(Chain)runIt.next();
     if (chain.contains(stmt)) {
     find = true;
     if (!chain.remove(stmt)){
     System.err.println("fail to remove begin node in from mainPegChain!");
     System.exit(1);
     }
     break;
     }
     }
     if (find == false){
     System.err.println("fail to find stmt: "+stmt+" in chains!");
     System.exit(1);
     }
     }
     //this.toString();
      }
      else{
      if (!mainPegChain.remove(stmt)) {
      System.err.println("fail to remove begin node in from mainPegChain!");
      System.exit(1);
      }
      else{
      // System.out.println("remove(from mainchain): "+stmt);
       }
       }
       */
    // remove stmt from unitToSuccs and unitToPreds
    if (unitToSuccs.containsKey(stmt)) {
      unitToSuccs.remove(stmt);
    }
    if (unitToPreds.containsKey(stmt)) {
      unitToPreds.remove(stmt);
    }
  }
  private static boolean internalAggregate(
      StmtBody body, Map<ValueBox, Zone> boxToZone, boolean onlyStackVars) {
    LocalUses localUses;
    LocalDefs localDefs;
    ExceptionalUnitGraph graph;
    boolean hadAggregation = false;
    Chain<Unit> units = body.getUnits();

    graph = new ExceptionalUnitGraph(body);
    localDefs = new SmartLocalDefs(graph, new SimpleLiveLocals(graph));
    localUses = new SimpleLocalUses(graph, localDefs);

    List<Unit> unitList = new PseudoTopologicalOrderer<Unit>().newList(graph, false);
    for (Unit u : unitList) {
      if (!(u instanceof AssignStmt)) continue;
      AssignStmt s = (AssignStmt) u;

      Value lhs = s.getLeftOp();
      if (!(lhs instanceof Local)) continue;
      Local lhsLocal = (Local) lhs;

      if (onlyStackVars && !lhsLocal.getName().startsWith("$")) continue;

      List<UnitValueBoxPair> lu = localUses.getUsesOf(s);
      if (lu.size() != 1) continue;

      UnitValueBoxPair usepair = lu.get(0);
      Unit use = usepair.unit;
      ValueBox useBox = usepair.valueBox;

      List<Unit> ld = localDefs.getDefsOfAt(lhsLocal, use);
      if (ld.size() != 1) continue;

      // Check to make sure aggregation pair in the same zone
      if (boxToZone.get(s.getRightOpBox()) != boxToZone.get(usepair.valueBox)) {
        continue;
      }

      /* we need to check the path between def and use */
      /* to see if there are any intervening re-defs of RHS */
      /* in fact, we should check that this path is unique. */
      /* if the RHS uses only locals, then we know what
      to do; if RHS has a method invocation f(a, b,
      c) or field access, we must ban field writes, other method
      calls and (as usual) writes to a, b, c. */

      boolean cantAggr = false;
      boolean propagatingInvokeExpr = false;
      boolean propagatingFieldRef = false;
      boolean propagatingArrayRef = false;
      ArrayList<FieldRef> fieldRefList = new ArrayList<FieldRef>();

      LinkedList<Value> localsUsed = new LinkedList<Value>();
      for (ValueBox vb : s.getUseBoxes()) {
        Value v = vb.getValue();
        if (v instanceof Local) localsUsed.add(v);
        else if (v instanceof InvokeExpr) propagatingInvokeExpr = true;
        else if (v instanceof ArrayRef) propagatingArrayRef = true;
        else if (v instanceof FieldRef) {
          propagatingFieldRef = true;
          fieldRefList.add((FieldRef) v);
        }
      }

      // look for a path from s to use in graph.
      // only look in an extended basic block, though.

      List<Unit> path = graph.getExtendedBasicBlockPathBetween(s, use);

      if (path == null) continue;

      Iterator<Unit> pathIt = path.iterator();

      // skip s.
      if (pathIt.hasNext()) pathIt.next();

      while (pathIt.hasNext() && !cantAggr) {
        Stmt between = (Stmt) (pathIt.next());

        if (between != use) {
          // Check for killing definitions

          for (ValueBox vb : between.getDefBoxes()) {
            Value v = vb.getValue();
            if (localsUsed.contains(v)) {
              cantAggr = true;
              break;
            }

            if (propagatingInvokeExpr || propagatingFieldRef || propagatingArrayRef) {
              if (v instanceof FieldRef) {
                if (propagatingInvokeExpr) {
                  cantAggr = true;
                  break;
                } else if (propagatingFieldRef) {
                  // Can't aggregate a field access if passing a definition of a field
                  // with the same name, because they might be aliased
                  for (FieldRef fieldRef : fieldRefList) {
                    if (((FieldRef) v).getField() == fieldRef.getField()) {
                      cantAggr = true;
                      break;
                    }
                  }
                }
              } else if (v instanceof ArrayRef) {
                if (propagatingInvokeExpr) {
                  // Cannot aggregate an invoke expr past an array write
                  cantAggr = true;
                  break;
                } else if (propagatingArrayRef) {
                  // cannot aggregate an array read past a write
                  // this is somewhat conservative
                  // (if types differ they may not be aliased)

                  cantAggr = true;
                  break;
                }
              }
            }
          }

          // Make sure not propagating past a {enter,exit}Monitor
          if (propagatingInvokeExpr && between instanceof MonitorStmt) cantAggr = true;
        }

        // Check for intervening side effects due to method calls
        if (propagatingInvokeExpr || propagatingFieldRef || propagatingArrayRef) {
          for (final ValueBox box : between.getUseBoxes()) {
            if (between == use && box == useBox) {
              // Reached use point, stop looking for
              // side effects
              break;
            }

            Value v = box.getValue();

            if (v instanceof InvokeExpr
                || (propagatingInvokeExpr && (v instanceof FieldRef || v instanceof ArrayRef))) {
              cantAggr = true;
              break;
            }
          }
        }
      }

      // we give up: can't aggregate.
      if (cantAggr) {
        continue;
      }
      /* assuming that the d-u chains are correct, */
      /* we need not check the actual contents of ld */

      Value aggregatee = s.getRightOp();

      if (usepair.valueBox.canContainValue(aggregatee)) {
        boolean wasSimpleCopy = isSimpleCopy(usepair.unit);
        usepair.valueBox.setValue(aggregatee);
        units.remove(s);
        hadAggregation = true;
        // clean up the tags. If s was not a simple copy, the new statement should get
        // the tags of s.
        // OK, this fix was wrong. The condition should not be
        // "If s was not a simple copy", but rather "If usepair.unit
        // was a simple copy". This way, when there's a load of a constant
        // followed by an invoke, the invoke gets the tags.
        if (wasSimpleCopy) {
          // usepair.unit.removeAllTags();
          usepair.unit.addAllTagsOf(s);
        }
      } else {
        /*
        if(Options.v().verbose())
        {
            G.v().out.println("[debug] failed aggregation");
              G.v().out.println("[debug] tried to put "+aggregatee+
                             " into "+usepair.stmt +
                             ": in particular, "+usepair.valueBox);
              G.v().out.println("[debug] aggregatee instanceof Expr: "
                             +(aggregatee instanceof Expr));
        }*/
      }
    }
    return hadAggregation;
  }