com.android.dx.rop.code.RegisterSpec Java Examples

The following examples show how to use com.android.dx.rop.code.RegisterSpec. You can vote up the ones you like or vote down the ones you don't like, and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example #1
Source File: RopTranslator.java    From Box with Apache License 2.0 6 votes vote down vote up
/** {@inheritDoc} */
@Override
public void visitThrowingInsn(ThrowingInsn insn) {
    SourcePosition pos = insn.getPosition();
    Dop opcode = RopToDop.dopFor(insn);
    Rop rop = insn.getOpcode();
    RegisterSpec realResult;

    if (rop.getBranchingness() != Rop.BRANCH_THROW) {
        throw new RuntimeException("shouldn't happen");
    }

    realResult = getNextMoveResultPseudo();

    if (opcode.hasResult() != (realResult != null)) {
        throw new RuntimeException(
                "Insn with result/move-result-pseudo mismatch" + insn);
    }

    addOutput(lastAddress);

    DalvInsn di = new SimpleInsn(opcode, pos,
            getRegs(insn, realResult));

    addOutput(di);
}
 
Example #2
Source File: BasicRegisterMapper.java    From Box with Apache License 2.0 6 votes vote down vote up
/** {@inheritDoc} */
@Override
public RegisterSpec map(RegisterSpec registerSpec) {
    if (registerSpec == null) {
        return null;
    }

    int newReg;
    try {
        newReg = oldToNew.get(registerSpec.getReg());
    } catch (IndexOutOfBoundsException ex) {
        newReg = -1;
    }

    if (newReg < 0) {
        throw new RuntimeException("no mapping specified for register");
    }

    return registerSpec.withReg(newReg);
}
 
Example #3
Source File: BasicRegisterMapper.java    From Box with Apache License 2.0 6 votes vote down vote up
/** {@inheritDoc} */
@Override
public RegisterSpec map(RegisterSpec registerSpec) {
    if (registerSpec == null) {
        return null;
    }

    int newReg;
    try {
        newReg = oldToNew.get(registerSpec.getReg());
    } catch (IndexOutOfBoundsException ex) {
        newReg = -1;
    }

    if (newReg < 0) {
        throw new RuntimeException("no mapping specified for register");
    }

    return registerSpec.withReg(newReg);
}
 
Example #4
Source File: HighRegisterPrefix.java    From Box with Apache License 2.0 6 votes vote down vote up
/** {@inheritDoc} */
@Override
protected String listingString0(boolean noteIndices) {
    RegisterSpecList registers = getRegisters();
    int sz = registers.size();
    StringBuilder sb = new StringBuilder(100);

    for (int i = 0, outAt = 0; i < sz; i++) {
        RegisterSpec src = registers.get(i);
        SimpleInsn insn = moveInsnFor(src, outAt);

        if (i != 0) {
            sb.append('\n');
        }

        sb.append(insn.listingString0(noteIndices));

        outAt += src.getCategory();
    }

    return sb.toString();
}
 
Example #5
Source File: NormalSsaInsn.java    From Box with Apache License 2.0 6 votes vote down vote up
/** {@inheritDoc} */
@Override
public RegisterSpec getLocalAssignment() {
    RegisterSpec assignment;

    if (insn.getOpcode().getOpcode() == RegOps.MARK_LOCAL) {
        assignment = insn.getSources().get(0);
    } else {
        assignment = getResult();
    }

    if (assignment == null) {
        return null;
    }

    LocalItem local = assignment.getLocalItem();

    if (local == null) {
        return null;
    }

    return assignment;
}
 
Example #6
Source File: EscapeAnalysis.java    From J2ME-Loader with Apache License 2.0 6 votes vote down vote up
/**
 * Handles phi uses of new objects. Will merge together the sources of a phi
 * into a single EscapeSet. Adds the result of the phi to the worklist so
 * its uses can be followed.
 *
 * @param use {@code non-null;} phi use being processed
 * @param escSet {@code non-null;} EscapeSet for the object
 * @param regWorklist {@code non-null;} worklist of instructions left to
 * process for this object
 */
