Stable capture while moving towards typed heap regions, type and field on edges,...
authorjjenista <jjenista>
Mon, 16 Mar 2009 18:13:49 +0000 (18:13 +0000)
committerjjenista <jjenista>
Mon, 16 Mar 2009 18:13:49 +0000 (18:13 +0000)
Robust/src/Analysis/OwnershipAnalysis/HeapRegionNode.java
Robust/src/Analysis/OwnershipAnalysis/OwnershipAnalysis.java
Robust/src/Analysis/OwnershipAnalysis/OwnershipGraph.java
Robust/src/Analysis/OwnershipAnalysis/OwnershipNode.java
Robust/src/Analysis/OwnershipAnalysis/ReferenceEdge.java

index 5436e856fcfb8730395b278ab7dcd84a38bf65fc..d245970c326a035962a5081242e436a95eb76ae0 100644 (file)
@@ -15,6 +15,8 @@ public class HeapRegionNode extends OwnershipNode {
 
   protected HashSet<ReferenceEdge> referencers;
 
+  protected TypeDescriptor type;
+
   protected AllocationSite allocSite;
 
   protected ReachabilitySet alpha;
@@ -29,6 +31,7 @@ public class HeapRegionNode extends OwnershipNode {
                         boolean isFlagged,
                        boolean isParameter,
                         boolean isNewSummary,
+                       TypeDescriptor type,
                         AllocationSite allocSite,
                         ReachabilitySet alpha,
                         String description) {
@@ -37,6 +40,7 @@ public class HeapRegionNode extends OwnershipNode {
     this.isFlagged      = isFlagged;
     this.isParameter    = isParameter;
     this.isNewSummary   = isNewSummary;
+    this.type           = type;
     this.allocSite      = allocSite;
     this.alpha          = alpha;
     this.description    = description;
@@ -51,6 +55,7 @@ public class HeapRegionNode extends OwnershipNode {
                               isFlagged,
                              isParameter,
                               isNewSummary,
+                             type,
                               allocSite,
                               alpha,
                               description);
@@ -142,14 +147,16 @@ public class HeapRegionNode extends OwnershipNode {
   }
 
   public ReferenceEdge getReferenceFrom(OwnershipNode on,
-                                        FieldDescriptor fd) {
+                                        TypeDescriptor type,
+                                       String field) {
     assert on != null;
 
     Iterator<ReferenceEdge> itrEdge = referencers.iterator();
     while( itrEdge.hasNext() ) {
       ReferenceEdge edge = itrEdge.next();
       if( edge.getSrc().equals(on) &&
-          edge.getFieldDesc() == fd     ) {
+         edge.typeEquals(type) &&
+          edge.fieldEquals(field) ) {
        return edge;
       }
     }
@@ -158,6 +165,10 @@ public class HeapRegionNode extends OwnershipNode {
   }
 
 
+  public TypeDescriptor getType() {
+    return type;
+  }  
+
   public AllocationSite getAllocationSite() {
     return allocSite;
   }
index 142bd5dd7348133087cfcca5c8a1cbf90534d1c5..04163ef02630ca16e5850d128e336fc00e161d56 100644 (file)
@@ -192,6 +192,7 @@ public class OwnershipAnalysis {
       }
     }
 
+    bw.write( "\n"+computeAliasContextHistogram() );
     bw.close();
   }
 
@@ -240,6 +241,7 @@ public class OwnershipAnalysis {
       bw.write("No aliases between flagged objects found.\n");
     }
 
+    bw.write( "\n"+computeAliasContextHistogram() );
     bw.close();
   }
   ///////////////////////////////////////////
@@ -1193,6 +1195,41 @@ public class OwnershipAnalysis {
 
 
 
+  private String computeAliasContextHistogram() {
+    
+    Hashtable<Integer, Integer> mapNumContexts2NumDesc = 
+      new Hashtable<Integer, Integer>();
+  
+    Iterator itr = mapDescriptorToAllMethodContexts.entrySet().iterator();
+    while( itr.hasNext() ) {
+      Map.Entry me = (Map.Entry) itr.next();
+      HashSet<MethodContext> s = (HashSet<MethodContext>) me.getValue();
+      
+      Integer i = mapNumContexts2NumDesc.get( s.size() );
+      if( i == null ) {
+       i = new Integer( 0 );
+      }
+      mapNumContexts2NumDesc.put( s.size(), i + 1 );
+    }   
+
+    String s = "";
+    int total = 0;
+
+    itr = mapNumContexts2NumDesc.entrySet().iterator();
+    while( itr.hasNext() ) {
+      Map.Entry me = (Map.Entry) itr.next();
+      Integer c0 = (Integer) me.getKey();
+      Integer d0 = (Integer) me.getValue();
+      total += d0;
+      s += String.format( "%4d methods had %4d unique alias contexts.\n", d0, c0 );
+    }
+
+    s += String.format( "\n%4d total methods analayzed.\n", total );
+
+    return s;
+  }
+
+
 
   // insert a call to debugSnapshot() somewhere in the analysis 
   // to get successive captures of the analysis state
index ae6b7af01dc9d6572865e5a007a6d99367ed4a70..438a3f17d39149add1c5600eb2dc793d32162848 100644 (file)
@@ -76,12 +76,20 @@ public class OwnershipGraph {
                           boolean isFlagged,
                           boolean isNewSummary,
                           boolean isParameter,
+                         TypeDescriptor type,
                           AllocationSite allocSite,
                           ReachabilitySet alpha,
                           String description) {
 
     boolean markForAnalysis = isFlagged || isParameter;
 
+    TypeDescriptor typeToUse = null;
+    if( allocSite != null ) {
+      typeToUse = allocSite.getType();
+    } else {
+      typeToUse = type;
+    }
+
     if( allocSite != null && allocSite.getDisjointId() != null ) {
       markForAnalysis = true;
     }
@@ -110,6 +118,7 @@ public class OwnershipGraph {
                                             markForAnalysis,
                                            isParameter,
                                             isNewSummary,
+                                           typeToUse,
                                             allocSite,
                                             alpha,
                                             description);
@@ -144,22 +153,26 @@ public class OwnershipGraph {
 
   protected void removeReferenceEdge(OwnershipNode referencer,
                                      HeapRegionNode referencee,
-                                     FieldDescriptor fieldDesc) {
+                                     TypeDescriptor type,
+                                    String field) {
     assert referencer != null;
     assert referencee != null;
-
+    
     ReferenceEdge edge = referencer.getReferenceTo(referencee,
-                                                   fieldDesc);
+                                                   type,
+                                                  field);
     assert edge != null;
     assert edge == referencee.getReferenceFrom(referencer,
-                                               fieldDesc);
+                                               type,
+                                              field);
 
     referencer.removeReferencee(edge);
     referencee.removeReferencer(edge);
   }
 
   protected void clearReferenceEdgesFrom(OwnershipNode referencer,
-                                         FieldDescriptor fieldDesc,
+                                         TypeDescriptor type,
+                                        String field,
                                          boolean removeAll) {
     assert referencer != null;
 
@@ -170,18 +183,24 @@ public class OwnershipGraph {
     while( i.hasNext() ) {
       ReferenceEdge edge = i.next();
 
-      if( removeAll || edge.getFieldDesc() == fieldDesc ) {
-       HeapRegionNode referencee = edge.getDst();
+      if( removeAll                                          || 
+         (type  != null && edge.getType() .equals( type  )) ||
+         (field != null && edge.getField().equals( field ))   
+        ){
 
+       HeapRegionNode referencee = edge.getDst();
+       
        removeReferenceEdge(referencer,
                            referencee,
-                           edge.getFieldDesc() );
+                           edge.getType(),
+                           edge.getField() );
       }
     }
   }
 
   protected void clearReferenceEdgesTo(HeapRegionNode referencee,
-                                       FieldDescriptor fieldDesc,
+                                      TypeDescriptor type,
+                                      String field,
                                        boolean removeAll) {
     assert referencee != null;
 
@@ -192,11 +211,17 @@ public class OwnershipGraph {
     while( i.hasNext() ) {
       ReferenceEdge edge = i.next();
 
-      if( removeAll || edge.getFieldDesc() == fieldDesc ) {
+      if( removeAll                                          || 
+         (type  != null && edge.getType() .equals( type  )) ||
+         (field != null && edge.getField().equals( field ))   
+        ){
+
        OwnershipNode referencer = edge.getSrc();
+
        removeReferenceEdge(referencer,
                            referencee,
-                           edge.getFieldDesc() );
+                           edge.getType(),
+                           edge.getField() );
       }
     }
   }
@@ -371,13 +396,13 @@ public class OwnershipGraph {
     LabelNode lnX = getLabelNodeFromTemp(x);
     LabelNode lnY = getLabelNodeFromTemp(y);
 
-    clearReferenceEdgesFrom(lnX, null, true);
+    clearReferenceEdgesFrom(lnX, null, null, true);
 
     Iterator<ReferenceEdge> itrYhrn = lnY.iteratorToReferencees();
     while( itrYhrn.hasNext() ) {
-      ReferenceEdge edgeY       = itrYhrn.next();
+      ReferenceEdge  edgeY      = itrYhrn.next();
       HeapRegionNode referencee = edgeY.getDst();
-      ReferenceEdge edgeNew    = edgeY.copy();
+      ReferenceEdge  edgeNew    = edgeY.copy();
       edgeNew.setSrc(lnX);
 
       addReferenceEdge(lnX, referencee, edgeNew);
@@ -392,15 +417,16 @@ public class OwnershipGraph {
     LabelNode lnX = getLabelNodeFromTemp(x);
     LabelNode lnY = getLabelNodeFromTemp(y);
     
-    clearReferenceEdgesFrom(lnX, null, true);
+    clearReferenceEdgesFrom(lnX, null, null, true);
 
     Iterator<ReferenceEdge> itrYhrn = lnY.iteratorToReferencees();
     while( itrYhrn.hasNext() ) {
-      ReferenceEdge edgeY       = itrYhrn.next();
+      ReferenceEdge  edgeY      = itrYhrn.next();
       HeapRegionNode referencee = edgeY.getDst();
-      ReferenceEdge edgeNew    = edgeY.copy();
-      edgeNew.setSrc(lnX);
-      edgeNew.setFieldDesc(f);
+      ReferenceEdge  edgeNew    = edgeY.copy();
+      edgeNew.setSrc( lnX );
+      edgeNew.setType( f.getType() );
+      edgeNew.setField( f.getSymbol() );
 
       addReferenceEdge(lnX, referencee, edgeNew);
     }
@@ -413,7 +439,7 @@ public class OwnershipGraph {
     LabelNode lnX = getLabelNodeFromTemp(x);
     LabelNode lnY = getLabelNodeFromTemp(y);
 
-    clearReferenceEdgesFrom(lnX, null, true);
+    clearReferenceEdgesFrom(lnX, null, null, true);
 
     Iterator<ReferenceEdge> itrYhrn = lnY.iteratorToReferencees();
     while( itrYhrn.hasNext() ) {
@@ -427,12 +453,13 @@ public class OwnershipGraph {
        HeapRegionNode hrnHrn  = edgeHrn.getDst();
        ReachabilitySet betaHrn = edgeHrn.getBeta();
 
-       if( edgeHrn.getFieldDesc() == null ||
-           edgeHrn.getFieldDesc() == f ) {
+       if( edgeHrn.getType() == null ||
+           edgeHrn.getType().equals( f.getType() ) ) {
 
          ReferenceEdge edgeNew = new ReferenceEdge(lnX,
                                                    hrnHrn,
-                                                   f,
+                                                   f.getType(),
+                                                   f.getSymbol(),
                                                    false,
                                                    betaY.intersection(betaHrn) );
 
@@ -469,12 +496,12 @@ public class OwnershipGraph {
        // we can do a strong update here if one of two cases holds     
        if( f != null &&
            hrnX.isSingleObject() &&
-           (   (hrnX.getNumReferencers() == 1)                           ||
+           (   (hrnX.getNumReferencers() == 1) ||
                ( lnX.getNumReferencees() == 1)
            )
          ) {
          strongUpdate = true;
-         clearReferenceEdgesFrom( hrnX, f, false );
+         clearReferenceEdgesFrom( hrnX, f.getType(), f.getSymbol(), false );
        }
       }
     }
@@ -549,14 +576,17 @@ public class OwnershipGraph {
        // prepare the new reference edge hrnX.f -> hrnY
        ReferenceEdge edgeNew = new ReferenceEdge(hrnX,
                                                  hrnY,
-                                                 f,
+                                                 f.getType(),
+                                                 f.getSymbol(),
                                                  false,
                                                  edgeY.getBeta().pruneBy( hrnX.getAlpha() )
                                                  );
 
        // look to see if an edge with same field exists
        // and merge with it, otherwise just add the edge
-       ReferenceEdge edgeExisting = hrnX.getReferenceTo( hrnY, f );
+       ReferenceEdge edgeExisting = hrnX.getReferenceTo( hrnY, 
+                                                         f.getType(),
+                                                         f.getSymbol() );
        
        if( edgeExisting != null ) {
          edgeExisting.setBeta(
@@ -590,6 +620,7 @@ public class OwnershipGraph {
                                                  isTask,
                                                  false,
                                                  true,
+                                                null,
                                                  null,
                                                  null,
                                                  "param" + paramIndex);
@@ -621,13 +652,13 @@ public class OwnershipGraph {
     // the worst here.
 
     ReferenceEdge edgeFromLabel =
-      new ReferenceEdge(lnParam, hrn, null, false, beta);
+      new ReferenceEdge(lnParam, hrn, null, null, false, beta);
 
     ReferenceEdge edgeFromLabelQ =
-      new ReferenceEdge(lnParamQ, hrn, null, false, beta);
+      new ReferenceEdge(lnParamQ, hrn, null, null, false, beta);
 
     ReferenceEdge edgeReflexive =
-      new ReferenceEdge(hrn,     hrn, null, true,  beta);
+      new ReferenceEdge(hrn,     hrn, null, null, true,  beta);
 
     addReferenceEdge(lnParam,  hrn, edgeFromLabel);
     addReferenceEdge(lnParamQ, hrn, edgeFromLabelQ);
@@ -643,6 +674,7 @@ public class OwnershipGraph {
                                                  false,
                                                  false,
                                                  true,
+                                                null,
                                                  null,
                                                  null,
                                                  "aliasedParams");
@@ -659,10 +691,10 @@ public class OwnershipGraph {
     // the worst here.
 
     ReferenceEdge edgeFromLabel =
-      new ReferenceEdge(lnParam, hrn, null, false, beta);
+      new ReferenceEdge(lnParam, hrn, null, null, false, beta);
 
     ReferenceEdge edgeReflexive =
-      new ReferenceEdge(hrn,     hrn, null, true,  beta);
+      new ReferenceEdge(hrn,     hrn, null, null, true,  beta);
 
     addReferenceEdge(lnParam, hrn, edgeFromLabel);
     addReferenceEdge(hrn,     hrn, edgeReflexive);
@@ -712,10 +744,10 @@ public class OwnershipGraph {
     // the worst here.
 
     ReferenceEdge edgeFromLabel =
-      new ReferenceEdge(lnParam, hrnAliasBlob, null, false, beta);
+      new ReferenceEdge(lnParam, hrnAliasBlob, null, null, false, beta);
 
     ReferenceEdge edgeFromLabelQ =
-      new ReferenceEdge(lnParamQ, hrnAliasBlob, null, false, beta);
+      new ReferenceEdge(lnParamQ, hrnAliasBlob, null, null, false, beta);
 
     addReferenceEdge(lnParam,  hrnAliasBlob, edgeFromLabel);
     addReferenceEdge(lnParamQ, hrnAliasBlob, edgeFromLabelQ);
@@ -728,7 +760,7 @@ public class OwnershipGraph {
     LabelNode lnR = getLabelNodeFromTemp(tdReturn);
     LabelNode lnX = getLabelNodeFromTemp(x);
 
-    clearReferenceEdgesFrom(lnR, null, true);
+    clearReferenceEdgesFrom(lnR, null, null, true);
 
     Iterator<ReferenceEdge> itrXhrn = lnX.iteratorToReferencees();
     while( itrXhrn.hasNext() ) {
@@ -760,10 +792,10 @@ public class OwnershipGraph {
     assert hrnNewest != null;
 
     LabelNode lnX = getLabelNodeFromTemp(x);
-    clearReferenceEdgesFrom(lnX, null, true);
+    clearReferenceEdgesFrom(lnX, null, null, true);
 
     ReferenceEdge edgeNew =
-      new ReferenceEdge(lnX, hrnNewest, null, false, hrnNewest.getAlpha() );
+      new ReferenceEdge(lnX, hrnNewest, null, null, false, hrnNewest.getAlpha() );
 
     addReferenceEdge(lnX, hrnNewest, edgeNew);
   }
@@ -823,8 +855,8 @@ public class OwnershipGraph {
     assert hrn0 != null;
 
     // clear all references in and out of newest node
-    clearReferenceEdgesFrom(hrn0, null, true);
-    clearReferenceEdgesTo(hrn0, null, true);
+    clearReferenceEdgesFrom(hrn0, null, null, true);
+    clearReferenceEdgesTo(hrn0, null, null, true);
 
 
     // now tokens in reachability sets need to "age" also
@@ -894,6 +926,7 @@ public class OwnershipGraph {
                                            hasFlags,
                                            true,
                                            false,
+                                          null,
                                            as,
                                            null,
                                            as.toStringForDOT() + "\\nsummary");
@@ -906,6 +939,7 @@ public class OwnershipGraph {
                                hasFlags,
                                false,
                                false,
+                               null,
                                as,
                                null,
                                as.toStringForDOT() + "\\n" + i + " oldest");
@@ -933,6 +967,7 @@ public class OwnershipGraph {
                                                  hasFlags,
                                                  true,
                                                  false,
+                                                null,
                                                  as,
                                                  null,
                                                  as + "\\n" + as.getType() + "\\nshadowSum");
@@ -945,6 +980,7 @@ public class OwnershipGraph {
                                hasFlags,
                                false,
                                false,
+                               null,
                                as,
                                null,
                                as + "\\n" + as.getType() + "\\n" + i + " shadow");
@@ -966,7 +1002,9 @@ public class OwnershipGraph {
       edgeMerged.setSrc(hrnSummary);
 
       HeapRegionNode hrnReferencee = edge.getDst();
-      ReferenceEdge edgeSummary   = hrnSummary.getReferenceTo(hrnReferencee, edge.getFieldDesc() );
+      ReferenceEdge edgeSummary   = hrnSummary.getReferenceTo(hrnReferencee, 
+                                                             edge.getType(),
+                                                             edge.getField() );
 
       if( edgeSummary == null ) {
        // the merge is trivial, nothing to be done
@@ -987,7 +1025,9 @@ public class OwnershipGraph {
       edgeMerged.setDst(hrnSummary);
 
       OwnershipNode onReferencer = edge.getSrc();
-      ReferenceEdge edgeSummary  = onReferencer.getReferenceTo(hrnSummary, edge.getFieldDesc() );
+      ReferenceEdge edgeSummary  = onReferencer.getReferenceTo(hrnSummary, 
+                                                              edge.getType(),
+                                                              edge.getField() );
 
       if( edgeSummary == null ) {
        // the merge is trivial, nothing to be done
@@ -1008,8 +1048,8 @@ public class OwnershipGraph {
   protected void transferOnto(HeapRegionNode hrnA, HeapRegionNode hrnB) {
 
     // clear references in and out of node b
-    clearReferenceEdgesFrom(hrnB, null, true);
-    clearReferenceEdgesTo(hrnB, null, true);
+    clearReferenceEdgesFrom(hrnB, null, null, true);
+    clearReferenceEdgesTo(hrnB, null, null, true);
 
     // copy each edge in and out of A to B
     Iterator<ReferenceEdge> itrReferencee = hrnA.iteratorToReferencees();
@@ -1243,7 +1283,7 @@ public class OwnershipGraph {
                               toShadowTokens(ogCallee, hrnParam.getAlpha() )
                               );
 
-      ReferenceEdge edgeReflexive_i = hrnParam.getReferenceTo(hrnParam, null);
+      ReferenceEdge edgeReflexive_i = hrnParam.getReferenceTo(hrnParam, null, null);
       assert edgeReflexive_i != null;
       paramIndex2rewriteJ.put(paramIndex,
                               toShadowTokens(ogCallee, edgeReflexive_i.getBeta() )
@@ -1253,7 +1293,7 @@ public class OwnershipGraph {
       assert tdParamQ != null;
       LabelNode lnParamQ = ogCallee.td2ln.get(tdParamQ);
       assert lnParamQ != null;
-      ReferenceEdge edgeSpecialQ_i = lnParamQ.getReferenceTo(hrnParam, null);
+      ReferenceEdge edgeSpecialQ_i = lnParamQ.getReferenceTo(hrnParam, null, null);
       assert edgeSpecialQ_i != null;
       paramIndex2rewriteK.put(paramIndex,
                               toShadowTokens(ogCallee, edgeSpecialQ_i.getBeta() )
@@ -1578,7 +1618,8 @@ public class OwnershipGraph {
          // calculated once, then copy it for each new edge in caller
          ReferenceEdge edgeNewInCallerTemplate = new ReferenceEdge(null,
                                                                    null,
-                                                                   edgeCallee.getFieldDesc(),
+                                                                   edgeCallee.getType(),
+                                                                   edgeCallee.getField(),
                                                                    false,
                                                                    toShadowTokens(ogCallee,
                                                                                   edgeCallee.getBeta() )
@@ -1637,7 +1678,9 @@ public class OwnershipGraph {
              edgeNewInCaller.setSrc(src);
              edgeNewInCaller.setDst(dst);            
 
-             ReferenceEdge edgeExisting = src.getReferenceTo(dst, edgeNewInCaller.getFieldDesc() );
+             ReferenceEdge edgeExisting = src.getReferenceTo(dst, 
+                                                             edgeNewInCaller.getType(),
+                                                             edgeNewInCaller.getField() );
              if( edgeExisting == null ) {
                // if this edge doesn't exist in the caller, create it
                addReferenceEdge(src, dst, edgeNewInCaller);
@@ -1658,7 +1701,7 @@ public class OwnershipGraph {
     if( returnTemp != null && !returnTemp.getType().isImmutable() ) {
 
       LabelNode lnLhsCaller = getLabelNodeFromTemp(returnTemp);
-      clearReferenceEdgesFrom(lnLhsCaller, null, true);
+      clearReferenceEdgesFrom(lnLhsCaller, null, null, true);
 
       LabelNode lnReturnCallee = ogCallee.getLabelNodeFromTemp(tdReturn);
       Iterator<ReferenceEdge> edgeCalleeItr = lnReturnCallee.iteratorToReferencees();
@@ -1667,7 +1710,8 @@ public class OwnershipGraph {
 
        ReferenceEdge edgeNewInCallerTemplate = new ReferenceEdge(null,
                                                                  null,
-                                                                 edgeCallee.getFieldDesc(),
+                                                                 edgeCallee.getType(),
+                                                                 edgeCallee.getField(),
                                                                  false,
                                                                  toShadowTokens(ogCallee,
                                                                                 edgeCallee.getBeta() )
@@ -1707,7 +1751,9 @@ public class OwnershipGraph {
          edgeNewInCaller.setSrc(lnLhsCaller);
          edgeNewInCaller.setDst(hrnCaller);
 
-         ReferenceEdge edgeExisting = lnLhsCaller.getReferenceTo(hrnCaller, edgeNewInCaller.getFieldDesc() );
+         ReferenceEdge edgeExisting = lnLhsCaller.getReferenceTo(hrnCaller, 
+                                                                 edgeNewInCaller.getType(),
+                                                                 edgeNewInCaller.getField() );
          if( edgeExisting == null ) {
 
            // if this edge doesn't exist in the caller, create it
@@ -1741,8 +1787,8 @@ public class OwnershipGraph {
       mergeIntoSummary(hrnSummaryShadow, hrnSummary);
 
       // then clear off after merge
-      clearReferenceEdgesFrom(hrnSummaryShadow, null, true);
-      clearReferenceEdgesTo(hrnSummaryShadow, null, true);
+      clearReferenceEdgesFrom(hrnSummaryShadow, null, null, true);
+      clearReferenceEdgesTo(hrnSummaryShadow, null, null, true);
       hrnSummaryShadow.setAlpha(new ReachabilitySet().makeCanonical() );
 
       // then transplant shadow nodes onto the now clean normal nodes
@@ -1757,8 +1803,8 @@ public class OwnershipGraph {
        transferOnto(hrnIthShadow, hrnIth);
 
        // clear off shadow nodes after transfer
-       clearReferenceEdgesFrom(hrnIthShadow, null, true);
-       clearReferenceEdgesTo(hrnIthShadow, null, true);
+       clearReferenceEdgesFrom(hrnIthShadow, null, null, true);
+       clearReferenceEdgesTo(hrnIthShadow, null, null, true);
        hrnIthShadow.setAlpha(new ReachabilitySet().makeCanonical() );
       }
 
@@ -1813,20 +1859,14 @@ public class OwnershipGraph {
 
   protected boolean hasMatchingField(HeapRegionNode src, ReferenceEdge edge) {
 
-    // if no allocation site, then it's a match-everything region
-    AllocationSite asSrc = src.getAllocationSite();
-    if( asSrc == null ) {
+    // if no type, then it's a match-everything region
+    TypeDescriptor tdSrc = src.getType();    
+    if( tdSrc == null ) {
       return true;
     }
 
-    TypeDescriptor tdSrc = asSrc.getType();
-    assert tdSrc != null;
-
     if( tdSrc.isArray() ) {
-      FieldDescriptor fd = edge.getFieldDesc();
-      assert fd != null;
-
-      TypeDescriptor td = fd.getType();
+      TypeDescriptor td = edge.getType();
       assert td != null;
 
       TypeDescriptor tdSrcDeref = tdSrc.dereference();
@@ -1836,7 +1876,7 @@ public class OwnershipGraph {
        return false;
       }
 
-      return fd.getSymbol().equals( OwnershipAnalysis.arrayElementFieldName );
+      return edge.getField().equals( OwnershipAnalysis.arrayElementFieldName );
     }
 
     // if it's not a class, it doesn't have any fields to match
@@ -1847,7 +1887,8 @@ public class OwnershipGraph {
     Iterator fieldsSrcItr = tdSrc.getClassDesc().getFields();
     while( fieldsSrcItr.hasNext() ) {
       FieldDescriptor fd = (FieldDescriptor) fieldsSrcItr.next();
-      if( fd == edge.getFieldDesc() ) {
+      if( fd.getType().equals( edge.getType() ) &&
+         fd.getSymbol().equals( edge.getField() ) ) {
        return true;
       }
     }
@@ -1859,32 +1900,27 @@ public class OwnershipGraph {
 
 
   protected boolean hasMatchingType(ReferenceEdge edge, HeapRegionNode dst) {
-
+   
     // if the region has no type, matches everything
-    AllocationSite asDst = dst.getAllocationSite();
-    if( asDst == null ) {
+    TypeDescriptor tdDst = dst.getType();
+    if( tdDst == null ) {
       return true;
     }
 
-    TypeDescriptor tdDst = asDst.getType();
-    assert tdDst != null;
-
-    // if the type is not a class don't match because
-    // primitives are copied, no memory aliases
+    // if the type is not a class or an array, don't
+    // match because primitives are copied, no aliases
     ClassDescriptor cdDst = tdDst.getClassDesc();
     if( cdDst == null && !tdDst.isArray() ) {
       return false;
     }
 
-    // if the field is null, it matches everything
-    FieldDescriptor fd = edge.getFieldDesc();
-    if( fd == null ) {
+    // if the edge type is null, it matches everything
+    TypeDescriptor tdEdge = edge.getType();
+    if( tdEdge == null ) {
       return true;
     }
-    TypeDescriptor tdFd = fd.getType();
-    assert tdFd != null;
 
-    return typeUtil.isSuperorType(tdFd, tdDst);
+    return typeUtil.isSuperorType(tdEdge, tdDst);
   }
 
 
@@ -2487,8 +2523,9 @@ public class OwnershipGraph {
 
          // don't use the ReferenceEdge.equals() here because
          // we're talking about existence between graphs
-         if( idChildB.equals(idChildA) &&
-             edgeB.getFieldDesc() == edgeA.getFieldDesc() ) {
+         if( idChildB.equals( idChildA ) &&
+             edgeB.typeAndFieldEquals( edgeA ) ) {
+
            edgeToMerge = edgeB;
          }
        }
@@ -2538,24 +2575,19 @@ public class OwnershipGraph {
        LabelNode lnB         = td2ln.get(tdA);
        ReferenceEdge edgeToMerge = null;
 
-       // labels never have edges with a field
-       //assert edgeA.getFieldDesc() == null;
-
        Iterator<ReferenceEdge> heapRegionsItrB = lnB.iteratorToReferencees();
        while( heapRegionsItrB.hasNext() &&
               edgeToMerge == null          ) {
 
-         ReferenceEdge edgeB     = heapRegionsItrB.next();
+         ReferenceEdge  edgeB     = heapRegionsItrB.next();
          HeapRegionNode hrnChildB = edgeB.getDst();
-         Integer idChildB  = hrnChildB.getID();
-
-         // labels never have edges with a field
-         //assert edgeB.getFieldDesc() == null;
+         Integer        idChildB  = hrnChildB.getID();
 
          // don't use the ReferenceEdge.equals() here because
          // we're talking about existence between graphs
-         if( idChildB.equals(idChildA) &&
-             edgeB.getFieldDesc() == edgeA.getFieldDesc() ) {
+         if( idChildB.equals( idChildA ) &&
+             edgeB.typeAndFieldEquals( edgeA ) ) {
+
            edgeToMerge = edgeB;
          }
        }
@@ -2811,16 +2843,13 @@ public class OwnershipGraph {
        HeapRegionNode hrnChildB = edgeB.getDst();
        Integer idChildB  = hrnChildB.getID();
 
-       if( idChildA.equals(idChildB) &&
-           edgeA.getFieldDesc() == edgeB.getFieldDesc() ) {
+       if( idChildA.equals( idChildB ) &&
+           edgeA.typeAndFieldEquals( edgeB ) ) {
 
          // there is an edge in the right place with the right field,
          // but do they have the same attributes?
          if( edgeA.getBeta().equals(edgeB.getBeta() ) ) {
-
            edgeFound = true;
-           //} else {
-           //return false;
          }
        }
       }
@@ -3334,6 +3363,7 @@ public class OwnershipGraph {
 
 
     // useful for debugging
+    // UNMAINTAINED
     /*
     if( writeReferencers ) {
       OwnershipNode onRef  = null;
index 390813e3167eaab6a6bf3dfdd999e9d75b990fac..6b0469a0c67475ba9b2e16484a0d6ae8b877142c 100644 (file)
@@ -40,14 +40,16 @@ public abstract class OwnershipNode {
   }
 
   public ReferenceEdge getReferenceTo(HeapRegionNode hrn,
-                                      FieldDescriptor fd) {
+                                      TypeDescriptor type,
+                                     String field) {
     assert hrn != null;
 
     Iterator<ReferenceEdge> itrEdge = referencees.iterator();
     while( itrEdge.hasNext() ) {
       ReferenceEdge edge = itrEdge.next();
       if( edge.getDst().equals(hrn) &&
-          edge.getFieldDesc() == fd     ) {
+         edge.typeEquals( type ) &&
+          edge.fieldEquals( field ) ) {
        return edge;
       }
     }
index 58c8d9e30e18db43fcfaf954826bf22f2d85ff93..67ca696a4c6a0c487b4b25e501a86fcddd2b15e4 100644 (file)
@@ -6,9 +6,9 @@ import IR.Flat.*;
 
 public class ReferenceEdge {
 
-
-  // a null field descriptor means "any field"
-  protected FieldDescriptor fieldDesc;
+  // null descriptors mean "any field"
+  protected TypeDescriptor type;
+  protected String field;
 
   protected boolean isInitialParamReflexive;
 
@@ -21,13 +21,15 @@ public class ReferenceEdge {
 
   public ReferenceEdge(OwnershipNode src,
                        HeapRegionNode dst,
-                       FieldDescriptor fieldDesc,
+                      TypeDescriptor type,
+                      String field,
                        boolean isInitialParamReflexive,
                        ReachabilitySet beta) {
 
     this.src                     = src;
     this.dst                     = dst;
-    this.fieldDesc               = fieldDesc;
+    this.type                    = type;
+    this.field                   = field;
     this.isInitialParamReflexive = isInitialParamReflexive;
 
     if( beta != null ) {
@@ -45,7 +47,8 @@ public class ReferenceEdge {
   public ReferenceEdge copy() {
     return new ReferenceEdge(src,
                              dst,
-                             fieldDesc,
+                            type,
+                            field,
                              isInitialParamReflexive,
                              beta);
   }
@@ -62,7 +65,11 @@ public class ReferenceEdge {
 
     ReferenceEdge edge = (ReferenceEdge) o;
 
-    if( fieldDesc != edge.fieldDesc ) {
+    if( !typeEquals( edge.type ) ) {
+      return false;
+    }
+
+    if( !fieldEquals( edge.field ) ) {
       return false;
     }
 
@@ -85,8 +92,12 @@ public class ReferenceEdge {
   public int hashCode() {
     int hash = 0;
 
-    if( fieldDesc != null ) {
-      hash += fieldDesc.hashCode();
+    if( type != null ) {
+      hash += type.hashCode();
+    }
+
+    if( field != null ) {
+      hash += field.hashCode()*7;
     }
 
     hash += src.hashCode()*11;
@@ -115,18 +126,53 @@ public class ReferenceEdge {
   }
 
 
-  public FieldDescriptor getFieldDesc() {
-    return fieldDesc;
+  public TypeDescriptor getType() {
+    return type;
+  }
+
+  public void setType( TypeDescriptor td ) {
+    type = td;
+  }
+
+  public String getField() {
+    return field;
+  }
+
+  public void setField( String s ) {
+    field = s;
+  }
+
+
+  public boolean typeEquals( TypeDescriptor td ) {
+    if( type == null && td == null ) {
+      return true;
+    }
+    if( type == null ) {
+      return false;
+    }
+    return type.equals( td );
+  }
+
+  public boolean fieldEquals( String s ) {
+    if( field == null && s == null ) {
+      return true;
+    }
+    if( field == null ) {
+      return false;
+    }
+    return field.equals( s );
   }
 
-  public void setFieldDesc(FieldDescriptor fieldDesc) {
-    this.fieldDesc = fieldDesc;
+  public boolean typeAndFieldEquals( ReferenceEdge e ) {
+    return typeEquals ( e.getType()  ) &&
+           fieldEquals( e.getField() );
   }
 
 
   public boolean isInitialParamReflexive() {
     return isInitialParamReflexive;
   }
+
   public void setIsInitialParamReflexive(boolean isInitialParamReflexive) {
     this.isInitialParamReflexive = isInitialParamReflexive;
   }
@@ -161,12 +207,12 @@ public class ReferenceEdge {
   public String toGraphEdgeString() {
     String edgeLabel = "";
 
-    if( fieldDesc != null ) {
-      edgeLabel += fieldDesc.toPrettyStringBrief() + "\\n";
+    if( type != null && field != null ) {
+      edgeLabel += type+" "+field+"\\n";
     }
 
     if( isInitialParamReflexive ) {
-      edgeLabel += "Rflx\\n";
+      edgeLabel += "init-param\\n";
     }
 
     edgeLabel += beta.toStringEscapeNewline();
@@ -175,6 +221,6 @@ public class ReferenceEdge {
   }
 
   public String toString() {
-    return new String("("+src+" "+fieldDesc+" "+dst+")");
+    return new String("("+src+"->"+type+" "+field+"->"+dst+")");
   }
 }