use of soot.jimple.spark.geom.geomPA.IVarAbstraction in project soot by Sable.
the class EvalResults method profileSparkBasicMetrics.
/**
* Collecting basic statistical information for SPARK.
*/
public void profileSparkBasicMetrics() {
int n_legal_var = 0;
int[] limits = new int[] { 1, 5, 10, 25, 50, 75, 100 };
evalRes.pts_size_bar_spark = new Histogram(limits);
for (IVarAbstraction pn : ptsProvider.pointers) {
// We don't consider exception pointers
Node var = pn.getWrappedNode();
if (ptsProvider.isExceptionPointer(var))
continue;
++n_legal_var;
int size = var.getP2Set().size();
evalRes.pts_size_bar_spark.addNumber(size);
evalRes.total_spark_pts += size;
if (size > evalRes.max_pts_spark)
evalRes.max_pts_spark = size;
}
evalRes.avg_spark_pts = (double) evalRes.total_spark_pts / n_legal_var;
}
use of soot.jimple.spark.geom.geomPA.IVarAbstraction in project soot by Sable.
the class PtInsNodeGenerator method initFlowGraph.
@Override
public void initFlowGraph(GeomPointsTo ptAnalyzer) {
int k;
int n_legal_cons;
int nf1, nf2;
int code;
CgEdge q;
IVarAbstraction my_lhs, my_rhs;
// Visit all the simple constraints
n_legal_cons = 0;
for (PlainConstraint cons : ptAnalyzer.constraints) {
if (!cons.isActive)
continue;
my_lhs = cons.getLHS().getRepresentative();
my_rhs = cons.getRHS().getRepresentative();
nf1 = ptAnalyzer.getMethodIDFromPtr(my_lhs);
nf2 = ptAnalyzer.getMethodIDFromPtr(my_rhs);
// Test how many globals are in this constraint
code = ((nf1 == Constants.SUPER_MAIN ? 1 : 0) << 1) | (nf2 == Constants.SUPER_MAIN ? 1 : 0);
switch(cons.type) {
case Constants.NEW_CONS:
// We directly add the objects to the points-to set
my_rhs.add_points_to_3((AllocNode) my_lhs.getWrappedNode(), nf2 == Constants.SUPER_MAIN ? 0 : 1, nf1 == Constants.SUPER_MAIN ? 0 : 1, nf2 == Constants.SUPER_MAIN ? ptAnalyzer.context_size[nf1] : ptAnalyzer.context_size[nf2]);
// Enqueue to the worklist
ptAnalyzer.getWorklist().push(my_rhs);
break;
case Constants.ASSIGN_CONS:
// The core part of any context sensitive algorithms
if (cons.interCallEdges != null) {
// Inter-procedural assignment
for (Iterator<Edge> it = cons.interCallEdges.iterator(); it.hasNext(); ) {
Edge sEdge = it.next();
q = ptAnalyzer.getInternalEdgeFromSootEdge(sEdge);
if (q.is_obsoleted == true) {
continue;
}
if (nf2 == q.t) {
// The receiver is a local, while the sender is perhaps not
if (nf1 == Constants.SUPER_MAIN) {
my_lhs.add_simple_constraint_3(my_rhs, 0, q.map_offset, ptAnalyzer.max_context_size_block[q.s]);
} else {
// We should treat the self recursive calls specially
if (q.s == q.t) {
my_lhs.add_simple_constraint_3(my_rhs, 1, 1, ptAnalyzer.context_size[nf1]);
} else {
for (k = 0; k < ptAnalyzer.block_num[nf1]; ++k) {
my_lhs.add_simple_constraint_3(my_rhs, k * ptAnalyzer.max_context_size_block[nf1] + 1, q.map_offset, ptAnalyzer.max_context_size_block[nf1]);
}
}
}
} else {
if (q.s == q.t) {
my_lhs.add_simple_constraint_3(my_rhs, 1, 1, ptAnalyzer.context_size[nf2]);
} else {
for (k = 0; k < ptAnalyzer.block_num[nf2]; ++k) {
my_lhs.add_simple_constraint_3(my_rhs, q.map_offset, k * ptAnalyzer.max_context_size_block[nf2] + 1, ptAnalyzer.max_context_size_block[nf2]);
}
}
}
}
} else {
// Intraprocedural
// And, assignment involves global variable goes here. By
// definition, global variables belong to SUPER_MAIN.
// By the Jimple IR, not both sides are global variables
my_lhs.add_simple_constraint_3(my_rhs, nf1 == Constants.SUPER_MAIN ? 0 : 1, nf2 == Constants.SUPER_MAIN ? 0 : 1, nf1 == Constants.SUPER_MAIN ? ptAnalyzer.context_size[nf2] : ptAnalyzer.context_size[nf1]);
}
break;
case Constants.LOAD_CONS:
// lhs is always a local
// rhs = lhs.f
cons.code = full_convertor[code];
cons.otherSide = my_rhs;
my_lhs.put_complex_constraint(cons);
break;
case Constants.STORE_CONS:
// rhs is always a local
// rhs.f = lhs
cons.code = full_convertor[code];
cons.otherSide = my_lhs;
my_rhs.put_complex_constraint(cons);
break;
default:
throw new RuntimeException("Invalid node type");
}
++n_legal_cons;
}
ptAnalyzer.ps.printf("Only %d (%.1f%%) constraints are needed for this run.\n", n_legal_cons, ((double) n_legal_cons / ptAnalyzer.n_init_constraints) * 100);
}
use of soot.jimple.spark.geom.geomPA.IVarAbstraction in project soot by Sable.
the class EvalResults method checkAliasAnalysis.
/**
* Count how many aliased base pointers appeared in all user's functions.
*/
public void checkAliasAnalysis() {
Set<IVarAbstraction> access_expr = new HashSet<IVarAbstraction>();
ArrayList<IVarAbstraction> al = new ArrayList<IVarAbstraction>();
Value[] values = new Value[2];
for (SootMethod sm : ptsProvider.getAllReachableMethods()) {
if (sm.isJavaLibraryMethod())
continue;
if (!sm.isConcrete())
continue;
if (!sm.hasActiveBody()) {
sm.retrieveActiveBody();
}
if (!ptsProvider.isValidMethod(sm))
continue;
// access_expr.clear();
for (Iterator<Unit> stmts = sm.getActiveBody().getUnits().iterator(); stmts.hasNext(); ) {
Stmt st = (Stmt) stmts.next();
if (st instanceof AssignStmt) {
AssignStmt a = (AssignStmt) st;
values[0] = a.getLeftOp();
values[1] = a.getRightOp();
for (Value v : values) {
// expression: p.f
if (v instanceof InstanceFieldRef) {
InstanceFieldRef ifr = (InstanceFieldRef) v;
final SootField field = ifr.getField();
if (!(field.getType() instanceof RefType))
continue;
LocalVarNode vn = ptsProvider.findLocalVarNode((Local) ifr.getBase());
if (vn == null)
continue;
if (ptsProvider.isExceptionPointer(vn))
continue;
IVarAbstraction pn = ptsProvider.findInternalNode(vn);
if (pn == null)
continue;
pn = pn.getRepresentative();
if (pn.hasPTResult())
access_expr.add(pn);
}
}
}
}
}
access_expr.remove(null);
al.addAll(access_expr);
access_expr = null;
// Next, we pair up all the pointers
Date begin = new Date();
int size = al.size();
for (int i = 0; i < size; ++i) {
IVarAbstraction pn = al.get(i);
VarNode n1 = (VarNode) pn.getWrappedNode();
for (int j = i + 1; j < size; ++j) {
IVarAbstraction qn = al.get(j);
VarNode n2 = (VarNode) qn.getWrappedNode();
if (pn.heap_sensitive_intersection(qn))
evalRes.n_hs_alias++;
// We directly use the SPARK points-to sets
if (n1.getP2Set().hasNonEmptyIntersection(n2.getP2Set()))
evalRes.n_hi_alias++;
}
}
evalRes.n_alias_pairs = size * (size - 1) / 2;
Date end = new Date();
ptsProvider.ps.println();
ptsProvider.ps.println("--------> Alias Pairs Evaluation <---------");
ptsProvider.ps.println("Number of pointer pairs in app code: " + evalRes.n_alias_pairs);
ptsProvider.ps.printf("Heap sensitive alias pairs (by Geom): %d, Percentage = %.3f%%\n", evalRes.n_hs_alias, (double) evalRes.n_hs_alias / evalRes.n_alias_pairs * 100);
ptsProvider.ps.printf("Heap insensitive alias pairs (by SPARK): %d, Percentage = %.3f%%\n", evalRes.n_hi_alias, (double) evalRes.n_hi_alias / evalRes.n_alias_pairs * 100);
ptsProvider.ps.printf("Using time: %dms \n", end.getTime() - begin.getTime());
ptsProvider.ps.println();
}
use of soot.jimple.spark.geom.geomPA.IVarAbstraction in project soot by Sable.
the class EvalResults method estimateHeapDefuseGraph.
/**
* Estimate the size of the def-use graph for the heap memory. The heap
* graph is estimated without context information.
*/
public void estimateHeapDefuseGraph() {
final Map<IVarAbstraction, int[]> defUseCounterForGeom = new HashMap<IVarAbstraction, int[]>();
final Map<AllocDotField, int[]> defUseCounterForSpark = new HashMap<AllocDotField, int[]>();
Date begin = new Date();
for (SootMethod sm : ptsProvider.getAllReachableMethods()) {
if (sm.isJavaLibraryMethod())
continue;
if (!sm.isConcrete())
continue;
if (!sm.hasActiveBody()) {
sm.retrieveActiveBody();
}
if (!ptsProvider.isValidMethod(sm))
continue;
// We first gather all the memory access expressions
for (Iterator<Unit> stmts = sm.getActiveBody().getUnits().iterator(); stmts.hasNext(); ) {
Stmt st = (Stmt) stmts.next();
if (!(st instanceof AssignStmt))
continue;
AssignStmt a = (AssignStmt) st;
final Value lValue = a.getLeftOp();
final Value rValue = a.getRightOp();
InstanceFieldRef ifr = null;
if (lValue instanceof InstanceFieldRef) {
// Def statement
ifr = (InstanceFieldRef) lValue;
} else if (rValue instanceof InstanceFieldRef) {
// Use statement
ifr = (InstanceFieldRef) rValue;
}
if (ifr != null) {
final SootField field = ifr.getField();
LocalVarNode vn = ptsProvider.findLocalVarNode((Local) ifr.getBase());
if (vn == null)
continue;
IVarAbstraction pn = ptsProvider.findInternalNode(vn);
if (pn == null)
continue;
pn = pn.getRepresentative();
if (!pn.hasPTResult())
continue;
// Spark
vn.getP2Set().forall(new P2SetVisitor() {
@Override
public void visit(Node n) {
IVarAbstraction padf = ptsProvider.findAndInsertInstanceField((AllocNode) n, field);
AllocDotField adf = (AllocDotField) padf.getWrappedNode();
int[] defUseUnit = defUseCounterForSpark.get(adf);
if (defUseUnit == null) {
defUseUnit = new int[2];
defUseCounterForSpark.put(adf, defUseUnit);
}
if (lValue instanceof InstanceFieldRef) {
defUseUnit[0]++;
} else {
defUseUnit[1]++;
}
}
});
// Geom
Set<AllocNode> objsSet = pn.get_all_points_to_objects();
for (AllocNode obj : objsSet) {
/*
* We will create a lot of instance fields. Because in
* points-to analysis, we concern only the reference
* type fields. But here, we concern all the fields read
* write including the primitive type fields.
*/
IVarAbstraction padf = ptsProvider.findAndInsertInstanceField(obj, field);
int[] defUseUnit = defUseCounterForGeom.get(padf);
if (defUseUnit == null) {
defUseUnit = new int[2];
defUseCounterForGeom.put(padf, defUseUnit);
}
if (lValue instanceof InstanceFieldRef) {
defUseUnit[0]++;
} else {
defUseUnit[1]++;
}
}
}
}
}
for (int[] defUseUnit : defUseCounterForSpark.values()) {
evalRes.n_spark_du_pairs += ((long) defUseUnit[0]) * defUseUnit[1];
}
for (int[] defUseUnit : defUseCounterForGeom.values()) {
evalRes.n_geom_du_pairs += ((long) defUseUnit[0]) * defUseUnit[1];
}
Date end = new Date();
ptsProvider.ps.println();
ptsProvider.ps.println("-----------> Heap Def Use Graph Evaluation <------------");
ptsProvider.ps.println("The edges in the heap def-use graph is (by Geom): " + evalRes.n_geom_du_pairs);
ptsProvider.ps.println("The edges in the heap def-use graph is (by Spark): " + evalRes.n_spark_du_pairs);
ptsProvider.ps.printf("Using time: %dms \n", end.getTime() - begin.getTime());
ptsProvider.ps.println();
}
use of soot.jimple.spark.geom.geomPA.IVarAbstraction in project soot by Sable.
the class EvalResults method test_1cfa_call_graph.
/**
* We assess the quality of building the 1-cfa call graph with the geometric
* points-to result.
*/
private void test_1cfa_call_graph(LocalVarNode vn, SootMethod caller, SootMethod callee_signature, Histogram ce_range) {
long l, r;
IVarAbstraction pn = ptsProvider.findInternalNode(vn);
if (pn == null)
return;
pn = pn.getRepresentative();
Set<SootMethod> tgts = new HashSet<SootMethod>();
Set<AllocNode> set = pn.get_all_points_to_objects();
LinkedList<CgEdge> list = ptsProvider.getCallEdgesInto(ptsProvider.getIDFromSootMethod(caller));
FastHierarchy hierarchy = Scene.v().getOrMakeFastHierarchy();
for (Iterator<CgEdge> it = list.iterator(); it.hasNext(); ) {
CgEdge p = it.next();
l = p.map_offset;
r = l + ptsProvider.max_context_size_block[p.s];
tgts.clear();
for (AllocNode obj : set) {
if (!pn.pointer_interval_points_to(l, r, obj))
continue;
Type t = obj.getType();
if (t == null)
continue;
else if (t instanceof AnySubType)
t = ((AnySubType) t).getBase();
else if (t instanceof ArrayType)
t = RefType.v("java.lang.Object");
try {
tgts.add(hierarchy.resolveConcreteDispatch(((RefType) t).getSootClass(), callee_signature));
} catch (Exception e) {
}
}
tgts.remove(null);
ce_range.addNumber(tgts.size());
}
}
Aggregations