com.android.dx.rop.code.BasicBlock Java Examples

The following examples show how to use com.android.dx.rop.code.BasicBlock. 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: BlockAddresses.java    From J2ME-Loader with Apache License 2.0 6 votes vote down vote up
/**
 * Sets up the address arrays.
 */
private void setupArrays(RopMethod method) {
    BasicBlockList blocks = method.getBlocks();
    int sz = blocks.size();

    for (int i = 0; i < sz; i++) {
        BasicBlock one = blocks.get(i);
        int label = one.getLabel();
        Insn insn = one.getInsns().get(0);

        starts[label] = new CodeAddress(insn.getPosition());

        SourcePosition pos = one.getLastInsn().getPosition();

        lasts[label] = new CodeAddress(pos);
        ends[label] = new CodeAddress(pos);
    }
}
 
Example #2
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 #3
Source File: StdCatchBuilder.java    From J2ME-Loader with Apache License 2.0 6 votes vote down vote up
/**
 * Gets whether the address range for the given two blocks is valid
 * for a catch handler. This is true as long as the covered range is
 * under 65536 code units.
 *
 * @param start {@code non-null;} the start block for the range (inclusive)
 * @param end {@code non-null;} the start block for the range (also inclusive)
 * @param addresses {@code non-null;} address objects for each block
 * @return {@code true} if the range is valid as a catch range
 */
private static boolean rangeIsValid(BasicBlock start, BasicBlock end,
        BlockAddresses addresses) {
    if (start == null) {
        throw new NullPointerException("start == null");
    }

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

    // See above about selection of instructions.
    int startAddress = addresses.getLast(start).getAddress();
    int endAddress = addresses.getEnd(end).getAddress();

    return (endAddress - startAddress) <= MAX_CATCH_RANGE;
}
 
Example #4
Source File: Ropper.java    From Box with Apache License 2.0 6 votes vote down vote up
/**
 * Merges the specified frame into this subroutine's successors,
 * setting {@code workSet} as appropriate. To be called with
 * the frame of a subroutine ret block.
 *
 * @param frame {@code non-null;} frame from ret block to merge
 * @param workSet {@code non-null;} workset to update
 */
void mergeToSuccessors(Frame frame, int[] workSet) {
    for (int label = callerBlocks.nextSetBit(0); label >= 0;
         label = callerBlocks.nextSetBit(label+1)) {
        BasicBlock subCaller = labelToBlock(label);
        int succLabel = subCaller.getSuccessors().get(0);

        Frame subFrame = frame.subFrameForLabel(startBlock, label);

        if (subFrame != null) {
            mergeAndWorkAsNecessary(succLabel, -1, null,
                    subFrame, workSet);
        } else {
            Bits.set(workSet, label);
        }
    }
}
 
Example #5
Source File: StdCatchBuilder.java    From Box with Apache License 2.0 6 votes vote down vote up
/**
 * Gets whether the address range for the given two blocks is valid
 * for a catch handler. This is true as long as the covered range is
 * under 65536 code units.
 *
 * @param start {@code non-null;} the start block for the range (inclusive)
 * @param end {@code non-null;} the start block for the range (also inclusive)
 * @param addresses {@code non-null;} address objects for each block
 * @return {@code true} if the range is valid as a catch range
 */
private static boolean rangeIsValid(BasicBlock start, BasicBlock end,
        BlockAddresses addresses) {
    if (start == null) {
        throw new NullPointerException("start == null");
    }

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

    // See above about selection of instructions.
    int startAddress = addresses.getLast(start).getAddress();
    int endAddress = addresses.getEnd(end).getAddress();

    return (endAddress - startAddress) <= MAX_CATCH_RANGE;
}
 
Example #6
Source File: StdCatchBuilder.java    From Box with Apache License 2.0 6 votes vote down vote up
/**
 * Makes a {@link CatchTable.Entry} for the given block range and
 * handlers.
 *
 * @param start {@code non-null;} the start block for the range (inclusive)
 * @param end {@code non-null;} the start block for the range (also inclusive)
 * @param handlers {@code non-null;} the handlers for the range
 * @param addresses {@code non-null;} address objects for each block
 */
