Search in sources :

Example 51 with RegisterSpec

use of com.taobao.android.dx.rop.code.RegisterSpec in project atlas by alibaba.

the class FirstFitLocalCombiningAllocator method handleLocalAssociatedParams.

/**
     * Maps all local-associated parameters to rop registers.
     */
private void handleLocalAssociatedParams() {
    for (ArrayList<RegisterSpec> ssaRegs : localVariables.values()) {
        int sz = ssaRegs.size();
        int paramIndex = -1;
        int paramCategory = 0;
        // First, find out if this local variable is a parameter.
        for (int i = 0; i < sz; i++) {
            RegisterSpec ssaSpec = ssaRegs.get(i);
            int ssaReg = ssaSpec.getReg();
            paramIndex = getParameterIndexForReg(ssaReg);
            if (paramIndex >= 0) {
                paramCategory = ssaSpec.getCategory();
                addMapping(ssaSpec, paramIndex);
                break;
            }
        }
        if (paramIndex < 0) {
            // This local wasn't a parameter.
            continue;
        }
        // Any remaining local-associated registers will be mapped later.
        tryMapRegs(ssaRegs, paramIndex, paramCategory, true);
    }
}
Also used : RegisterSpec(com.taobao.android.dx.rop.code.RegisterSpec)

Example 52 with RegisterSpec

use of com.taobao.android.dx.rop.code.RegisterSpec in project atlas by alibaba.

the class LocalVariableExtractor method processBlock.

/**
     * Processes a single block.
     *
     * @param blockIndex {@code >= 0;} block index of the block to process
     */
private void processBlock(int blockIndex) {
    RegisterSpecSet primaryState = resultInfo.mutableCopyOfStarts(blockIndex);
    SsaBasicBlock block = blocks.get(blockIndex);
    List<SsaInsn> insns = block.getInsns();
    int insnSz = insns.size();
    // The exit block has no insns and no successors
    if (blockIndex == method.getExitBlockIndex()) {
        return;
    }
    /*
         * We may have to treat the last instruction specially: If it
         * can (but doesn't always) throw, and the exception can be
         * caught within the same method, then we need to use the
         * state *before* executing it to be what is merged into
         * exception targets.
         */
    SsaInsn lastInsn = insns.get(insnSz - 1);
    boolean hasExceptionHandlers = lastInsn.getOriginalRopInsn().getCatches().size() != 0;
    boolean canThrowDuringLastInsn = hasExceptionHandlers && (lastInsn.getResult() != null);
    int freezeSecondaryStateAt = insnSz - 1;
    RegisterSpecSet secondaryState = primaryState;
    for (int i = 0; i < insnSz; i++) {
        if (canThrowDuringLastInsn && (i == freezeSecondaryStateAt)) {
            // Until this point, primaryState == secondaryState.
            primaryState.setImmutable();
            primaryState = primaryState.mutableCopy();
        }
        SsaInsn insn = insns.get(i);
        RegisterSpec result;
        result = insn.getLocalAssignment();
        if (result == null) {
            // We may be nuking an existing local
            result = insn.getResult();
            if (result != null && primaryState.get(result.getReg()) != null) {
                primaryState.remove(primaryState.get(result.getReg()));
            }
            continue;
        }
        result = result.withSimpleType();
        RegisterSpec already = primaryState.get(result);
        /*
             * The equals() check ensures we only add new info if
             * the instruction causes a change to the set of
             * active variables.
             */
        if (!result.equals(already)) {
            /*
                 * If this insn represents a local moving from one register
                 * to another, remove the association between the old register
                 * and the local.
                 */
            RegisterSpec previous = primaryState.localItemToSpec(result.getLocalItem());
            if (previous != null && (previous.getReg() != result.getReg())) {
                primaryState.remove(previous);
            }
            resultInfo.addAssignment(insn, result);
            primaryState.put(result);
        }
    }
    primaryState.setImmutable();
    /*
         * Merge this state into the start state for each successor,
         * and update the work set where required (that is, in cases
         * where the start state for a block changes).
         */
    IntList successors = block.getSuccessorList();
    int succSz = successors.size();
    int primarySuccessor = block.getPrimarySuccessorIndex();
    for (int i = 0; i < succSz; i++) {
        int succ = successors.get(i);
        RegisterSpecSet state = (succ == primarySuccessor) ? primaryState : secondaryState;
        if (resultInfo.mergeStarts(succ, state)) {
            workSet.set(succ);
        }
    }
}
Also used : RegisterSpecSet(com.taobao.android.dx.rop.code.RegisterSpecSet) RegisterSpec(com.taobao.android.dx.rop.code.RegisterSpec) IntList(com.taobao.android.dx.util.IntList)

Example 53 with RegisterSpec

use of com.taobao.android.dx.rop.code.RegisterSpec in project atlas by alibaba.

the class NormalSsaInsn method changeOneSource.

/**
     * Changes one of the insn's sources. New source should be of same type
     * and category.
     *
     * @param index {@code >=0;} index of source to change
     * @param newSpec spec for new source
     */
