Search in sources :

Example 41 with Constant

use of com.android.dx.rop.cst.Constant in project J2ME-Loader by nikita36078.

the class RegisterSpec method toString0.

/**
 * Helper for {@link #toString} and {@link #toHuman}.
 *
 * @param human whether to be human-oriented
 * @return {@code non-null;} the string form
 */
private String toString0(boolean human) {
    StringBuffer sb = new StringBuffer(40);
    sb.append(regString());
    sb.append(":");
    if (local != null) {
        sb.append(local.toString());
    }
    Type justType = type.getType();
    sb.append(justType);
    if (justType != type) {
        sb.append("=");
        if (human && (type instanceof CstString)) {
            sb.append(((CstString) type).toQuoted());
        } else if (human && (type instanceof Constant)) {
            sb.append(type.toHuman());
        } else {
            sb.append(type);
        }
    }
    return sb.toString();
}
Also used : Type(com.android.dx.rop.type.Type) Constant(com.android.dx.rop.cst.Constant) CstString(com.android.dx.rop.cst.CstString)

Example 42 with Constant

use of com.android.dx.rop.cst.Constant in project J2ME-Loader by nikita36078.

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.android.dx.rop.cst.Constant) TypedConstant(com.android.dx.rop.cst.TypedConstant) CstString(com.android.dx.rop.cst.CstString) ArrayList(java.util.ArrayList) TypedConstant(com.android.dx.rop.cst.TypedConstant) TypeBearer(com.android.dx.rop.type.TypeBearer) HashMap(java.util.HashMap) Map(java.util.Map) RegisterSpec(com.android.dx.rop.code.RegisterSpec) HashSet(java.util.HashSet)

Example 43 with Constant

use of com.android.dx.rop.cst.Constant in project RocooFix by dodola.

the class ClassReferenceListBuilder method addDependencies.

private void addDependencies(DirectClassFile classFile) {
    for (Constant constant : classFile.getConstantPool().getEntries()) {
        if (constant instanceof CstType) {
            checkDescriptor(((CstType) constant).getClassType().getDescriptor());
        } else if (constant instanceof CstFieldRef) {
            checkDescriptor(((CstFieldRef) constant).getType().getDescriptor());
        } else if (constant instanceof CstBaseMethodRef) {
            checkPrototype(((CstBaseMethodRef) constant).getPrototype());
        }
    }
    FieldList fields = classFile.getFields();
    int nbField = fields.size();
    for (int i = 0; i < nbField; i++) {
        checkDescriptor(fields.get(i).getDescriptor().getString());
    }
    MethodList methods = classFile.getMethods();
    int nbMethods = methods.size();
    for (int i = 0; i < nbMethods; i++) {
        checkPrototype(Prototype.intern(methods.get(i).getDescriptor().getString()));
    }
}
Also used : CstBaseMethodRef(com.android.dx.rop.cst.CstBaseMethodRef) Constant(com.android.dx.rop.cst.Constant) CstType(com.android.dx.rop.cst.CstType) CstFieldRef(com.android.dx.rop.cst.CstFieldRef) MethodList(com.android.dx.cf.iface.MethodList) FieldList(com.android.dx.cf.iface.FieldList)

Example 44 with Constant

use of com.android.dx.rop.cst.Constant in project buck by facebook.

the class EscapeAnalysis method replaceDef.

/**
     * Replaces the instructions that define an array with equivalent registers.
     * For each entry in the array, a register is created, initialized to zero.
     * A mapping between this register and the corresponding array index is
     * added.
     *
     * @param def {@code non-null;} move result instruction for array
     * @param prev {@code non-null;} instruction for instantiating new array
     * @param length size of the new array
     * @param newRegs {@code non-null;} mapping of array indices to new
     * registers to be populated
     */
private void replaceDef(SsaInsn def, SsaInsn prev, int length, ArrayList<RegisterSpec> newRegs) {
    Type resultType = def.getResult().getType();
    // Create new zeroed out registers for each element in the array
    for (int i = 0; i < length; i++) {
        Constant newZero = Zeroes.zeroFor(resultType.getComponentType());
        TypedConstant typedZero = (TypedConstant) newZero;
        RegisterSpec newReg = RegisterSpec.make(ssaMeth.makeNewSsaReg(), typedZero);
        newRegs.add(newReg);
        insertPlainInsnBefore(def, RegisterSpecList.EMPTY, newReg, RegOps.CONST, newZero);
    }
}
Also used : Type(com.android.dx.rop.type.Type) CstType(com.android.dx.rop.cst.CstType) TypedConstant(com.android.dx.rop.cst.TypedConstant) Constant(com.android.dx.rop.cst.Constant) TypedConstant(com.android.dx.rop.cst.TypedConstant) RegisterSpec(com.android.dx.rop.code.RegisterSpec)

Example 45 with Constant

use of com.android.dx.rop.cst.Constant in project buck by facebook.

the class EscapeAnalysis method replaceUse.

/**
     * Replaces the use for a scalar replaceable array. Gets and puts become
     * move instructions, and array lengths and fills are handled. Can also
     * identify ArrayIndexOutOfBounds exceptions and throw them if detected.
     *
     * @param use {@code non-null;} move result instruction for array
     * @param prev {@code non-null;} instruction for instantiating new array
     * @param newRegs {@code non-null;} mapping of array indices to new
     * registers
     * @param deletedInsns {@code non-null;} set of instructions marked for
     * deletion
     */
