Search in sources :

Example 6 with CstString

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

the class EscapeAnalysis method insertExceptionThrow.

/**
     * Replaces instructions that trigger an ArrayIndexOutofBounds exception
     * with an actual throw of the exception.
     *
     * @param insn {@code non-null;} instruction causing the exception
     * @param index {@code non-null;} index value that is out of bounds
     * @param deletedInsns {@code non-null;} set of instructions marked for
     * deletion
     */
private void insertExceptionThrow(SsaInsn insn, RegisterSpec index, HashSet<SsaInsn> deletedInsns) {
    // Create a new ArrayIndexOutOfBoundsException
    CstType exception = new CstType(Exceptions.TYPE_ArrayIndexOutOfBoundsException);
    insertThrowingInsnBefore(insn, RegisterSpecList.EMPTY, null, RegOps.NEW_INSTANCE, exception);
    // Add a successor block with a move result pseudo for the exception
    SsaBasicBlock currBlock = insn.getBlock();
    SsaBasicBlock newBlock = currBlock.insertNewSuccessor(currBlock.getPrimarySuccessor());
    SsaInsn newInsn = newBlock.getInsns().get(0);
    RegisterSpec newReg = RegisterSpec.make(ssaMeth.makeNewSsaReg(), exception);
    insertPlainInsnBefore(newInsn, RegisterSpecList.EMPTY, newReg, RegOps.MOVE_RESULT_PSEUDO, null);
    // Add another successor block to initialize the exception
    SsaBasicBlock newBlock2 = newBlock.insertNewSuccessor(newBlock.getPrimarySuccessor());
    SsaInsn newInsn2 = newBlock2.getInsns().get(0);
    CstNat newNat = new CstNat(new CstString("<init>"), new CstString("(I)V"));
    CstMethodRef newRef = new CstMethodRef(exception, newNat);
    insertThrowingInsnBefore(newInsn2, RegisterSpecList.make(newReg, index), null, RegOps.INVOKE_DIRECT, newRef);
    deletedInsns.add(newInsn2);
    // Add another successor block to throw the new exception
    SsaBasicBlock newBlock3 = newBlock2.insertNewSuccessor(newBlock2.getPrimarySuccessor());
    SsaInsn newInsn3 = newBlock3.getInsns().get(0);
    insertThrowingInsnBefore(newInsn3, RegisterSpecList.make(newReg), null, RegOps.THROW, null);
    newBlock3.replaceSuccessor(newBlock3.getPrimarySuccessorIndex(), ssaMeth.getExitBlock().getIndex());
    deletedInsns.add(newInsn3);
}
Also used : CstNat(com.android.dx.rop.cst.CstNat) CstType(com.android.dx.rop.cst.CstType) CstString(com.android.dx.rop.cst.CstString) CstMethodRef(com.android.dx.rop.cst.CstMethodRef) RegisterSpec(com.android.dx.rop.code.RegisterSpec)

Example 7 with CstString

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

the class DebugInfoEncoder method entryAnnotationString.

/**
     * Returns a string representation of this LocalList entry that is
     * appropriate for emitting as an annotation.
     *
     * @param e {@code non-null;} entry
     * @return {@code non-null;} annotation string
     */
private String entryAnnotationString(LocalList.Entry e) {
    StringBuilder sb = new StringBuilder();
    sb.append(RegisterSpec.PREFIX);
    sb.append(e.getRegister());
    sb.append(' ');
    CstString name = e.getName();
    if (name == null) {
        sb.append("null");
    } else {
        sb.append(name.toHuman());
    }
    sb.append(' ');
    CstType type = e.getType();
    if (type == null) {
        sb.append("null");
    } else {
        sb.append(type.toHuman());
    }
    CstString signature = e.getSignature();
    if (signature != null) {
        sb.append(' ');
        sb.append(signature.toHuman());
    }
    return sb.toString();
}
Also used : CstType(com.android.dx.rop.cst.CstType) CstString(com.android.dx.rop.cst.CstString)

Example 8 with CstString

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

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 9 with CstString

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

the class HeaderItem method writeTo.

