Search in sources :

Example 11 with BasicBlockList

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

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 12 with BasicBlockList

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

the class BlockDumper method ropDump.

/**
     * Does a registerizing dump.
     *
     * @param meth {@code non-null;} method data to dump
     */
private void ropDump(ConcreteMethod meth) {
    TranslationAdvice advice = DexTranslationAdvice.THE_ONE;
    BytecodeArray code = meth.getCode();
    ByteArray bytes = code.getBytes();
    RopMethod rmeth = Ropper.convert(meth, advice, classFile.getMethods());
    StringBuffer sb = new StringBuffer(2000);
    if (optimize) {
        boolean isStatic = AccessFlags.isStatic(meth.getAccessFlags());
        int paramWidth = computeParamWidth(meth, isStatic);
        rmeth = Optimizer.optimize(rmeth, paramWidth, isStatic, true, advice);
    }
    BasicBlockList blocks = rmeth.getBlocks();
    int[] order = blocks.getLabelsInOrder();
    sb.append("first " + Hex.u2(rmeth.getFirstLabel()) + "\n");
    for (int label : order) {
        BasicBlock bb = blocks.get(blocks.indexOfLabel(label));
        sb.append("block ");
        sb.append(Hex.u2(label));
        sb.append("\n");
        IntList preds = rmeth.labelToPredecessors(label);
        int psz = preds.size();
        for (int i = 0; i < psz; i++) {
            sb.append("  pred ");
            sb.append(Hex.u2(preds.get(i)));
            sb.append("\n");
        }
        InsnList il = bb.getInsns();
        int ilsz = il.size();
        for (int i = 0; i < ilsz; i++) {
            Insn one = il.get(i);
            sb.append("  ");
            sb.append(il.get(i).toHuman());
            sb.append("\n");
        }
        IntList successors = bb.getSuccessors();
        int ssz = successors.size();
        if (ssz == 0) {
            sb.append("  returns\n");
        } else {
            int primary = bb.getPrimarySuccessor();
            for (int i = 0; i < ssz; i++) {
                int succ = successors.get(i);
                sb.append("  next ");
                sb.append(Hex.u2(succ));
                if ((ssz != 1) && (succ == primary)) {
                    sb.append(" *");
                }
                sb.append("\n");
            }
        }
    }
    suppressDump = false;
    setAt(bytes, 0);
    parsed(bytes, 0, bytes.size(), sb.toString());
    suppressDump = true;
}
Also used : BytecodeArray(com.android.dx.cf.code.BytecodeArray) Insn(com.android.dx.rop.code.Insn) RopMethod(com.android.dx.rop.code.RopMethod) BasicBlock(com.android.dx.rop.code.BasicBlock) DexTranslationAdvice(com.android.dx.rop.code.DexTranslationAdvice) TranslationAdvice(com.android.dx.rop.code.TranslationAdvice) InsnList(com.android.dx.rop.code.InsnList) IntList(com.android.dx.util.IntList) ByteArray(com.android.dx.util.ByteArray) BasicBlockList(com.android.dx.rop.code.BasicBlockList)

Example 13 with BasicBlockList

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

the class RopTranslator method outputInstructions.

/**
     * Performs initial creation of output instructions based on the
     * original blocks.
     */
private void outputInstructions() {
    BasicBlockList blocks = method.getBlocks();
    int[] order = this.order;
    int len = order.length;
    // Process the blocks in output order.
    for (int i = 0; i < len; i++) {
        int nextI = i + 1;
        int nextLabel = (nextI == order.length) ? -1 : order[nextI];
        outputBlock(blocks.labelToBlock(order[i]), nextLabel);
    }
}
Also used : BasicBlockList(com.android.dx.rop.code.BasicBlockList)

Example 14 with BasicBlockList

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

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 15 with BasicBlockList

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

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

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