com.android.dx.util.IntList Java Examples

The following examples show how to use com.android.dx.util.IntList. You can vote up the ones you like or vote down the ones you don't like, and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example #1
Source File: Frame.java    From Box with Apache License 2.0 6 votes vote down vote up
/**
 * Merges two frames. If the merged result is the same as this frame,
 * then this instance is returned.
 *
 * @param other {@code non-null;} another frame
 * @return {@code non-null;} the result of merging the two frames
 */
public Frame mergeWith(Frame other) {
    LocalsArray resultLocals;
    ExecutionStack resultStack;
    IntList resultSubroutines;

    resultLocals = getLocals().merge(other.getLocals());
    resultStack = getStack().merge(other.getStack());
    resultSubroutines = mergeSubroutineLists(other.subroutines);

    resultLocals = adjustLocalsForSubroutines(
            resultLocals, resultSubroutines);

    if ((resultLocals == getLocals())
            && (resultStack == getStack())
            && subroutines == resultSubroutines) {
        return this;
    }

    return new Frame(resultLocals, resultStack, resultSubroutines);
}
 
Example #2
Source File: BasicBlocker.java    From Box with Apache License 2.0 6 votes vote down vote up
/**
 * Constructs an instance. This class is not publicly instantiable; use
 * {@link #identifyBlocks}.
 *
 * @param method {@code non-null;} method to convert
 */
private BasicBlocker(ConcreteMethod method) {
    if (method == null) {
        throw new NullPointerException("method == null");
    }

    this.method = method;

    /*
     * The "+1" below is so the idx-past-end is also valid,
     * avoiding a special case, but without preventing
     * flow-of-control falling past the end of the method from
     * getting properly reported.
     */
    int sz = method.getCode().size() + 1;

    workSet = Bits.makeBitSet(sz);
    liveSet = Bits.makeBitSet(sz);
    blockSet = Bits.makeBitSet(sz);
    targetLists = new IntList[sz];
    catchLists = new ByteCatchList[sz];
    previousOffset = -1;
}
 
Example #3
Source File: Ropper.java    From buck with Apache License 2.0 6 votes vote down vote up
/**
 * 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);
        }
    }
}
 
Example #4
Source File: Frame.java    From Box with Apache License 2.0 6 votes vote down vote up
/**
 * Constructs an instance.
 *
 * @param locals {@code non-null;} the locals array to use
 * @param stack {@code non-null;} the execution stack to use
 * @param subroutines {@code non-null;} list of subroutine start labels for
 * subroutines this frame is nested in
 */
private Frame(LocalsArray locals,
        ExecutionStack stack, IntList subroutines) {
    if (locals == null) {
        throw new NullPointerException("locals == null");
    }

    if (stack == null) {
        throw new NullPointerException("stack == null");
    }

    subroutines.throwIfMutable();

    this.locals = locals;
    this.stack = stack;
    this.subroutines = subroutines;
}
 
Example #5
Source File: Ropper.java    From Box with Apache License 2.0 6 votes vote down vote up
/**
 * Adds or replaces a block in the output result. Do not delete
 * any successors.
 *
 * @param block {@code non-null;} the block to add or replace
 * @param subroutines {@code non-null;} subroutine label list
 * as described in {@link Frame#getSubroutines}
 * @return {@code true} if the block was replaced or
 * {@code false} if it was added for the first time
 */
private boolean addOrReplaceBlockNoDelete(BasicBlock block,
        IntList subroutines) {
    if (block == null) {
        throw new NullPointerException("block == null");
    }

    int idx = labelToResultIndex(block.getLabel());
    boolean ret;

    if (idx < 0) {
        ret = false;
    } else {
        result.remove(idx);
        resultSubroutines.remove(idx);
        ret = true;
    }

    result.add(block);
    subroutines.throwIfMutable();
    resultSubroutines.add(subroutines);
    return ret;
}
 
Example #6
Source File: Ropper.java    From Box with Apache License 2.0 6 votes vote down vote up
/**
 * 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);
        }
    }
}
 
Example #7
Source File: Frame.java    From J2ME-Loader with Apache License 2.0 6 votes vote down vote up
/**
 * Merges this frame's subroutine lists with another. The result
 * is the deepest common nesting (effectively, the common prefix of the
 * two lists).
 *
 * @param otherSubroutines label list of subroutine start blocks, from
 * least-nested to most-nested.
 * @return {@code non-null;} merged subroutine nest list as described above
 */