public final void changeOneSource(int index, RegisterSpec newSpec) {
    RegisterSpecList origSources = insn.getSources();
    int sz = origSources.size();
    RegisterSpecList newSources = new RegisterSpecList(sz);
    for (int i = 0; i < sz; i++) {
        newSources.set(i, i == index ? newSpec : origSources.get(i));
    }
    newSources.setImmutable();
    RegisterSpec origSpec = origSources.get(index);
    if (origSpec.getReg() != newSpec.getReg()) {
        /*
             * If the register remains unchanged, we're only changing
             * the type or local var name so don't update use list
             */
        getBlock().getParent().onSourceChanged(this, origSpec, newSpec);
    }
    insn = insn.withNewRegisters(getResult(), newSources);
}
Also used : RegisterSpecList(com.taobao.android.dx.rop.code.RegisterSpecList) RegisterSpec(com.taobao.android.dx.rop.code.RegisterSpec)

Example 54 with RegisterSpec

use of com.taobao.android.dx.rop.code.RegisterSpec in project atlas by alibaba.

the class Form31c method isCompatible.

/** {@inheritDoc} */
@Override
public boolean isCompatible(DalvInsn insn) {
    if (!(insn instanceof CstInsn)) {
        return false;
    }
    RegisterSpecList regs = insn.getRegisters();
    RegisterSpec reg;
    switch(regs.size()) {
        case 1:
            {
                reg = regs.get(0);
                break;
            }
        case 2:
            {
                /*
                 * This format is allowed for ops that are effectively
                 * 2-arg but where the two args are identical.
                 */
                reg = regs.get(0);
                if (reg.getReg() != regs.get(1).getReg()) {
                    return false;
                }
                break;
            }
        default:
            {
                return false;
            }
    }
    if (!unsignedFitsInByte(reg.getReg())) {
        return false;
    }
    CstInsn ci = (CstInsn) insn;
    Constant cst = ci.getConstant();
    return (cst instanceof CstType) || (cst instanceof CstFieldRef) || (cst instanceof CstString);
}
Also used : CstInsn(com.taobao.android.dx.dex.code.CstInsn) Constant(com.taobao.android.dx.rop.cst.Constant) CstType(com.taobao.android.dx.rop.cst.CstType) CstFieldRef(com.taobao.android.dx.rop.cst.CstFieldRef) CstString(com.taobao.android.dx.rop.cst.CstString) RegisterSpecList(com.taobao.android.dx.rop.code.RegisterSpecList) RegisterSpec(com.taobao.android.dx.rop.code.RegisterSpec)

Example 55 with RegisterSpec

use of com.taobao.android.dx.rop.code.RegisterSpec in project atlas by alibaba.

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 : Insn(com.taobao.android.dx.rop.code.Insn) PlainCstInsn(com.taobao.android.dx.rop.code.PlainCstInsn) PlainInsn(com.taobao.android.dx.rop.code.PlainInsn) ThrowingInsn(com.taobao.android.dx.rop.code.ThrowingInsn) ThrowingCstInsn(com.taobao.android.dx.rop.code.ThrowingCstInsn) Prototype(com.taobao.android.dx.rop.type.Prototype) ThrowingCstInsn(com.taobao.android.dx.rop.code.ThrowingCstInsn) BasicBlock(com.taobao.android.dx.rop.code.BasicBlock) InsnList(com.taobao.android.dx.rop.code.InsnList) ThrowingInsn(com.taobao.android.dx.rop.code.ThrowingInsn) PlainCstInsn(com.taobao.android.dx.rop.code.PlainCstInsn) PlainInsn(com.taobao.android.dx.rop.code.PlainInsn) CstType(com.taobao.android.dx.rop.cst.CstType) Type(com.taobao.android.dx.rop.type.Type) StdTypeList(com.taobao.android.dx.rop.type.StdTypeList) SourcePosition(com.taobao.android.dx.rop.code.SourcePosition) RegisterSpec(com.taobao.android.dx.rop.code.RegisterSpec)

Aggregations

RegisterSpec (com.taobao.android.dx.rop.code.RegisterSpec)66 RegisterSpecList (com.taobao.android.dx.rop.code.RegisterSpecList)24 PlainInsn (com.taobao.android.dx.rop.code.PlainInsn)12 Constant (com.taobao.android.dx.rop.cst.Constant)10 TypedConstant (com.taobao.android.dx.rop.cst.TypedConstant)8 ArrayList (java.util.ArrayList)8 Insn (com.taobao.android.dx.rop.code.Insn)7 PlainCstInsn (com.taobao.android.dx.rop.code.PlainCstInsn)7 Rop (com.taobao.android.dx.rop.code.Rop)7 ThrowingCstInsn (com.taobao.android.dx.rop.code.ThrowingCstInsn)7 CstType (com.taobao.android.dx.rop.cst.CstType)7 TypeBearer (com.taobao.android.dx.rop.type.TypeBearer)7 LocalItem (com.taobao.android.dx.rop.code.LocalItem)5 RegisterSpecSet (com.taobao.android.dx.rop.code.RegisterSpecSet)5 ThrowingInsn (com.taobao.android.dx.rop.code.ThrowingInsn)5 CstString (com.taobao.android.dx.rop.cst.CstString)5 BitSet (java.util.BitSet)5 HashSet (java.util.HashSet)5 SourcePosition (com.taobao.android.dx.rop.code.SourcePosition)4 CstFieldRef (com.taobao.android.dx.rop.cst.CstFieldRef)4