/** {@inheritDoc} */
@Override
public void writeTo(DexFile file, AnnotatedOutput out) {
    int mapOff = file.getMap().getFileOffset();
    Section firstDataSection = file.getFirstDataSection();
    Section lastDataSection = file.getLastDataSection();
    int dataOff = firstDataSection.getFileOffset();
    int dataSize = lastDataSection.getFileOffset() + lastDataSection.writeSize() - dataOff;
    String magic = file.getDexOptions().getMagic();
    if (out.annotates()) {
        out.annotate(8, "magic: " + new CstString(magic).toQuoted());
        out.annotate(4, "checksum");
        out.annotate(20, "signature");
        out.annotate(4, "file_size:       " + Hex.u4(file.getFileSize()));
        out.annotate(4, "header_size:     " + Hex.u4(SizeOf.HEADER_ITEM));
        out.annotate(4, "endian_tag:      " + Hex.u4(DexFormat.ENDIAN_TAG));
        out.annotate(4, "link_size:       0");
        out.annotate(4, "link_off:        0");
        out.annotate(4, "map_off:         " + Hex.u4(mapOff));
    }
    // Write the magic number.
    for (int i = 0; i < 8; i++) {
        out.writeByte(magic.charAt(i));
    }
    // Leave space for the checksum and signature.
    out.writeZeroes(24);
    out.writeInt(file.getFileSize());
    out.writeInt(SizeOf.HEADER_ITEM);
    out.writeInt(DexFormat.ENDIAN_TAG);
    /*
         * Write zeroes for the link size and data, as the output
         * isn't a staticly linked file.
         */
    out.writeZeroes(8);
    out.writeInt(mapOff);
    // Write out each section's respective header part.
    file.getStringIds().writeHeaderPart(out);
    file.getTypeIds().writeHeaderPart(out);
    file.getProtoIds().writeHeaderPart(out);
    file.getFieldIds().writeHeaderPart(out);
    file.getMethodIds().writeHeaderPart(out);
    file.getClassDefs().writeHeaderPart(out);
    if (out.annotates()) {
        out.annotate(4, "data_size:       " + Hex.u4(dataSize));
        out.annotate(4, "data_off:        " + Hex.u4(dataOff));
    }
    out.writeInt(dataSize);
    out.writeInt(dataOff);
}
Also used : CstString(com.android.dx.rop.cst.CstString) CstString(com.android.dx.rop.cst.CstString)

Example 10 with CstString

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

the class ProtoIdItem method makeShortForm.

/**
     * Creates the short-form of the given prototype.
     *
     * @param prototype {@code non-null;} the prototype
     * @return {@code non-null;} the short form
     */
private static CstString makeShortForm(Prototype prototype) {
    StdTypeList parameters = prototype.getParameterTypes();
    int size = parameters.size();
    StringBuilder sb = new StringBuilder(size + 1);
    sb.append(shortFormCharFor(prototype.getReturnType()));
    for (int i = 0; i < size; i++) {
        sb.append(shortFormCharFor(parameters.getType(i)));
    }
    return new CstString(sb.toString());
}
Also used : StdTypeList(com.android.dx.rop.type.StdTypeList) CstString(com.android.dx.rop.cst.CstString)

Aggregations

CstString (com.android.dx.rop.cst.CstString)35 CstType (com.android.dx.rop.cst.CstType)15 Constant (com.android.dx.rop.cst.Constant)13 ByteArray (com.android.dx.util.ByteArray)7 ConstantPool (com.android.dx.rop.cst.ConstantPool)6 ParseException (com.android.dx.cf.iface.ParseException)5 NameValuePair (com.android.dx.rop.annotation.NameValuePair)5 RegisterSpec (com.android.dx.rop.code.RegisterSpec)5 CstFieldRef (com.android.dx.rop.cst.CstFieldRef)5 CstNat (com.android.dx.rop.cst.CstNat)5 Annotation (com.android.dx.rop.annotation.Annotation)4 Type (com.android.dx.rop.type.Type)4 ClassDefItem (com.android.dx.dex.file.ClassDefItem)3 CstAnnotation (com.android.dx.rop.cst.CstAnnotation)3 CstMethodRef (com.android.dx.rop.cst.CstMethodRef)3 Attribute (com.android.dx.cf.iface.Attribute)2 CstInsn (com.android.dx.dex.code.CstInsn)2 Annotations (com.android.dx.rop.annotation.Annotations)2 AnnotationsList (com.android.dx.rop.annotation.AnnotationsList)2 LocalItem (com.android.dx.rop.code.LocalItem)2