private IntList mergeSubroutineLists(IntList otherSubroutines) {
    if (subroutines.equals(otherSubroutines)) {
        return subroutines;
    }

    IntList resultSubroutines = new IntList();

    int szSubroutines = subroutines.size();
    int szOthers = otherSubroutines.size();
    for (int i = 0; i < szSubroutines && i < szOthers
            && (subroutines.get(i) == otherSubroutines.get(i)); i++) {
        resultSubroutines.add(i);
    }

    resultSubroutines.setImmutable();

    return resultSubroutines;
}
 
Example #8
Source File: IdenticalBlockCombiner.java    From Box with Apache License 2.0 6 votes vote down vote up
/**
 * Replaces one of a block's successors with a different label. Constructs
 * an updated BasicBlock instance and places it in {@code newBlocks}.
 *
 * @param block block to replace
 * @param oldLabel label of successor to replace
 * @param newLabel label of new successor
 */
private void replaceSucc(BasicBlock block, int oldLabel, int newLabel) {
    IntList newSuccessors = block.getSuccessors().mutableCopy();
    int newPrimarySuccessor;

    newSuccessors.set(newSuccessors.indexOf(oldLabel), newLabel);
    newPrimarySuccessor = block.getPrimarySuccessor();

    if (newPrimarySuccessor == oldLabel) {
        newPrimarySuccessor = newLabel;
    }

    newSuccessors.setImmutable();

    BasicBlock newBB = new BasicBlock(block.getLabel(),
            block.getInsns(), newSuccessors, newPrimarySuccessor);

    newBlocks.set(newBlocks.indexOfLabel(block.getLabel()), newBB);
}
 
Example #9
Source File: Frame.java    From J2ME-Loader with Apache License 2.0 6 votes vote down vote up
/**
 * Constructs an instance.
 *
 * @param locals {@code non-null;} the locals array to use
 * @param stack {@code non-null;} the execution stack to use
 * @param subroutines {@code non-null;} list of subroutine start labels for
 * subroutines this frame is nested in
 */
private Frame(LocalsArray locals,
        ExecutionStack stack, IntList subroutines) {
    if (locals == null) {
        throw new NullPointerException("locals == null");
    }

    if (stack == null) {
        throw new NullPointerException("stack == null");
    }

    subroutines.throwIfMutable();

    this.locals = locals;
    this.stack = stack;
    this.subroutines = subroutines;
}
 
Example #10
Source File: Ropper.java    From J2ME-Loader with Apache License 2.0 6 votes vote down vote up
/**
  * Deletes all blocks that cannot be reached. This is run to delete
  * original subroutine blocks after subroutine inlining.
  */
 private void deleteUnreachableBlocks() {
     final IntList reachableLabels = new IntList(result.size());

     // subroutine inlining is done now and we won't update this list here
     resultSubroutines.clear();

     forEachNonSubBlockDepthFirst(getSpecialLabel(PARAM_ASSIGNMENT),
             new BasicBlock.Visitor() {

         @Override
public void visitBlock(BasicBlock b) {
             reachableLabels.add(b.getLabel());
         }
     });

     reachableLabels.sort();

     for (int i = result.size() - 1 ; i >= 0 ; i--) {
         if (reachableLabels.indexOf(result.get(i).getLabel()) < 0) {
             result.remove(i);
             // unnecessary here really, since subroutine inlining is done
             //resultSubroutines.remove(i);
         }
     }
 }
 
Example #11
Source File: IdenticalBlockCombiner.java    From buck with Apache License 2.0 6 votes vote down vote up
/**
 * Replaces one of a block's successors with a different label. Constructs
 * an updated BasicBlock instance and places it in {@code newBlocks}.
 *
 * @param block block to replace
 * @param oldLabel label of successor to replace
 * @param newLabel label of new successor
 */
private void replaceSucc(BasicBlock block, int oldLabel, int newLabel) {
    IntList newSuccessors = block.getSuccessors().mutableCopy();
    int newPrimarySuccessor;

    newSuccessors.set(newSuccessors.indexOf(oldLabel), newLabel);
    newPrimarySuccessor = block.getPrimarySuccessor();

    if (newPrimarySuccessor == oldLabel) {
        newPrimarySuccessor = newLabel;
    }

    newSuccessors.setImmutable();

    BasicBlock newBB = new BasicBlock(block.getLabel(),
            block.getInsns(), newSuccessors, newPrimarySuccessor);

    newBlocks.set(newBlocks.indexOfLabel(block.getLabel()), newBB);
}
 