private void processPhiUse(SsaInsn use, EscapeSet escSet,
                               ArrayList<RegisterSpec> regWorklist) {
    int setIndex = findSetIndex(use.getResult());
    if (setIndex != latticeValues.size()) {
        // Check if result is in a set already
        EscapeSet mergeSet = latticeValues.get(setIndex);
        if (mergeSet != escSet) {
            // If it is, merge the sets and states, then delete the copy
            escSet.replaceableArray = false;
            escSet.regSet.or(mergeSet.regSet);
            if (escSet.escape.compareTo(mergeSet.escape) < 0) {
                escSet.escape = mergeSet.escape;
            }
            replaceNode(escSet, mergeSet);
            latticeValues.remove(setIndex);
        }
    } else {
        // If no set is found, add it to this escSet and the worklist
        escSet.regSet.set(use.getResult().getReg());
        regWorklist.add(use.getResult());
    }
}
 
Example #7
Source File: FirstFitLocalCombiningAllocator.java    From Box with Apache License 2.0 6 votes vote down vote up
/**
 * Dumps local variable table to stdout for debugging.
 */
private void printLocalVars() {
    System.out.println("Printing local vars");
    for (Map.Entry<LocalItem, ArrayList<RegisterSpec>> e :
            localVariables.entrySet()) {
        StringBuilder regs = new StringBuilder();

        regs.append('{');
        regs.append(' ');
        for (RegisterSpec reg : e.getValue()) {
            regs.append('v');
            regs.append(reg.getReg());
            regs.append(' ');
        }
        regs.append('}');
        System.out.printf("Local: %s Registers: %s\n", e.getKey(), regs);
    }
}
 
Example #8
Source File: LocalVariableInfo.java    From buck with Apache License 2.0 6 votes vote down vote up
/**
 * Constructs an instance.
 *
 * @param method {@code non-null;} the method being represented by this instance
 */
public LocalVariableInfo(SsaMethod method) {
    if (method == null) {
        throw new NullPointerException("method == null");
    }

    List<SsaBasicBlock> blocks = method.getBlocks();

    this.regCount = method.getRegCount();
    this.emptySet = new RegisterSpecSet(regCount);
    this.blockStarts = new RegisterSpecSet[blocks.size()];
    this.insnAssignments =
        new HashMap<SsaInsn, RegisterSpec>(/*hint here*/);

    emptySet.setImmutable();
}
 
Example #9
Source File: LocalList.java    From Box with Apache License 2.0 6 votes vote down vote up
/**
 * Constructs an instance.
 *
 * @param address {@code >= 0;} address
 * @param disposition {@code non-null;} disposition of the local
 * @param spec {@code non-null;} register spec representing
 * the variable
 */
public Entry(int address, Disposition disposition, RegisterSpec spec) {
    if (address < 0) {
        throw new IllegalArgumentException("address < 0");
    }

    if (disposition == null) {
        throw new NullPointerException("disposition == null");
    }

    try {
        if (spec.getLocalItem() == null) {
            throw new NullPointerException(
                    "spec.getLocalItem() == null");
        }
    } catch (NullPointerException ex) {
        // Elucidate the exception.
        throw new NullPointerException("spec == null");
    }

    this.address = address;
    this.disposition = disposition;
    this.spec = spec;
    this.type = CstType.intern(spec.getType());
}
 
Example #10
Source File: FirstFitLocalCombiningAllocator.java    From J2ME-Loader with Apache License 2.0 6 votes vote down vote up
/**
 * Dumps local variable table to stdout for debugging.
 */
private void printLocalVars() {
    System.out.println("Printing local vars");
    for (Map.Entry<LocalItem, ArrayList<RegisterSpec>> e :
            localVariables.entrySet()) {
        StringBuilder regs = new StringBuilder();

        regs.append('{');
        regs.append(' ');
        for (RegisterSpec reg : e.getValue()) {
            regs.append('v');
            regs.append(reg.getReg());
            regs.append(' ');
        }
        regs.append('}');
        System.out.printf("Local: %s Registers: %s\n", e.getKey(), regs);
    }
}
 
Example #11
Source File: Form35c.java    From J2ME-Loader with Apache License 2.0 6 votes vote down vote up
/** {@inheritDoc} */
@Override
public BitSet compatibleRegs(DalvInsn insn) {
    RegisterSpecList regs = insn.getRegisters();
    int sz = regs.size();
    BitSet bits = new BitSet(sz);

    for (int i = 0; i < sz; i++) {
        RegisterSpec reg = regs.get(i);
        /*
         * The check below adds (category - 1) to the register, to
         * account for the fact that the second half of a
         * category-2 register has to be represented explicitly in
         * the result.
         */
        bits.set(i, unsignedFitsInNibble(reg.getReg() +
                                         reg.getCategory() - 1));
    }

    return bits;
}
 