private void replaceUse(SsaInsn use, SsaInsn prev, ArrayList<RegisterSpec> newRegs, HashSet<SsaInsn> deletedInsns) {
    int index;
    int length = newRegs.size();
    SsaInsn next;
    RegisterSpecList sources;
    RegisterSpec source, result;
    CstLiteralBits indexReg;
    switch(use.getOpcode().getOpcode()) {
        case RegOps.AGET:
            // Replace array gets with moves
            next = getMoveForInsn(use);
            sources = use.getSources();
            indexReg = ((CstLiteralBits) sources.get(1).getTypeBearer());
            index = indexReg.getIntBits();
            if (index < length) {
                source = newRegs.get(index);
                result = source.withReg(next.getResult().getReg());
                insertPlainInsnBefore(next, RegisterSpecList.make(source), result, RegOps.MOVE, null);
            } else {
                // Throw an exception if the index is out of bounds
                insertExceptionThrow(next, sources.get(1), deletedInsns);
                deletedInsns.add(next.getBlock().getInsns().get(2));
            }
            deletedInsns.add(next);
            break;
        case RegOps.APUT:
            // Replace array puts with moves
            sources = use.getSources();
            indexReg = ((CstLiteralBits) sources.get(2).getTypeBearer());
            index = indexReg.getIntBits();
            if (index < length) {
                source = sources.get(0);
                result = source.withReg(newRegs.get(index).getReg());
                insertPlainInsnBefore(use, RegisterSpecList.make(source), result, RegOps.MOVE, null);
                // Update the newReg entry to mark value as unknown now
                newRegs.set(index, result.withSimpleType());
            } else {
                // Throw an exception if the index is out of bounds
                insertExceptionThrow(use, sources.get(2), deletedInsns);
            }
            break;
        case RegOps.ARRAY_LENGTH:
            // Replace array lengths with const instructions
            TypeBearer lengthReg = prev.getSources().get(0).getTypeBearer();
            //CstInteger lengthReg = CstInteger.make(length);
            next = getMoveForInsn(use);
            insertPlainInsnBefore(next, RegisterSpecList.EMPTY, next.getResult(), RegOps.CONST, (Constant) lengthReg);
            deletedInsns.add(next);
            break;
        case RegOps.MARK_LOCAL:
            // Remove mark local instructions
            break;
        case RegOps.FILL_ARRAY_DATA:
            // Create const instructions for each fill value
            Insn ropUse = use.getOriginalRopInsn();
            FillArrayDataInsn fill = (FillArrayDataInsn) ropUse;
            ArrayList<Constant> constList = fill.getInitValues();
            for (int i = 0; i < length; i++) {
                RegisterSpec newFill = RegisterSpec.make(newRegs.get(i).getReg(), (TypeBearer) constList.get(i));
                insertPlainInsnBefore(use, RegisterSpecList.EMPTY, newFill, RegOps.CONST, constList.get(i));
                // Update the newRegs to hold the new const value
                newRegs.set(i, newFill);
            }
            break;
        default:
    }
}
Also used : ThrowingCstInsn(com.android.dx.rop.code.ThrowingCstInsn) ThrowingInsn(com.android.dx.rop.code.ThrowingInsn) PlainInsn(com.android.dx.rop.code.PlainInsn) FillArrayDataInsn(com.android.dx.rop.code.FillArrayDataInsn) Insn(com.android.dx.rop.code.Insn) PlainCstInsn(com.android.dx.rop.code.PlainCstInsn) CstLiteralBits(com.android.dx.rop.cst.CstLiteralBits) FillArrayDataInsn(com.android.dx.rop.code.FillArrayDataInsn) Constant(com.android.dx.rop.cst.Constant) TypedConstant(com.android.dx.rop.cst.TypedConstant) TypeBearer(com.android.dx.rop.type.TypeBearer) RegisterSpecList(com.android.dx.rop.code.RegisterSpecList) RegisterSpec(com.android.dx.rop.code.RegisterSpec)

Aggregations

Constant (com.android.dx.rop.cst.Constant)91 RegisterSpecList (com.android.dx.rop.code.RegisterSpecList)36 CstType (com.android.dx.rop.cst.CstType)30 CstString (com.android.dx.rop.cst.CstString)27 CstInsn (com.android.dx.dex.code.CstInsn)24 RegisterSpec (com.android.dx.rop.code.RegisterSpec)20 TypedConstant (com.android.dx.rop.cst.TypedConstant)20 CstLiteralBits (com.android.dx.rop.cst.CstLiteralBits)18 CstFieldRef (com.android.dx.rop.cst.CstFieldRef)17 CstMethodRef (com.android.dx.rop.cst.CstMethodRef)14 CstInteger (com.android.dx.rop.cst.CstInteger)12 NameValuePair (com.android.dx.rop.annotation.NameValuePair)8 Insn (com.android.dx.rop.code.Insn)8 PlainInsn (com.android.dx.rop.code.PlainInsn)8 Type (com.android.dx.rop.type.Type)8 TypeBearer (com.android.dx.rop.type.TypeBearer)8 Rop (com.android.dx.rop.code.Rop)6 ThrowingCstInsn (com.android.dx.rop.code.ThrowingCstInsn)6 ArrayList (java.util.ArrayList)6 ParseException (com.android.dx.cf.iface.ParseException)4