Example #12
Source File: SwitchData.java    From buck with Apache License 2.0 6 votes vote down vote up
/**
 * Determines whether the given list of cases warrant being packed.
 *
 * @param cases {@code non-null;} sorted list of cases
 * @return {@code true} iff the table encoding the cases
 * should be packed
 */
private static boolean shouldPack(IntList cases) {
    int sz = cases.size();

    if (sz < 2) {
        return true;
    }

    long packedSize = packedCodeSize(cases);
    long sparseSize = sparseCodeSize(cases);

    /*
     * We pick the packed representation if it is possible and
     * would be as small or smaller than 5/4 of the sparse
     * representation. That is, we accept some size overhead on
     * the packed representation, since that format is faster to
     * execute at runtime.
     */
    return (packedSize >= 0) && (packedSize <= ((sparseSize * 5) / 4));
}
 
Example #13
Source File: IdenticalBlockCombiner.java    From J2ME-Loader with Apache License 2.0 6 votes vote down vote up
/**
 * Replaces one of a block's successors with a different label. Constructs
 * an updated BasicBlock instance and places it in {@code newBlocks}.
 *
 * @param block block to replace
 * @param oldLabel label of successor to replace
 * @param newLabel label of new successor
 */
private void replaceSucc(BasicBlock block, int oldLabel, int newLabel) {
    IntList newSuccessors = block.getSuccessors().mutableCopy();
    int newPrimarySuccessor;

    newSuccessors.set(newSuccessors.indexOf(oldLabel), newLabel);
    newPrimarySuccessor = block.getPrimarySuccessor();

    if (newPrimarySuccessor == oldLabel) {
        newPrimarySuccessor = newLabel;
    }

    newSuccessors.setImmutable();

    BasicBlock newBB = new BasicBlock(block.getLabel(),
            block.getInsns(), newSuccessors, newPrimarySuccessor);

    newBlocks.set(newBlocks.indexOfLabel(block.getLabel()), newBB);
}
 
Example #14
Source File: SsaToRop.java    From buck with Apache License 2.0 5 votes vote down vote up
/**
 * 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;
}
 
Example #15
Source File: SsaMethod.java    From Box with Apache License 2.0 5 votes vote down vote up
/**
 * Builds an IntList of block indices from a basic block list and a list
 * of labels taken from Rop form.
 *
 * @param ropBlocks Rop blocks
 * @param labelList list of rop block labels
 * @return IntList of block indices
 */
public static IntList indexListFromLabelList(BasicBlockList ropBlocks,
        IntList labelList) {

    IntList result = new IntList(labelList.size());

    for (int i = 0, sz = labelList.size(); i < sz; i++) {
        result.add(ropBlocks.indexOfLabel(labelList.get(i)));
    }

    return result;
}
 
Example #16
Source File: SsaBasicBlock.java    From buck with Apache License 2.0 5 votes vote down vote up
/**
 * @return successor list of rop labels
 */
public IntList getRopLabelSuccessorList() {
    IntList result = new IntList(successorList.size());

    int sz = successorList.size();

    for (int i = 0; i < sz; i++) {
        result.add(parent.blockIndexToRopLabel(successorList.get(i)));
    }
    return result;
}
 
Example #17
Source File: SwitchList.java    From buck with Apache License 2.0 5 votes vote down vote up
/**
 * Constructs an instance.
 *
 * @param size {@code >= 0;} the number of elements to be in the table
 */
public SwitchList(int size) {
    super(true);
    this.values = new IntList(size);
    this.targets = new IntList(size + 1);
    this.size = size;
}
 
Example #18
Source File: SsaMethod.java    From buck with Apache License 2.0 5 votes vote down vote up
/**
 * Builds an IntList of block indices from a basic block list and a list
 * of labels taken from Rop form.
 *
 * @param ropBlocks Rop blocks
 * @param labelList list of rop block labels
 * @return IntList of block indices
 */
public static IntList indexListFromLabelList(BasicBlockList ropBlocks,
        IntList labelList) {

    IntList result = new IntList(labelList.size());

    for (int i = 0, sz = labelList.size(); i < sz; i++) {
        result.add(ropBlocks.indexOfLabel(labelList.get(i)));
    }

    return result;
}
 