Example #12
Source File: InsnFormat.java    From buck with Apache License 2.0 6 votes vote down vote up
/**
 * Helper method to determine if a list of registers are sequential,
 * including degenerate cases for empty or single-element lists.
 *
 * @param list {@code non-null;} the list of registers
 * @return {@code true} iff the list is sequentially ordered
 */
protected static boolean isRegListSequential(RegisterSpecList list) {
    int sz = list.size();

    if (sz < 2) {
        return true;
    }

    int first = list.get(0).getReg();
    int next = first;

    for (int i = 0; i < sz; i++) {
        RegisterSpec one = list.get(i);
        if (one.getReg() != next) {
            return false;
        }
        next += one.getCategory();
    }

    return true;
}
 
Example #13
Source File: SsaMethod.java    From Box with Apache License 2.0 6 votes vote down vote up
/**
 * Checks to see if the given SSA reg is ever associated with a local
 * local variable. Each SSA reg may be associated with at most one
 * local var.
 *
 * @param spec {@code non-null;} ssa reg
 * @return true if reg is ever associated with a local
 */
public boolean isRegALocal(RegisterSpec spec) {
    SsaInsn defn = getDefinitionForRegister(spec.getReg());

    if (defn == null) {
        // version 0 registers are never used as locals
        return false;
    }

    // Does the definition have a local associated with it?
    if (defn.getLocalAssignment() != null) return true;

    // If not, is there a mark-local insn?
    for (SsaInsn use : getUseListForRegister(spec.getReg())) {
        Insn insn = use.getOriginalRopInsn();

        if (insn != null
                && insn.getOpcode().getOpcode() == RegOps.MARK_LOCAL) {
            return true;
        }
    }

    return false;
}
 
Example #14
Source File: EscapeAnalysis.java    From buck with Apache License 2.0 6 votes vote down vote up
/**
 * Process a single instruction, looking for new objects resulting from
 * move result or move param.
 *
 * @param insn {@code non-null;} instruction to process
 */
private void processInsn(SsaInsn insn) {
    int op = insn.getOpcode().getOpcode();
    RegisterSpec result = insn.getResult();
    EscapeSet escSet;

    // Identify new objects
    if (op == RegOps.MOVE_RESULT_PSEUDO &&
            result.getTypeBearer().getBasicType() == Type.BT_OBJECT) {
        // Handle objects generated through move_result_pseudo
        escSet = processMoveResultPseudoInsn(insn);
        processRegister(result, escSet);
    } else if (op == RegOps.MOVE_PARAM &&
                  result.getTypeBearer().getBasicType() == Type.BT_OBJECT) {
        // Track method arguments that are objects
        escSet = new EscapeSet(result.getReg(), regCount, EscapeState.NONE);
        latticeValues.add(escSet);
        processRegister(result, escSet);
    } else if (op == RegOps.MOVE_RESULT &&
            result.getTypeBearer().getBasicType() == Type.BT_OBJECT) {
        // Track method return values that are objects
        escSet = new EscapeSet(result.getReg(), regCount, EscapeState.NONE);
        latticeValues.add(escSet);
        processRegister(result, escSet);
    }
}
 
Example #15
Source File: DalvInsn.java    From J2ME-Loader with Apache License 2.0 6 votes vote down vote up
/**
 * Makes a move instruction, appropriate and ideal for the given arguments.
 *
 * @param position {@code non-null;} source position information
 * @param dest {@code non-null;} destination register
 * @param src {@code non-null;} source register
 * @return {@code non-null;} an appropriately-constructed instance
 */
public static SimpleInsn makeMove(SourcePosition position,
        RegisterSpec dest, RegisterSpec src) {
    boolean category1 = dest.getCategory() == 1;
    boolean reference = dest.getType().isReference();
    int destReg = dest.getReg();
    int srcReg = src.getReg();
    Dop opcode;

    if ((srcReg | destReg) < 16) {
        opcode = reference ? Dops.MOVE_OBJECT :
            (category1 ? Dops.MOVE : Dops.MOVE_WIDE);
    } else if (destReg < 256) {
        opcode = reference ? Dops.MOVE_OBJECT_FROM16 :
            (category1 ? Dops.MOVE_FROM16 : Dops.MOVE_WIDE_FROM16);
    } else {
        opcode = reference ? Dops.MOVE_OBJECT_16 :
            (category1 ? Dops.MOVE_16 : Dops.MOVE_WIDE_16);
    }

    return new SimpleInsn(opcode, position,
                          RegisterSpecList.make(dest, src));
}
 
