Search in sources :

Example 36 with Constant

use of com.taobao.android.dx.rop.cst.Constant in project atlas by alibaba.

the class Form21s method isCompatible.

/** {@inheritDoc} */
@Override
public boolean isCompatible(DalvInsn insn) {
    RegisterSpecList regs = insn.getRegisters();
    if (!((insn instanceof CstInsn) && (regs.size() == 1) && unsignedFitsInByte(regs.get(0).getReg()))) {
        return false;
    }
    CstInsn ci = (CstInsn) insn;
    Constant cst = ci.getConstant();
    if (!(cst instanceof CstLiteralBits)) {
        return false;
    }
    CstLiteralBits cb = (CstLiteralBits) cst;
    return cb.fitsInInt() && signedFitsInShort(cb.getIntBits());
}
Also used : CstInsn(com.taobao.android.dx.dex.code.CstInsn) CstLiteralBits(com.taobao.android.dx.rop.cst.CstLiteralBits) Constant(com.taobao.android.dx.rop.cst.Constant) RegisterSpecList(com.taobao.android.dx.rop.code.RegisterSpecList)

Example 37 with Constant

use of com.taobao.android.dx.rop.cst.Constant in project atlas by alibaba.

the class Form22b method isCompatible.

/** {@inheritDoc} */
@Override
public boolean isCompatible(DalvInsn insn) {
    RegisterSpecList regs = insn.getRegisters();
    if (!((insn instanceof CstInsn) && (regs.size() == 2) && unsignedFitsInByte(regs.get(0).getReg()) && unsignedFitsInByte(regs.get(1).getReg()))) {
        return false;
    }
    CstInsn ci = (CstInsn) insn;
    Constant cst = ci.getConstant();
    if (!(cst instanceof CstLiteralBits)) {
        return false;
    }
    CstLiteralBits cb = (CstLiteralBits) cst;
    return cb.fitsInInt() && signedFitsInByte(cb.getIntBits());
}
Also used : CstInsn(com.taobao.android.dx.dex.code.CstInsn) CstLiteralBits(com.taobao.android.dx.rop.cst.CstLiteralBits) Constant(com.taobao.android.dx.rop.cst.Constant) RegisterSpecList(com.taobao.android.dx.rop.code.RegisterSpecList)

Example 38 with Constant

use of com.taobao.android.dx.rop.cst.Constant in project atlas by alibaba.

the class CodeItem method addContents.

/** {@inheritDoc} */
public void addContents(DexFile file) {
    MixedItemSection byteData = file.getByteData();
    TypeIdsSection typeIds = file.getTypeIds();
    if (code.hasPositions() || code.hasLocals()) {
        debugInfo = new DebugInfoItem(code, isStatic, ref);
        byteData.add(debugInfo);
    }
    if (code.hasAnyCatches()) {
        for (Type type : code.getCatchTypes()) {
            typeIds.intern(type);
        }
        catches = new CatchStructs(code);
    }
    for (Constant c : code.getInsnConstants()) {
        file.internIfAppropriate(c);
    }
}
Also used : Type(com.taobao.android.dx.rop.type.Type) Constant(com.taobao.android.dx.rop.cst.Constant)

Example 39 with Constant

use of com.taobao.android.dx.rop.cst.Constant in project atlas by alibaba.

the class PlainInsn method withSourceLiteral.

/** {@inheritDoc} */
@Override
public Insn withSourceLiteral() {
    RegisterSpecList sources = getSources();
    int szSources = sources.size();
    if (szSources == 0) {
        return this;
    }
    TypeBearer lastType = sources.get(szSources - 1).getTypeBearer();
    if (!lastType.isConstant()) {
        // Check for reverse subtraction, where first source is constant
        TypeBearer firstType = sources.get(0).getTypeBearer();
        if (szSources == 2 && firstType.isConstant()) {
            Constant cst = (Constant) firstType;
            RegisterSpecList newSources = sources.withoutFirst();
            Rop newRop = Rops.ropFor(getOpcode().getOpcode(), getResult(), newSources, cst);
            return new PlainCstInsn(newRop, getPosition(), getResult(), newSources, cst);
        }
        return this;
    } else {
        Constant cst = (Constant) lastType;
        RegisterSpecList newSources = sources.withoutLast();
        Rop newRop;
        try {
            // Check for constant subtraction and flip it to be addition
            int opcode = getOpcode().getOpcode();
            if (opcode == RegOps.SUB && cst instanceof CstInteger) {
                opcode = RegOps.ADD;
                cst = CstInteger.make(-((CstInteger) cst).getValue());
            }
            newRop = Rops.ropFor(opcode, getResult(), newSources, cst);
        } catch (IllegalArgumentException ex) {
            // There's no rop for this case
            return this;
        }
        return new PlainCstInsn(newRop, getPosition(), getResult(), newSources, cst);
    }
}
Also used : Constant(com.taobao.android.dx.rop.cst.Constant) CstInteger(com.taobao.android.dx.rop.cst.CstInteger) TypeBearer(com.taobao.android.dx.rop.type.TypeBearer)

Example 40 with Constant

use of com.taobao.android.dx.rop.cst.Constant in project atlas by alibaba.

the class ConstCollector method getConstsSortedByCountUse.

/**
     * Gets all of the collectable constant values used in this method,
     * sorted by most used first. Skips non-collectable consts, such as
     * non-string object constants
     *
     * @return {@code non-null;} list of constants in most-to-least used order
     */
