use of com.taobao.android.dx.rop.code.BasicBlock in project atlas by alibaba.
the class Ropper method addSynchExceptionHandlerBlock.
/**
* Constructs and adds, if necessary, the catch-all exception handler
* block to deal with unwinding the lock taken on entry to a synchronized
* method.
*/
private void addSynchExceptionHandlerBlock() {
if (!synchNeedsExceptionHandler) {
/*
* The method being converted either isn't synchronized or
* can't possibly throw exceptions in its main body, so
* there's no need for a synchronized method exception
* handler.
*/
return;
}
SourcePosition pos = method.makeSourcePosistion(0);
RegisterSpec exReg = RegisterSpec.make(0, Type.THROWABLE);
BasicBlock bb;
Insn insn;
InsnList insns = new InsnList(2);
insn = new PlainInsn(Rops.opMoveException(Type.THROWABLE), pos, exReg, RegisterSpecList.EMPTY);
insns.set(0, insn);
insn = new ThrowingInsn(Rops.MONITOR_EXIT, pos, RegisterSpecList.make(getSynchReg()), StdTypeList.EMPTY);
insns.set(1, insn);
insns.setImmutable();
int label2 = getSpecialLabel(SYNCH_CATCH_2);
bb = new BasicBlock(getSpecialLabel(SYNCH_CATCH_1), insns, IntList.makeImmutable(label2), label2);
addBlock(bb, IntList.EMPTY);
insns = new InsnList(1);
insn = new ThrowingInsn(Rops.THROW, pos, RegisterSpecList.make(exReg), StdTypeList.EMPTY);
insns.set(0, insn);
insns.setImmutable();
bb = new BasicBlock(label2, insns, IntList.EMPTY, -1);
addBlock(bb, IntList.EMPTY);
}
use of com.taobao.android.dx.rop.code.BasicBlock 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();
}
use of com.taobao.android.dx.rop.code.BasicBlock in project atlas by alibaba.
the class Ropper method addExceptionSetupBlocks.
/**
* Creates the exception handler setup blocks. "maxLocals"
* below is because that's the register number corresponding
* to the sole element on a one-deep stack (which is the
* situation at the start of an exception handler block).
*/
private void addExceptionSetupBlocks() {
int len = catchInfos.length;
for (int i = 0; i < len; i++) {
CatchInfo catches = catchInfos[i];
if (catches != null) {
for (ExceptionHandlerSetup one : catches.getSetups()) {
Insn proto = labelToBlock(i).getFirstInsn();
SourcePosition pos = proto.getPosition();
InsnList il = new InsnList(2);
Insn insn = new PlainInsn(Rops.opMoveException(one.getCaughtType()), pos, RegisterSpec.make(maxLocals, one.getCaughtType()), RegisterSpecList.EMPTY);
il.set(0, insn);
insn = new PlainInsn(Rops.GOTO, pos, null, RegisterSpecList.EMPTY);
il.set(1, insn);
il.setImmutable();
BasicBlock bb = new BasicBlock(one.getLabel(), il, IntList.makeImmutable(i), i);
addBlock(bb, startFrames[i].getSubroutines());
}
}
}
}
use of com.taobao.android.dx.rop.code.BasicBlock in project atlas by alibaba.
the class BlockDumper method ropDump.
/**
* Does a registerizing dump.
*
* @param meth {@code non-null;} method data to dump
*/
private void ropDump(ConcreteMethod meth) {
TranslationAdvice advice = DexTranslationAdvice.THE_ONE;
BytecodeArray code = meth.getCode();
ByteArray bytes = code.getBytes();
RopMethod rmeth = Ropper.convert(meth, advice, classFile.getMethods());
StringBuffer sb = new StringBuffer(2000);
if (optimize) {
boolean isStatic = AccessFlags.isStatic(meth.getAccessFlags());
int paramWidth = computeParamWidth(meth, isStatic);
rmeth = new Optimizer().optimize(rmeth, paramWidth, isStatic, true, advice);
}
BasicBlockList blocks = rmeth.getBlocks();
int[] order = blocks.getLabelsInOrder();
sb.append("first " + Hex.u2(rmeth.getFirstLabel()) + "\n");
for (int label : order) {
BasicBlock bb = blocks.get(blocks.indexOfLabel(label));
sb.append("block ");
sb.append(Hex.u2(label));
sb.append("\n");
IntList preds = rmeth.labelToPredecessors(label);
int psz = preds.size();
for (int i = 0; i < psz; i++) {
sb.append(" pred ");
sb.append(Hex.u2(preds.get(i)));
sb.append("\n");
}
InsnList il = bb.getInsns();
int ilsz = il.size();
for (int i = 0; i < ilsz; i++) {
Insn one = il.get(i);
sb.append(" ");
sb.append(il.get(i).toHuman());
sb.append("\n");
}
IntList successors = bb.getSuccessors();
int ssz = successors.size();
if (ssz == 0) {
sb.append(" returns\n");
} else {
int primary = bb.getPrimarySuccessor();
for (int i = 0; i < ssz; i++) {
int succ = successors.get(i);
sb.append(" next ");
sb.append(Hex.u2(succ));
if ((ssz != 1) && (succ == primary)) {
sb.append(" *");
}
sb.append("\n");
}
}
}
suppressDump = false;
setAt(bytes, 0);
parsed(bytes, 0, bytes.size(), sb.toString());
suppressDump = true;
}
use of com.taobao.android.dx.rop.code.BasicBlock in project atlas by alibaba.
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 = new 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("}");
}
Aggregations