use of com.taobao.android.dx.rop.code.InsnList 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 = 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.InsnList in project atlas by alibaba.
the class SsaToRop method convertInsns.
/**
* Converts an insn list to rop form.
*
* @param ssaInsns {@code non-null;} old instructions
* @return {@code non-null;} immutable instruction list
*/
private InsnList convertInsns(ArrayList<SsaInsn> ssaInsns) {
int insnCount = ssaInsns.size();
InsnList result = new InsnList(insnCount);
for (int i = 0; i < insnCount; i++) {
result.set(i, ssaInsns.get(i).toRopInsn());
}
result.setImmutable();
return result;
}
use of com.taobao.android.dx.rop.code.InsnList 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.InsnList 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.InsnList in project atlas by alibaba.
the class Ropper method filterMoveReturnAddressInsns.
/**
* Removes all {@code move-return-address} instructions, returning a new
* {@code InsnList} if necessary. The {@code move-return-address}
* insns are dead code after subroutines have been inlined.
*
* @param insns {@code InsnList} that may contain
* {@code move-return-address} insns
* @return {@code InsnList} with {@code move-return-address} removed
*/
private InsnList filterMoveReturnAddressInsns(InsnList insns) {
int sz;
int newSz = 0;
// First see if we need to filter, and if so what the new size will be
sz = insns.size();
for (int i = 0; i < sz; i++) {
if (insns.get(i).getOpcode() != Rops.MOVE_RETURN_ADDRESS) {
newSz++;
}
}
if (newSz == sz) {
return insns;
}
// Make a new list without the MOVE_RETURN_ADDRESS insns
InsnList newInsns = new InsnList(newSz);
int newIndex = 0;
for (int i = 0; i < sz; i++) {
Insn insn = insns.get(i);
if (insn.getOpcode() != Rops.MOVE_RETURN_ADDRESS) {
newInsns.set(newIndex++, insn);
}
}
newInsns.setImmutable();
return newInsns;
}
Aggregations