Search in sources :

Example 6 with BasicBlock

use of com.taobao.android.dx.rop.code.BasicBlock in project atlas by alibaba.

the class RopTranslator method pickOrder.

/**
     * Picks an order for the blocks by doing "trace" analysis.
     */
private void pickOrder() {
    BasicBlockList blocks = method.getBlocks();
    int sz = blocks.size();
    int maxLabel = blocks.getMaxLabel();
    int[] workSet = Bits.makeBitSet(maxLabel);
    int[] tracebackSet = Bits.makeBitSet(maxLabel);
    for (int i = 0; i < sz; i++) {
        BasicBlock one = blocks.get(i);
        Bits.set(workSet, one.getLabel());
    }
    int[] order = new int[sz];
    int at = 0;
    /*
         * Starting with the designated "first label" (that is, the
         * first block of the method), add that label to the order,
         * and then pick its first as-yet unordered successor to
         * immediately follow it, giving top priority to the primary
         * (aka default) successor (if any). Keep following successors
         * until the trace runs out of possibilities. Then, continue
         * by finding an unordered chain containing the first as-yet
         * unordered block, and adding it to the order, and so on.
         */
    for (int label = method.getFirstLabel(); label != -1; label = Bits.findFirst(workSet, 0)) {
        /*
             * Attempt to trace backward from the chosen block to an
             * as-yet unordered predecessor which lists the chosen
             * block as its primary successor, and so on, until we
             * fail to find such an unordered predecessor. Start the
             * trace with that block. Note that the first block in the
             * method has no predecessors, so in that case this loop
             * will simply terminate with zero iterations and without
             * picking a new starter block.
             */
        traceBack: for (; ; ) {
            IntList preds = method.labelToPredecessors(label);
            int psz = preds.size();
            for (int i = 0; i < psz; i++) {
                int predLabel = preds.get(i);
                if (Bits.get(tracebackSet, predLabel)) {
                    /*
                         * We found a predecessor loop; stop tracing back
                         * from here.
                         */
                    break;
                }
                if (!Bits.get(workSet, predLabel)) {
                    // This one's already ordered.
                    continue;
                }
                BasicBlock pred = blocks.labelToBlock(predLabel);
                if (pred.getPrimarySuccessor() == label) {
                    // Found one!
                    label = predLabel;
                    Bits.set(tracebackSet, label);
                    continue traceBack;
                }
            }
            // Failed to find a better block to start the trace.
            break;
        }
        /*
             * Trace a path from the chosen block to one of its
             * unordered successors (hopefully the primary), and so
             * on, until we run out of unordered successors.
             */
        while (label != -1) {
            Bits.clear(workSet, label);
            Bits.clear(tracebackSet, label);
            order[at] = label;
            at++;
            BasicBlock one = blocks.labelToBlock(label);
            BasicBlock preferredBlock = blocks.preferredSuccessorOf(one);
            if (preferredBlock == null) {
                break;
            }
            int preferred = preferredBlock.getLabel();
            int primary = one.getPrimarySuccessor();
            if (Bits.get(workSet, preferred)) {
                /*
                     * Order the current block's preferred successor
                     * next, as it has yet to be scheduled.
                     */
                label = preferred;
            } else if ((primary != preferred) && (primary >= 0) && Bits.get(workSet, primary)) {
                /*
                     * The primary is available, so use that.
                     */
                label = primary;
            } else {
                /*
                     * There's no obvious candidate, so pick the first
                     * one that's available, if any.
                     */
                IntList successors = one.getSuccessors();
                int ssz = successors.size();
                label = -1;
                for (int i = 0; i < ssz; i++) {
                    int candidate = successors.get(i);
                    if (Bits.get(workSet, candidate)) {
                        label = candidate;
                        break;
                    }
                }
            }
        }
    }
    if (at != sz) {
        // There was a duplicate block label.
        throw new RuntimeException("shouldn't happen");
    }
    this.order = order;
}
Also used : BasicBlock(com.taobao.android.dx.rop.code.BasicBlock) BasicBlockList(com.taobao.android.dx.rop.code.BasicBlockList) IntList(com.taobao.android.dx.util.IntList)

Example 7 with BasicBlock

use of com.taobao.android.dx.rop.code.BasicBlock in project atlas by alibaba.

the class StdCatchBuilder method hasAnyCatches.

