Search in sources :

Example 1 with SimpleLiveAnalyze

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;
    }
}
Also used : Local(com.googlecode.dex2jar.ir.expr.Local) Stmt(com.googlecode.dex2jar.ir.stmt.Stmt) SimpleLiveAnalyze(com.googlecode.dex2jar.ir.ts.an.SimpleLiveAnalyze)

Aggregations

Local (com.googlecode.dex2jar.ir.expr.Local)1 Stmt (com.googlecode.dex2jar.ir.stmt.Stmt)1 SimpleLiveAnalyze (com.googlecode.dex2jar.ir.ts.an.SimpleLiveAnalyze)1