use of com.taobao.android.dx.util.IntList in project atlas by alibaba.
the class RopMethod method calcPredecessors.
/**
* Calculates the predecessor sets for each block as well as for the
* exit.
*/
private void calcPredecessors() {
int maxLabel = blocks.getMaxLabel();
IntList[] predecessors = new IntList[maxLabel];
IntList exitPredecessors = new IntList(10);
int sz = blocks.size();
/*
* For each block, find its successors, and add the block's label to
* the successor's predecessors.
*/
for (int i = 0; i < sz; i++) {
BasicBlock one = blocks.get(i);
int label = one.getLabel();
IntList successors = one.getSuccessors();
int ssz = successors.size();
if (ssz == 0) {
// This block exits.
exitPredecessors.add(label);
} else {
for (int j = 0; j < ssz; j++) {
int succLabel = successors.get(j);
IntList succPreds = predecessors[succLabel];
if (succPreds == null) {
succPreds = new IntList(10);
predecessors[succLabel] = succPreds;
}
succPreds.add(label);
}
}
}
// Sort and immutablize all the predecessor lists.
for (int i = 0; i < maxLabel; i++) {
IntList preds = predecessors[i];
if (preds != null) {
preds.sort();
preds.setImmutable();
}
}
exitPredecessors.sort();
exitPredecessors.setImmutable();
/*
* The start label might not ever have had any predecessors
* added to it (probably doesn't, because of how Java gets
* translated into rop form). So, check for this and rectify
* the situation if required.
*/
if (predecessors[firstLabel] == null) {
predecessors[firstLabel] = IntList.EMPTY;
}
this.predecessors = predecessors;
this.exitPredecessors = exitPredecessors;
}
use of com.taobao.android.dx.util.IntList in project atlas by alibaba.
the class LocalVariableExtractor method processBlock.
/**
* Processes a single block.
*
* @param label {@code >= 0;} label of the block to process
*/
private void processBlock(int label) {
RegisterSpecSet primaryState = resultInfo.mutableCopyOfStarts(label);
BasicBlock block = blocks.labelToBlock(label);
InsnList insns = block.getInsns();
int insnSz = insns.size();
/*
* 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.
*/
boolean canThrowDuringLastInsn = block.hasExceptionHandlers() && (insns.getLast().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();
}
Insn insn = insns.get(i);
RegisterSpec result;
result = insn.getLocalAssignment();
if (result == null) {
/*
* If an assignment assigns over an existing local, make
* sure to mark the local as going out of scope.
*/
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.getSuccessors();
int succSz = successors.size();
int primarySuccessor = block.getPrimarySuccessor();
for (int i = 0; i < succSz; i++) {
int succ = successors.get(i);
RegisterSpecSet state = (succ == primarySuccessor) ? primaryState : secondaryState;
if (resultInfo.mergeStarts(succ, state)) {
Bits.set(workSet, succ);
}
}
}
use of com.taobao.android.dx.util.IntList in project atlas by alibaba.
the class SsaBasicBlock method getRopLabelSuccessorList.
/**
* @return successor list of rop labels
*/
public IntList getRopLabelSuccessorList() {
IntList result = new IntList(successorList.size());
int sz = successorList.size();
for (int i = 0; i < sz; i++) {
result.add(parent.blockIndexToRopLabel(successorList.get(i)));
}
return result;
}
use of com.taobao.android.dx.util.IntList in project atlas by alibaba.
the class SsaToRop method convertBasicBlock.
/**
* Converts a single basic block to rop form.
*
* @param block SSA block to process
* @return {@code non-null;} ROP block
*/
private BasicBlock convertBasicBlock(SsaBasicBlock block) {
IntList successorList = block.getRopLabelSuccessorList();
int primarySuccessorLabel = block.getPrimarySuccessorRopLabel();
// Filter out any reference to the SSA form's exit block.
// Exit block may be null.
SsaBasicBlock exitBlock = ssaMeth.getExitBlock();
int exitRopLabel = (exitBlock == null) ? -1 : exitBlock.getRopLabel();
if (successorList.contains(exitRopLabel)) {
if (successorList.size() > 1) {
throw new RuntimeException("Exit predecessor must have no other successors" + Hex.u2(block.getRopLabel()));
} else {
successorList = IntList.EMPTY;
primarySuccessorLabel = -1;
verifyValidExitPredecessor(block);
}
}
successorList.setImmutable();
BasicBlock result = new BasicBlock(block.getRopLabel(), convertInsns(block.getInsns()), successorList, primarySuccessorLabel);
return result;
}
use of com.taobao.android.dx.util.IntList in project atlas by alibaba.
the class IdenticalBlockCombiner method replaceSucc.
/**
* Replaces one of a block's successors with a different label. Constructs
* an updated BasicBlock instance and places it in {@code newBlocks}.
*
* @param block block to replace
* @param oldLabel label of successor to replace
* @param newLabel label of new successor
*/
private void replaceSucc(BasicBlock block, int oldLabel, int newLabel) {
IntList newSuccessors = block.getSuccessors().mutableCopy();
int newPrimarySuccessor;
newSuccessors.set(newSuccessors.indexOf(oldLabel), newLabel);
newPrimarySuccessor = block.getPrimarySuccessor();
if (newPrimarySuccessor == oldLabel) {
newPrimarySuccessor = newLabel;
}
newSuccessors.setImmutable();
BasicBlock newBB = new BasicBlock(block.getLabel(), block.getInsns(), newSuccessors, newPrimarySuccessor);
newBlocks.set(newBlocks.indexOfLabel(block.getLabel()), newBB);
}
Aggregations