Search in sources :

Example 11 with CstLiteralBits

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

the class EscapeAnalysis method scalarReplacement.

/**
     * Performs scalar replacement on all eligible arrays.
     */
private void scalarReplacement() {
    // Iterate through lattice, looking for non-escaping replaceable arrays
    for (EscapeSet escSet : latticeValues) {
        if (!escSet.replaceableArray || escSet.escape != EscapeState.NONE) {
            continue;
        }
        // Get the instructions for the definition and move of the array
        int e = escSet.regSet.nextSetBit(0);
        SsaInsn def = ssaMeth.getDefinitionForRegister(e);
        SsaInsn prev = getInsnForMove(def);
        // Create a map for the new registers that will be created
        TypeBearer lengthReg = prev.getSources().get(0).getTypeBearer();
        int length = ((CstLiteralBits) lengthReg).getIntBits();
        ArrayList<RegisterSpec> newRegs = new ArrayList<RegisterSpec>(length);
        HashSet<SsaInsn> deletedInsns = new HashSet<SsaInsn>();
        // Replace the definition of the array with registers
        replaceDef(def, prev, length, newRegs);
        // Mark definition instructions for deletion
        deletedInsns.add(prev);
        deletedInsns.add(def);
        // Go through all uses of the array
        List<SsaInsn> useList = ssaMeth.getUseListForRegister(e);
        for (SsaInsn use : useList) {
            // Replace the use with scalars and then mark it for deletion
            replaceUse(use, prev, newRegs, deletedInsns);
            deletedInsns.add(use);
        }
        // Delete all marked instructions
        ssaMeth.deleteInsns(deletedInsns);
        ssaMeth.onInsnsChanged();
        // Convert the method back to SSA form
        SsaConverter.updateSsaMethod(ssaMeth, regCount);
        // Propagate and remove extra moves added by scalar replacement
        movePropagate();
    }
}
Also used : CstLiteralBits(com.android.dx.rop.cst.CstLiteralBits) ArrayList(java.util.ArrayList) TypeBearer(com.android.dx.rop.type.TypeBearer) RegisterSpec(com.android.dx.rop.code.RegisterSpec) HashSet(java.util.HashSet)

Example 12 with CstLiteralBits

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

the class BytecodeArray method parseNewarray.

/**
 * Helper to deal with {@code newarray}.
 *
 * @param offset the offset to the {@code newarray} opcode itself
 * @param visitor {@code non-null;} visitor to use
 * @return instruction length, in bytes
 */
