/** Remember to clean the is_new flag */ @Override public void do_after_propagation() { for (HeapInsIntervalManager im : new_pts.values()) { im.flush(); } new_pts = new HashMap<AllocNode, HeapInsIntervalManager>(); }
/** An efficient implementation of differential propagation. */ @Override public void propagate(GeomPointsTo ptAnalyzer, IWorklist worklist) { int i, j; AllocNode obj; SegmentNode pts, pe, int_entry1[], int_entry2[]; HeapInsIntervalManager him; HeapInsNode qn, objn; boolean added, has_new_edges; // We first build the new flow edges via the field dereferences if (complex_cons != null) { for (Map.Entry<AllocNode, HeapInsIntervalManager> entry : new_pts.entrySet()) { obj = entry.getKey(); int_entry1 = entry.getValue().get_intervals(); for (PlainConstraint pcons : complex_cons) { // Construct the two variables in assignment objn = (HeapInsNode) ptAnalyzer.findAndInsertInstanceField(obj, pcons.f); qn = (HeapInsNode) pcons.otherSide; for (i = 0; i < HeapInsIntervalManager.Divisions; ++i) { pts = int_entry1[i]; while (pts != null && pts.is_new) { switch (pcons.type) { case GeomPointsTo.STORE_CONS: // Store, qv -> pv.field // pts.I2 may be zero, pts.L may be less than zero if (qn.add_simple_constraint_3( objn, pcons.code == GeomPointsTo.ONE_TO_ONE ? pts.I1 : 0, pts.I2, pts.L < 0 ? -pts.L : pts.L)) worklist.push(qn); break; case GeomPointsTo.LOAD_CONS: // Load, pv.field -> qv if (objn.add_simple_constraint_3( qn, pts.I2, pcons.code == GeomPointsTo.ONE_TO_ONE ? pts.I1 : 0, pts.L < 0 ? -pts.L : pts.L)) worklist.push(objn); break; default: throw new RuntimeException("Wrong Complex Constraint"); } pts = pts.next; } } } } } for (Map.Entry<HeapInsNode, HeapInsIntervalManager> entry1 : flowto.entrySet()) { // Second get the flow-to intervals added = false; qn = entry1.getKey(); him = entry1.getValue(); int_entry2 = him.get_intervals(); has_new_edges = him.isThereUnprocessedObject(); Map<AllocNode, HeapInsIntervalManager> objs = (has_new_edges ? pt_objs : new_pts); for (Map.Entry<AllocNode, HeapInsIntervalManager> entry2 : objs.entrySet()) { // First get the points-to intervals obj = entry2.getKey(); if (!ptAnalyzer.castNeverFails(obj.getType(), qn.getWrappedNode().getType())) continue; int_entry1 = entry2.getValue().get_intervals(); // We pair up all the interval points-to tuples and interval flow edges for (i = 0; i < HeapInsIntervalManager.Divisions; ++i) { pts = int_entry1[i]; while (pts != null) { if (!has_new_edges && !pts.is_new) break; for (j = 0; j < HeapInsIntervalManager.Divisions; ++j) { pe = int_entry2[j]; while (pe != null) { if (pts.is_new || pe.is_new) { // Propagate this object if (add_new_points_to_tuple(pts, pe, obj, qn)) added = true; } else break; pe = pe.next; } } pts = pts.next; } } } if (added) worklist.push(qn); // Now, we clean the new edges if necessary if (has_new_edges) { him.flush(); } } }