Search in sources :

Example 1 with BasicBlock

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

the class Ropper method addSynchExceptionHandlerBlock.

/**
     * Constructs and adds, if necessary, the catch-all exception handler
     * block to deal with unwinding the lock taken on entry to a synchronized
     * method.
     */
private void addSynchExceptionHandlerBlock() {
    if (!synchNeedsExceptionHandler) {
        /*
             * The method being converted either isn't synchronized or
             * can't possibly throw exceptions in its main body, so
             * there's no need for a synchronized method exception
             * handler.
             */
        return;
    }
    SourcePosition pos = method.makeSourcePosistion(0);
    RegisterSpec exReg = RegisterSpec.make(0, Type.THROWABLE);
    BasicBlock bb;
    Insn insn;
    InsnList insns = new InsnList(2);
    insn = new PlainInsn(Rops.opMoveException(Type.THROWABLE), pos, exReg, RegisterSpecList.EMPTY);
    insns.set(0, insn);
    insn = new ThrowingInsn(Rops.MONITOR_EXIT, pos, RegisterSpecList.make(getSynchReg()), StdTypeList.EMPTY);
    insns.set(1, insn);
    insns.setImmutable();
    int label2 = getSpecialLabel(SYNCH_CATCH_2);
    bb = new BasicBlock(getSpecialLabel(SYNCH_CATCH_1), insns, IntList.makeImmutable(label2), label2);
    addBlock(bb, IntList.EMPTY);
    insns = new InsnList(1);
    insn = new ThrowingInsn(Rops.THROW, pos, RegisterSpecList.make(exReg), StdTypeList.EMPTY);
    insns.set(0, insn);
    insns.setImmutable();
    bb = new BasicBlock(label2, insns, IntList.EMPTY, -1);
    addBlock(bb, IntList.EMPTY);
}
Also used : PlainInsn(com.taobao.android.dx.rop.code.PlainInsn) Insn(com.taobao.android.dx.rop.code.Insn) PlainCstInsn(com.taobao.android.dx.rop.code.PlainCstInsn) PlainInsn(com.taobao.android.dx.rop.code.PlainInsn) ThrowingInsn(com.taobao.android.dx.rop.code.ThrowingInsn) ThrowingCstInsn(com.taobao.android.dx.rop.code.ThrowingCstInsn) SourcePosition(com.taobao.android.dx.rop.code.SourcePosition) BasicBlock(com.taobao.android.dx.rop.code.BasicBlock) InsnList(com.taobao.android.dx.rop.code.InsnList) ThrowingInsn(com.taobao.android.dx.rop.code.ThrowingInsn) RegisterSpec(com.taobao.android.dx.rop.code.RegisterSpec)

Example 2 with BasicBlock

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

the class Ropper method inlineSubroutines.

/**
     * Inlines any subroutine calls.
     */
private void inlineSubroutines() {
    final IntList reachableSubroutineCallerLabels = new IntList(4);
    /*
         * Compile a list of all subroutine calls reachable
         * through the normal (non-subroutine) flow.  We do this first, since
         * we'll be affecting the call flow as we go.
         *
         * Start at label 0 --  the param assignment block has nothing for us
         */
    forEachNonSubBlockDepthFirst(0, new BasicBlock.Visitor() {

        public void visitBlock(BasicBlock b) {
            if (isSubroutineCaller(b)) {
                reachableSubroutineCallerLabels.add(b.getLabel());
            }
        }
    });
    /*
         * Convert the resultSubroutines list, indexed by block index,
         * to a label-to-subroutines mapping used by the inliner.
         */
    int largestAllocedLabel = getAvailableLabel();
    ArrayList<IntList> labelToSubroutines = new ArrayList<IntList>(largestAllocedLabel);
    for (int i = 0; i < largestAllocedLabel; i++) {
        labelToSubroutines.add(null);
    }
    for (int i = 0; i < result.size(); i++) {
        BasicBlock b = result.get(i);
        if (b == null) {
            continue;
        }
        IntList subroutineList = resultSubroutines.get(i);
        labelToSubroutines.set(b.getLabel(), subroutineList);
    }
    /*
         * Inline all reachable subroutines.
         * Inner subroutines will be inlined as they are encountered.
         */
    int sz = reachableSubroutineCallerLabels.size();
    for (int i = 0; i < sz; i++) {
        int label = reachableSubroutineCallerLabels.get(i);
        new SubroutineInliner(new LabelAllocator(getAvailableLabel()), labelToSubroutines).inlineSubroutineCalledFrom(labelToBlock(label));
    }
    // Now find the blocks that aren't reachable and remove them
    deleteUnreachableBlocks();
}
Also used : BasicBlock(com.taobao.android.dx.rop.code.BasicBlock) ArrayList(java.util.ArrayList) IntList(com.taobao.android.dx.util.IntList)

