use of com.android.dx.rop.code.BasicBlock in project J2ME-Loader by nikita36078.
the class Ropper method deleteUnreachableBlocks.
/**
* Deletes all blocks that cannot be reached. This is run to delete
* original subroutine blocks after subroutine inlining.
*/
private void deleteUnreachableBlocks() {
final IntList reachableLabels = new IntList(result.size());
// subroutine inlining is done now and we won't update this list here
resultSubroutines.clear();
forEachNonSubBlockDepthFirst(getSpecialLabel(PARAM_ASSIGNMENT), new BasicBlock.Visitor() {
public void visitBlock(BasicBlock b) {
reachableLabels.add(b.getLabel());
}
});
reachableLabels.sort();
for (int i = result.size() - 1; i >= 0; i--) {
if (reachableLabels.indexOf(result.get(i).getLabel()) < 0) {
result.remove(i);
// unnecessary here really, since subroutine inlining is done
// resultSubroutines.remove(i);
}
}
}
use of com.android.dx.rop.code.BasicBlock in project J2ME-Loader by nikita36078.
the class Ropper method inlineSubroutines.
/**
* Inlines any subroutine calls.
*/
private void inlineSubroutines() {
final IntList reachableSubroutineCallerLabels = new IntList(4);
/*
* Compile a list of all subroutine calls reachable
* through the normal (non-subroutine) flow. We do this first, since
* we'll be affecting the call flow as we go.
*
* Start at label 0 -- the param assignment block has nothing for us
*/
forEachNonSubBlockDepthFirst(0, new BasicBlock.Visitor() {
public void visitBlock(BasicBlock b) {
if (isSubroutineCaller(b)) {
reachableSubroutineCallerLabels.add(b.getLabel());
}
}
});
/*
* Convert the resultSubroutines list, indexed by block index,
* to a label-to-subroutines mapping used by the inliner.
*/
int largestAllocedLabel = getAvailableLabel();
ArrayList<IntList> labelToSubroutines = new ArrayList<IntList>(largestAllocedLabel);
for (int i = 0; i < largestAllocedLabel; i++) {
labelToSubroutines.add(null);
}
for (int i = 0; i < result.size(); i++) {
BasicBlock b = result.get(i);
if (b == null) {
continue;
}
IntList subroutineList = resultSubroutines.get(i);
labelToSubroutines.set(b.getLabel(), subroutineList);
}
/*
* Inline all reachable subroutines.
* Inner subroutines will be inlined as they are encountered.
*/
int sz = reachableSubroutineCallerLabels.size();
for (int i = 0; i < sz; i++) {
int label = reachableSubroutineCallerLabels.get(i);
new SubroutineInliner(new LabelAllocator(getAvailableLabel()), labelToSubroutines).inlineSubroutineCalledFrom(labelToBlock(label));
}
// Now find the blocks that aren't reachable and remove them
deleteUnreachableBlocks();
}
use of com.android.dx.rop.code.BasicBlock in project J2ME-Loader by nikita36078.
the class StdCatchBuilder method build.
/**
* Builds and returns the catch table for a given method.
*
* @param method {@code non-null;} method to build the list for
* @param order {@code non-null;} block output order
* @param addresses {@code non-null;} address objects for each block
* @return {@code non-null;} the constructed table
*/
public static CatchTable build(RopMethod method, int[] order, BlockAddresses addresses) {
int len = order.length;
BasicBlockList blocks = method.getBlocks();
ArrayList<CatchTable.Entry> resultList = new ArrayList<CatchTable.Entry>(len);
CatchHandlerList currentHandlers = CatchHandlerList.EMPTY;
BasicBlock currentStartBlock = null;
BasicBlock currentEndBlock = null;
for (int i = 0; i < len; i++) {
BasicBlock block = blocks.labelToBlock(order[i]);
if (!block.canThrow()) {
/*
* There is no need to concern ourselves with the
* placement of blocks that can't throw with respect
* to the blocks that *can* throw.
*/
continue;
}
CatchHandlerList handlers = handlersFor(block, addresses);
if (currentHandlers.size() == 0) {
// This is the start of a new catch range.
currentStartBlock = block;
currentEndBlock = block;
currentHandlers = handlers;
continue;
}
if (currentHandlers.equals(handlers) && rangeIsValid(currentStartBlock, block, addresses)) {
/*
* The block we are looking at now has the same handlers
* as the block that started the currently open catch
* range, and adding it to the currently open range won't
* cause it to be too long.
*/
currentEndBlock = block;
continue;
}
/*
* The block we are looking at now has incompatible handlers,
* so we need to finish off the last entry and start a new
* one. Note: We only emit an entry if it has associated handlers.
*/
if (currentHandlers.size() != 0) {
CatchTable.Entry entry = makeEntry(currentStartBlock, currentEndBlock, currentHandlers, addresses);
resultList.add(entry);
}
currentStartBlock = block;
currentEndBlock = block;
currentHandlers = handlers;
}
if (currentHandlers.size() != 0) {
// Emit an entry for the range that was left hanging.
CatchTable.Entry entry = makeEntry(currentStartBlock, currentEndBlock, currentHandlers, addresses);
resultList.add(entry);
}
// Construct the final result.
int resultSz = resultList.size();
if (resultSz == 0) {
return CatchTable.EMPTY;
}
CatchTable result = new CatchTable(resultSz);
for (int i = 0; i < resultSz; i++) {
result.set(i, resultList.get(i));
}
result.setImmutable();
return result;
}
use of com.android.dx.rop.code.BasicBlock in project J2ME-Loader by nikita36078.
the class StdCatchBuilder method hasAnyCatches.
/**
* {@inheritDoc}
*/
public boolean hasAnyCatches() {
BasicBlockList blocks = method.getBlocks();
int size = blocks.size();
for (int i = 0; i < size; i++) {
BasicBlock block = blocks.get(i);
TypeList catches = block.getLastInsn().getCatches();
if (catches.size() != 0) {
return true;
}
}
return false;
}
use of com.android.dx.rop.code.BasicBlock in project J2ME-Loader by nikita36078.
the class SsaBasicBlock method newFromRop.
/**
* Creates a new SSA basic block from a ROP form basic block.
*
* @param rmeth original method
* @param basicBlockIndex index this block will have
* @param parent method of this block predecessor set will be
* updated
* @return new instance
*/
public static SsaBasicBlock newFromRop(RopMethod rmeth, int basicBlockIndex, final SsaMethod parent) {
BasicBlockList ropBlocks = rmeth.getBlocks();
BasicBlock bb = ropBlocks.get(basicBlockIndex);
SsaBasicBlock result = new SsaBasicBlock(basicBlockIndex, bb.getLabel(), parent);
InsnList ropInsns = bb.getInsns();
result.insns.ensureCapacity(ropInsns.size());
for (int i = 0, sz = ropInsns.size(); i < sz; i++) {
result.insns.add(new NormalSsaInsn(ropInsns.get(i), result));
}
result.predecessors = SsaMethod.bitSetFromLabelList(ropBlocks, rmeth.labelToPredecessors(bb.getLabel()));
result.successors = SsaMethod.bitSetFromLabelList(ropBlocks, bb.getSuccessors());
result.successorList = SsaMethod.indexListFromLabelList(ropBlocks, bb.getSuccessors());
if (result.successorList.size() != 0) {
int primarySuccessor = bb.getPrimarySuccessor();
result.primarySuccessor = (primarySuccessor < 0) ? -1 : ropBlocks.indexOfLabel(primarySuccessor);
}
return result;
}
Aggregations