Example #16
Source File: EscapeAnalysis.java    From Box with Apache License 2.0 6 votes vote down vote up
/**
 * Handles phi uses of new objects. Will merge together the sources of a phi
 * into a single EscapeSet. Adds the result of the phi to the worklist so
 * its uses can be followed.
 *
 * @param use {@code non-null;} phi use being processed
 * @param escSet {@code non-null;} EscapeSet for the object
 * @param regWorklist {@code non-null;} worklist of instructions left to
 * process for this object
 */
private void processPhiUse(SsaInsn use, EscapeSet escSet,
                               ArrayList<RegisterSpec> regWorklist) {
    int setIndex = findSetIndex(use.getResult());
    if (setIndex != latticeValues.size()) {
        // Check if result is in a set already
        EscapeSet mergeSet = latticeValues.get(setIndex);
        if (mergeSet != escSet) {
            // If it is, merge the sets and states, then delete the copy
            escSet.replaceableArray = false;
            escSet.regSet.or(mergeSet.regSet);
            if (escSet.escape.compareTo(mergeSet.escape) < 0) {
                escSet.escape = mergeSet.escape;
            }
            replaceNode(escSet, mergeSet);
            latticeValues.remove(setIndex);
        }
    } else {
        // If no set is found, add it to this escSet and the worklist
        escSet.regSet.set(use.getResult().getReg());
        regWorklist.add(use.getResult());
    }
}
 
Example #17
Source File: InterferenceRegisterMapper.java    From buck with Apache License 2.0 6 votes vote down vote up
/**
 * Checks to see if any of a set of old-namespace registers are
 * pinned to the specified new-namespace reg + category. Takes into
 * account the category of the old-namespace registers.
 *
 * @param oldSpecs {@code non-null;} set of old-namespace regs
 * @param newReg {@code >= 0;} new-namespace register
 * @param targetCategory {@code 1..2;} the number of adjacent new-namespace
 * registers (starting at ropReg) to consider
 * @return true if any of the old-namespace register have been mapped
 * to the new-namespace register + category
 */
public boolean areAnyPinned(RegisterSpecList oldSpecs,
        int newReg, int targetCategory) {
    int sz = oldSpecs.size();

    for (int i = 0; i < sz; i++) {
        RegisterSpec oldSpec = oldSpecs.get(i);
        int r = oldToNew(oldSpec.getReg());

        /*
         * If oldSpec is a category-2 register, then check both newReg
         * and newReg - 1.
         */
        if (r == newReg
            || (oldSpec.getCategory() == 2 && (r + 1) == newReg)
            || (targetCategory == 2 && (r == newReg + 1))) {
            return true;
        }
    }

    return false;
}
 
Example #18
Source File: BasicRegisterMapper.java    From buck with Apache License 2.0 6 votes vote down vote up
/** {@inheritDoc} */
@Override
public RegisterSpec map(RegisterSpec registerSpec) {
    if (registerSpec == null) {
        return null;
    }

    int newReg;
    try {
        newReg = oldToNew.get(registerSpec.getReg());
    } catch (IndexOutOfBoundsException ex) {
        newReg = -1;
    }

    if (newReg < 0) {
        throw new RuntimeException("no mapping specified for register");
    }

    return registerSpec.withReg(newReg);
}
 
Example #19
Source File: EscapeAnalysis.java    From Box with Apache License 2.0 6 votes vote down vote up
/**
 * Process a single instruction, looking for new objects resulting from
 * move result or move param.
 *
 * @param insn {@code non-null;} instruction to process
 */
private void processInsn(SsaInsn insn) {
    int op = insn.getOpcode().getOpcode();
    RegisterSpec result = insn.getResult();
    EscapeSet escSet;

    // Identify new objects
    if (op == RegOps.MOVE_RESULT_PSEUDO &&
            result.getTypeBearer().getBasicType() == Type.BT_OBJECT) {
        // Handle objects generated through move_result_pseudo
        escSet = processMoveResultPseudoInsn(insn);
        processRegister(result, escSet);
    } else if (op == RegOps.MOVE_PARAM &&
                  result.getTypeBearer().getBasicType() == Type.BT_OBJECT) {
        // Track method arguments that are objects
        escSet = new EscapeSet(result.getReg(), regCount, EscapeState.NONE);
        latticeValues.add(escSet);
        processRegister(result, escSet);
    } else if (op == RegOps.MOVE_RESULT &&
            result.getTypeBearer().getBasicType() == Type.BT_OBJECT) {
        // Track method return values that are objects
        escSet = new EscapeSet(result.getReg(), regCount, EscapeState.NONE);
        latticeValues.add(escSet);
        processRegister(result, escSet);
    }
}
 
