use of com.taobao.android.dx.util.IntList in project atlas by alibaba.
the class Ropper method forEachNonSubBlockDepthFirst0.
/**
* Visits each block once in depth-first successor order, ignoring
* {@code jsr} targets. Worker for {@link #forEachNonSubBlockDepthFirst}.
*
* @param next next block to visit
* @param v callback interface
* @param visited set of blocks already visited
*/
private void forEachNonSubBlockDepthFirst0(BasicBlock next, BasicBlock.Visitor v, BitSet visited) {
v.visitBlock(next);
visited.set(next.getLabel());
IntList successors = next.getSuccessors();
int sz = successors.size();
for (int i = 0; i < sz; i++) {
int succ = successors.get(i);
if (visited.get(succ)) {
continue;
}
if (isSubroutineCaller(next) && i > 0) {
// ignore jsr targets
continue;
}
/*
* Ignore missing labels: they're successors of
* subroutines that never invoke a ret.
*/
int idx = labelToResultIndex(succ);
if (idx >= 0) {
forEachNonSubBlockDepthFirst0(result.get(idx), v, visited);
}
}
}
use of com.taobao.android.dx.util.IntList in project atlas by alibaba.
the class Frame method subFrameForLabel.
/**
* Returns a Frame instance representing the frame state that should
* be used when returning from a subroutine. The stack state of all
* subroutine invocations is identical, but the locals state may differ.
*
* @param startLabel {@code >=0;} The label of the returning subroutine's
* start block
* @param subLabel {@code >=0;} A calling label of a subroutine
* @return {@code null-ok;} an appropriatly-constructed instance, or null
* if label is not in the set
*/
public Frame subFrameForLabel(int startLabel, int subLabel) {
LocalsArray subLocals = null;
if (locals instanceof LocalsArraySet) {
subLocals = ((LocalsArraySet) locals).subArrayForLabel(subLabel);
}
IntList newSubroutines;
try {
newSubroutines = subroutines.mutableCopy();
if (newSubroutines.pop() != startLabel) {
throw new RuntimeException("returning from invalid subroutine");
}
newSubroutines.setImmutable();
} catch (IndexOutOfBoundsException ex) {
throw new RuntimeException("returning from invalid subroutine");
} catch (NullPointerException ex) {
throw new NullPointerException("can't return from non-subroutine");
}
return (subLocals == null) ? null : new Frame(subLocals, stack, newSubroutines);
}
use of com.taobao.android.dx.util.IntList in project atlas by alibaba.
the class Frame method mergeWithSubroutineCaller.
/**
* Merges this frame with the frame of a subroutine caller at
* {@code predLabel}. Only called on the frame at the first
* block of a subroutine.
*
* @param other {@code non-null;} another frame
* @param subLabel label of subroutine start block
* @param predLabel label of calling block
* @return {@code non-null;} the result of merging the two frames
*/
public Frame mergeWithSubroutineCaller(Frame other, int subLabel, int predLabel) {
LocalsArray resultLocals;
ExecutionStack resultStack;
resultLocals = getLocals().mergeWithSubroutineCaller(other.getLocals(), predLabel);
resultStack = getStack().merge(other.getStack());
IntList newOtherSubroutines = other.subroutines.mutableCopy();
newOtherSubroutines.add(subLabel);
newOtherSubroutines.setImmutable();
if ((resultLocals == getLocals()) && (resultStack == getStack()) && subroutines.equals(newOtherSubroutines)) {
return this;
}
IntList resultSubroutines;
if (subroutines.equals(newOtherSubroutines)) {
resultSubroutines = subroutines;
} else {
/*
* The new subroutines list should be the deepest of the two
* lists being merged, but the postfix of the resultant list
* must be equal to the shorter list.
*/
IntList nonResultSubroutines;
if (subroutines.size() > newOtherSubroutines.size()) {
resultSubroutines = subroutines;
nonResultSubroutines = newOtherSubroutines;
} else {
resultSubroutines = newOtherSubroutines;
nonResultSubroutines = subroutines;
}
int szResult = resultSubroutines.size();
int szNonResult = nonResultSubroutines.size();
for (int i = szNonResult - 1; i >= 0; i--) {
if (nonResultSubroutines.get(i) != resultSubroutines.get(i + (szResult - szNonResult))) {
throw new RuntimeException("Incompatible merged subroutines");
}
}
}
return new Frame(resultLocals, resultStack, resultSubroutines);
}
use of com.taobao.android.dx.util.IntList in project atlas by alibaba.
the class Frame method mergeSubroutineLists.
/**
* 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;
}
use of com.taobao.android.dx.util.IntList in project atlas by alibaba.
the class BasicBlocker method getBlockList.
/**
* Extracts the list of basic blocks from the bit sets.
*
* @return {@code non-null;} the list of basic blocks
*/
private ByteBlockList getBlockList() {
BytecodeArray bytes = method.getCode();
ByteBlock[] bbs = new ByteBlock[bytes.size()];
int count = 0;
for (int at = 0, next; ; /*at*/
at = next) {
next = Bits.findFirst(blockSet, at + 1);
if (next < 0) {
break;
}
if (Bits.get(liveSet, at)) {
/*
* Search backward for the branch or throwing
* instruction at the end of this block, if any. If
* there isn't any, then "next" is the sole target.
*/
IntList targets = null;
int targetsAt = -1;
ByteCatchList blockCatches;
for (int i = next - 1; i >= at; i--) {
targets = targetLists[i];
if (targets != null) {
targetsAt = i;
break;
}
}
if (targets == null) {
targets = IntList.makeImmutable(next);
blockCatches = ByteCatchList.EMPTY;
} else {
blockCatches = catchLists[targetsAt];
if (blockCatches == null) {
blockCatches = ByteCatchList.EMPTY;
}
}
bbs[count] = new ByteBlock(at, at, next, targets, blockCatches);
count++;
}
}
ByteBlockList result = new ByteBlockList(count);
for (int i = 0; i < count; i++) {
result.set(i, bbs[i]);
}
return result;
}
Aggregations