use of com.android.dx.rop.code.RegisterSpecSet in project buck by facebook.
the class RopTranslator method outputBlock.
/**
* Helper for {@link #outputInstructions}, which does the processing
* and output of one block.
*
* @param block {@code non-null;} the block to process and output
* @param nextLabel {@code >= -1;} the next block that will be processed, or
* {@code -1} if there is no next block
*/
private void outputBlock(BasicBlock block, int nextLabel) {
// Append the code address for this block.
CodeAddress startAddress = addresses.getStart(block);
output.add(startAddress);
// Append the local variable state for the block.
if (locals != null) {
RegisterSpecSet starts = locals.getStarts(block);
output.add(new LocalSnapshot(startAddress.getPosition(), starts));
}
/*
* Choose and append an output instruction for each original
* instruction.
*/
translationVisitor.setBlock(block, addresses.getLast(block));
block.getInsns().forEach(translationVisitor);
// Insert the block end code address.
output.add(addresses.getEnd(block));
// Set up for end-of-block activities.
int succ = block.getPrimarySuccessor();
Insn lastInsn = block.getLastInsn();
if ((succ >= 0) && (succ != nextLabel)) {
/*
* The block has a "primary successor" and that primary
* successor isn't the next block to be output.
*/
Rop lastRop = lastInsn.getOpcode();
if ((lastRop.getBranchingness() == Rop.BRANCH_IF) && (block.getSecondarySuccessor() == nextLabel)) {
/*
* The block ends with an "if" of some sort, and its
* secondary successor (the "then") is in fact the
* next block to output. So, reverse the sense of
* the test, so that we can just emit the next block
* without an interstitial goto.
*/
output.reverseBranch(1, addresses.getStart(succ));
} else {
/*
* Our only recourse is to add a goto here to get the
* flow to be correct.
*/
TargetInsn insn = new TargetInsn(Dops.GOTO, lastInsn.getPosition(), RegisterSpecList.EMPTY, addresses.getStart(succ));
output.add(insn);
}
}
}
use of com.android.dx.rop.code.RegisterSpecSet in project J2ME-Loader by nikita36078.
the class OutputFinisher method hasLocalInfo.
/**
* Helper for {@link #add} which scrutinizes a single
* instruction for local variable information.
*
* @param insn {@code non-null;} instruction to scrutinize
* @return {@code true} iff the instruction refers to any
* named locals
*/
private static boolean hasLocalInfo(DalvInsn insn) {
if (insn instanceof LocalSnapshot) {
RegisterSpecSet specs = ((LocalSnapshot) insn).getLocals();
int size = specs.size();
for (int i = 0; i < size; i++) {
if (hasLocalInfo(specs.get(i))) {
return true;
}
}
} else if (insn instanceof LocalStart) {
RegisterSpec spec = ((LocalStart) insn).getLocal();
if (hasLocalInfo(spec)) {
return true;
}
}
return false;
}
use of com.android.dx.rop.code.RegisterSpecSet in project J2ME-Loader by nikita36078.
the class OutputFinisher method addConstants.
/**
* Helper for {@link #getAllConstants} which adds all the info for
* a single instruction.
*
* @param result {@code non-null;} result set to add to
* @param insn {@code non-null;} instruction to scrutinize
*/
private static void addConstants(HashSet<Constant> result, DalvInsn insn) {
if (insn instanceof CstInsn) {
Constant cst = ((CstInsn) insn).getConstant();
result.add(cst);
} else if (insn instanceof MultiCstInsn) {
MultiCstInsn m = (MultiCstInsn) insn;
for (int i = 0; i < m.getNumberOfConstants(); i++) {
result.add(m.getConstant(i));
}
} else if (insn instanceof LocalSnapshot) {
RegisterSpecSet specs = ((LocalSnapshot) insn).getLocals();
int size = specs.size();
for (int i = 0; i < size; i++) {
addConstants(result, specs.get(i));
}
} else if (insn instanceof LocalStart) {
RegisterSpec spec = ((LocalStart) insn).getLocal();
addConstants(result, spec);
}
}
use of com.android.dx.rop.code.RegisterSpecSet in project J2ME-Loader by nikita36078.
the class LocalVariableInfo method mergeStarts.
/**
* Merges the given register set into the set for the block with the
* given index. If there was not already an associated set, then this
* is the same as calling {@link #setStarts}. Otherwise, this will
* merge the two sets and call {@link #setStarts} on the result of the
* merge.
*
* @param index {@code >= 0;} the block index
* @param specs {@code non-null;} the register set to merge into the start set
* for the block
* @return {@code true} if the merge resulted in an actual change
* to the associated set (including storing one for the first time) or
* {@code false} if there was no change
*/
public boolean mergeStarts(int index, RegisterSpecSet specs) {
RegisterSpecSet start = getStarts0(index);
boolean changed = false;
if (start == null) {
setStarts(index, specs);
return true;
}
RegisterSpecSet newStart = start.mutableCopy();
newStart.intersect(specs, true);
if (start.equals(newStart)) {
return false;
}
newStart.setImmutable();
setStarts(index, newStart);
return true;
}
Aggregations