Example #20
Source File: NormalSsaInsn.java    From J2ME-Loader with Apache License 2.0 6 votes vote down vote up
/**
 * 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);
}
 
Example #21
Source File: InterferenceRegisterMapper.java    From Box with Apache License 2.0 6 votes vote down vote up
/**
 * Checks to see if any of a set of old-namespace registers are
 * pinned to the specified new-namespace reg + category. Takes into
 * account the category of the old-namespace registers.
 *
 * @param oldSpecs {@code non-null;} set of old-namespace regs
 * @param newReg {@code >= 0;} new-namespace register
 * @param targetCategory {@code 1..2;} the number of adjacent new-namespace
 * registers (starting at ropReg) to consider
 * @return true if any of the old-namespace register have been mapped
 * to the new-namespace register + category
 */
public boolean areAnyPinned(RegisterSpecList oldSpecs,
        int newReg, int targetCategory) {
    int sz = oldSpecs.size();

    for (int i = 0; i < sz; i++) {
        RegisterSpec oldSpec = oldSpecs.get(i);
        int r = oldToNew(oldSpec.getReg());

        /*
         * If oldSpec is a category-2 register, then check both newReg
         * and newReg - 1.
         */
        if (r == newReg
            || (oldSpec.getCategory() == 2 && (r + 1) == newReg)
            || (targetCategory == 2 && (r == newReg + 1))) {
            return true;
        }
    }

    return false;
}
 
Example #22
Source File: NormalSsaInsn.java    From Box with Apache License 2.0 6 votes vote down vote up
/**
 * 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);
}
 
Example #23
Source File: LocalList.java    From Box with Apache License 2.0 5 votes vote down vote up
/**
 * Adds or updates an end local (changing its disposition). If
 * this would cause an empty range for a local, this instead
 * removes the local entirely.
 *
 * @param address {@code >= 0;} the address
 * @param disposition {@code non-null;} the disposition
 * @param spec {@code non-null;} spec representing the local
 */
private void addOrUpdateEnd(int address, Disposition disposition,
        RegisterSpec spec) {
    if (disposition == Disposition.START) {
        throw new RuntimeException("shouldn't happen");
    }

    int regNum = spec.getReg();
    int endAt = endIndices[regNum];

    if (endAt >= 0) {
        // There is a previous end.
        Entry endEntry = result.get(endAt);
        if ((endEntry.getAddress() == address) &&
                endEntry.getRegisterSpec().equals(spec)) {
            /*
             * The end is for the right address and variable, so
             * update it.
             */
            result.set(endAt, endEntry.withDisposition(disposition));
            regs.remove(spec); // TODO: Is this line superfluous?
            return;
        }
    }

    endLocal(address, spec, disposition);
}
 
Example #24
Source File: SsaToRop.java    From Box with Apache License 2.0 5 votes vote down vote up
@Override
public void visitPhiInsn(PhiInsn insn) {
    RegisterSpecList sources = insn.getSources();
    RegisterSpec result = insn.getResult();
    int sz = sources.size();

    for (int i = 0; i < sz; i++) {
        RegisterSpec source = sources.get(i);
        SsaBasicBlock predBlock = blocks.get(
                insn.predBlockIndexForSourcesIndex(i));

        predBlock.addMoveToEnd(result, source);
    }
}
 
Example #25
Source File: SsaMethod.java    From J2ME-Loader with Apache License 2.0 5 votes vote down vote up
/**
 * Removes an instruction from use and def lists. For use during
 * instruction removal.
 *
 * @param insn {@code non-null;} insn to remove
 */
/*package*/ void onInsnRemoved(SsaInsn insn) {
    if (useList != null) {
        removeFromUseList(insn, insn.getSources());
    }

    RegisterSpec resultReg = insn.getResult();
    if (definitionList != null && resultReg != null) {
        definitionList[resultReg.getReg()] = null;
    }
}
 
