/* Matches the subgraphs rooted at two nodes and records the * isomorphism into a map. */ private static void matchSubgraph(Node node1, Node node2, Map<RegionVar, RegionVar> map) { RegionVar r1 = node1.getRep().getRegion(); RegionVar r2 = node2.getRep().getRegion(); if (map.containsKey(r1)) { assert (r2 == map.get(r1)) : "at call: " + node2.graph.method + " to " + node1.graph.method + "\n" + r2 + "(" + node2 + ") vs " + map.get(r1) + " corresponding to " + r1 + "(" + node1 + ")"; return; } map.put(r1, r2); if (secondary_index[3]) { node1 = node1.getRep(); node2 = node2.getRep(); for (Field f : node1.outfields.keySet()) { FieldEdge fe1 = node1.outfields.get(f); assert (fe1.src == node1); FieldEdge fe2 = node2.outfields.get(f); assert (fe2 != null); matchSubgraph(fe1.dst, fe2.dst, map); } } else { for (Field f : node1.graph.fedges.keySet()) for (FieldEdge fe1 : node1.graph.fedges.get(f)) { if (fe1.src != node1) continue; boolean found = false; assert (node2.graph.fedges.get(f) != null); for (FieldEdge fe2 : node2.graph.fedges.get(f)) { if (fe2.src != node2) continue; if (!fe1.field.equals(fe2.field)) continue; matchSubgraph(fe1.dst, fe2.dst, map); found = true; break; } assert (found); } } }
private static void matchNodeSubgraph(Node node1, Node node2, Map<Node, Node> map) { if (map.containsKey(node1)) { assert (node2 == map.get(node1)); return; } map.put(node1, node2); if (secondary_index[4]) { for (Field f : node1.outfields.keySet()) { FieldEdge fe1 = node1.outfields.get(f); assert (fe1.src.getRep() == node1); FieldEdge fe2 = node2.outfields.get(f); assert (fe2 != null); assert (fe2.src.getRep() == node2); matchNodeSubgraph(fe1.dst.getRep(), fe2.dst.getRep(), map); } } else { for (Field f : node1.graph.fedges.keySet()) for (FieldEdge fe1 : node1.graph.fedges.get(f)) { if (fe1.src.getRep() != node1) continue; boolean found = false; assert (node2.graph.fedges.get(f) != null); for (FieldEdge fe2 : node2.graph.fedges.get(f)) { if (fe2.src.getRep() != node2) continue; if (!fe1.field.equals(fe2.field)) continue; matchNodeSubgraph(fe1.dst.getRep(), fe2.dst.getRep(), map); found = true; break; } assert (found); } } }
/* Processing assignments of allocation statements. Left hand side is either a variable or the field of a variable. The right hand side is the allocation site, represented by the allocation instruction. */ public void assignAlloc(Var x, Field f, New a) { Node nodeL = getNode(x, f); nodeL.hasallocs = true; nodeL.istouched = true; setTouched(x); if (IRHelper.isLibrary(method.getDeclaringClass())) nodeL.hasliballocs = true; Node nodeR = allocmap.get(a); assert (nodeR == null) : "Allocation site already entered"; allocmap.put(a, nodeL); }
/* Lookup node for field, create new node if not present */ public Node getNode(Var var, Field field) { Map<Field, Node> map = varmap.get(var); if (map == null) { map = new HashMap<Field, Node>(); varmap.put(var, map); } Node fnode = map.get(field); if (fnode == null) { assert var != null; fnode = new Node(var, field, this); map.put(field, fnode); if (field != null) { Node node = getNode(var, null); w.add(new FieldConstraint(node, fnode, field)); } } return fnode; }
/* Return the region of an allocation site in this method */ protected RegionVar getAllocRegion(New alloc) { Node node = allocmap.get(alloc); assert (node != null); return node.getRep().getRegion(); }