Example #19
Source File: Ropper.java    From buck with Apache License 2.0 5 votes vote down vote up
/**
 * Adds a block to the output result.
 *
 * @param block {@code non-null;} the block to add
 * @param subroutines {@code non-null;} subroutine label list
 * as described in {@link Frame#getSubroutines}
 */
private void addBlock(BasicBlock block, IntList subroutines) {
    if (block == null) {
        throw new NullPointerException("block == null");
    }

    result.add(block);
    subroutines.throwIfMutable();
    resultSubroutines.add(subroutines);
}
 
Example #20
Source File: SsaBasicBlock.java    From J2ME-Loader with Apache License 2.0 5 votes vote down vote up
/**
 * @return successor list of rop labels
 */
public IntList getRopLabelSuccessorList() {
    IntList result = new IntList(successorList.size());

    int sz = successorList.size();

    for (int i = 0; i < sz; i++) {
        result.add(parent.blockIndexToRopLabel(successorList.get(i)));
    }
    return result;
}
 
Example #21
Source File: RopMethod.java    From Box with Apache License 2.0 5 votes vote down vote up
/**
 * Gets the predecessors associated with the given block. This throws
 * an exception if there is no block with the given label.
 *
 * @param label {@code >= 0;} the label of the block in question
 * @return {@code non-null;} the predecessors of that block
 */
public IntList labelToPredecessors(int label) {
    if (exitPredecessors == null) {
        calcPredecessors();
    }

    IntList result = predecessors[label];

    if (result == null) {
        throw new RuntimeException("no such block: " + Hex.u2(label));
    }

    return result;
}
 
Example #22
Source File: Frame.java    From buck with Apache License 2.0 5 votes vote down vote up
/**
 * Adjusts a locals array to account for a merged subroutines list.
 * If a frame merge results in, effectively, a subroutine return through
 * a throw then the current locals will be a LocalsArraySet that will
 * need to be trimmed of all OneLocalsArray elements that relevent to
 * the subroutine that is returning.
 *
 * @param locals {@code non-null;} LocalsArray from before a merge
 * @param subroutines {@code non-null;} a label list of subroutine start blocks
 * representing the subroutine nesting of the block being merged into.
 * @return {@code non-null;} locals set appropriate for merge
 */
private static LocalsArray adjustLocalsForSubroutines(
        LocalsArray locals, IntList subroutines) {
    if (! (locals instanceof LocalsArraySet)) {
        // nothing to see here
        return locals;
    }

    LocalsArraySet laSet = (LocalsArraySet)locals;

    if (subroutines.size() == 0) {
        /*
         * We've merged from a subroutine context to a non-subroutine
         * context, likely via a throw. Our successor will only need
         * to consider the primary locals state, not the state of
         * all possible subroutine paths.
         */

        return laSet.getPrimary();
    }

    /*
     * It's unclear to me if the locals set needs to be trimmed here.
     * If it does, then I believe it is all of the calling blocks
     * in the subroutine at the end of "subroutines" passed into
     * this method that should be removed.
     */
    return laSet;
}
 
Example #23
Source File: SsaMethod.java    From Box with Apache License 2.0 5 votes vote down vote up
/**
 * Builds an IntList of block indices from a basic block list and a list
 * of labels taken from Rop form.
 *
 * @param ropBlocks Rop blocks
 * @param labelList list of rop block labels
 * @return IntList of block indices
 */
public static IntList indexListFromLabelList(BasicBlockList ropBlocks,
        IntList labelList) {

    IntList result = new IntList(labelList.size());

    for (int i = 0, sz = labelList.size(); i < sz; i++) {
        result.add(ropBlocks.indexOfLabel(labelList.get(i)));
    }

    return result;
}
 
Example #24
Source File: SsaMethod.java    From Box with Apache License 2.0 5 votes vote down vote up
/**
 * Builds a BitSet of block indices from a basic block list and a list
 * of labels taken from Rop form.
 *
 * @param blocks Rop blocks
 * @param labelList list of rop block labels
 * @return BitSet of block indices
 */
static BitSet bitSetFromLabelList(BasicBlockList blocks,
        IntList labelList) {
    BitSet result = new BitSet(blocks.size());

    for (int i = 0, sz = labelList.size(); i < sz; i++) {
        result.set(blocks.indexOfLabel(labelList.get(i)));
    }

    return result;
}
 
