Search in sources :

Example 6 with BasicBlock

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

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.android.dx.rop.code.PlainInsn) ThrowingCstInsn(com.android.dx.rop.code.ThrowingCstInsn) ThrowingInsn(com.android.dx.rop.code.ThrowingInsn) PlainInsn(com.android.dx.rop.code.PlainInsn) Insn(com.android.dx.rop.code.Insn) PlainCstInsn(com.android.dx.rop.code.PlainCstInsn) SourcePosition(com.android.dx.rop.code.SourcePosition) BasicBlock(com.android.dx.rop.code.BasicBlock) InsnList(com.android.dx.rop.code.InsnList) ThrowingInsn(com.android.dx.rop.code.ThrowingInsn) RegisterSpec(com.android.dx.rop.code.RegisterSpec)

Example 7 with BasicBlock

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

the class Ropper method removeBlockAndSpecialSuccessors.

/**
     * Helper for {@link #addOrReplaceBlock} which recursively removes
     * the given block and all blocks that are (direct and indirect)
     * successors of it whose labels indicate that they are not in the
     * normally-translated range.
     *
     * @param idx {@code non-null;} block to remove (etc.)
     */
private void removeBlockAndSpecialSuccessors(int idx) {
    int minLabel = getMinimumUnreservedLabel();
    BasicBlock block = result.get(idx);
    IntList successors = block.getSuccessors();
    int sz = successors.size();
    result.remove(idx);
    resultSubroutines.remove(idx);
    for (int i = 0; i < sz; i++) {
        int label = successors.get(i);
        if (label >= minLabel) {
            idx = labelToResultIndex(label);
            if (idx < 0) {
                throw new RuntimeException("Invalid label " + Hex.u2(label));
            }
            removeBlockAndSpecialSuccessors(idx);
        }
    }
}
Also used : BasicBlock(com.android.dx.rop.code.BasicBlock) IntList(com.android.dx.util.IntList)

Example 8 with BasicBlock

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

the class SsaToRop method convertBasicBlock.

/**
     * Converts a single basic block to rop form.
     *
     * @param block SSA block to process
     * @return {@code non-null;} ROP block
     */
private BasicBlock convertBasicBlock(SsaBasicBlock block) {
    IntList successorList = block.getRopLabelSuccessorList();
    int primarySuccessorLabel = block.getPrimarySuccessorRopLabel();
    // Filter out any reference to the SSA form's exit block.
    // Exit block may be null.
    SsaBasicBlock exitBlock = ssaMeth.getExitBlock();
    int exitRopLabel = (exitBlock == null) ? -1 : exitBlock.getRopLabel();
    if (successorList.contains(exitRopLabel)) {
        if (successorList.size() > 1) {
            throw new RuntimeException("Exit predecessor must have no other successors" + Hex.u2(block.getRopLabel()));
        } else {
            successorList = IntList.EMPTY;
            primarySuccessorLabel = -1;
            verifyValidExitPredecessor(block);
        }
    }
    successorList.setImmutable();
    BasicBlock result = new BasicBlock(block.getRopLabel(), convertInsns(block.getInsns()), successorList, primarySuccessorLabel);
    return result;
}
Also used : SsaBasicBlock(com.android.dx.ssa.SsaBasicBlock) SsaBasicBlock(com.android.dx.ssa.SsaBasicBlock) BasicBlock(com.android.dx.rop.code.BasicBlock) IntList(com.android.dx.util.IntList)

Example 9 with BasicBlock

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

the class IdenticalBlockCombiner method combineBlocks.

/**
     * Combines blocks proven identical into one alpha block, re-writing
     * all of the successor links that point to the beta blocks to point
     * to the alpha block instead.
     *
     * @param alphaLabel block that will replace all the beta block
     * @param betaLabels label list of blocks to combine
     */
private void combineBlocks(int alphaLabel, IntList betaLabels) {
    int szBetas = betaLabels.size();
    for (int i = 0; i < szBetas; i++) {
        int betaLabel = betaLabels.get(i);
        BasicBlock bb = blocks.labelToBlock(betaLabel);
        IntList preds = ropMethod.labelToPredecessors(bb.getLabel());
        int szPreds = preds.size();
        for (int j = 0; j < szPreds; j++) {
            BasicBlock predBlock = newBlocks.labelToBlock(preds.get(j));
            replaceSucc(predBlock, betaLabel, alphaLabel);
        }
    }
}
Also used : BasicBlock(com.android.dx.rop.code.BasicBlock) IntList(com.android.dx.util.IntList)

Example 10 with BasicBlock

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

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.android.dx.rop.code.BasicBlock) ArrayList(java.util.ArrayList) IntList(com.android.dx.util.IntList)

Aggregations

BasicBlock (com.android.dx.rop.code.BasicBlock)38 IntList (com.android.dx.util.IntList)20 BasicBlockList (com.android.dx.rop.code.BasicBlockList)14 Insn (com.android.dx.rop.code.Insn)13 InsnList (com.android.dx.rop.code.InsnList)13 SourcePosition (com.android.dx.rop.code.SourcePosition)12 PlainCstInsn (com.android.dx.rop.code.PlainCstInsn)10 PlainInsn (com.android.dx.rop.code.PlainInsn)10 ThrowingCstInsn (com.android.dx.rop.code.ThrowingCstInsn)10 ThrowingInsn (com.android.dx.rop.code.ThrowingInsn)10 RegisterSpec (com.android.dx.rop.code.RegisterSpec)6 CstType (com.android.dx.rop.cst.CstType)6 TypeList (com.android.dx.rop.type.TypeList)6 RopMethod (com.android.dx.rop.code.RopMethod)4 StdTypeList (com.android.dx.rop.type.StdTypeList)4 Type (com.android.dx.rop.type.Type)4 ArrayList (java.util.ArrayList)4 DexTranslationAdvice (com.android.dx.rop.code.DexTranslationAdvice)2 RegisterSpecList (com.android.dx.rop.code.RegisterSpecList)2 Rop (com.android.dx.rop.code.Rop)2