예제 #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
    /**
     * Returns a <code>ThrowableSet</code> representing the set of exceptions included in <code>
     * include</code> minus the set of exceptions included in <code>exclude</code>. Creates a new
     * <code>ThrowableSet</code> only if there was not already one whose contents correspond to
     * <code>include</code> - <code>exclude</code>.
     *
     * @param include A set of {@link RefLikeType} objects representing exception types included in
     *     the result; may be <code>null</code> if there are no included types.
     * @param exclude A set of {@link AnySubType} objects representing exception types excluded from
     *     the result; may be <code>null</code> if there are no excluded types.
     * @return a <code>ThrowableSet</code> representing the set of exceptions corresponding to
     *     <code>include</code> - <code>exclude</code>.
     */
    private ThrowableSet registerSetIfNew(Set include, Set exclude) {
      if (INSTRUMENTING) {
        registrationCalls++;
      }
      if (include == null) {
        include = Collections.EMPTY_SET;
      }
      if (exclude == null) {
        exclude = Collections.EMPTY_SET;
      }
      int size = include.size() + exclude.size();
      Integer sizeKey = new Integer(size);

      List sizeList = (List) sizeToSets.get(sizeKey);
      if (sizeList == null) {
        sizeList = new LinkedList();
        sizeToSets.put(sizeKey, sizeList);
      }
      for (Iterator i = sizeList.iterator(); i.hasNext(); ) {
        ThrowableSet set = (ThrowableSet) i.next();
        if (set.exceptionsIncluded.equals(include) && set.exceptionsExcluded.equals(exclude)) {
          return set;
        }
      }
      if (INSTRUMENTING) {
        registeredSets++;
      }
      ThrowableSet result = new ThrowableSet(include, exclude);
      sizeList.add(result);
      return result;
    }
예제 #3
0
  private void addBoxToPatch(String aLabelName, UnitBox aUnitBox) {
    List patchList = (List) mLabelToPatchList.get(aLabelName);
    if (patchList == null) {
      patchList = new ArrayList();
      mLabelToPatchList.put(aLabelName, patchList);
    }

    patchList.add(aUnitBox);
  }
예제 #4
0
  public void outADeclaration(ADeclaration node) {
    List localNameList = (List) mProductions.removeLast();
    Type type = (Type) mProductions.removeLast();
    Iterator it = localNameList.iterator();
    List localList = new ArrayList();

    while (it.hasNext()) {
      Local l = Jimple.v().newLocal((String) it.next(), type);
      mLocals.put(l.getName(), l);
      localList.add(l);
    }
    mProductions.addLast(localList);
  }
예제 #5
0
 /**
  * Returns a <code>ThrowableSet</code> which contains all the exceptions in <code>s</code> in
  * addition to those in this <code>ThrowableSet</code>.
  *
  * @param s set of exceptions to add to this set.
  * @return the union of this set with <code>s</code>
  * @throws ThrowableSet.AlreadyHasExclusionsException if this <code>ThrowableSet</code> or <code>s
  *     </code> is the result of a {@link #whichCatchableAs(RefType)} operation, so that it is not
  *     possible to represent the addition of <code>s</code> to this <code>ThrowableSet</code>.
  */
 public ThrowableSet add(ThrowableSet s) throws ThrowableSet.AlreadyHasExclusionsException {
   if (INSTRUMENTING) {
     Manager.v().addsOfSet++;
   }
   if (exceptionsExcluded.size() > 0 || s.exceptionsExcluded.size() > 0) {
     throw new AlreadyHasExclusionsException(
         "ThrowableSet.Add(ThrowableSet): attempt to add to ["
             + this.toString()
             + "] after removals recorded.");
   }
   ThrowableSet result = getMemoizedAdds(s);
   if (result == null) {
     if (INSTRUMENTING) {
       Manager.v().addsInclusionFromSearch++;
       Manager.v().addsExclusionWithoutSearch++;
     }
     result = this.add(s.exceptionsIncluded);
     memoizedAdds.put(s, result);
   } else if (INSTRUMENTING) {
     Manager.v().addsInclusionFromMemo++;
     Manager.v().addsExclusionWithoutSearch++;
   }
   return result;
 }
