Search in sources :

Example 1 with BasicBlockList

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

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 = new 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.taobao.android.dx.cf.code.BytecodeArray) Insn(com.taobao.android.dx.rop.code.Insn) RopMethod(com.taobao.android.dx.rop.code.RopMethod) Optimizer(com.taobao.android.dx.ssa.Optimizer) BasicBlock(com.taobao.android.dx.rop.code.BasicBlock) TranslationAdvice(com.taobao.android.dx.rop.code.TranslationAdvice) DexTranslationAdvice(com.taobao.android.dx.rop.code.DexTranslationAdvice) InsnList(com.taobao.android.dx.rop.code.InsnList) IntList(com.taobao.android.dx.util.IntList) ByteArray(com.taobao.android.dx.util.ByteArray) BasicBlockList(com.taobao.android.dx.rop.code.BasicBlockList)

Example 2 with BasicBlockList

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

the class DotDumper method endParsingMember.

public void endParsingMember(ByteArray bytes, int offset, String name, String descriptor, Member member) {
    if (!(member instanceof Method)) {
        return;
    }
    if (!shouldDumpMethod(name)) {
        return;
    }
    ConcreteMethod meth = new ConcreteMethod((Method) member, classFile, true, true);
    TranslationAdvice advice = DexTranslationAdvice.THE_ONE;
    RopMethod rmeth = Ropper.convert(meth, advice, classFile.getMethods());
    if (optimize) {
        boolean isStatic = AccessFlags.isStatic(meth.getAccessFlags());
        rmeth = new Optimizer().optimize(rmeth, BaseDumper.computeParamWidth(meth, isStatic), isStatic, true, advice);
    }
    System.out.println("digraph " + name + "{");
    System.out.println("\tfirst -> n" + Hex.u2(rmeth.getFirstLabel()) + ";");
    BasicBlockList blocks = rmeth.getBlocks();
    int sz = blocks.size();
    for (int i = 0; i < sz; i++) {
        BasicBlock bb = blocks.get(i);
        int label = bb.getLabel();
        IntList successors = bb.getSuccessors();
        if (successors.size() == 0) {
            System.out.println("\tn" + Hex.u2(label) + " -> returns;");
        } else if (successors.size() == 1) {
            System.out.println("\tn" + Hex.u2(label) + " -> n" + Hex.u2(successors.get(0)) + ";");
        } else {
            System.out.print("\tn" + Hex.u2(label) + " -> {");
            for (int j = 0; j < successors.size(); j++) {
                int successor = successors.get(j);
                if (successor != bb.getPrimarySuccessor()) {
                    System.out.print(" n" + Hex.u2(successor) + " ");
                }
            }
            System.out.println("};");
            System.out.println("\tn" + Hex.u2(label) + " -> n" + Hex.u2(bb.getPrimarySuccessor()) + " [label=\"primary\"];");
        }
    }
    System.out.println("}");
}
Also used : RopMethod(com.taobao.android.dx.rop.code.RopMethod) Optimizer(com.taobao.android.dx.ssa.Optimizer) ConcreteMethod(com.taobao.android.dx.cf.code.ConcreteMethod) BasicBlock(com.taobao.android.dx.rop.code.BasicBlock) DexTranslationAdvice(com.taobao.android.dx.rop.code.DexTranslationAdvice) TranslationAdvice(com.taobao.android.dx.rop.code.TranslationAdvice) ConcreteMethod(com.taobao.android.dx.cf.code.ConcreteMethod) RopMethod(com.taobao.android.dx.rop.code.RopMethod) Method(com.taobao.android.dx.cf.iface.Method) BasicBlockList(com.taobao.android.dx.rop.code.BasicBlockList) IntList(com.taobao.android.dx.util.IntList)

Example 3 with BasicBlockList

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

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

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.taobao.android.dx.rop.code.BasicBlockList)

Example 5 with BasicBlockList

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

Aggregations

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