Fields Summary |
---|
private final BasicBlockList | blocksnon-null; basic block list of the method |
private final int | firstLabel>= 0; label for the block which starts the method |
private com.android.dx.util.IntList[] | predecessorsnull-ok; array of predecessors for each block, indexed by block
label |
private com.android.dx.util.IntList | exitPredecessorsnull-ok; the predecessors for the implicit "exit" block, that is
the labels for the blocks that return, if calculated |
Methods Summary |
---|
private void | calcPredecessors()Calculates the predecessor sets for each block as well as for the
exit.
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;
|
public BasicBlockList | getBlocks()Gets the basic block list for this method.
return blocks;
|
public com.android.dx.util.IntList | getExitPredecessors()Gets the exit predecessors for this instance.
if (exitPredecessors == null) {
calcPredecessors();
}
return exitPredecessors;
|
public int | getFirstLabel()Gets the label for the first block in the method that this list
represents.
return firstLabel;
|
public com.android.dx.util.IntList | labelToPredecessors(int label)Gets the predecessors associated with the given block. This throws
an exception if there is no block with the given label.
if (exitPredecessors == null) {
calcPredecessors();
}
IntList result = predecessors[label];
if (result == null) {
throw new RuntimeException("no such block: " + Hex.u2(label));
}
return result;
|
public com.android.dx.rop.code.RopMethod | withRegisterOffset(int delta)Returns an instance that is identical to this one, except that
the registers in each instruction are offset by the given
amount.
RopMethod result = new RopMethod(blocks.withRegisterOffset(delta),
firstLabel);
if (exitPredecessors != null) {
/*
* The predecessors have been calculated. It's safe to
* inject these into the new instance, since the
* transformation being applied doesn't affect the
* predecessors.
*/
result.exitPredecessors = exitPredecessors;
result.predecessors = predecessors;
}
return result;
|