예제 #6
0
  /**
   * Returns a <code>ThrowableSet</code> which contains <code>e</code> and all of its subclasses as
   * well as the exceptions in this set.
   *
   * <p><code>e</code> should be an instance of {@link AnySubType} if you know that the compile-time
   * type of the exception you are representing is <code>e</code>, but the exception may be
   * instantiated at run-time by a subclass of <code>e</code>.
   *
   * <p>For example, if you were recording the type of the exception thrown by
   *
   * <pre>
   * catch (IOException e) {
   *    throw e;
   * }
   * </pre>
   *
   * you would call
   *
   * <pre>
   * <code>add(AnySubtype.v(Scene.v().getRefType("java.lang.Exception.IOException")))</code>
   * </pre>
   *
   * since the handler might rethrow any subclass of <code>IOException</code>.
   *
   * @param e represents a subtree of the exception class hierarchy to add to this set.
   * @return a set containing <code>e</code> and all its subclasses, as well as the exceptions
   *     represented by this set.
   * @throws ThrowableSet.AlreadyHasExclusionsException if this <code>ThrowableSet</code> is the
   *     result of a {@link #whichCatchableAs(RefType)} operation and, thus, unable to represent the
   *     addition of <code>e</code>.
   */
  public ThrowableSet add(AnySubType e) throws ThrowableSet.AlreadyHasExclusionsException {
    if (INSTRUMENTING) {
      Manager.v().addsOfAnySubType++;
    }

    ThrowableSet result = getMemoizedAdds(e);
    if (result != null) {
      if (INSTRUMENTING) {
        Manager.v().addsInclusionFromMemo++;
        Manager.v().addsExclusionWithoutSearch++;
      }
      return result;
    } else {
      FastHierarchy hierarchy = Scene.v().getOrMakeFastHierarchy();
      RefType newBase = e.getBase();

      if (INSTRUMENTING) {
        if (exceptionsExcluded.size() != 0) {
          Manager.v().addsExclusionWithSearch++;
        } else {
          Manager.v().addsExclusionWithoutSearch++;
        }
      }
      for (Iterator i = exceptionsExcluded.iterator(); i.hasNext(); ) {
        RefType exclusionBase = ((AnySubType) i.next()).getBase();
        if (hierarchy.canStoreType(newBase, exclusionBase)
            || hierarchy.canStoreType(exclusionBase, newBase)) {
          if (INSTRUMENTING) {
            // To ensure that the subcategories total properly:
            Manager.v().addsInclusionInterrupted++;
          }
          throw new AlreadyHasExclusionsException(
              "ThrowableSet.add("
                  + e.toString()
                  + ") to the set [ "
                  + this.toString()
                  + "] where "
                  + exclusionBase.toString()
                  + " is excluded.");
        }
      }

      if (this.exceptionsIncluded.contains(e)) {
        if (INSTRUMENTING) {
          Manager.v().addsInclusionFromMap++;
        }
        return this;

      } else {
        if (INSTRUMENTING) {
          Manager.v().addsInclusionFromSearch++;
        }

        int changes = 0;
        boolean addNewException = true;
        Set resultSet = new HashSet();

        for (Iterator i = this.exceptionsIncluded.iterator(); i.hasNext(); ) {
          RefLikeType incumbent = (RefLikeType) i.next();
          if (incumbent instanceof RefType) {
            if (hierarchy.canStoreType(incumbent, newBase)) {
              // Omit incumbent from result.
              changes++;
            } else {
              resultSet.add(incumbent);
            }
          } else if (incumbent instanceof AnySubType) {
            RefType incumbentBase = ((AnySubType) incumbent).getBase();
            // We have to use the base types in these hierarchy calls
            // because we want to know if _all_ possible
            // types represented by e can be represented by
            // the incumbent, or vice versa.
            if (hierarchy.canStoreType(newBase, incumbentBase)) {
              addNewException = false;
              resultSet.add(incumbent);
            } else if (hierarchy.canStoreType(incumbentBase, newBase)) {
              // Omit incumbent from result;
              changes++;
            } else {
              resultSet.add(incumbent);
            }
          } else { // assertion failure.
            throw new IllegalStateException(
                "ThrowableSet.add(AnySubType): Set element "
                    + incumbent.toString()
                    + " is neither a RefType nor an AnySubType.");
          }
        }
        if (addNewException) {
          resultSet.add(e);
          changes++;
        }
        if (changes > 0) {
          result = Manager.v().registerSetIfNew(resultSet, this.exceptionsExcluded);
        } else {
          result = this;
        }
        memoizedAdds.put(e, result);
        return result;
      }
    }
  }
