use of com.android.dx.rop.code.RegisterSpecSet in project buck by facebook.
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 buck by facebook.
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);
}
}
}
use of com.android.dx.rop.code.RegisterSpecSet in project buck by facebook.
the class RegisterMapper method map.
/**
*
* @param sources old register set
* @return new mapped register set, or old if nothing has changed.
*/
public final RegisterSpecSet map(RegisterSpecSet sources) {
int sz = sources.getMaxSize();
RegisterSpecSet newSources = new RegisterSpecSet(getNewRegisterCount());
for (int i = 0; i < sz; i++) {
RegisterSpec registerSpec = sources.get(i);
if (registerSpec != null) {
newSources.put(map(registerSpec));
}
}
newSources.setImmutable();
// Return the old sources if nothing has changed.
return newSources.equals(sources) ? sources : newSources;
}
use of com.android.dx.rop.code.RegisterSpecSet in project J2ME-Loader by nikita36078.
the class LocalList method make.
/**
* Constructs an instance for the given method, based on the given
* block order and intermediate local information.
*
* @param insns {@code non-null;} instructions to convert
* @return {@code non-null;} the constructed list
*/
public static LocalList make(DalvInsnList insns) {
int sz = insns.size();
/*
* Go through the insn list, looking for all the local
* variable pseudoinstructions, splitting out LocalSnapshots
* into separate per-variable starts, adding explicit ends
* wherever a variable is replaced or moved, and collecting
* these and all the other local variable "activity"
* together into an output list (without the other insns).
*
* Note: As of this writing, this method won't be handed any
* insn lists that contain local ends, but I (danfuzz) expect
* that to change at some point, when we start feeding that
* info explicitly into the rop layer rather than only trying
* to infer it. So, given that expectation, this code is
* written to deal with them.
*/
MakeState state = new MakeState(sz);
for (int i = 0; i < sz; i++) {
DalvInsn insn = insns.get(i);
if (insn instanceof LocalSnapshot) {
RegisterSpecSet snapshot = ((LocalSnapshot) insn).getLocals();
state.snapshot(insn.getAddress(), snapshot);
} else if (insn instanceof LocalStart) {
RegisterSpec local = ((LocalStart) insn).getLocal();
state.startLocal(insn.getAddress(), local);
}
}
LocalList result = state.finish();
if (DEBUG) {
debugVerify(result);
}
return result;
}
use of com.android.dx.rop.code.RegisterSpecSet in project J2ME-Loader by nikita36078.
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);
}
}
}
Aggregations