private static CatchTable.Entry makeEntry(BasicBlock start,
        BasicBlock end, CatchHandlerList handlers,
        BlockAddresses addresses) {
    /*
     * We start at the *last* instruction of the start block, since
     * that's the instruction that can throw...
     */
    CodeAddress startAddress = addresses.getLast(start);

    // ...And we end *after* the last instruction of the end block.
    CodeAddress endAddress = addresses.getEnd(end);

    return new CatchTable.Entry(startAddress.getAddress(),
            endAddress.getAddress(), handlers);
}
 
Example #7
Source File: IdenticalBlockCombiner.java    From buck with Apache License 2.0 6 votes vote down vote up
/**
 * 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);
        }
    }
}
 
Example #8
Source File: StdCatchBuilder.java    From Box with Apache License 2.0 6 votes vote down vote up
/** {@inheritDoc} */
@Override
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;
}
 
Example #9
Source File: BlockAddresses.java    From Box with Apache License 2.0 6 votes vote down vote up
/**
 * Sets up the address arrays.
 */
private void setupArrays(RopMethod method) {
    BasicBlockList blocks = method.getBlocks();
    int sz = blocks.size();

    for (int i = 0; i < sz; i++) {
        BasicBlock one = blocks.get(i);
        int label = one.getLabel();
        Insn insn = one.getInsns().get(0);

        starts[label] = new CodeAddress(insn.getPosition());

        SourcePosition pos = one.getLastInsn().getPosition();

        lasts[label] = new CodeAddress(pos);
        ends[label] = new CodeAddress(pos);
    }
}
 
Example #10
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 #11
Source File: Ropper.java    From Box 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 #12
Source File: StdCatchBuilder.java    From J2ME-Loader with Apache License 2.0 6 votes vote down vote up
/**
 * Makes a {@link CatchTable#Entry} for the given block range and
 * handlers.
 *
 * @param start {@code non-null;} the start block for the range (inclusive)
 * @param end {@code non-null;} the start block for the range (also inclusive)
 * @param handlers {@code non-null;} the handlers for the range
 * @param addresses {@code non-null;} address objects for each block
 */
private static CatchTable.Entry makeEntry(BasicBlock start,
        BasicBlock end, CatchHandlerList handlers,
        BlockAddresses addresses) {
    /*
     * We start at the *last* instruction of the start block, since
     * that's the instruction that can throw...
     */
    CodeAddress startAddress = addresses.getLast(start);

    // ...And we end *after* the last instruction of the end block.
    CodeAddress endAddress = addresses.getEnd(end);

    return new CatchTable.Entry(startAddress.getAddress(),
            endAddress.getAddress(), handlers);
}
 
Example #13
Source File: StdCatchBuilder.java    From buck with Apache License 2.0 6 votes vote down vote up
/**
 * Makes a {@link CatchTable#Entry} for the given block range and
 * handlers.
 *
 * @param start {@code non-null;} the start block for the range (inclusive)
 * @param end {@code non-null;} the start block for the range (also inclusive)
 * @param handlers {@code non-null;} the handlers for the range
 * @param addresses {@code non-null;} address objects for each block
 */
private static CatchTable.Entry makeEntry(BasicBlock start,
        BasicBlock end, CatchHandlerList handlers,
        BlockAddresses addresses) {
    /*
     * We start at the *last* instruction of the start block, since
     * that's the instruction that can throw...
     */
    CodeAddress startAddress = addresses.getLast(start);

    // ...And we end *after* the last instruction of the end block.
    CodeAddress endAddress = addresses.getEnd(end);

    return new CatchTable.Entry(startAddress.getAddress(),
            endAddress.getAddress(), handlers);
}
 
Example #14
Source File: Ropper.java    From buck 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 #15
Source File: StdCatchBuilder.java    From J2ME-Loader with Apache License 2.0 6 votes vote down vote up
/** {@inheritDoc} */
   @Override
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;
   }
 
Example #16
Source File: StdCatchBuilder.java    From J2ME-Loader with Apache License 2.0 6 votes vote down vote up
/** {@inheritDoc} */
   @Override
public HashSet<Type> getCatchTypes() {
       HashSet<Type> result = new HashSet<Type>(20);
       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();
           int catchSize = catches.size();

           for (int j = 0; j < catchSize; j++) {
               result.add(catches.getType(j));
           }
       }

       return result;
   }
 
