Search in sources :

Example 11 with ThrowingCstInsn

use of com.android.dx.rop.code.ThrowingCstInsn in project J2ME-Loader by nikita36078.

the class Ropper method addSetupBlocks.

/**
 * Constructs and adds the blocks that perform setup for the rest of
 * the method. This includes a first block which merely contains
 * assignments from parameters to the same-numbered registers and
 * a possible second block which deals with synchronization.
 */
private void addSetupBlocks() {
    LocalVariableList localVariables = method.getLocalVariables();
    SourcePosition pos = method.makeSourcePosistion(0);
    Prototype desc = method.getEffectiveDescriptor();
    StdTypeList params = desc.getParameterTypes();
    int sz = params.size();
    InsnList insns = new InsnList(sz + 1);
    int at = 0;
    for (int i = 0; i < sz; i++) {
        Type one = params.get(i);
        LocalVariableList.Item local = localVariables.pcAndIndexToLocal(0, at);
        RegisterSpec result = (local == null) ? RegisterSpec.make(at, one) : RegisterSpec.makeLocalOptional(at, one, local.getLocalItem());
        Insn insn = new PlainCstInsn(Rops.opMoveParam(one), pos, result, RegisterSpecList.EMPTY, CstInteger.make(at));
        insns.set(i, insn);
        at += one.getCategory();
    }
    insns.set(sz, new PlainInsn(Rops.GOTO, pos, null, RegisterSpecList.EMPTY));
    insns.setImmutable();
    boolean synch = isSynchronized();
    int label = synch ? getSpecialLabel(SYNCH_SETUP_1) : 0;
    BasicBlock bb = new BasicBlock(getSpecialLabel(PARAM_ASSIGNMENT), insns, IntList.makeImmutable(label), label);
    addBlock(bb, IntList.EMPTY);
    if (synch) {
        RegisterSpec synchReg = getSynchReg();
        Insn insn;
        if (isStatic()) {
            insn = new ThrowingCstInsn(Rops.CONST_OBJECT, pos, RegisterSpecList.EMPTY, StdTypeList.EMPTY, method.getDefiningClass());
            insns = new InsnList(1);
            insns.set(0, insn);
        } else {
            insns = new InsnList(2);
            insn = new PlainCstInsn(Rops.MOVE_PARAM_OBJECT, pos, synchReg, RegisterSpecList.EMPTY, CstInteger.VALUE_0);
            insns.set(0, insn);
            insns.set(1, new PlainInsn(Rops.GOTO, pos, null, RegisterSpecList.EMPTY));
        }
        int label2 = getSpecialLabel(SYNCH_SETUP_2);
        insns.setImmutable();
        bb = new BasicBlock(label, insns, IntList.makeImmutable(label2), label2);
        addBlock(bb, IntList.EMPTY);
        insns = new InsnList(isStatic() ? 2 : 1);
        if (isStatic()) {
            insns.set(0, new PlainInsn(Rops.opMoveResultPseudo(synchReg), pos, synchReg, RegisterSpecList.EMPTY));
        }
        insn = new ThrowingInsn(Rops.MONITOR_ENTER, pos, RegisterSpecList.make(synchReg), StdTypeList.EMPTY);
        insns.set(isStatic() ? 1 : 0, insn);
        insns.setImmutable();
        bb = new BasicBlock(label2, insns, IntList.makeImmutable(0), 0);
        addBlock(bb, IntList.EMPTY);
    }
}
Also used : ThrowingCstInsn(com.android.dx.rop.code.ThrowingCstInsn) ThrowingInsn(com.android.dx.rop.code.ThrowingInsn) PlainInsn(com.android.dx.rop.code.PlainInsn) Insn(com.android.dx.rop.code.Insn) PlainCstInsn(com.android.dx.rop.code.PlainCstInsn) Prototype(com.android.dx.rop.type.Prototype) ThrowingCstInsn(com.android.dx.rop.code.ThrowingCstInsn) BasicBlock(com.android.dx.rop.code.BasicBlock) InsnList(com.android.dx.rop.code.InsnList) ThrowingInsn(com.android.dx.rop.code.ThrowingInsn) PlainCstInsn(com.android.dx.rop.code.PlainCstInsn) PlainInsn(com.android.dx.rop.code.PlainInsn) Type(com.android.dx.rop.type.Type) CstType(com.android.dx.rop.cst.CstType) StdTypeList(com.android.dx.rop.type.StdTypeList) SourcePosition(com.android.dx.rop.code.SourcePosition) RegisterSpec(com.android.dx.rop.code.RegisterSpec)

