use of com.googlecode.dex2jar.ir.ts.an.SimpleLiveAnalyze in project dex2jar by pxb1988.
the class Ir2JRegAssignTransformer method transform.
@Override
public void transform(IrMethod method) {
if (method.locals.size() == 0) {
return;
}
SimpleLiveAnalyze sa = new SimpleLiveAnalyze(method, true);
sa.analyze();
// init regs
int maxLocalSize = sa.getLocalSize();
final Reg[] regs = new Reg[maxLocalSize];
for (Local local : method.locals) {
Reg reg = new Reg();
char type = local.valueType.charAt(0);
if (type == '[') {
type = 'L';
}
reg.type = type;
local.tag = reg;
regs[local._ls_index] = reg;
}
// gen graph
Reg[] args = genGraph(method, regs);
// fix up the graph, make sure @this is not share index with others
if (!method.isStatic) {
Reg atThis = args[0];
for (Reg reg : regs) {
if (reg == atThis) {
continue;
}
reg.excludes.add(atThis);
atThis.excludes.add(reg);
}
}
{
// assgin @this, @parameter_x from index 0
int i = 0;
int index = 0;
if (!method.isStatic) {
args[i++].reg = index++;
}
for (int j = 0; j < method.args.length; j++) {
Reg reg = args[i++];
String type = method.args[j];
if (reg == null) {
index++;
} else {
reg.reg = index++;
}
if ("J".equals(type) || "D".equals(type)) {
index++;
}
}
}
Map<Character, List<Reg>> groups = groupAndCleanUpByType(regs);
// type each group
BitSet excludeColor = new BitSet();
BitSet suggestColor = new BitSet();
BitSet globalExcludes = new BitSet();
BitSet usedInOneType = new BitSet();
for (Map.Entry<Character, List<Reg>> e : groups.entrySet()) {
List<Reg> assigns = e.getValue();
Collections.sort(assigns, OrderRegAssignByPreferredSizeDesc);
char type = e.getKey();
boolean doubleOrLong = type == 'J' || type == 'D';
for (Reg as : assigns) {
if (as.reg < 0) {
// need color
initExcludeColor(excludeColor, as);
excludeParameters(excludeColor, args, type);
// exclude index used by other types
excludeColor.or(globalExcludes);
initSuggestColor(suggestColor, as);
// first find a preferred color
for (int i = suggestColor.nextSetBit(0); i >= 0; i = suggestColor.nextSetBit(i + 1)) {
if (doubleOrLong) {
// need 2
if (!excludeColor.get(i) && !excludeColor.get(i + 1)) {
as.reg = i;
break;
}
} else {
if (!excludeColor.get(i)) {
as.reg = i;
break;
}
}
}
if (as.reg < 0) {
if (doubleOrLong) {
int reg = -1;
do {
reg++;
reg = excludeColor.nextClearBit(reg);
} while (excludeColor.get(reg + 1));
as.reg = reg;
} else {
int reg = excludeColor.nextClearBit(0);
as.reg = reg;
}
}
}
usedInOneType.set(as.reg);
if (doubleOrLong) {
usedInOneType.set(as.reg + 1);
}
}
globalExcludes.or(usedInOneType);
usedInOneType.clear();
}
for (Local local : method.locals) {
Reg as = (Reg) local.tag;
local._ls_index = as.reg;
local.tag = null;
}
for (Stmt stmt : method.stmts) {
stmt.frame = null;
}
}
Aggregations