Example #17
Source File: BlockAddresses.java    From Box with Apache License 2.0 6 votes vote down vote up
/**
 * Sets up the address arrays.
 */
private void setupArrays(RopMethod method) {
    BasicBlockList blocks = method.getBlocks();
    int sz = blocks.size();

    for (int i = 0; i < sz; i++) {
        BasicBlock one = blocks.get(i);
        int label = one.getLabel();
        Insn insn = one.getInsns().get(0);

        starts[label] = new CodeAddress(insn.getPosition());

        SourcePosition pos = one.getLastInsn().getPosition();

        lasts[label] = new CodeAddress(pos);
        ends[label] = new CodeAddress(pos);
    }
}
 
Example #18
Source File: StdCatchBuilder.java    From Box with Apache License 2.0 6 votes vote down vote up
/** {@inheritDoc} */
@Override
public HashSet<Type> getCatchTypes() {
    HashSet<Type> result = new HashSet<Type>(20);
    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();
        int catchSize = catches.size();

        for (int j = 0; j < catchSize; j++) {
            result.add(catches.getType(j));
        }
    }

    return result;
}
 
Example #19
Source File: Ropper.java    From J2ME-Loader 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 #20
Source File: StdCatchBuilder.java    From Box with Apache License 2.0 6 votes vote down vote up
/**
 * Makes a {@link CatchTable.Entry} for the given block range and
 * handlers.
 *
 * @param start {@code non-null;} the start block for the range (inclusive)
 * @param end {@code non-null;} the start block for the range (also inclusive)
 * @param handlers {@code non-null;} the handlers for the range
 * @param addresses {@code non-null;} address objects for each block
 */
private static CatchTable.Entry makeEntry(BasicBlock start,
        BasicBlock end, CatchHandlerList handlers,
        BlockAddresses addresses) {
    /*
     * We start at the *last* instruction of the start block, since
     * that's the instruction that can throw...
     */
    CodeAddress startAddress = addresses.getLast(start);

    // ...And we end *after* the last instruction of the end block.
    CodeAddress endAddress = addresses.getEnd(end);

    return new CatchTable.Entry(startAddress.getAddress(),
            endAddress.getAddress(), handlers);
}
 
Example #21
Source File: StdCatchBuilder.java    From Box with Apache License 2.0 6 votes vote down vote up
/**
 * Gets whether the address range for the given two blocks is valid
 * for a catch handler. This is true as long as the covered range is
 * under 65536 code units.
 *
 * @param start {@code non-null;} the start block for the range (inclusive)
 * @param end {@code non-null;} the start block for the range (also inclusive)
 * @param addresses {@code non-null;} address objects for each block
 * @return {@code true} if the range is valid as a catch range
 */
private static boolean rangeIsValid(BasicBlock start, BasicBlock end,
        BlockAddresses addresses) {
    if (start == null) {
        throw new NullPointerException("start == null");
    }

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

    // See above about selection of instructions.
    int startAddress = addresses.getLast(start).getAddress();
    int endAddress = addresses.getEnd(end).getAddress();

    return (endAddress - startAddress) <= MAX_CATCH_RANGE;
}
 
Example #22
Source File: StdCatchBuilder.java    From buck with Apache License 2.0 6 votes vote down vote up
/** {@inheritDoc} */
public HashSet<Type> getCatchTypes() {
    HashSet<Type> result = new HashSet<Type>(20);
    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();
        int catchSize = catches.size();

        for (int j = 0; j < catchSize; j++) {
            result.add(catches.getType(j));
        }
    }

    return result;
}
 
Example #23
Source File: Ropper.java    From Box with Apache License 2.0 6 votes vote down vote up
/**
 * Generates a list of subroutine successors. Note: successor blocks
 * could be listed more than once. This is ok, because this successor
 * list (and the block it's associated with) will be copied and inlined
 * before we leave the ropper. Redundent successors will result in
 * redundent (no-op) merges.
 *
 * @return all currently known successors
 * (return destinations) for that subroutine
 */