Example 12 with ThrowingCstInsn

use of com.android.dx.rop.code.ThrowingCstInsn in project buck by facebook.

the class ConstCollector method run.

/**
     * Applies the optimization.
     */
private void run() {
    int regSz = ssaMeth.getRegCount();
    ArrayList<TypedConstant> constantList = getConstsSortedByCountUse();
    int toCollect = Math.min(constantList.size(), MAX_COLLECTED_CONSTANTS);
    SsaBasicBlock start = ssaMeth.getEntryBlock();
    // Constant to new register containing the constant
    HashMap<TypedConstant, RegisterSpec> newRegs = new HashMap<TypedConstant, RegisterSpec>(toCollect);
    for (int i = 0; i < toCollect; i++) {
        TypedConstant cst = constantList.get(i);
        RegisterSpec result = RegisterSpec.make(ssaMeth.makeNewSsaReg(), cst);
        Rop constRop = Rops.opConst(cst);
        if (constRop.getBranchingness() == Rop.BRANCH_NONE) {
            start.addInsnToHead(new PlainCstInsn(Rops.opConst(cst), SourcePosition.NO_INFO, result, RegisterSpecList.EMPTY, cst));
        } else {
            // We need two new basic blocks along with the new insn
            SsaBasicBlock entryBlock = ssaMeth.getEntryBlock();
            SsaBasicBlock successorBlock = entryBlock.getPrimarySuccessor();
            // Insert a block containing the const insn.
            SsaBasicBlock constBlock = entryBlock.insertNewSuccessor(successorBlock);
            constBlock.replaceLastInsn(new ThrowingCstInsn(constRop, SourcePosition.NO_INFO, RegisterSpecList.EMPTY, StdTypeList.EMPTY, cst));
            // Insert a block containing the move-result-pseudo insn.
            SsaBasicBlock resultBlock = constBlock.insertNewSuccessor(successorBlock);
            PlainInsn insn = new PlainInsn(Rops.opMoveResultPseudo(result.getTypeBearer()), SourcePosition.NO_INFO, result, RegisterSpecList.EMPTY);
            resultBlock.addInsnToHead(insn);
        }
        newRegs.put(cst, result);
    }
    updateConstUses(newRegs, regSz);
}
Also used : PlainCstInsn(com.android.dx.rop.code.PlainCstInsn) PlainInsn(com.android.dx.rop.code.PlainInsn) Rop(com.android.dx.rop.code.Rop) ThrowingCstInsn(com.android.dx.rop.code.ThrowingCstInsn) TypedConstant(com.android.dx.rop.cst.TypedConstant) HashMap(java.util.HashMap) RegisterSpec(com.android.dx.rop.code.RegisterSpec)

Example 13 with ThrowingCstInsn

use of com.android.dx.rop.code.ThrowingCstInsn in project dexmaker by linkedin.

the class Code method newArray.

/**
 * Assigns {@code target} to a newly allocated array of length {@code
 * length}. The array's type is the same as {@code target}'s type.
 */
public <T> void newArray(Local<T> target, Local<Integer> length) {
    addInstruction(new ThrowingCstInsn(Rops.opNewArray(target.type.ropType), sourcePosition, RegisterSpecList.make(length.spec()), catches, target.type.constant));
    moveResult(target, true);
}
Also used : ThrowingCstInsn(com.android.dx.rop.code.ThrowingCstInsn)

Example 14 with ThrowingCstInsn

use of com.android.dx.rop.code.ThrowingCstInsn in project J2ME-Loader by nikita36078.

the class RopToDop method dopFor.

/**
 * Returns the dalvik opcode appropriate for the given register-based
 * instruction.
 *
 * @param insn {@code non-null;} the original instruction
 * @return the corresponding dalvik opcode; one of the constants in
 * {@link Dops}
 */
