Search in sources :

Example 6 with IntList

use of com.taobao.android.dx.util.IntList in project atlas by alibaba.

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 : TypeList(com.taobao.android.dx.rop.type.TypeList) StdTypeList(com.taobao.android.dx.rop.type.StdTypeList) IntList(com.taobao.android.dx.util.IntList)

Example 7 with IntList

use of com.taobao.android.dx.util.IntList in project atlas by alibaba.

the class BasicBlockList method preferredSuccessorOf.

/**
 * Gets the preferred successor for the given block. If the block
 * only has one successor, then that is the preferred successor.
 * Otherwise, if the block has a primay successor, then that is
 * the preferred successor. If the block has no successors, then
 * this returns {@code null}.
 *
 * @param block {@code non-null;} the block in question
 * @return {@code null-ok;} the preferred successor, if any
 */
public BasicBlock preferredSuccessorOf(BasicBlock block) {
    int primarySuccessor = block.getPrimarySuccessor();
    IntList successors = block.getSuccessors();
    int succSize = successors.size();
    switch(succSize) {
        case 0:
            {
                return null;
            }
        case 1:
            {
                return labelToBlock(successors.get(0));
            }
    }
    if (primarySuccessor != -1) {
        return labelToBlock(primarySuccessor);
    } else {
        return labelToBlock(successors.get(0));
    }
}
Also used : IntList(com.taobao.android.dx.util.IntList)

Example 8 with IntList

use of com.taobao.android.dx.util.IntList in project atlas by alibaba.

the class IdenticalBlockCombiner method process.

/**
 * Runs algorithm. TODO: This is n^2, and could be made linear-ish with
 * a hash. In particular, hash the contents of each block and only
 * compare blocks with the same hash.
 *
 * @return {@code non-null;} new method that has been processed
 */
public RopMethod process() {
    int szBlocks = blocks.size();
    // indexed by label
    BitSet toDelete = new BitSet(blocks.getMaxLabel());
    // For each non-deleted block...
    for (int bindex = 0; bindex < szBlocks; bindex++) {
        BasicBlock b = blocks.get(bindex);
        if (toDelete.get(b.getLabel())) {
            // doomed block
            continue;
        }
        IntList preds = ropMethod.labelToPredecessors(b.getLabel());
        // ...look at all of it's predecessors that have only one succ...
        int szPreds = preds.size();
        for (int i = 0; i < szPreds; i++) {
            int iLabel = preds.get(i);
            BasicBlock iBlock = blocks.labelToBlock(iLabel);
            if (toDelete.get(iLabel) || iBlock.getSuccessors().size() > 1 || iBlock.getFirstInsn().getOpcode().getOpcode() == RegOps.MOVE_RESULT) {
                continue;
            }
            IntList toCombine = new IntList();
            // ...and see if they can be combined with any other preds...
            for (int j = i + 1; j < szPreds; j++) {
                int jLabel = preds.get(j);
                BasicBlock jBlock = blocks.labelToBlock(jLabel);
                if (jBlock.getSuccessors().size() == 1 && compareInsns(iBlock, jBlock)) {
                    toCombine.add(jLabel);
                    toDelete.set(jLabel);
                }
            }
            combineBlocks(iLabel, toCombine);
        }
    }
    for (int i = szBlocks - 1; i >= 0; i--) {
        if (toDelete.get(newBlocks.get(i).getLabel())) {
            newBlocks.set(i, null);
        }
    }
    newBlocks.shrinkToFit();
    newBlocks.setImmutable();
    return new RopMethod(newBlocks, ropMethod.getFirstLabel());
}
Also used : RopMethod(com.taobao.android.dx.rop.code.RopMethod) BitSet(java.util.BitSet) BasicBlock(com.taobao.android.dx.rop.code.BasicBlock) IntList(com.taobao.android.dx.util.IntList)

Example 9 with IntList

use of com.taobao.android.dx.util.IntList in project atlas by alibaba.

the class IdenticalBlockCombiner method combineBlocks.

/**
 * Combines blocks proven identical into one alpha block, re-writing
 * all of the successor links that point to the beta blocks to point
 * to the alpha block instead.
 *
 * @param alphaLabel block that will replace all the beta block
 * @param betaLabels label list of blocks to combine
 */
private void combineBlocks(int alphaLabel, IntList betaLabels) {
    int szBetas = betaLabels.size();
    for (int i = 0; i < szBetas; i++) {
        int betaLabel = betaLabels.get(i);
        BasicBlock bb = blocks.labelToBlock(betaLabel);
        IntList preds = ropMethod.labelToPredecessors(bb.getLabel());
        int szPreds = preds.size();
        for (int j = 0; j < szPreds; j++) {
            BasicBlock predBlock = newBlocks.labelToBlock(preds.get(j));
            replaceSucc(predBlock, betaLabel, alphaLabel);
        }
    }
}
Also used : BasicBlock(com.taobao.android.dx.rop.code.BasicBlock) IntList(com.taobao.android.dx.util.IntList)

Example 10 with IntList

use of com.taobao.android.dx.util.IntList in project atlas by alibaba.

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.taobao.android.dx.rop.code.BasicBlock) ArrayList(java.util.ArrayList) IntList(com.taobao.android.dx.util.IntList)

Aggregations

IntList (com.taobao.android.dx.util.IntList)30 BasicBlock (com.taobao.android.dx.rop.code.BasicBlock)11 RopMethod (com.taobao.android.dx.rop.code.RopMethod)4 CstType (com.taobao.android.dx.rop.cst.CstType)4 BasicBlockList (com.taobao.android.dx.rop.code.BasicBlockList)3 DexTranslationAdvice (com.taobao.android.dx.rop.code.DexTranslationAdvice)3 Insn (com.taobao.android.dx.rop.code.Insn)3 TranslationAdvice (com.taobao.android.dx.rop.code.TranslationAdvice)3 BytecodeArray (com.taobao.android.dx.cf.code.BytecodeArray)2 ConcreteMethod (com.taobao.android.dx.cf.code.ConcreteMethod)2 Method (com.taobao.android.dx.cf.iface.Method)2 InsnList (com.taobao.android.dx.rop.code.InsnList)2 PlainCstInsn (com.taobao.android.dx.rop.code.PlainCstInsn)2 PlainInsn (com.taobao.android.dx.rop.code.PlainInsn)2 RegisterSpec (com.taobao.android.dx.rop.code.RegisterSpec)2 SourcePosition (com.taobao.android.dx.rop.code.SourcePosition)2 ThrowingCstInsn (com.taobao.android.dx.rop.code.ThrowingCstInsn)2 ThrowingInsn (com.taobao.android.dx.rop.code.ThrowingInsn)2 Type (com.taobao.android.dx.rop.type.Type)2 TypeList (com.taobao.android.dx.rop.type.TypeList)2