Search in sources :

Example 6 with TypedConstant

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

the class SCCP method replaceConstants.

/**
     * Replaces TypeBearers in source register specs with constant type
     * bearers if possible. These are then referenced in later optimization
     * steps.
     */
private void replaceConstants() {
    for (int reg = 0; reg < regCount; reg++) {
        if (latticeValues[reg] != CONSTANT) {
            continue;
        }
        if (!(latticeConstants[reg] instanceof TypedConstant)) {
            // We can't do much with these
            continue;
        }
        SsaInsn defn = ssaMeth.getDefinitionForRegister(reg);
        TypeBearer typeBearer = defn.getResult().getTypeBearer();
        if (typeBearer.isConstant()) {
            /*
                 * The definition was a constant already.
                 * The uses should be as well.
                 */
            continue;
        }
        // Update the destination RegisterSpec with the constant value
        RegisterSpec dest = defn.getResult();
        RegisterSpec newDest = dest.withType((TypedConstant) latticeConstants[reg]);
        defn.setResult(newDest);
        /*
             * Update the sources RegisterSpec's of all non-move uses.
             * These will be used in later steps.
             */
        for (SsaInsn insn : ssaMeth.getUseListForRegister(reg)) {
            if (insn.isPhiOrMove()) {
                continue;
            }
            NormalSsaInsn nInsn = (NormalSsaInsn) insn;
            RegisterSpecList sources = insn.getSources();
            int index = sources.indexOfRegister(reg);
            RegisterSpec spec = sources.get(index);
            RegisterSpec newSpec = spec.withType((TypedConstant) latticeConstants[reg]);
            nInsn.changeOneSource(index, newSpec);
        }
    }
}
Also used : TypedConstant(com.taobao.android.dx.rop.cst.TypedConstant) TypeBearer(com.taobao.android.dx.rop.type.TypeBearer) RegisterSpecList(com.taobao.android.dx.rop.code.RegisterSpecList) RegisterSpec(com.taobao.android.dx.rop.code.RegisterSpec)

Example 7 with TypedConstant

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

the class CfTranslator method processFields.

/**
     * Processes the fields of the given class.
     *
     * @param cf {@code non-null;} class being translated
     * @param out {@code non-null;} output class
     * @param dexFile {@code non-null;} dex output
     */
private static void processFields(DirectClassFile cf, ClassDefItem out, DexFile dexFile) {
    CstType thisClass = cf.getThisClass();
    FieldList fields = cf.getFields();
    int sz = fields.size();
    for (int i = 0; i < sz; i++) {
        Field one = fields.get(i);
        try {
            CstFieldRef field = new CstFieldRef(thisClass, one.getNat());
            int accessFlags = one.getAccessFlags();
            if (AccessFlags.isStatic(accessFlags)) {
                TypedConstant constVal = one.getConstantValue();
                EncodedField fi = new EncodedField(field, accessFlags);
                if (constVal != null) {
                    constVal = coerceConstant(constVal, field.getType());
                }
                out.addStaticField(fi, constVal);
            } else {
                EncodedField fi = new EncodedField(field, accessFlags);
                out.addInstanceField(fi);
            }
            Annotations annotations = AttributeTranslator.getAnnotations(one.getAttributes());
            if (annotations.size() != 0) {
                out.addFieldAnnotations(field, annotations, dexFile);
            }
            dexFile.getFieldIds().intern(field);
        } catch (RuntimeException ex) {
            String msg = "...while processing " + one.getName().toHuman() + " " + one.getDescriptor().toHuman();
            throw ExceptionWithContext.withContext(ex, msg);
        }
    }
}
Also used : Field(com.taobao.android.dx.cf.iface.Field) EncodedField(com.taobao.android.dx.dex.file.EncodedField) Annotations(com.taobao.android.dx.rop.annotation.Annotations) TypedConstant(com.taobao.android.dx.rop.cst.TypedConstant) CstType(com.taobao.android.dx.rop.cst.CstType) CstFieldRef(com.taobao.android.dx.rop.cst.CstFieldRef) EncodedField(com.taobao.android.dx.dex.file.EncodedField) CstString(com.taobao.android.dx.rop.cst.CstString) FieldList(com.taobao.android.dx.cf.iface.FieldList)

Example 8 with TypedConstant

use of com.taobao.android.dx.rop.cst.TypedConstant 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

TypedConstant (com.taobao.android.dx.rop.cst.TypedConstant)8 RegisterSpec (com.taobao.android.dx.rop.code.RegisterSpec)6 Constant (com.taobao.android.dx.rop.cst.Constant)3 TypeBearer (com.taobao.android.dx.rop.type.TypeBearer)3 RegisterSpecList (com.taobao.android.dx.rop.code.RegisterSpecList)2 Rop (com.taobao.android.dx.rop.code.Rop)2 CstString (com.taobao.android.dx.rop.cst.CstString)2 CstType (com.taobao.android.dx.rop.cst.CstType)2 ArrayList (java.util.ArrayList)2 HashMap (java.util.HashMap)2 HashSet (java.util.HashSet)2 AttConstantValue (com.taobao.android.dx.cf.attrib.AttConstantValue)1 Attribute (com.taobao.android.dx.cf.iface.Attribute)1 Field (com.taobao.android.dx.cf.iface.Field)1 FieldList (com.taobao.android.dx.cf.iface.FieldList)1 EncodedField (com.taobao.android.dx.dex.file.EncodedField)1 Annotations (com.taobao.android.dx.rop.annotation.Annotations)1 PlainCstInsn (com.taobao.android.dx.rop.code.PlainCstInsn)1 PlainInsn (com.taobao.android.dx.rop.code.PlainInsn)1 ThrowingCstInsn (com.taobao.android.dx.rop.code.ThrowingCstInsn)1