예제 #7
0
  /**
   * Returns a <code>ThrowableSet</code> which contains <code>e</code> in addition to the exceptions
   * in this <code>ThrowableSet</code>.
   *
   * <p>Add <code>e</code> as a {@link RefType} when you know that the run-time class of the
   * exception you are representing is necessarily <code>e</code> and cannot be a subclass of <code>
   * e</code>.
   *
   * <p>For example, if you were recording the type of the exception thrown by
   *
   * <pre>
   * throw new IOException("Permission denied");
   * </pre>
   *
   * you would call
   *
   * <pre>
   * <code>add(Scene.v().getRefType("java.lang.Exception.IOException"))</code>
   * </pre>
   *
   * since the class of the exception is necessarily <code>IOException</code>.
   *
   * @param e the exception class
   * @return a set containing <code>e</code> as well as the exceptions in this set.
   * @throws {@link ThrowableSet.IllegalStateException} if this <code>ThrowableSet</code> is the
   *     result of a {@link #whichCatchableAs(RefType)} operation and, thus, unable to represent the
   *     addition of <code>e</code>.
   */
  public ThrowableSet add(RefType e) throws ThrowableSet.AlreadyHasExclusionsException {
    if (INSTRUMENTING) {
      Manager.v().addsOfRefType++;
    }
    if (this.exceptionsIncluded.contains(e)) {
      if (INSTRUMENTING) {
        Manager.v().addsInclusionFromMap++;
        Manager.v().addsExclusionWithoutSearch++;
      }
      return this;
    } else {
      ThrowableSet result = getMemoizedAdds(e);
      if (result != null) {
        if (INSTRUMENTING) {
          Manager.v().addsInclusionFromMemo++;
          Manager.v().addsExclusionWithoutSearch++;
        }
        return result;
      } else {
        if (INSTRUMENTING) {
          Manager.v().addsInclusionFromSearch++;
          if (exceptionsExcluded.size() != 0) {
            Manager.v().addsExclusionWithSearch++;
          } else {
            Manager.v().addsExclusionWithoutSearch++;
          }
        }
        FastHierarchy hierarchy = Scene.v().getOrMakeFastHierarchy();

        for (Iterator i = exceptionsExcluded.iterator(); i.hasNext(); ) {
          RefType exclusionBase = ((AnySubType) i.next()).getBase();
          if (hierarchy.canStoreType(e, exclusionBase)) {
            throw new AlreadyHasExclusionsException(
                "ThrowableSet.add(RefType): adding"
                    + e.toString()
                    + " to the set [ "
                    + this.toString()
                    + "] where "
                    + exclusionBase.toString()
                    + " is excluded.");
          }
        }

        for (Iterator i = exceptionsIncluded.iterator(); i.hasNext(); ) {
          RefLikeType incumbent = (RefLikeType) i.next();
          if (incumbent instanceof AnySubType) {
            // Need to use incumbent.getBase() because
            // hierarchy.canStoreType() assumes that parent
            // is not an AnySubType.
            RefType incumbentBase = ((AnySubType) incumbent).getBase();
            if (hierarchy.canStoreType(e, incumbentBase)) {
              memoizedAdds.put(e, this);
              return this;
            }
          } else if (!(incumbent instanceof RefType)) {
            // assertion failure.
            throw new IllegalStateException(
                "ThrowableSet.add(RefType): Set element "
                    + incumbent.toString()
                    + " is neither a RefType nor an AnySubType.");
          }
        }
        Set resultSet = new HashSet(this.exceptionsIncluded);
        resultSet.add(e);
        result = Manager.v().registerSetIfNew(resultSet, this.exceptionsExcluded);
        memoizedAdds.put(e, result);
        return result;
      }
    }
  }
예제 #8
0
  public void outAFullMethodBody(AFullMethodBody node) {
    Object catchClause = null;
    JimpleBody jBody = Jimple.v().newBody();

    if (node.getCatchClause() != null) {
      int size = node.getCatchClause().size();
      for (int i = 0; i < size; i++) jBody.getTraps().addFirst((Trap) mProductions.removeLast());
    }

    if (node.getStatement() != null) {
      int size = node.getStatement().size();
      Unit lastStmt = null;
      for (int i = 0; i < size; i++) {
        Object o = mProductions.removeLast();
        if (o instanceof Unit) {
          jBody.getUnits().addFirst(o);
          lastStmt = (Unit) o;
        } else if (o instanceof String) {
          if (lastStmt == null) throw new RuntimeException("impossible");
          mLabelToStmtMap.put(o, lastStmt);
        } else throw new RuntimeException("impossible");
      }
    }

    if (node.getDeclaration() != null) {
      int size = node.getDeclaration().size();
      for (int i = 0; i < size; i++) {
        List localList = (List) mProductions.removeLast();

        int listSize = localList.size();
        for (int j = listSize - 1; j >= 0; j--) jBody.getLocals().addFirst(localList.get(j));
      }
    }

    Iterator it = mLabelToPatchList.keySet().iterator();
    while (it.hasNext()) {
      String label = (String) it.next();
      Unit target = (Unit) mLabelToStmtMap.get(label);

      Iterator patchIt = ((List) mLabelToPatchList.get(label)).iterator();
      while (patchIt.hasNext()) {
        UnitBox box = (UnitBox) patchIt.next();
        box.setUnit(target);
      }
    }

    /*
    Iterator it = mLabelToStmtMap.keySet().iterator();
    while(it.hasNext()) {
        String label = (String) it.next();
        Unit target = (Unit) mLabelToStmtMap.get(label);

        List l =         (List) mLabelToPatchList.get(label);
        if(l != null) {
            Iterator patchIt = l.iterator();
            while(patchIt.hasNext()) {
                UnitBox box = (UnitBox) patchIt.next();
                box.setUnit(target);
            }
        }
    }
    */

    mProductions.addLast(jBody);
  }