Search in sources :

Example 16 with BasicBlock

use of com.android.dx.rop.code.BasicBlock in project J2ME-Loader by nikita36078.

the class Ropper method removeBlockAndSpecialSuccessors.

/**
 * Helper for {@link #addOrReplaceBlock} which recursively removes
 * the given block and all blocks that are (direct and indirect)
 * successors of it whose labels indicate that they are not in the
 * normally-translated range.
 *
 * @param idx {@code non-null;} block to remove (etc.)
 */
private void removeBlockAndSpecialSuccessors(int idx) {
    int minLabel = getMinimumUnreservedLabel();
    BasicBlock block = result.get(idx);
    IntList successors = block.getSuccessors();
    int sz = successors.size();
    result.remove(idx);
    resultSubroutines.remove(idx);
    for (int i = 0; i < sz; i++) {
        int label = successors.get(i);
        if (label >= minLabel) {
            idx = labelToResultIndex(label);
            if (idx < 0) {
                throw new RuntimeException("Invalid label " + Hex.u2(label));
            }
            removeBlockAndSpecialSuccessors(idx);
        }
    }
}
Also used : BasicBlock(com.android.dx.rop.code.BasicBlock) IntList(com.android.dx.util.IntList)

Example 17 with BasicBlock

use of com.android.dx.rop.code.BasicBlock in project J2ME-Loader by nikita36078.

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

Example 18 with BasicBlock

use of com.android.dx.rop.code.BasicBlock in project J2ME-Loader by nikita36078.

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

Example 19 with BasicBlock

use of com.android.dx.rop.code.BasicBlock in project J2ME-Loader by nikita36078.

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 : Type(com.android.dx.rop.type.Type) CstType(com.android.dx.rop.cst.CstType) BasicBlock(com.android.dx.rop.code.BasicBlock) BasicBlockList(com.android.dx.rop.code.BasicBlockList) TypeList(com.android.dx.rop.type.TypeList) HashSet(java.util.HashSet)

Example 20 with BasicBlock

use of com.android.dx.rop.code.BasicBlock in project buck by facebook.

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

Aggregations

BasicBlock (com.android.dx.rop.code.BasicBlock)38 IntList (com.android.dx.util.IntList)20 BasicBlockList (com.android.dx.rop.code.BasicBlockList)14 Insn (com.android.dx.rop.code.Insn)13 InsnList (com.android.dx.rop.code.InsnList)13 SourcePosition (com.android.dx.rop.code.SourcePosition)12 PlainCstInsn (com.android.dx.rop.code.PlainCstInsn)10 PlainInsn (com.android.dx.rop.code.PlainInsn)10 ThrowingCstInsn (com.android.dx.rop.code.ThrowingCstInsn)10 ThrowingInsn (com.android.dx.rop.code.ThrowingInsn)10 RegisterSpec (com.android.dx.rop.code.RegisterSpec)6 CstType (com.android.dx.rop.cst.CstType)6 TypeList (com.android.dx.rop.type.TypeList)6 RopMethod (com.android.dx.rop.code.RopMethod)4 StdTypeList (com.android.dx.rop.type.StdTypeList)4 Type (com.android.dx.rop.type.Type)4 ArrayList (java.util.ArrayList)4 DexTranslationAdvice (com.android.dx.rop.code.DexTranslationAdvice)2 RegisterSpecList (com.android.dx.rop.code.RegisterSpecList)2 Rop (com.android.dx.rop.code.Rop)2