use of com.taobao.android.dx.util.IntList in project atlas by alibaba.
the class BasicBlockList method catchesEqual.
/**
* Compares the catches of two blocks for equality. This includes
* both the catch types and target labels.
*
* @param block1 {@code non-null;} one block to compare
* @param block2 {@code non-null;} the other block to compare
* @return {@code true} if the two blocks' non-primary successors
* are identical
*/
public boolean catchesEqual(BasicBlock block1, BasicBlock block2) {
TypeList catches1 = block1.getExceptionHandlerTypes();
TypeList catches2 = block2.getExceptionHandlerTypes();
if (!StdTypeList.equalContents(catches1, catches2)) {
return false;
}
IntList succ1 = block1.getSuccessors();
IntList succ2 = block2.getSuccessors();
// Both are guaranteed to be the same size.
int size = succ1.size();
int primary1 = block1.getPrimarySuccessor();
int primary2 = block2.getPrimarySuccessor();
if (((primary1 == -1) || (primary2 == -1)) && (primary1 != primary2)) {
/*
* For the current purpose, both blocks in question must
* either both have a primary or both not have a primary to
* be considered equal, and it turns out here that that's not
* the case.
*/
return false;
}
for (int i = 0; i < size; i++) {
int label1 = succ1.get(i);
int label2 = succ2.get(i);
if (label1 == primary1) {
/*
* It should be the case that block2's primary is at the
* same index. If not, we consider the blocks unequal for
* the current purpose.
*/
if (label2 != primary2) {
return false;
}
continue;
}
if (label1 != label2) {
return false;
}
}
return true;
}
use of com.taobao.android.dx.util.IntList in project atlas by alibaba.
the class BasicBlockList method preferredSuccessorOf.
/**
* Gets the preferred successor for the given block. If the block
* only has one successor, then that is the preferred successor.
* Otherwise, if the block has a primay successor, then that is
* the preferred successor. If the block has no successors, then
* this returns {@code null}.
*
* @param block {@code non-null;} the block in question
* @return {@code null-ok;} the preferred successor, if any
*/
public BasicBlock preferredSuccessorOf(BasicBlock block) {
int primarySuccessor = block.getPrimarySuccessor();
IntList successors = block.getSuccessors();
int succSize = successors.size();
switch(succSize) {
case 0:
{
return null;
}
case 1:
{
return labelToBlock(successors.get(0));
}
}
if (primarySuccessor != -1) {
return labelToBlock(primarySuccessor);
} else {
return labelToBlock(successors.get(0));
}
}
use of com.taobao.android.dx.util.IntList in project atlas by alibaba.
the class IdenticalBlockCombiner method process.
/**
* Runs algorithm. TODO: This is n^2, and could be made linear-ish with
* a hash. In particular, hash the contents of each block and only
* compare blocks with the same hash.
*
* @return {@code non-null;} new method that has been processed
*/
public RopMethod process() {
int szBlocks = blocks.size();
// indexed by label
BitSet toDelete = new BitSet(blocks.getMaxLabel());
// For each non-deleted block...
for (int bindex = 0; bindex < szBlocks; bindex++) {
BasicBlock b = blocks.get(bindex);
if (toDelete.get(b.getLabel())) {
// doomed block
continue;
}
IntList preds = ropMethod.labelToPredecessors(b.getLabel());
// ...look at all of it's predecessors that have only one succ...
int szPreds = preds.size();
for (int i = 0; i < szPreds; i++) {
int iLabel = preds.get(i);
BasicBlock iBlock = blocks.labelToBlock(iLabel);
if (toDelete.get(iLabel) || iBlock.getSuccessors().size() > 1 || iBlock.getFirstInsn().getOpcode().getOpcode() == RegOps.MOVE_RESULT) {
continue;
}
IntList toCombine = new IntList();
// ...and see if they can be combined with any other preds...
for (int j = i + 1; j < szPreds; j++) {
int jLabel = preds.get(j);
BasicBlock jBlock = blocks.labelToBlock(jLabel);
if (jBlock.getSuccessors().size() == 1 && compareInsns(iBlock, jBlock)) {
toCombine.add(jLabel);
toDelete.set(jLabel);
}
}
combineBlocks(iLabel, toCombine);
}
}
for (int i = szBlocks - 1; i >= 0; i--) {
if (toDelete.get(newBlocks.get(i).getLabel())) {
newBlocks.set(i, null);
}
}
newBlocks.shrinkToFit();
newBlocks.setImmutable();
return new RopMethod(newBlocks, ropMethod.getFirstLabel());
}
use of com.taobao.android.dx.util.IntList in project atlas by alibaba.
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);
}
}
}
use of com.taobao.android.dx.util.IntList 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();
}
Aggregations