Example 3 with BasicBlock

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

the class Ropper method addExceptionSetupBlocks.

/**
     * Creates the exception handler setup blocks. "maxLocals"
     * below is because that's the register number corresponding
     * to the sole element on a one-deep stack (which is the
     * situation at the start of an exception handler block).
     */
private void addExceptionSetupBlocks() {
    int len = catchInfos.length;
    for (int i = 0; i < len; i++) {
        CatchInfo catches = catchInfos[i];
        if (catches != null) {
            for (ExceptionHandlerSetup one : catches.getSetups()) {
                Insn proto = labelToBlock(i).getFirstInsn();
                SourcePosition pos = proto.getPosition();
                InsnList il = new InsnList(2);
                Insn insn = new PlainInsn(Rops.opMoveException(one.getCaughtType()), pos, RegisterSpec.make(maxLocals, one.getCaughtType()), RegisterSpecList.EMPTY);
                il.set(0, insn);
                insn = new PlainInsn(Rops.GOTO, pos, null, RegisterSpecList.EMPTY);
                il.set(1, insn);
                il.setImmutable();
                BasicBlock bb = new BasicBlock(one.getLabel(), il, IntList.makeImmutable(i), i);
                addBlock(bb, startFrames[i].getSubroutines());
            }
        }
    }
}
Also used : PlainInsn(com.taobao.android.dx.rop.code.PlainInsn) Insn(com.taobao.android.dx.rop.code.Insn) PlainCstInsn(com.taobao.android.dx.rop.code.PlainCstInsn) PlainInsn(com.taobao.android.dx.rop.code.PlainInsn) ThrowingInsn(com.taobao.android.dx.rop.code.ThrowingInsn) ThrowingCstInsn(com.taobao.android.dx.rop.code.ThrowingCstInsn) SourcePosition(com.taobao.android.dx.rop.code.SourcePosition) BasicBlock(com.taobao.android.dx.rop.code.BasicBlock) InsnList(com.taobao.android.dx.rop.code.InsnList)

Example 4 with BasicBlock

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

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

Aggregations

BasicBlock (com.taobao.android.dx.rop.code.BasicBlock)20 IntList (com.taobao.android.dx.util.IntList)11 BasicBlockList (com.taobao.android.dx.rop.code.BasicBlockList)8 Insn (com.taobao.android.dx.rop.code.Insn)7 InsnList (com.taobao.android.dx.rop.code.InsnList)7 SourcePosition (com.taobao.android.dx.rop.code.SourcePosition)6 PlainCstInsn (com.taobao.android.dx.rop.code.PlainCstInsn)5 PlainInsn (com.taobao.android.dx.rop.code.PlainInsn)5 ThrowingCstInsn (com.taobao.android.dx.rop.code.ThrowingCstInsn)5 ThrowingInsn (com.taobao.android.dx.rop.code.ThrowingInsn)5 RegisterSpec (com.taobao.android.dx.rop.code.RegisterSpec)3 RopMethod (com.taobao.android.dx.rop.code.RopMethod)3 CstType (com.taobao.android.dx.rop.cst.CstType)3 TypeList (com.taobao.android.dx.rop.type.TypeList)3 DexTranslationAdvice (com.taobao.android.dx.rop.code.DexTranslationAdvice)2 TranslationAdvice (com.taobao.android.dx.rop.code.TranslationAdvice)2 StdTypeList (com.taobao.android.dx.rop.type.StdTypeList)2 Type (com.taobao.android.dx.rop.type.Type)2 Optimizer (com.taobao.android.dx.ssa.Optimizer)2 ArrayList (java.util.ArrayList)2