/* process call edge constraint */ public void process(CallConstraint c) { Node csrc = c.ncaller.getRep(); Node cdst = c.ncallee.getRep(); assert (cdst.graph == this); if (heapfix && csrc.graph == this && !csrc.isheap && cdst.isheap) w.addFirst(new UnifyConstraint(csrc, cdst)); Collection<CallEdge> ced = cedges.get(c.call); if (ced != null) for (CallEdge e : ced) { Node esrc = e.src.getRep(); Node edst = e.dst.getRep(); if (edst == cdst && e.call.equals(c.call)) { if (esrc != csrc) { Graph g = esrc.graph; assert (g != this || !Options.mergeGraphs.value); g.w.addFirst(new UnifyConstraint(esrc, csrc)); } return; } } else { ced = new ArrayList<CallEdge>(); cedges.put(c.call, ced); } ced.add(new CallEdge(csrc, cdst, c.call)); }
private static void addInField(Node n, Field f, FieldEdge e) { Collection<FieldEdge> s = n.infields.get(f); if (s == null) { s = new ArrayList<FieldEdge>(); n.infields.put(f, s); } s.add(e); }
/* process field edge constraint */ public void process(FieldConstraint c) { Node csrc = c.src.getRep(); Node cdst = c.dst.getRep(); assert (csrc.graph == this); assert (cdst.graph == this); if (heapfix && csrc.isheap && !cdst.isheap) w.addFirst(new UnifyConstraint(csrc, cdst)); Collection<FieldEdge> fed = fedges.get(c.field); if (secondary_index[9]) { FieldEdge e = csrc.outfields.get(c.field); if (e != null) { if (e.dst != cdst) w.addFirst(new UnifyConstraint(e.dst, cdst)); return; } } else { if (fed != null) for (FieldEdge e : fed) { Node esrc = e.src.getRep(); Node edst = e.dst.getRep(); assert (e.field.equals(c.field)); if (esrc == csrc) { if (edst != cdst) w.addFirst(new UnifyConstraint(edst, cdst)); return; } } } FieldEdge e = new FieldEdge(csrc, cdst, c.field); if (fed == null) { fed = new ArrayList<FieldEdge>(); fedges.put(c.field, fed); } fed.add(e); if (secondary_index[1]) { csrc.outfields.put(e.field, e); addInField(cdst, e.field, e); } // Merge nodes according to Tag information Node find = Options.detailed.value ? reachesTag(csrc, cdst.tag, new HashSet<Node>()) : containsTag(cdst.tag); if (find != null) w.addFirst(new UnifyConstraint(cdst, find)); }
/* process unification constraints */ protected void process(UnifyConstraint c) { Node n1 = c.node1.getRep(); Node n2 = c.node2.getRep(); assert (n1.graph == this); assert (n2.graph == this); if (n1 == n2) return; if (heapfix && n2.isheap && !n1.isheap) { Node sw = n1; n1 = n2; n2 = sw; } n1.mergeTags(n2); n1.mergeFlags(n2); n2.parent = n1; n2.tag = null; n2.region = null; if (secondary_index[0]) { for (FieldEdge e : n2.outfields.values()) { assert (e.src == n2); if (e.dst == n2) w.addLast(new FieldConstraint(n1, n1, e.field)); else { w.addLast(new FieldConstraint(n1, e.dst, e.field)); e.dst.infields.get(e.field).remove(e); } fedges.get(e.field).remove(e); } for (Field f : n2.infields.keySet()) for (FieldEdge e : n2.infields.get(f)) { assert (e.dst == n2); e.dst = n1; addInField(n1, f, e); } n2.outfields = null; n2.infields = null; } else { HashSet<FieldEdge> fremove = new HashSet<FieldEdge>(); for (Field f : fedges.keySet()) { Collection<FieldEdge> fed = fedges.get(f); int size = fed.size(); fremove.clear(); for (FieldEdge e : fed) { if (e.src == n2) { if (e.dst == n2) w.addLast(new FieldConstraint(n1, n1, e.field)); else w.addLast(new FieldConstraint(n1, e.dst, e.field)); } else { if (e.dst == n2) e.dst = n1; continue; } if (!fremove.contains(e)) { fremove.add(e); size--; } } fed.removeAll(fremove); assert (fed.size() == size); } } HashSet<CallEdge> cremove = new HashSet<CallEdge>(); for (Call ce : cedges.keySet()) { Collection<CallEdge> ced = cedges.get(ce); cremove.clear(); int size = ced.size(); for (CallEdge e : ced) { if (e.dst == n2) { if (e.src == n2) w.addLast(new CallConstraint(n1, n1, e.call)); else w.addLast(new CallConstraint(e.src, n1, e.call)); } else { if (e.src == n2) e.src = n1; continue; } if (!cremove.contains(e)) { cremove.add(e); size--; } } ced.removeAll(cremove); assert (ced.size() == size); } }
public Collection<CallEdge> getCallEdges() { Collection<CallEdge> cf = new ArrayList<CallEdge>(); for (Collection<CallEdge> c : cedges.values()) cf.addAll(c); return cf; }
public Collection<FieldEdge> getFieldEdges() { Collection<FieldEdge> cf = new ArrayList<FieldEdge>(); for (Collection<FieldEdge> c : fedges.values()) cf.addAll(c); return cf; }
/* Print the current type graph to the dotfile */ public void printDot(String title, Call call) { boolean printUnifications = false; PrintStream ps = PointsToAnalysis.v().file; if (ps == null) return; ps.println("\ndigraph F {"); ps.println(" size = \"7,7\"; rankdir = LR;"); ps.println(" orientation = landscape;"); ps.println(" subgraph cluster1 {"); ps.println(" \"Method: " + method.getName() + "\" [color=white];"); if (nodes.isEmpty()) { ps.println(" \"empty graph\" [color = white];"); ps.println(" }"); ps.println("}"); return; } for (Node node : nodes) { if (!printUnifications && !node.isRep()) continue; String color = "style=filled,fillcolor="; if (node.isheap && node.hasallocs) color += "red,"; else if (node.isheap) color += "orange,"; else if (node.hasallocs) color += "grey,"; else color += "white,"; // if (node.istouched) color = "khaki"; // if (node.hassync) color = "khaki"; String shape = "shape="; if (node.istouched) shape += "box"; else shape += "ellipse"; ps.println(" o" + node.id + "[label = \"" + node.getName() + "\"," + color + shape + "];"); } ps.println(" }"); Map<Integer, Map<Integer, String>> labels = new HashMap<Integer, Map<Integer, String>>(); for (Field f : fedges.keySet()) for (FieldEdge e : fedges.get(f)) { if (labels.containsKey(e.src.id)) { if (labels.get(e.src.id).containsKey(e.dst.id)) { labels.get(e.src.id).put(e.dst.id, "*"); // labels.get(e.src.id).get(e.dst.id) + ", " + // e.field.getName()); } else labels.get(e.src.id).put(e.dst.id, e.field.getName()); } else { Map<Integer, String> is = new HashMap<Integer, String>(); is.put(e.dst.id, e.field.getName()); labels.put(e.src.id, is); } } for (Integer i : labels.keySet()) for (Integer j : labels.get(i).keySet()) ps.print( " o" + i + " -> o" + j + "[label=\"" + labels.get(i).get(j) + "\",style=solid,color=black];"); for (Call ce : cedges.keySet()) for (CallEdge e : cedges.get(ce)) { if (!(e.call instanceof VirtualCallExpr)) continue; // if (!e.call.equals(call)) continue; ps.print( " o" + e.src.id + " -> o" + e.dst.id + "[label=\"" + e.call + "\",style=solid,color=red];"); } if (printUnifications) for (Node node : nodes) if (node.parent != null) ps.println(" o" + node.id + " -> o" + node.parent.id + " [color = blue];"); ps.println("}"); }