Search in sources :

Example 46 with IntList

use of com.android.dx.util.IntList in project J2ME-Loader by nikita36078.

the class Frame method mergeSubroutineLists.

/**
 * Merges this frame's subroutine lists with another. The result
 * is the deepest common nesting (effectively, the common prefix of the
 * two lists).
 *
 * @param otherSubroutines label list of subroutine start blocks, from
 * least-nested to most-nested.
 * @return {@code non-null;} merged subroutine nest list as described above
 */
private IntList mergeSubroutineLists(IntList otherSubroutines) {
    if (subroutines.equals(otherSubroutines)) {
        return subroutines;
    }
    IntList resultSubroutines = new IntList();
    int szSubroutines = subroutines.size();
    int szOthers = otherSubroutines.size();
    for (int i = 0; i < szSubroutines && i < szOthers && (subroutines.get(i) == otherSubroutines.get(i)); i++) {
        resultSubroutines.add(i);
    }
    resultSubroutines.setImmutable();
    return resultSubroutines;
}
Also used : IntList(com.android.dx.util.IntList)

Example 47 with IntList

use of com.android.dx.util.IntList in project J2ME-Loader by nikita36078.

the class Ropper method forEachNonSubBlockDepthFirst0.

/**
 * Visits each block once in depth-first successor order, ignoring
 * {@code jsr} targets. Worker for {@link #forEachNonSubBlockDepthFirst}.
 *
 * @param next next block to visit
 * @param v callback interface
 * @param visited set of blocks already visited
 */
private void forEachNonSubBlockDepthFirst0(BasicBlock next, BasicBlock.Visitor v, BitSet visited) {
    v.visitBlock(next);
    visited.set(next.getLabel());
    IntList successors = next.getSuccessors();
    int sz = successors.size();
    for (int i = 0; i < sz; i++) {
        int succ = successors.get(i);
        if (visited.get(succ)) {
            continue;
        }
        if (isSubroutineCaller(next) && i > 0) {
            // ignore jsr targets
            continue;
        }
        /*
             * Ignore missing labels: they're successors of
             * subroutines that never invoke a ret.
             */
        int idx = labelToResultIndex(succ);
        if (idx >= 0) {
            forEachNonSubBlockDepthFirst0(result.get(idx), v, visited);
        }
    }
}
Also used : IntList(com.android.dx.util.IntList)

Example 48 with IntList

use of com.android.dx.util.IntList in project J2ME-Loader by nikita36078.

the class Ropper method deleteUnreachableBlocks.

/**
 * Deletes all blocks that cannot be reached. This is run to delete
 * original subroutine blocks after subroutine inlining.
 */
private void deleteUnreachableBlocks() {
    final IntList reachableLabels = new IntList(result.size());
    // subroutine inlining is done now and we won't update this list here
    resultSubroutines.clear();
    forEachNonSubBlockDepthFirst(getSpecialLabel(PARAM_ASSIGNMENT), new BasicBlock.Visitor() {

        public void visitBlock(BasicBlock b) {
            reachableLabels.add(b.getLabel());
        }
    });
    reachableLabels.sort();
    for (int i = result.size() - 1; i >= 0; i--) {
        if (reachableLabels.indexOf(result.get(i).getLabel()) < 0) {
            result.remove(i);
        // unnecessary here really, since subroutine inlining is done
        // resultSubroutines.remove(i);
        }
    }
}
Also used : BasicBlock(com.android.dx.rop.code.BasicBlock) IntList(com.android.dx.util.IntList)

Example 49 with IntList

use of com.android.dx.util.IntList in project J2ME-Loader by nikita36078.

the class Ropper method inlineSubroutines.

/**
 * Inlines any subroutine calls.
 */
