[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Tightening Exception-based Control flow graph
Hi,
While using locking constructs the compiler creates over-approximate exceptions regions to ensure safe release of locks. This
injects incorrect control flow into the Jimple graphs that consider exceptions. The following code will ensure that the
control flow via exceptions in Jimple graphs closely mimics the dynamic control flow in the method.
The method can be added to JimpleMethodSource and called in JimpleMethodSource.getBody() to fix the body after it has been
constructed from the class file rather than each application trying to massage the body upon retrieval.
void processBody(body) {
Jimple jimple = Jimple.v();
Chain traps = body.getTraps();
Chain units = body.getUnits();
List t = new ArrayList(traps);
for(int i = 0; i < t.size(); i++) {
Trap enclosedTrap = (Trap)t.get(i);
SootClass exception = enclosedTrap.getException();
Stmt enclosedBeginStmt = (Stmt)enclosedTrap.getBeginUnit();
Stmt enclosedEndStmt = (Stmt)enclosedTrap.getEndUnit();
Stmt enclosedHandlerStmt = (Stmt)enclosedTrap.getHandlerUnit();
for(int j = 0; j < t.size(); j++) {
Trap enclosingTrap = (Trap)t.get(j);
Stmt enclosingBeginStmt = (Stmt)enclosingTrap.getBeginUnit();
Stmt enclosingEndStmt = (Stmt)enclosingTrap.getEndUnit();
if (enclosedTrap != enclosingTrap && exception.equals(enclosingTrap.getException())) {
if (enclosedBeginStmt == enclosingBeginStmt
&& units.follows(enclosingEndStmt, enclosedEndStmt)
&& units.follows(enclosedEndStmt, enclosingBeginStmt)
) {
enclosingTrap.setBeginUnit(enclosedEndStmt);
} else if (enclosedEndStmt == enclosingEndStmt
&& units.follows(enclosedBeginStmt, enclosingBeginStmt)
&& units.follows(enclosingEndStmt, enclosedBeginStmt)) {
enclosingTrap.setEndUnit(enclosedBeginStmt);
} else if (units.follows(enclosedBeginStmt, enclosingBeginStmt)
&& units.follows(enclosingEndStmt, enclosedBeginStmt)
&& units.follows(enclosingEndStmt, enclosedEndStmt)
&& units.follows(enclosedEndStmt, enclosingBeginStmt)) {
enclosingTrap.setEndUnit(enclosedBeginStmt);
Trap newTrap = jimple.newTrap(enclosingTrap.getException(), enclosedEndStmt, enclosingEndStmt,
enclosingTrap.getHandlerUnit());
traps.insertAfter(newTrap, enclosingTrap);
t.add(j + 1, newTrap);
}
}
}
}
}
--
Venkatesh Prasad Ranganath,
Dept. Computing and Information Science,
Kansas State University, US.
web: http://www.cis.ksu.edu/~rvprasad