private int parseNewarray(int offset, Visitor visitor) {
    int value = bytes.getUnsignedByte(offset + 1);
    CstType type;
    switch(value) {
        case ByteOps.NEWARRAY_BOOLEAN:
            {
                type = CstType.BOOLEAN_ARRAY;
                break;
            }
        case ByteOps.NEWARRAY_CHAR:
            {
                type = CstType.CHAR_ARRAY;
                break;
            }
        case ByteOps.NEWARRAY_DOUBLE:
            {
                type = CstType.DOUBLE_ARRAY;
                break;
            }
        case ByteOps.NEWARRAY_FLOAT:
            {
                type = CstType.FLOAT_ARRAY;
                break;
            }
        case ByteOps.NEWARRAY_BYTE:
            {
                type = CstType.BYTE_ARRAY;
                break;
            }
        case ByteOps.NEWARRAY_SHORT:
            {
                type = CstType.SHORT_ARRAY;
                break;
            }
        case ByteOps.NEWARRAY_INT:
            {
                type = CstType.INT_ARRAY;
                break;
            }
        case ByteOps.NEWARRAY_LONG:
            {
                type = CstType.LONG_ARRAY;
                break;
            }
        default:
            {
                throw new SimException("bad newarray code " + Hex.u1(value));
            }
    }
    // Revisit the previous bytecode to find out the length of the array
    int previousOffset = visitor.getPreviousOffset();
    ConstantParserVisitor constantVisitor = new ConstantParserVisitor();
    int arrayLength = 0;
    /*
         * For visitors that don't record the previous offset, -1 will be
         * seen here
         */
    if (previousOffset >= 0) {
        parseInstruction(previousOffset, constantVisitor);
        if (constantVisitor.cst instanceof CstInteger && constantVisitor.length + previousOffset == offset) {
            arrayLength = constantVisitor.value;
        }
    }
    /*
         * Try to match the array initialization idiom. For example, if the
         * subsequent code is initializing an int array, we are expecting the
         * following pattern repeatedly:
         *  dup
         *  push index
         *  push value
         *  *astore
         *
         * where the index value will be incrimented sequentially from 0 up.
         */
    int nInit = 0;
    int curOffset = offset + 2;
    int lastOffset = curOffset;
    ArrayList<Constant> initVals = new ArrayList<Constant>();
    if (arrayLength != 0) {
        while (true) {
            boolean punt = false;
            // First, check if the next bytecode is dup.
            int nextByte = bytes.getUnsignedByte(curOffset++);
            if (nextByte != ByteOps.DUP)
                break;
            /*
                 * Next, check if the expected array index is pushed to
                 * the stack.
                 */
            parseInstruction(curOffset, constantVisitor);
            if (constantVisitor.length == 0 || !(constantVisitor.cst instanceof CstInteger) || constantVisitor.value != nInit)
                break;
            // Next, fetch the init value and record it.
            curOffset += constantVisitor.length;
            /*
                 * Next, find out what kind of constant is pushed onto
                 * the stack.
                 */
            parseInstruction(curOffset, constantVisitor);
            if (constantVisitor.length == 0 || !(constantVisitor.cst instanceof CstLiteralBits))
                break;
            curOffset += constantVisitor.length;
            initVals.add(constantVisitor.cst);
            nextByte = bytes.getUnsignedByte(curOffset++);
            // Now, check if the value is stored to the array properly.
            switch(value) {
                case ByteOps.NEWARRAY_BYTE:
                case ByteOps.NEWARRAY_BOOLEAN:
                    {
                        if (nextByte != ByteOps.BASTORE) {
                            punt = true;
                        }
                        break;
                    }
                case ByteOps.NEWARRAY_CHAR:
                    {
                        if (nextByte != ByteOps.CASTORE) {
                            punt = true;
                        }
                        break;
                    }
                case ByteOps.NEWARRAY_DOUBLE:
                    {
                        if (nextByte != ByteOps.DASTORE) {
                            punt = true;
                        }
                        break;
                    }
                case ByteOps.NEWARRAY_FLOAT:
                    {
                        if (nextByte != ByteOps.FASTORE) {
                            punt = true;
                        }
                        break;
                    }
                case ByteOps.NEWARRAY_SHORT:
                    {
                        if (nextByte != ByteOps.SASTORE) {
                            punt = true;
                        }
                        break;
                    }
                case ByteOps.NEWARRAY_INT:
                    {
                        if (nextByte != ByteOps.IASTORE) {
                            punt = true;
                        }
                        break;
                    }
                case ByteOps.NEWARRAY_LONG:
                    {
                        if (nextByte != ByteOps.LASTORE) {
                            punt = true;
                        }
                        break;
                    }
                default:
                    punt = true;
                    break;
            }
            if (punt) {
                break;
            }
            lastOffset = curOffset;
            nInit++;
        }
    }
    /*
         * For singleton arrays it is still more economical to
         * generate the aput.
         */
    if (nInit < 2 || nInit != arrayLength) {
        visitor.visitNewarray(offset, 2, type, null);
        return 2;
    } else {
        visitor.visitNewarray(offset, lastOffset - offset, type, initVals);
        return lastOffset - offset;
    }
}
Also used : CstLiteralBits(com.android.dx.rop.cst.CstLiteralBits) CstInteger(com.android.dx.rop.cst.CstInteger) Constant(com.android.dx.rop.cst.Constant) CstType(com.android.dx.rop.cst.CstType) ArrayList(java.util.ArrayList)

Example 13 with CstLiteralBits

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

the class EscapeAnalysis method scalarReplacement.

/**
 * Performs scalar replacement on all eligible arrays.
 */