Example #26
Source File: Form35c.java    From J2ME-Loader with Apache License 2.0 5 votes vote down vote up
/**
 * Returns a register list which is equivalent to the given one,
 * except that it splits category-2 registers into two explicit
 * entries. This returns the original list if no modification is
 * required
 *
 * @param orig {@code non-null;} the original list
 * @return {@code non-null;} the list with the described transformation
 */
private static RegisterSpecList explicitize(RegisterSpecList orig) {
    int wordCount = wordCount(orig);
    int sz = orig.size();

    if (wordCount == sz) {
        return orig;
    }

    RegisterSpecList result = new RegisterSpecList(wordCount);
    int wordAt = 0;

    for (int i = 0; i < sz; i++) {
        RegisterSpec one = orig.get(i);
        result.set(wordAt, one);
        if (one.getCategory() == 2) {
            result.set(wordAt + 1,
                       RegisterSpec.make(one.getReg() + 1, Type.VOID));
            wordAt += 2;
        } else {
            wordAt++;
        }
    }

    result.setImmutable();
    return result;
}
 
Example #27
Source File: LocalList.java    From Box with Apache License 2.0 5 votes vote down vote up
/**
 * Adds an entry to the result, updating the adjunct tables
 * accordingly.
 *
 * @param address {@code >= 0;} the address
 * @param disposition {@code non-null;} the disposition
 * @param spec {@code non-null;} spec representing the local
 */
private void add(int address, Disposition disposition,
        RegisterSpec spec) {
    int regNum = spec.getReg();

    result.add(new Entry(address, disposition, spec));

    if (disposition == Disposition.START) {
        regs.put(spec);
        endIndices[regNum] = -1;
    } else {
        regs.remove(spec);
        endIndices[regNum] = result.size() - 1;
    }
}
 
Example #28
Source File: LocalList.java    From Box with Apache License 2.0 5 votes vote down vote up
/**
 * Adds or updates an end local (changing its disposition). If
 * this would cause an empty range for a local, this instead
 * removes the local entirely.
 *
 * @param address {@code >= 0;} the address
 * @param disposition {@code non-null;} the disposition
 * @param spec {@code non-null;} spec representing the local
 */
private void addOrUpdateEnd(int address, Disposition disposition,
        RegisterSpec spec) {
    if (disposition == Disposition.START) {
        throw new RuntimeException("shouldn't happen");
    }

    int regNum = spec.getReg();
    int endAt = endIndices[regNum];

    if (endAt >= 0) {
        // There is a previous end.
        Entry endEntry = result.get(endAt);
        if ((endEntry.getAddress() == address) &&
                endEntry.getRegisterSpec().equals(spec)) {
            /*
             * The end is for the right address and variable, so
             * update it.
             */
            result.set(endAt, endEntry.withDisposition(disposition));
            regs.remove(spec); // TODO: Is this line superfluous?
            return;
        }
    }

    endLocal(address, spec, disposition);
}
 
Example #29
Source File: InsnFormat.java    From Box with Apache License 2.0 5 votes vote down vote up
/**
 * Helper method to return a register range string.
 *
 * @param list {@code non-null;} the list of registers (which must be
 * sequential)
 * @return {@code non-null;} the string form
 */
protected static String regRangeString(RegisterSpecList list) {
    int size = list.size();
    StringBuilder sb = new StringBuilder(30);

    sb.append("{");

    switch (size) {
        case 0: {
            // Nothing to do.
            break;
        }
        case 1: {
            sb.append(list.get(0).regString());
            break;
        }
        default: {
            RegisterSpec lastReg = list.get(size - 1);
            if (lastReg.getCategory() == 2) {
                /*
                 * Add one to properly represent a list-final
                 * category-2 register.
                 */
                lastReg = lastReg.withOffset(1);
            }

            sb.append(list.get(0).regString());
            sb.append("..");
            sb.append(lastReg.regString());
        }
    }

    sb.append("}");

    return sb.toString();
}
 
Example #30
Source File: SsaMethod.java    From Box with Apache License 2.0 5 votes vote down vote up
/**
 * Removes an instruction from use and def lists. For use during
 * instruction removal.
 *
 * @param insn {@code non-null;} insn to remove
 */
/*package*/ void onInsnRemoved(SsaInsn insn) {
    if (useList != null) {
        removeFromUseList(insn, insn.getSources());
    }

    RegisterSpec resultReg = insn.getResult();
    if (definitionList != null && resultReg != null) {
        definitionList[resultReg.getReg()] = null;
    }
}