-
-
Save arpith20/d4ccb3476e71a2e2bedd1258c6a5c3f6 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* Inserts instrumentation in a manner such that the resulting control flow | |
* graph (CFG) of the program will contain <code>toInsert</code> on an edge | |
* that is defined by <code>point_source</code> and <code>point_target</code>. | |
* | |
* @param toInsert the instrumentation to be added in the Chain | |
* @param point_src the source point of an edge in CFG | |
* @param point_tgt the target point of an edge | |
*/ | |
public void insertOnEdge(E toInsert, E point_src, E point_tgt) { | |
if (toInsert == null) | |
throw new RuntimeException("Bad idea! You tried to insert " + "a null object into a Chain!"); | |
if (map.containsKey(toInsert)) | |
throw new RuntimeException("Chain already contains object."); | |
// Insert 'toInsert' before 'target' point in chain if the source point is null | |
if (point_src == null && point_tgt != null) { | |
((Unit) point_tgt).redirectJumpsToThisTo((Unit) toInsert); | |
insertBefore(toInsert, point_tgt); | |
return; | |
} | |
// Insert 'toInsert' after 'source' point in chain if the target point is null | |
if (point_src != null && point_tgt == null) { | |
insertAfter(toInsert, point_src); | |
return; | |
} | |
// Throw an exception if both source and target is null | |
if (point_src == null && point_tgt == null) { | |
throw new RuntimeException("insertOnEdge failed! Both source and target points are null"); | |
} | |
// If target is right after the source in the Chain | |
// 1- Redirect all jumps (if any) from 'source' to 'target', to 'toInsert' | |
// (source->target) ==> (source->toInsert) | |
// 2- Insert 'toInsert' after 'source' in Chain | |
if (getSuccOf(point_src) == point_tgt) { | |
List<UnitBox> boxes = ((Unit) point_src).getUnitBoxes(); | |
for (UnitBox box : boxes) { | |
if (box.getUnit() == point_tgt) { | |
box.setUnit((Unit) toInsert); | |
} | |
} | |
insertAfter(toInsert, point_src); | |
return; | |
} | |
// If the target is not right after the source in chain then, | |
// 1- Redirect all jumps (if any) from 'source' to 'target', to 'toInsert' | |
// (source->target) ==> (source->toInsert) | |
// 1.1- if there are no jumps from source to target, then such an edge does not exist. Throw an exception. | |
// 2- Insert 'toInsert' before 'target' in Chain | |
// 3- If required, add a 'goto target' statement so that no other edge executes 'toInsert' | |
boolean validEdgeFound = false; | |
E originalPred = getPredOf(point_tgt); | |
List<UnitBox> boxes = ((Unit) point_src).getUnitBoxes(); | |
for (UnitBox box : boxes) { | |
if (box.getUnit() == point_tgt) { | |
if (point_src instanceof GotoStmt) { | |
box.setUnit((Unit) toInsert); | |
insertAfter(toInsert, point_src); | |
E goto_unit = (E) new JGotoStmt((Unit) point_tgt); | |
insertAfter(goto_unit, toInsert); | |
return; | |
} | |
box.setUnit((Unit) toInsert); | |
validEdgeFound = true; | |
} | |
} | |
if (validEdgeFound) { | |
insertBefore(toInsert, point_tgt); | |
if (originalPred != point_src) { | |
if (originalPred instanceof GotoStmt) | |
return; | |
E goto_unit = (E) new JGotoStmt((Unit) point_tgt); | |
insertBefore(goto_unit, (E) toInsert); | |
} | |
return; | |
} | |
// In certain scenarios, the above code can add extra 'goto' units on a different edge | |
// So, an edge [src --> tgt] becomes [src -> goto tgt -> tgt]. | |
// When this happens, the original edge [src -> tgt] ceases to exist. | |
// The following code handles such scenarios. | |
if (getSuccOf(point_src) instanceof GotoStmt) { | |
if (((Unit) getSuccOf(point_src)).getUnitBoxes().get(0).getUnit() == point_tgt) { | |
((Unit) getSuccOf(point_src)).redirectJumpsToThisTo((Unit) toInsert); | |
insertBefore(toInsert, getSuccOf(point_src)); | |
return; | |
} | |
} | |
// If the control reaches this point, it means that an edge [stc -> tgt] as specified by user does not exist and is thus invalid | |
// Return an exception. | |
throw new RuntimeException( | |
"insertOnEdge failed! No such edge found. The edge on which you want to insert an instrumentation is invalid."); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment