use of com.android.dx.rop.code.RegisterSpec in project J2ME-Loader by nikita36078.
the class EscapeAnalysis method processInsn.
/**
* 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);
}
}
use of com.android.dx.rop.code.RegisterSpec in project J2ME-Loader by nikita36078.
the class InterferenceRegisterMapper method areAnyPinned.
/**
* 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;
}
use of com.android.dx.rop.code.RegisterSpec 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);
}
}
}
use of com.android.dx.rop.code.RegisterSpec in project J2ME-Loader by nikita36078.
the class NormalSsaInsn method getLocalAssignment.
/**
* {@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;
}
use of com.android.dx.rop.code.RegisterSpec in project J2ME-Loader by nikita36078.
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);
}
Aggregations