public static Dop dopFor(Insn insn) {
    Rop rop = insn.getOpcode();
    /*
         * First, just try looking up the rop in the MAP of easy
         * cases.
         */
    Dop result = MAP.get(rop);
    if (result != null) {
        return result;
    }
    switch(rop.getOpcode()) {
        case RegOps.MOVE_EXCEPTION:
            return Dops.MOVE_EXCEPTION;
        case RegOps.INVOKE_STATIC:
            return Dops.INVOKE_STATIC;
        case RegOps.INVOKE_VIRTUAL:
            return Dops.INVOKE_VIRTUAL;
        case RegOps.INVOKE_SUPER:
            return Dops.INVOKE_SUPER;
        case RegOps.INVOKE_DIRECT:
            return Dops.INVOKE_DIRECT;
        case RegOps.INVOKE_INTERFACE:
            return Dops.INVOKE_INTERFACE;
        case RegOps.INVOKE_POLYMORPHIC:
            return Dops.INVOKE_POLYMORPHIC;
        case RegOps.NEW_ARRAY:
            return Dops.NEW_ARRAY;
        case RegOps.FILLED_NEW_ARRAY:
            return Dops.FILLED_NEW_ARRAY;
        case RegOps.FILL_ARRAY_DATA:
            return Dops.FILL_ARRAY_DATA;
        case RegOps.MOVE_RESULT:
            {
                RegisterSpec resultReg = insn.getResult();
                if (resultReg == null) {
                    return Dops.NOP;
                } else {
                    switch(resultReg.getBasicType()) {
                        case Type.BT_INT:
                        case Type.BT_FLOAT:
                        case Type.BT_BOOLEAN:
                        case Type.BT_BYTE:
                        case Type.BT_CHAR:
                        case Type.BT_SHORT:
                            return Dops.MOVE_RESULT;
                        case Type.BT_LONG:
                        case Type.BT_DOUBLE:
                            return Dops.MOVE_RESULT_WIDE;
                        case Type.BT_OBJECT:
                            return Dops.MOVE_RESULT_OBJECT;
                        default:
                            {
                                throw new RuntimeException("Unexpected basic type");
                            }
                    }
                }
            }
        case RegOps.GET_FIELD:
            {
                CstFieldRef ref = (CstFieldRef) ((ThrowingCstInsn) insn).getConstant();
                int basicType = ref.getBasicType();
                switch(basicType) {
                    case Type.BT_BOOLEAN:
                        return Dops.IGET_BOOLEAN;
                    case Type.BT_BYTE:
                        return Dops.IGET_BYTE;
                    case Type.BT_CHAR:
                        return Dops.IGET_CHAR;
                    case Type.BT_SHORT:
                        return Dops.IGET_SHORT;
                    case Type.BT_INT:
                        return Dops.IGET;
                }
                break;
            }
        case RegOps.PUT_FIELD:
            {
                CstFieldRef ref = (CstFieldRef) ((ThrowingCstInsn) insn).getConstant();
                int basicType = ref.getBasicType();
                switch(basicType) {
                    case Type.BT_BOOLEAN:
                        return Dops.IPUT_BOOLEAN;
                    case Type.BT_BYTE:
                        return Dops.IPUT_BYTE;
                    case Type.BT_CHAR:
                        return Dops.IPUT_CHAR;
                    case Type.BT_SHORT:
                        return Dops.IPUT_SHORT;
                    case Type.BT_INT:
                        return Dops.IPUT;
                }
                break;
            }
        case RegOps.GET_STATIC:
            {
                CstFieldRef ref = (CstFieldRef) ((ThrowingCstInsn) insn).getConstant();
                int basicType = ref.getBasicType();
                switch(basicType) {
                    case Type.BT_BOOLEAN:
                        return Dops.SGET_BOOLEAN;
                    case Type.BT_BYTE:
                        return Dops.SGET_BYTE;
                    case Type.BT_CHAR:
                        return Dops.SGET_CHAR;
                    case Type.BT_SHORT:
                        return Dops.SGET_SHORT;
                    case Type.BT_INT:
                        return Dops.SGET;
                }
                break;
            }
        case RegOps.PUT_STATIC:
            {
                CstFieldRef ref = (CstFieldRef) ((ThrowingCstInsn) insn).getConstant();
                int basicType = ref.getBasicType();
                switch(basicType) {
                    case Type.BT_BOOLEAN:
                        return Dops.SPUT_BOOLEAN;
                    case Type.BT_BYTE:
                        return Dops.SPUT_BYTE;
                    case Type.BT_CHAR:
                        return Dops.SPUT_CHAR;
                    case Type.BT_SHORT:
                        return Dops.SPUT_SHORT;
                    case Type.BT_INT:
                        return Dops.SPUT;
                }
                break;
            }
        case RegOps.CONST:
            {
                Constant cst = ((ThrowingCstInsn) insn).getConstant();
                if (cst instanceof CstType) {
                    return Dops.CONST_CLASS;
                } else if (cst instanceof CstString) {
                    return Dops.CONST_STRING;
                }
                break;
            }
    }
    throw new RuntimeException("unknown rop: " + rop);
}
Also used : Rop(com.android.dx.rop.code.Rop) ThrowingCstInsn(com.android.dx.rop.code.ThrowingCstInsn) Constant(com.android.dx.rop.cst.Constant) CstType(com.android.dx.rop.cst.CstType) CstFieldRef(com.android.dx.rop.cst.CstFieldRef) CstString(com.android.dx.rop.cst.CstString) RegisterSpec(com.android.dx.rop.code.RegisterSpec)