private void scalarReplacement() {
    // Iterate through lattice, looking for non-escaping replaceable arrays
    for (EscapeSet escSet : latticeValues) {
        if (!escSet.replaceableArray || escSet.escape != EscapeState.NONE) {
            continue;
        }
        // Get the instructions for the definition and move of the array
        int e = escSet.regSet.nextSetBit(0);
        SsaInsn def = ssaMeth.getDefinitionForRegister(e);
        SsaInsn prev = getInsnForMove(def);
        // Create a map for the new registers that will be created
        TypeBearer lengthReg = prev.getSources().get(0).getTypeBearer();
        int length = ((CstLiteralBits) lengthReg).getIntBits();
        ArrayList<RegisterSpec> newRegs = new ArrayList<RegisterSpec>(length);
        HashSet<SsaInsn> deletedInsns = new HashSet<SsaInsn>();
        // Replace the definition of the array with registers
        replaceDef(def, prev, length, newRegs);
        // Mark definition instructions for deletion
        deletedInsns.add(prev);
        deletedInsns.add(def);
        // Go through all uses of the array
        List<SsaInsn> useList = ssaMeth.getUseListForRegister(e);
        for (SsaInsn use : useList) {
            // Replace the use with scalars and then mark it for deletion
            replaceUse(use, prev, newRegs, deletedInsns);
            deletedInsns.add(use);
        }
        // Delete all marked instructions
        ssaMeth.deleteInsns(deletedInsns);
        ssaMeth.onInsnsChanged();
        // Convert the method back to SSA form
        SsaConverter.updateSsaMethod(ssaMeth, regCount);
        // Propagate and remove extra moves added by scalar replacement
        movePropagate();
    }
}
Also used : CstLiteralBits(com.android.dx.rop.cst.CstLiteralBits) ArrayList(java.util.ArrayList) TypeBearer(com.android.dx.rop.type.TypeBearer) RegisterSpec(com.android.dx.rop.code.RegisterSpec) HashSet(java.util.HashSet)

Example 14 with CstLiteralBits

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

the class Form11n method writeTo.

/**
 * {@inheritDoc}
 */
@Override
public void writeTo(AnnotatedOutput out, DalvInsn insn) {
    RegisterSpecList regs = insn.getRegisters();
    int value = ((CstLiteralBits) ((CstInsn) insn).getConstant()).getIntBits();
    write(out, opcodeUnit(insn, makeByte(regs.get(0).getReg(), value & 0xf)));
}
Also used : CstLiteralBits(com.android.dx.rop.cst.CstLiteralBits) RegisterSpecList(com.android.dx.rop.code.RegisterSpecList)

Example 15 with CstLiteralBits

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

the class Form11n method insnArgString.

/**
 * {@inheritDoc}
 */
@Override
public String insnArgString(DalvInsn insn) {
    RegisterSpecList regs = insn.getRegisters();
    CstLiteralBits value = (CstLiteralBits) ((CstInsn) insn).getConstant();
    return regs.get(0).regString() + ", " + literalBitsString(value);
}
Also used : CstLiteralBits(com.android.dx.rop.cst.CstLiteralBits) RegisterSpecList(com.android.dx.rop.code.RegisterSpecList)

Aggregations

CstLiteralBits (com.android.dx.rop.cst.CstLiteralBits)48 RegisterSpecList (com.android.dx.rop.code.RegisterSpecList)42 Constant (com.android.dx.rop.cst.Constant)18 CstInsn (com.android.dx.dex.code.CstInsn)12 ArrayList (java.util.ArrayList)6 RegisterSpec (com.android.dx.rop.code.RegisterSpec)4 TypeBearer (com.android.dx.rop.type.TypeBearer)4 FillArrayDataInsn (com.android.dx.rop.code.FillArrayDataInsn)2 Insn (com.android.dx.rop.code.Insn)2 PlainCstInsn (com.android.dx.rop.code.PlainCstInsn)2 PlainInsn (com.android.dx.rop.code.PlainInsn)2 ThrowingCstInsn (com.android.dx.rop.code.ThrowingCstInsn)2 ThrowingInsn (com.android.dx.rop.code.ThrowingInsn)2 CstArray (com.android.dx.rop.cst.CstArray)2 CstInteger (com.android.dx.rop.cst.CstInteger)2 CstType (com.android.dx.rop.cst.CstType)2 TypedConstant (com.android.dx.rop.cst.TypedConstant)2 HashSet (java.util.HashSet)2