use of com.android.dx.util.IntList in project buck by facebook.
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;
}
use of com.android.dx.util.IntList in project buck by facebook.
the class ByteCatchList method toTargetList.
/**
* Returns a target list corresponding to this instance. The result
* is a list of all the exception handler addresses, with the given
* {@code noException} address appended if appropriate. The
* result is automatically made immutable.
*
* @param noException {@code >= -1;} the no-exception address to append, or
* {@code -1} not to append anything
* @return {@code non-null;} list of exception targets, with
* {@code noException} appended if necessary
*/
public IntList toTargetList(int noException) {
if (noException < -1) {
throw new IllegalArgumentException("noException < -1");
}
boolean hasDefault = (noException >= 0);
int sz = size();
if (sz == 0) {
if (hasDefault) {
/*
* The list is empty, but there is a no-exception
* address; so, the result is just that address.
*/
return IntList.makeImmutable(noException);
}
/*
* The list is empty and there isn't even a no-exception
* address.
*/
return IntList.EMPTY;
}
IntList result = new IntList(sz + (hasDefault ? 1 : 0));
for (int i = 0; i < sz; i++) {
result.add(get(i).getHandlerPc());
}
if (hasDefault) {
result.add(noException);
}
result.setImmutable();
return result;
}
use of com.android.dx.util.IntList in project buck by facebook.
the class BlockDumper method regularDump.
/**
* Does a regular basic block dump.
*
* @param meth {@code non-null;} method data to dump
*/
private void regularDump(ConcreteMethod meth) {
BytecodeArray code = meth.getCode();
ByteArray bytes = code.getBytes();
ByteBlockList list = BasicBlocker.identifyBlocks(meth);
int sz = list.size();
CodeObserver codeObserver = new CodeObserver(bytes, BlockDumper.this);
// Reset the dump cursor to the start of the bytecode.
setAt(bytes, 0);
suppressDump = false;
int byteAt = 0;
for (int i = 0; i < sz; i++) {
ByteBlock bb = list.get(i);
int start = bb.getStart();
int end = bb.getEnd();
if (byteAt < start) {
parsed(bytes, byteAt, start - byteAt, "dead code " + Hex.u2(byteAt) + ".." + Hex.u2(start));
}
parsed(bytes, start, 0, "block " + Hex.u2(bb.getLabel()) + ": " + Hex.u2(start) + ".." + Hex.u2(end));
changeIndent(1);
int len;
for (int j = start; j < end; j += len) {
len = code.parseInstruction(j, codeObserver);
codeObserver.setPreviousOffset(j);
}
IntList successors = bb.getSuccessors();
int ssz = successors.size();
if (ssz == 0) {
parsed(bytes, end, 0, "returns");
} else {
for (int j = 0; j < ssz; j++) {
int succ = successors.get(j);
parsed(bytes, end, 0, "next " + Hex.u2(succ));
}
}
ByteCatchList catches = bb.getCatches();
int csz = catches.size();
for (int j = 0; j < csz; j++) {
ByteCatchList.Item one = catches.get(j);
CstType exceptionClass = one.getExceptionClass();
parsed(bytes, end, 0, "catch " + ((exceptionClass == CstType.OBJECT) ? "<any>" : exceptionClass.toHuman()) + " -> " + Hex.u2(one.getHandlerPc()));
}
changeIndent(-1);
byteAt = end;
}
int end = bytes.size();
if (byteAt < end) {
parsed(bytes, byteAt, end - byteAt, "dead code " + Hex.u2(byteAt) + ".." + Hex.u2(end));
}
suppressDump = true;
}
use of com.android.dx.util.IntList in project buck by facebook.
the class DotDumper method endParsingMember.
public void endParsingMember(ByteArray bytes, int offset, String name, String descriptor, Member member) {
if (!(member instanceof Method)) {
return;
}
if (!shouldDumpMethod(name)) {
return;
}
ConcreteMethod meth = new ConcreteMethod((Method) member, classFile, true, true);
TranslationAdvice advice = DexTranslationAdvice.THE_ONE;
RopMethod rmeth = Ropper.convert(meth, advice, classFile.getMethods());
if (optimize) {
boolean isStatic = AccessFlags.isStatic(meth.getAccessFlags());
rmeth = Optimizer.optimize(rmeth, BaseDumper.computeParamWidth(meth, isStatic), isStatic, true, advice);
}
System.out.println("digraph " + name + "{");
System.out.println("\tfirst -> n" + Hex.u2(rmeth.getFirstLabel()) + ";");
BasicBlockList blocks = rmeth.getBlocks();
int sz = blocks.size();
for (int i = 0; i < sz; i++) {
BasicBlock bb = blocks.get(i);
int label = bb.getLabel();
IntList successors = bb.getSuccessors();
if (successors.size() == 0) {
System.out.println("\tn" + Hex.u2(label) + " -> returns;");
} else if (successors.size() == 1) {
System.out.println("\tn" + Hex.u2(label) + " -> n" + Hex.u2(successors.get(0)) + ";");
} else {
System.out.print("\tn" + Hex.u2(label) + " -> {");
for (int j = 0; j < successors.size(); j++) {
int successor = successors.get(j);
if (successor != bb.getPrimarySuccessor()) {
System.out.print(" n" + Hex.u2(successor) + " ");
}
}
System.out.println("};");
System.out.println("\tn" + Hex.u2(label) + " -> n" + Hex.u2(bb.getPrimarySuccessor()) + " [label=\"primary\"];");
}
}
System.out.println("}");
}
use of com.android.dx.util.IntList in project buck by facebook.
the class Ropper method isSubroutineCaller.
/**
* Checks to see if the basic block is a subroutine caller block.
*
* @param bb {@code non-null;} the basic block in question
* @return true if this block calls a subroutine
*/
private boolean isSubroutineCaller(BasicBlock bb) {
IntList successors = bb.getSuccessors();
if (successors.size() < 2)
return false;
int subLabel = successors.get(1);
return (subLabel < subroutines.length) && (subroutines[subLabel] != null);
}
Aggregations