use of soot.toolkits.graph.Block in project soot by Sable.
the class RegionAnalysis method weakRegionDFS2.
/**
* This algorithm starts from a head node in the CFG and is exactly the same as the above
* with the difference that post dominator and dominator trees switch positions.
* @param v
* @param r
*/
private void weakRegionDFS2(Block v, int r) {
// regions keep an implicit order of the contained blocks so it matters where blocks are added
// below.
this.m_regions.get(r).add2Back(v);
DominatorNode<Block> parentOfV = this.m_pdom.getParentOf(this.m_pdom.getDode(v));
Block u2 = (parentOfV == null) ? null : parentOfV.getGode();
List<DominatorNode<Block>> children = this.m_dom.getChildrenOf(this.m_dom.getDode(v));
for (int i = 0; i < children.size(); i++) {
DominatorNode<Block> w = children.get(i);
Block u1 = w.getGode();
if (u2 != null && u1.equals(u2)) {
this.weakRegionDFS2(w.getGode(), r);
} else {
this.m_regCount++;
this.m_regions.put(this.m_regCount, this.createRegion(this.m_regCount));
this.weakRegionDFS2(w.getGode(), this.m_regCount);
}
}
}
use of soot.toolkits.graph.Block in project soot by Sable.
the class RegionAnalysis method getBlock2RegionMap.
public Hashtable<Block, Region> getBlock2RegionMap() {
if (this.m_block2region == null) {
this.m_block2region = new Hashtable<Block, Region>();
List<Region> regions = this.getRegions();
for (Iterator<Region> itr = regions.iterator(); itr.hasNext(); ) {
Region r = itr.next();
List<Block> blocks = r.getBlocks();
for (Iterator<Block> itr1 = blocks.iterator(); itr1.hasNext(); ) {
Block u = itr1.next();
m_block2region.put(u, r);
}
}
}
return this.m_block2region;
}
use of soot.toolkits.graph.Block in project soot by Sable.
the class RegionAnalysis method weakRegionDFS.
/**
* This algorithms assumes that the first time it's called with a tail of the CFG. Then for each
* child node w of v in the post-dominator tree, it compares the parent of v in the dominator tree
* with w and if they are the same, that means w belongs to the same region as v, so weakRegionDFS
* is recursively called with w and the same region id as v.
* If the comparison fails, then a new region is created and weakRegionDFS is called recursively with
* w but this time with the newly created region id.
*
* @param v
* @param r
*/
private void weakRegionDFS(Block v, int r) {
try {
// System.out.println("##entered weakRegionDFS for region " + r);
this.m_regions.get(r).add(v);
DominatorNode<Block> parentOfV = this.m_dom.getParentOf(this.m_dom.getDode(v));
Block u2 = (parentOfV == null) ? null : parentOfV.getGode();
List<DominatorNode<Block>> children = this.m_pdom.getChildrenOf(this.m_pdom.getDode(v));
for (int i = 0; i < children.size(); i++) {
DominatorNode<Block> w = children.get(i);
Block u1 = w.getGode();
if (u2 != null && u1.equals(u2)) {
this.weakRegionDFS(w.getGode(), r);
} else {
this.m_regCount++;
this.m_regions.put(this.m_regCount, this.createRegion(this.m_regCount));
this.weakRegionDFS(w.getGode(), this.m_regCount);
}
}
} catch (RuntimeException e) {
logger.debug("[RegionAnalysis] Exception in weakRegionDFS: ", e);
logger.debug("v is " + v.toShortString() + " in region " + r);
G.v().out.flush();
}
}
use of soot.toolkits.graph.Block in project soot by Sable.
the class CFGToDotGraph method formatNodeText.
/**
* A utility method which formats the text for each node in
* a <code>DotGraph</code> representing a CFG.
*
* @param body the <code>Body</code> whose control flow is visualized in
* <code>canvas</code>.
*
* @param canvas the <code>DotGraph</code> for visualizing the CFG.
*
* @param namer provides a mapping from CFG objects to identifiers in
* generated dot source.
*/
private <N> void formatNodeText(Body body, DotGraph canvas, DotNamer<N> namer) {
LabeledUnitPrinter printer = null;
if (body != null) {
printer = new BriefUnitPrinter(body);
printer.noIndent();
}
for (Iterator<N> nodesIt = namer.keySet().iterator(); nodesIt.hasNext(); ) {
N node = nodesIt.next();
DotGraphNode dotnode = canvas.getNode(namer.getName(node));
String nodeLabel = null;
if (node instanceof DominatorNode) {
node = ((DominatorNode<N>) node).getGode();
}
if (printer == null) {
nodeLabel = node.toString();
} else {
if (node instanceof Unit) {
((Unit) node).toString(printer);
String targetLabel = printer.labels().get(node);
if (targetLabel == null) {
nodeLabel = printer.toString();
} else {
nodeLabel = targetLabel + ": " + printer.toString();
}
} else if (node instanceof Block) {
Iterator<Unit> units = ((Block) node).iterator();
StringBuffer buffer = new StringBuffer();
while (units.hasNext()) {
Unit unit = units.next();
String targetLabel = (String) printer.labels().get(unit);
if (targetLabel != null) {
buffer.append(targetLabel).append(":\\n");
}
unit.toString(printer);
buffer.append(printer.toString()).append("\\l");
}
nodeLabel = buffer.toString();
} else {
nodeLabel = node.toString();
}
}
dotnode.setLabel(nodeLabel);
}
}
use of soot.toolkits.graph.Block in project soot by Sable.
the class GroupIntPair method emitMethodBody.
@Override
protected void emitMethodBody(SootMethod method) {
if (Options.v().time())
Timers.v().buildJasminTimer.end();
Body activeBody = method.getActiveBody();
if (!(activeBody instanceof BafBody)) {
if (activeBody instanceof JimpleBody) {
if (Options.v().verbose()) {
logger.debug("Was expecting Baf body for " + method + " but found a Jimple body. Will convert body to Baf on the fly.");
}
activeBody = PackManager.v().convertJimpleBodyToBaf(method);
} else
throw new RuntimeException("method: " + method.getName() + " has an invalid active body!");
}
BafBody body = (BafBody) activeBody;
if (body == null)
throw new RuntimeException("method: " + method.getName() + " has no active body!");
if (Options.v().time())
Timers.v().buildJasminTimer.start();
Chain<Unit> instList = body.getUnits();
int stackLimitIndex = -1;
subroutineToReturnAddressSlot = new HashMap<Unit, Integer>(10, 0.7f);
// Determine the unitToLabel map
{
unitToLabel = new HashMap<Unit, String>(instList.size() * 2 + 1, 0.7f);
labelCount = 0;
for (UnitBox uBox : body.getUnitBoxes(true)) {
// Assign a label for each statement reference
{
InstBox box = (InstBox) uBox;
if (!unitToLabel.containsKey(box.getUnit()))
unitToLabel.put(box.getUnit(), "label" + labelCount++);
}
}
}
// Emit the exceptions, recording the Units at the beginning
// of handlers so that later on we can recognize blocks that
// begin with an exception on the stack.
Set<Unit> handlerUnits = new ArraySet<Unit>(body.getTraps().size());
{
for (Trap trap : body.getTraps()) {
handlerUnits.add(trap.getHandlerUnit());
if (trap.getBeginUnit() != trap.getEndUnit()) {
emit(".catch " + slashify(trap.getException().getName()) + " from " + unitToLabel.get(trap.getBeginUnit()) + " to " + unitToLabel.get(trap.getEndUnit()) + " using " + unitToLabel.get(trap.getHandlerUnit()));
}
}
}
// Determine where the locals go
{
int localCount = 0;
int[] paramSlots = new int[method.getParameterCount()];
int thisSlot = 0;
Set<Local> assignedLocals = new HashSet<Local>();
localToSlot = new HashMap<Local, Integer>(body.getLocalCount() * 2 + 1, 0.7f);
// assignColorsToLocals(body);
// Determine slots for 'this' and parameters
{
if (!method.isStatic()) {
thisSlot = 0;
localCount++;
}
for (int i = 0; i < method.getParameterCount(); i++) {
paramSlots[i] = localCount;
localCount += sizeOfType(method.getParameterType(i));
}
}
// Handle identity statements
{
for (Unit u : instList) {
Inst s = (Inst) u;
if (s instanceof IdentityInst && ((IdentityInst) s).getLeftOp() instanceof Local) {
Local l = (Local) ((IdentityInst) s).getLeftOp();
IdentityRef identity = (IdentityRef) ((IdentityInst) s).getRightOp();
int slot = 0;
if (identity instanceof ThisRef) {
if (method.isStatic())
throw new RuntimeException("Attempting to use 'this' in static method");
slot = thisSlot;
} else if (identity instanceof ParameterRef)
slot = paramSlots[((ParameterRef) identity).getIndex()];
else {
// Exception ref. Skip over this
continue;
}
localToSlot.put(l, new Integer(slot));
assignedLocals.add(l);
}
}
}
// Assign the rest of the locals
{
for (Local local : body.getLocals()) {
if (assignedLocals.add(local)) {
localToSlot.put(local, new Integer(localCount));
localCount += sizeOfType(local.getType());
}
}
if (!Modifier.isNative(method.getModifiers()) && !Modifier.isAbstract(method.getModifiers())) {
emit(" .limit stack ?");
stackLimitIndex = code.size() - 1;
emit(" .limit locals " + localCount);
}
}
}
// Emit code in one pass
{
isEmittingMethodCode = true;
maxStackHeight = 0;
isNextGotoAJsr = false;
for (Unit u : instList) {
Inst s = (Inst) u;
if (unitToLabel.containsKey(s))
emit(unitToLabel.get(s) + ":");
// emit this statement
{
emitInst(s);
}
}
isEmittingMethodCode = false;
// calculate max stack height
{
maxStackHeight = 0;
if (activeBody.getUnits().size() != 0) {
BlockGraph blockGraph = new BriefBlockGraph(activeBody);
List<Block> blocks = blockGraph.getBlocks();
if (blocks.size() != 0) {
// set the stack height of the entry points
List<Block> entryPoints = ((DirectedGraph<Block>) blockGraph).getHeads();
for (Block entryBlock : entryPoints) {
Integer initialHeight;
if (handlerUnits.contains(entryBlock.getHead())) {
initialHeight = new Integer(1);
} else {
initialHeight = new Integer(0);
}
if (blockToStackHeight == null) {
blockToStackHeight = new HashMap<Block, Integer>();
}
blockToStackHeight.put(entryBlock, initialHeight);
if (blockToLogicalStackHeight == null) {
blockToLogicalStackHeight = new HashMap<Block, Integer>();
}
blockToLogicalStackHeight.put(entryBlock, initialHeight);
}
// entryPoints list as roots
for (Block nextBlock : entryPoints) {
calculateStackHeight(nextBlock);
calculateLogicalStackHeightCheck(nextBlock);
}
}
}
}
if (!Modifier.isNative(method.getModifiers()) && !Modifier.isAbstract(method.getModifiers()))
code.set(stackLimitIndex, " .limit stack " + maxStackHeight);
}
// emit code attributes
{
for (Tag t : body.getTags()) {
if (t instanceof JasminAttribute) {
emit(".code_attribute " + t.getName() + " \"" + ((JasminAttribute) t).getJasminValue(unitToLabel) + "\"");
}
}
}
}
Aggregations