/** {@inheritDoc} */
public boolean hasAnyCatches() {
    BasicBlockList blocks = method.getBlocks();
    int size = blocks.size();
    for (int i = 0; i < size; i++) {
        BasicBlock block = blocks.get(i);
        TypeList catches = block.getLastInsn().getCatches();
        if (catches.size() != 0) {
            return true;
        }
    }
    return false;
}
Also used : BasicBlock(com.taobao.android.dx.rop.code.BasicBlock) BasicBlockList(com.taobao.android.dx.rop.code.BasicBlockList) TypeList(com.taobao.android.dx.rop.type.TypeList)

Example 8 with BasicBlock

use of com.taobao.android.dx.rop.code.BasicBlock in project atlas by alibaba.

the class StdCatchBuilder method getCatchTypes.

/** {@inheritDoc} */
public HashSet<Type> getCatchTypes() {
    HashSet<Type> result = new HashSet<Type>(20);
    BasicBlockList blocks = method.getBlocks();
    int size = blocks.size();
    for (int i = 0; i < size; i++) {
        BasicBlock block = blocks.get(i);
        TypeList catches = block.getLastInsn().getCatches();
        int catchSize = catches.size();
        for (int j = 0; j < catchSize; j++) {
            result.add(catches.getType(j));
        }
    }
    return result;
}
Also used : CstType(com.taobao.android.dx.rop.cst.CstType) Type(com.taobao.android.dx.rop.type.Type) BasicBlock(com.taobao.android.dx.rop.code.BasicBlock) BasicBlockList(com.taobao.android.dx.rop.code.BasicBlockList) TypeList(com.taobao.android.dx.rop.type.TypeList) HashSet(java.util.HashSet)

Example 9 with BasicBlock

use of com.taobao.android.dx.rop.code.BasicBlock in project atlas by alibaba.

the class BlockAddresses method setupArrays.

/**
     * Sets up the address arrays.
     */
private void setupArrays(RopMethod method) {
    BasicBlockList blocks = method.getBlocks();
    int sz = blocks.size();
    for (int i = 0; i < sz; i++) {
        BasicBlock one = blocks.get(i);
        int label = one.getLabel();
        Insn insn = one.getInsns().get(0);
        starts[label] = new CodeAddress(insn.getPosition());
        SourcePosition pos = one.getLastInsn().getPosition();
        lasts[label] = new CodeAddress(pos);
        ends[label] = new CodeAddress(pos);
    }
}
Also used : Insn(com.taobao.android.dx.rop.code.Insn) SourcePosition(com.taobao.android.dx.rop.code.SourcePosition) BasicBlock(com.taobao.android.dx.rop.code.BasicBlock) BasicBlockList(com.taobao.android.dx.rop.code.BasicBlockList)

Example 10 with BasicBlock

use of com.taobao.android.dx.rop.code.BasicBlock 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)

Aggregations

BasicBlock (com.taobao.android.dx.rop.code.BasicBlock)20 IntList (com.taobao.android.dx.util.IntList)11 BasicBlockList (com.taobao.android.dx.rop.code.BasicBlockList)8 Insn (com.taobao.android.dx.rop.code.Insn)7 InsnList (com.taobao.android.dx.rop.code.InsnList)7 SourcePosition (com.taobao.android.dx.rop.code.SourcePosition)6 PlainCstInsn (com.taobao.android.dx.rop.code.PlainCstInsn)5 PlainInsn (com.taobao.android.dx.rop.code.PlainInsn)5 ThrowingCstInsn (com.taobao.android.dx.rop.code.ThrowingCstInsn)5 ThrowingInsn (com.taobao.android.dx.rop.code.ThrowingInsn)5 RegisterSpec (com.taobao.android.dx.rop.code.RegisterSpec)3 RopMethod (com.taobao.android.dx.rop.code.RopMethod)3 CstType (com.taobao.android.dx.rop.cst.CstType)3 TypeList (com.taobao.android.dx.rop.type.TypeList)3 DexTranslationAdvice (com.taobao.android.dx.rop.code.DexTranslationAdvice)2 TranslationAdvice (com.taobao.android.dx.rop.code.TranslationAdvice)2 StdTypeList (com.taobao.android.dx.rop.type.StdTypeList)2 Type (com.taobao.android.dx.rop.type.Type)2 Optimizer (com.taobao.android.dx.ssa.Optimizer)2 ArrayList (java.util.ArrayList)2