Example 15 with ThrowingCstInsn

use of com.android.dx.rop.code.ThrowingCstInsn in project J2ME-Loader by nikita36078.

the class ConstCollector method run.

/**
 * Applies the optimization.
 */
private void run() {
    int regSz = ssaMeth.getRegCount();
    ArrayList<TypedConstant> constantList = getConstsSortedByCountUse();
    int toCollect = Math.min(constantList.size(), MAX_COLLECTED_CONSTANTS);
    SsaBasicBlock start = ssaMeth.getEntryBlock();
    // Constant to new register containing the constant
    HashMap<TypedConstant, RegisterSpec> newRegs = new HashMap<TypedConstant, RegisterSpec>(toCollect);
    for (int i = 0; i < toCollect; i++) {
        TypedConstant cst = constantList.get(i);
        RegisterSpec result = RegisterSpec.make(ssaMeth.makeNewSsaReg(), cst);
        Rop constRop = Rops.opConst(cst);
        if (constRop.getBranchingness() == Rop.BRANCH_NONE) {
            start.addInsnToHead(new PlainCstInsn(Rops.opConst(cst), SourcePosition.NO_INFO, result, RegisterSpecList.EMPTY, cst));
        } else {
            // We need two new basic blocks along with the new insn
            SsaBasicBlock entryBlock = ssaMeth.getEntryBlock();
            SsaBasicBlock successorBlock = entryBlock.getPrimarySuccessor();
            // Insert a block containing the const insn.
            SsaBasicBlock constBlock = entryBlock.insertNewSuccessor(successorBlock);
            constBlock.replaceLastInsn(new ThrowingCstInsn(constRop, SourcePosition.NO_INFO, RegisterSpecList.EMPTY, StdTypeList.EMPTY, cst));
            // Insert a block containing the move-result-pseudo insn.
            SsaBasicBlock resultBlock = constBlock.insertNewSuccessor(successorBlock);
            PlainInsn insn = new PlainInsn(Rops.opMoveResultPseudo(result.getTypeBearer()), SourcePosition.NO_INFO, result, RegisterSpecList.EMPTY);
            resultBlock.addInsnToHead(insn);
        }
        newRegs.put(cst, result);
    }
    updateConstUses(newRegs, regSz);
}
Also used : PlainCstInsn(com.android.dx.rop.code.PlainCstInsn) PlainInsn(com.android.dx.rop.code.PlainInsn) Rop(com.android.dx.rop.code.Rop) ThrowingCstInsn(com.android.dx.rop.code.ThrowingCstInsn) TypedConstant(com.android.dx.rop.cst.TypedConstant) HashMap(java.util.HashMap) RegisterSpec(com.android.dx.rop.code.RegisterSpec)

Aggregations

ThrowingCstInsn (com.android.dx.rop.code.ThrowingCstInsn)17 PlainCstInsn (com.android.dx.rop.code.PlainCstInsn)9 PlainInsn (com.android.dx.rop.code.PlainInsn)9 Rop (com.android.dx.rop.code.Rop)9 RegisterSpec (com.android.dx.rop.code.RegisterSpec)8 Insn (com.android.dx.rop.code.Insn)6 ThrowingInsn (com.android.dx.rop.code.ThrowingInsn)6 CstType (com.android.dx.rop.cst.CstType)6 FillArrayDataInsn (com.android.dx.rop.code.FillArrayDataInsn)4 SourcePosition (com.android.dx.rop.code.SourcePosition)4 Constant (com.android.dx.rop.cst.Constant)4 CstFieldRef (com.android.dx.rop.cst.CstFieldRef)4 Type (com.android.dx.rop.type.Type)4 BasicBlock (com.android.dx.rop.code.BasicBlock)2 InsnList (com.android.dx.rop.code.InsnList)2 RegisterSpecList (com.android.dx.rop.code.RegisterSpecList)2 SwitchInsn (com.android.dx.rop.code.SwitchInsn)2 CstInteger (com.android.dx.rop.cst.CstInteger)2 CstMethodRef (com.android.dx.rop.cst.CstMethodRef)2 CstString (com.android.dx.rop.cst.CstString)2