IntList getSuccessors() {
    IntList successors = new IntList(callerBlocks.size());

    /*
     * For each subroutine caller, get it's target. If the
     * target is us, add the ret target (subroutine successor)
     * to our list
     */

    for (int label = callerBlocks.nextSetBit(0); label >= 0;
         label = callerBlocks.nextSetBit(label+1)) {
        BasicBlock subCaller = labelToBlock(label);
        successors.add(subCaller.getSuccessors().get(0));
    }

    successors.setImmutable();

    return successors;
}
 
Example #24
Source File: Ropper.java    From J2ME-Loader with Apache License 2.0 6 votes vote down vote up
/**
 * Merges the specified frame into this subroutine's successors,
 * setting {@code workSet} as appropriate. To be called with
 * the frame of a subroutine ret block.
 *
 * @param frame {@code non-null;} frame from ret block to merge
 * @param workSet {@code non-null;} workset to update
 */
void mergeToSuccessors(Frame frame, int[] workSet) {
    for (int label = callerBlocks.nextSetBit(0); label >= 0;
         label = callerBlocks.nextSetBit(label+1)) {
        BasicBlock subCaller = labelToBlock(label);
        int succLabel = subCaller.getSuccessors().get(0);

        Frame subFrame = frame.subFrameForLabel(startBlock, label);

        if (subFrame != null) {
            mergeAndWorkAsNecessary(succLabel, -1, null,
                    subFrame, workSet);
        } else {
            Bits.set(workSet, label);
        }
    }
}
 
Example #25
Source File: Label.java    From dexmaker with Apache License 2.0 6 votes vote down vote up
BasicBlock toBasicBlock() {
    InsnList result = new InsnList(instructions.size());
    for (int i = 0; i < instructions.size(); i++) {
        result.set(i, instructions.get(i));
    }
    result.setImmutable();

    int primarySuccessorIndex = -1;
    IntList successors = new IntList();
    for (Label catchLabel : catchLabels) {
        successors.add(catchLabel.id);
    }
    if (primarySuccessor != null) {
        primarySuccessorIndex = primarySuccessor.id;
        successors.add(primarySuccessorIndex);
    }
    if (alternateSuccessor != null) {
        successors.add(alternateSuccessor.id);
    }
    successors.setImmutable();

    return new BasicBlock(id, result, successors, primarySuccessorIndex);
}
 
Example #26
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 #27
Source File: Ropper.java    From Box 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 #28
Source File: Ropper.java    From buck with Apache License 2.0 6 votes vote down vote up
/**
 * Merges the specified frame into this subroutine's successors,
 * setting {@code workSet} as appropriate. To be called with
 * the frame of a subroutine ret block.
 *
 * @param frame {@code non-null;} frame from ret block to merge
 * @param workSet {@code non-null;} workset to update
 */
void mergeToSuccessors(Frame frame, int[] workSet) {
    for (int label = callerBlocks.nextSetBit(0); label >= 0;
         label = callerBlocks.nextSetBit(label+1)) {
        BasicBlock subCaller = labelToBlock(label);
        int succLabel = subCaller.getSuccessors().get(0);

        Frame subFrame = frame.subFrameForLabel(startBlock, label);

        if (subFrame != null) {
            mergeAndWorkAsNecessary(succLabel, -1, null,
                    subFrame, workSet);
        } else {
            Bits.set(workSet, label);
        }
    }
}
 
Example #29
Source File: Ropper.java    From buck 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() {

        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 #30
Source File: Ropper.java    From buck with Apache License 2.0 6 votes vote down vote up
/**
 * Generates a list of subroutine successors. Note: successor blocks
 * could be listed more than once. This is ok, because this successor
 * list (and the block it's associated with) will be copied and inlined
 * before we leave the ropper. Redundent successors will result in
 * redundent (no-op) merges.
 *
 * @return all currently known successors
 * (return destinations) for that subroutine
 */
IntList getSuccessors() {
    IntList successors = new IntList(callerBlocks.size());

    /*
     * For each subroutine caller, get it's target. If the
     * target is us, add the ret target (subroutine successor)
     * to our list
     */

    for (int label = callerBlocks.nextSetBit(0); label >= 0;
         label = callerBlocks.nextSetBit(label+1)) {
        BasicBlock subCaller = labelToBlock(label);
        successors.add(subCaller.getSuccessors().get(0));
    }

    successors.setImmutable();

    return successors;
}