Example #25
Source File: SsaBasicBlock.java    From Box with Apache License 2.0 5 votes vote down vote up
/**
 * Creates a new empty basic block.
 *
 * @param basicBlockIndex index this block will have
 * @param ropLabel original rop-form label
 * @param parent method of this block
 */
public SsaBasicBlock(final int basicBlockIndex, final int ropLabel,
        final SsaMethod parent) {
    this.parent = parent;
    this.index = basicBlockIndex;
    this.insns = new ArrayList<SsaInsn>();
    this.ropLabel = ropLabel;

    this.predecessors = new BitSet(parent.getBlocks().size());
    this.successors = new BitSet(parent.getBlocks().size());
    this.successorList = new IntList();

    domChildren = new ArrayList<SsaBasicBlock>();
}
 
Example #26
Source File: SwitchList.java    From Box with Apache License 2.0 5 votes vote down vote up
/**
 * Constructs an instance.
 *
 * @param size {@code >= 0;} the number of elements to be in the table
 */
public SwitchList(int size) {
    super(true);
    this.values = new IntList(size);
    this.targets = new IntList(size + 1);
    this.size = size;
}
 
Example #27
Source File: RopMethod.java    From Box with Apache License 2.0 5 votes vote down vote up
/**
 * Gets the predecessors associated with the given block. This throws
 * an exception if there is no block with the given label.
 *
 * @param label {@code >= 0;} the label of the block in question
 * @return {@code non-null;} the predecessors of that block
 */
public IntList labelToPredecessors(int label) {
    if (exitPredecessors == null) {
        calcPredecessors();
    }

    IntList result = predecessors[label];

    if (result == null) {
        throw new RuntimeException("no such block: " + Hex.u2(label));
    }

    return result;
}
 
Example #28
Source File: SsaBasicBlock.java    From Box with Apache License 2.0 5 votes vote down vote up
/**
 * @return successor list of rop labels
 */
public IntList getRopLabelSuccessorList() {
    IntList result = new IntList(successorList.size());

    int sz = successorList.size();

    for (int i = 0; i < sz; i++) {
        result.add(parent.blockIndexToRopLabel(successorList.get(i)));
    }
    return result;
}
 
Example #29
Source File: Ropper.java    From Box with Apache License 2.0 5 votes vote down vote up
/**
 * Inlines a subroutine.
 *
 * @param b block where {@code jsr} occurred in the original bytecode
 */
void inlineSubroutineCalledFrom(final BasicBlock b) {
    /*
     * The 0th successor of a subroutine caller block is where
     * the subroutine should return to. The 1st successor is
     * the start block of the subroutine.
     */
    subroutineSuccessor = b.getSuccessors().get(0);
    subroutineStart = b.getSuccessors().get(1);

    /*
     * This allocates an initial label and adds the first
     * block to the worklist.
     */
    int newSubStartLabel = mapOrAllocateLabel(subroutineStart);

    for (int label = workList.nextSetBit(0); label >= 0;
         label = workList.nextSetBit(0)) {
        workList.clear(label);
        int newLabel = origLabelToCopiedLabel.get(label);

        copyBlock(label, newLabel);

        if (isSubroutineCaller(labelToBlock(label))) {
            new SubroutineInliner(labelAllocator, labelToSubroutines)
                .inlineSubroutineCalledFrom(labelToBlock(newLabel));
        }
    }

    /*
     * Replace the original caller block, since we now have a
     * new successor
     */

    addOrReplaceBlockNoDelete(
        new BasicBlock(b.getLabel(), b.getInsns(),
            IntList.makeImmutable (newSubStartLabel),
                    newSubStartLabel),
        labelToSubroutines.get(b.getLabel()));
}
 
Example #30
Source File: Ropper.java    From J2ME-Loader with Apache License 2.0 5 votes vote down vote up
/**
 * Adds a block to the output result.
 *
 * @param block {@code non-null;} the block to add
 * @param subroutines {@code non-null;} subroutine label list
 * as described in {@link Frame#getSubroutines}
 */
private void addBlock(BasicBlock block, IntList subroutines) {
    if (block == null) {
        throw new NullPointerException("block == null");
    }

    result.add(block);
    subroutines.throwIfMutable();
    resultSubroutines.add(subroutines);
}