private ArrayList<TypedConstant> getConstsSortedByCountUse() {
    int regSz = ssaMeth.getRegCount();
    final HashMap<TypedConstant, Integer> countUses = new HashMap<TypedConstant, Integer>();
    /*
         * Each collected constant can be used by just one local
         * (used only if COLLECT_ONE_LOCAL is true).
         */
    final HashSet<TypedConstant> usedByLocal = new HashSet<TypedConstant>();
    // Count how many times each const value is used.
    for (int i = 0; i < regSz; i++) {
        SsaInsn insn = ssaMeth.getDefinitionForRegister(i);
        if (insn == null || insn.getOpcode() == null)
            continue;
        RegisterSpec result = insn.getResult();
        TypeBearer typeBearer = result.getTypeBearer();
        if (!typeBearer.isConstant())
            continue;
        TypedConstant cst = (TypedConstant) typeBearer;
        // Find defining instruction for move-result-pseudo instructions
        if (insn.getOpcode().getOpcode() == RegOps.MOVE_RESULT_PSEUDO) {
            int pred = insn.getBlock().getPredecessors().nextSetBit(0);
            ArrayList<SsaInsn> predInsns;
            predInsns = ssaMeth.getBlocks().get(pred).getInsns();
            insn = predInsns.get(predInsns.size() - 1);
        }
        if (insn.canThrow()) {
            /*
                 * Don't move anything other than strings -- the risk
                 * of changing where an exception is thrown is too high.
                 */
            if (!(cst instanceof CstString) || !COLLECT_STRINGS) {
                continue;
            }
            /*
                 * We can't move any throwable const whose throw will be
                 * caught, so don't count them.
                 */
            if (insn.getBlock().getSuccessors().cardinality() > 1) {
                continue;
            }
        }
        /*
             * TODO: Might be nice to try and figure out which local
             * wins most when collected.
             */
        if (ssaMeth.isRegALocal(result)) {
            if (!COLLECT_ONE_LOCAL) {
                continue;
            } else {
                if (usedByLocal.contains(cst)) {
                    // Count one local usage only.
                    continue;
                } else {
                    usedByLocal.add(cst);
                }
            }
        }
        Integer has = countUses.get(cst);
        if (has == null) {
            countUses.put(cst, 1);
        } else {
            countUses.put(cst, has + 1);
        }
    }
    // Collect constants that have been reused.
    ArrayList<TypedConstant> constantList = new ArrayList<TypedConstant>();
    for (Map.Entry<TypedConstant, Integer> entry : countUses.entrySet()) {
        if (entry.getValue() > 1) {
            constantList.add(entry.getKey());
        }
    }
    // Sort by use, with most used at the beginning of the list.
    Collections.sort(constantList, new Comparator<Constant>() {

        public int compare(Constant a, Constant b) {
            int ret;
            ret = countUses.get(b) - countUses.get(a);
            if (ret == 0) {
                /*
                     * Provide sorting determinisim for constants with same
                     * usage count.
                     */
                ret = a.compareTo(b);
            }
            return ret;
        }

        @Override
        public boolean equals(Object obj) {
            return obj == this;
        }
    });
    return constantList;
}
Also used : HashMap(java.util.HashMap) Constant(com.taobao.android.dx.rop.cst.Constant) TypedConstant(com.taobao.android.dx.rop.cst.TypedConstant) CstString(com.taobao.android.dx.rop.cst.CstString) ArrayList(java.util.ArrayList) TypedConstant(com.taobao.android.dx.rop.cst.TypedConstant) TypeBearer(com.taobao.android.dx.rop.type.TypeBearer) HashMap(java.util.HashMap) Map(java.util.Map) RegisterSpec(com.taobao.android.dx.rop.code.RegisterSpec) HashSet(java.util.HashSet)

Aggregations

Constant (com.taobao.android.dx.rop.cst.Constant)42 RegisterSpecList (com.taobao.android.dx.rop.code.RegisterSpecList)17 CstType (com.taobao.android.dx.rop.cst.CstType)13 CstInsn (com.taobao.android.dx.dex.code.CstInsn)12 CstString (com.taobao.android.dx.rop.cst.CstString)12 RegisterSpec (com.taobao.android.dx.rop.code.RegisterSpec)10 TypedConstant (com.taobao.android.dx.rop.cst.TypedConstant)10 CstLiteralBits (com.taobao.android.dx.rop.cst.CstLiteralBits)9 CstFieldRef (com.taobao.android.dx.rop.cst.CstFieldRef)6 CstInteger (com.taobao.android.dx.rop.cst.CstInteger)6 Type (com.taobao.android.dx.rop.type.Type)5 NameValuePair (com.taobao.android.dx.rop.annotation.NameValuePair)4 Insn (com.taobao.android.dx.rop.code.Insn)4 PlainInsn (com.taobao.android.dx.rop.code.PlainInsn)4 CstMethodRef (com.taobao.android.dx.rop.cst.CstMethodRef)4 TypeBearer (com.taobao.android.dx.rop.type.TypeBearer)4 Rop (com.taobao.android.dx.rop.code.Rop)3 ThrowingCstInsn (com.taobao.android.dx.rop.code.ThrowingCstInsn)3 ArrayList (java.util.ArrayList)3 CstInsn (com.taobao.android.dx.rop.code.CstInsn)2