Search in sources :

Example 6 with BasicBlockList

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

the class SsaBasicBlock method newFromRop.

/**
     * Creates a new SSA basic block from a ROP form basic block.
     *
     * @param rmeth original method
     * @param basicBlockIndex index this block will have
     * @param parent method of this block predecessor set will be
     * updated
     * @return new instance
     */
public static SsaBasicBlock newFromRop(RopMethod rmeth, int basicBlockIndex, final SsaMethod parent) {
    BasicBlockList ropBlocks = rmeth.getBlocks();
    BasicBlock bb = ropBlocks.get(basicBlockIndex);
    SsaBasicBlock result = new SsaBasicBlock(basicBlockIndex, bb.getLabel(), parent);
    InsnList ropInsns = bb.getInsns();
    result.insns.ensureCapacity(ropInsns.size());
    for (int i = 0, sz = ropInsns.size(); i < sz; i++) {
        result.insns.add(new NormalSsaInsn(ropInsns.get(i), result));
    }
    result.predecessors = SsaMethod.bitSetFromLabelList(ropBlocks, rmeth.labelToPredecessors(bb.getLabel()));
    result.successors = SsaMethod.bitSetFromLabelList(ropBlocks, bb.getSuccessors());
    result.successorList = SsaMethod.indexListFromLabelList(ropBlocks, bb.getSuccessors());
    if (result.successorList.size() != 0) {
        int primarySuccessor = bb.getPrimarySuccessor();
        result.primarySuccessor = (primarySuccessor < 0) ? -1 : ropBlocks.indexOfLabel(primarySuccessor);
    }
    return result;
}
Also used : BasicBlock(com.android.dx.rop.code.BasicBlock) InsnList(com.android.dx.rop.code.InsnList) BasicBlockList(com.android.dx.rop.code.BasicBlockList)

Example 7 with BasicBlockList

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

the class SsaMethod method convertRopToSsaBlocks.

private void convertRopToSsaBlocks(RopMethod rmeth) {
    BasicBlockList ropBlocks = rmeth.getBlocks();
    int sz = ropBlocks.size();
    blocks = new ArrayList<SsaBasicBlock>(sz + 2);
    for (int i = 0; i < sz; i++) {
        SsaBasicBlock sbb = SsaBasicBlock.newFromRop(rmeth, i, this);
        blocks.add(sbb);
    }
    // Add an no-op entry block.
    int origEntryBlockIndex = rmeth.getBlocks().indexOfLabel(rmeth.getFirstLabel());
    SsaBasicBlock entryBlock = blocks.get(origEntryBlockIndex).insertNewPredecessor();
    entryBlockIndex = entryBlock.getIndex();
    // This gets made later.
    exitBlockIndex = -1;
}
Also used : BasicBlockList(com.android.dx.rop.code.BasicBlockList)

Example 8 with BasicBlockList

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

the class SsaToRop method convertBasicBlocks.

/**
 * @return rop-form basic block list
 */
private BasicBlockList convertBasicBlocks() {
    ArrayList<SsaBasicBlock> blocks = ssaMeth.getBlocks();
    // Exit block may be null.
    SsaBasicBlock exitBlock = ssaMeth.getExitBlock();
    ssaMeth.computeReachability();
    int ropBlockCount = ssaMeth.getCountReachableBlocks();
    // Don't count the exit block, if it exists and is reachable.
    ropBlockCount -= (exitBlock != null && exitBlock.isReachable()) ? 1 : 0;
    BasicBlockList result = new BasicBlockList(ropBlockCount);
    // Convert all the reachable blocks except the exit block.
    int ropBlockIndex = 0;
    for (SsaBasicBlock b : blocks) {
        if (b.isReachable() && b != exitBlock) {
            result.set(ropBlockIndex++, convertBasicBlock(b));
        }
    }
    // The exit block, which is discarded, must do nothing.
    if (exitBlock != null && exitBlock.getInsns().size() != 0) {
        throw new RuntimeException("Exit block must have no insns when leaving SSA form");
    }
    return result;
}
Also used : SsaBasicBlock(com.android.dx.ssa.SsaBasicBlock) BasicBlockList(com.android.dx.rop.code.BasicBlockList)

Example 9 with BasicBlockList

use of com.android.dx.rop.code.BasicBlockList 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 10 with BasicBlockList

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

Aggregations

BasicBlockList (com.android.dx.rop.code.BasicBlockList)22 BasicBlock (com.android.dx.rop.code.BasicBlock)14 RopMethod (com.android.dx.rop.code.RopMethod)4 TypeList (com.android.dx.rop.type.TypeList)4 IntList (com.android.dx.util.IntList)4 Insn (com.android.dx.rop.code.Insn)3 InsnList (com.android.dx.rop.code.InsnList)3 DexTranslationAdvice (com.android.dx.rop.code.DexTranslationAdvice)2 SourcePosition (com.android.dx.rop.code.SourcePosition)2 TranslationAdvice (com.android.dx.rop.code.TranslationAdvice)2 CstType (com.android.dx.rop.cst.CstType)2 Type (com.android.dx.rop.type.Type)2 SsaBasicBlock (com.android.dx.ssa.SsaBasicBlock)2 ArrayList (java.util.ArrayList)2 HashSet (java.util.HashSet)2 BytecodeArray (com.android.dx.cf.code.BytecodeArray)1 ConcreteMethod (com.android.dx.cf.code.ConcreteMethod)1 Method (com.android.dx.cf.iface.Method)1 ByteArray (com.android.dx.util.ByteArray)1