private void inlineSubroutines() {
    final IntList reachableSubroutineCallerLabels = new IntList(4);
    /*
         * Compile a list of all subroutine calls reachable
         * through the normal (non-subroutine) flow.  We do this first, since
         * we'll be affecting the call flow as we go.
         *
         * Start at label 0 --  the param assignment block has nothing for us
         */
    forEachNonSubBlockDepthFirst(0, new BasicBlock.Visitor() {

        public void visitBlock(BasicBlock b) {
            if (isSubroutineCaller(b)) {
                reachableSubroutineCallerLabels.add(b.getLabel());
            }
        }
    });
    /*
         * Convert the resultSubroutines list, indexed by block index,
         * to a label-to-subroutines mapping used by the inliner.
         */
    int largestAllocedLabel = getAvailableLabel();
    ArrayList<IntList> labelToSubroutines = new ArrayList<IntList>(largestAllocedLabel);
    for (int i = 0; i < largestAllocedLabel; i++) {
        labelToSubroutines.add(null);
    }
    for (int i = 0; i < result.size(); i++) {
        BasicBlock b = result.get(i);
        if (b == null) {
            continue;
        }
        IntList subroutineList = resultSubroutines.get(i);
        labelToSubroutines.set(b.getLabel(), subroutineList);
    }
    /*
         * Inline all reachable subroutines.
         * Inner subroutines will be inlined as they are encountered.
         */
    int sz = reachableSubroutineCallerLabels.size();
    for (int i = 0; i < sz; i++) {
        int label = reachableSubroutineCallerLabels.get(i);
        new SubroutineInliner(new LabelAllocator(getAvailableLabel()), labelToSubroutines).inlineSubroutineCalledFrom(labelToBlock(label));
    }
    // Now find the blocks that aren't reachable and remove them
    deleteUnreachableBlocks();
}
Also used : BasicBlock(com.android.dx.rop.code.BasicBlock) ArrayList(java.util.ArrayList) IntList(com.android.dx.util.IntList)

Example 50 with IntList

use of com.android.dx.util.IntList in project J2ME-Loader by nikita36078.

the class BasicBlockList method catchesEqual.

/**
 * Compares the catches of two blocks for equality. This includes
 * both the catch types and target labels.
 *
 * @param block1 {@code non-null;} one block to compare
 * @param block2 {@code non-null;} the other block to compare
 * @return {@code true} if the two blocks' non-primary successors
 * are identical
 */
public boolean catchesEqual(BasicBlock block1, BasicBlock block2) {
    TypeList catches1 = block1.getExceptionHandlerTypes();
    TypeList catches2 = block2.getExceptionHandlerTypes();
    if (!StdTypeList.equalContents(catches1, catches2)) {
        return false;
    }
    IntList succ1 = block1.getSuccessors();
    IntList succ2 = block2.getSuccessors();
    // Both are guaranteed to be the same size.
    int size = succ1.size();
    int primary1 = block1.getPrimarySuccessor();
    int primary2 = block2.getPrimarySuccessor();
    if (((primary1 == -1) || (primary2 == -1)) && (primary1 != primary2)) {
        /*
             * For the current purpose, both blocks in question must
             * either both have a primary or both not have a primary to
             * be considered equal, and it turns out here that that's not
             * the case.
             */
        return false;
    }
    for (int i = 0; i < size; i++) {
        int label1 = succ1.get(i);
        int label2 = succ2.get(i);
        if (label1 == primary1) {
            /*
                 * It should be the case that block2's primary is at the
                 * same index. If not, we consider the blocks unequal for
                 * the current purpose.
                 */
            if (label2 != primary2) {
                return false;
            }
            continue;
        }
        if (label1 != label2) {
            return false;
        }
    }
    return true;
}
Also used : StdTypeList(com.android.dx.rop.type.StdTypeList) TypeList(com.android.dx.rop.type.TypeList) IntList(com.android.dx.util.IntList)

Aggregations

IntList (com.android.dx.util.IntList)56 BasicBlock (com.android.dx.rop.code.BasicBlock)20 CstType (com.android.dx.rop.cst.CstType)7 Insn (com.android.dx.rop.code.Insn)5 RopMethod (com.android.dx.rop.code.RopMethod)5 BasicBlockList (com.android.dx.rop.code.BasicBlockList)4 PlainCstInsn (com.android.dx.rop.code.PlainCstInsn)4 PlainInsn (com.android.dx.rop.code.PlainInsn)4 RegisterSpec (com.android.dx.rop.code.RegisterSpec)4 SourcePosition (com.android.dx.rop.code.SourcePosition)4 ThrowingCstInsn (com.android.dx.rop.code.ThrowingCstInsn)4 ThrowingInsn (com.android.dx.rop.code.ThrowingInsn)4 Type (com.android.dx.rop.type.Type)4 TypeList (com.android.dx.rop.type.TypeList)4 DexTranslationAdvice (com.android.dx.rop.code.DexTranslationAdvice)3 InsnList (com.android.dx.rop.code.InsnList)3 TranslationAdvice (com.android.dx.rop.code.TranslationAdvice)3 SsaBasicBlock (com.android.dx.ssa.SsaBasicBlock)3 ArrayList (java.util.ArrayList)3 BitSet (java.util.BitSet)3