Search in sources :

Example 26 with IntList

use of com.android.dx.util.IntList 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 27 with IntList

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

the class StdCatchBuilder method handlersFor.

/**
 * Makes the {@link CatchHandlerList} for the given basic block.
 *
 * @param block {@code non-null;} block to get entries for
 * @param addresses {@code non-null;} address objects for each block
 * @return {@code non-null;} array of entries
 */
private static CatchHandlerList handlersFor(BasicBlock block, BlockAddresses addresses) {
    IntList successors = block.getSuccessors();
    int succSize = successors.size();
    int primary = block.getPrimarySuccessor();
    TypeList catches = block.getLastInsn().getCatches();
    int catchSize = catches.size();
    if (catchSize == 0) {
        return CatchHandlerList.EMPTY;
    }
    if (((primary == -1) && (succSize != catchSize)) || ((primary != -1) && ((succSize != (catchSize + 1)) || (primary != successors.get(catchSize))))) {
        /*
             * Blocks that throw are supposed to list their primary
             * successor -- if any -- last in the successors list, but
             * that constraint appears to be violated here.
             */
        throw new RuntimeException("shouldn't happen: weird successors list");
    }
    /*
         * Reduce the effective catchSize if we spot a catch-all that
         * isn't at the end.
         */
    for (int i = 0; i < catchSize; i++) {
        Type type = catches.getType(i);
        if (type.equals(Type.OBJECT)) {
            catchSize = i + 1;
            break;
        }
    }
    CatchHandlerList result = new CatchHandlerList(catchSize);
    for (int i = 0; i < catchSize; i++) {
        CstType oneType = new CstType(catches.getType(i));
        CodeAddress oneHandler = addresses.getStart(successors.get(i));
        result.set(i, oneType, oneHandler.getAddress());
    }
    result.setImmutable();
    return result;
}
Also used : Type(com.android.dx.rop.type.Type) CstType(com.android.dx.rop.cst.CstType) CstType(com.android.dx.rop.cst.CstType) TypeList(com.android.dx.rop.type.TypeList) IntList(com.android.dx.util.IntList)

Example 28 with IntList

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

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.android.dx.util.IntList)

Example 29 with IntList

use of com.android.dx.util.IntList 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)

Example 30 with IntList

use of com.android.dx.util.IntList in project buck by facebook.

the class IdenticalBlockCombiner method replaceSucc.

/**
     * Replaces one of a block's successors with a different label. Constructs
     * an updated BasicBlock instance and places it in {@code newBlocks}.
     *
     * @param block block to replace
     * @param oldLabel label of successor to replace
     * @param newLabel label of new successor
     */
private void replaceSucc(BasicBlock block, int oldLabel, int newLabel) {
    IntList newSuccessors = block.getSuccessors().mutableCopy();
    int newPrimarySuccessor;
    newSuccessors.set(newSuccessors.indexOf(oldLabel), newLabel);
    newPrimarySuccessor = block.getPrimarySuccessor();
    if (newPrimarySuccessor == oldLabel) {
        newPrimarySuccessor = newLabel;
    }
    newSuccessors.setImmutable();
    BasicBlock newBB = new BasicBlock(block.getLabel(), block.getInsns(), newSuccessors, newPrimarySuccessor);
    newBlocks.set(newBlocks.indexOfLabel(block.getLabel()), newBB);
}
Also used : BasicBlock(com.android.dx.rop.code.BasicBlock) 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