Fix implementation to use little d when possible, and big D only if there's no other...
[IRC.git] / Robust / src / Analysis / OwnershipAnalysis / TokenTupleSet.java
index 334b7d56d2af9102796adaaae4758d040208a87b..d190bed23f1723d56df81f1d5c40b83e856ba7f3 100644 (file)
@@ -58,6 +58,33 @@ public class TokenTupleSet extends Canonical {
     return ttsOut.makeCanonical();
   }
 
+  public TokenTupleSet unionUpArity(TokenTupleSet ttsIn) {
+    assert ttsIn != null;
+    TokenTupleSet ttsOut = new TokenTupleSet();
+
+    Iterator<TokenTuple> ttItr = this.iterator();
+    while( ttItr.hasNext() ) {
+      TokenTuple tt = ttItr.next();
+
+      if( ttsIn.containsToken(tt.getToken() ) ) {
+       ttsOut.tokenTuples.add(tt.increaseArity());
+      } else {
+       ttsOut.tokenTuples.add(tt);
+      }
+    }
+
+    ttItr = ttsIn.iterator();
+    while( ttItr.hasNext() ) {
+      TokenTuple tt = ttItr.next();
+
+      if( !ttsOut.containsToken(tt.getToken()) ) {
+       ttsOut.tokenTuples.add(tt);
+      }
+    }
+
+    return ttsOut.makeCanonical();
+  }
+
   public TokenTupleSet add(TokenTuple tt) {
     assert tt != null;
     TokenTupleSet ttsOut = new TokenTupleSet(tt);
@@ -128,32 +155,34 @@ public class TokenTupleSet extends Canonical {
       TokenTuple tt = (TokenTuple) itrT.next();
 
       Integer token = tt.getToken();
-      int age = as.getAge(token);
+      int age = as.getAgeCategory(token);
 
-      // summary tokens and tokens not associated with
+      // tokens not associated with
       // the site should be left alone
       if( age == AllocationSite.AGE_notInThisSite ) {
        ttsOut.tokenTuples.add(tt);
 
+      } else if( age == AllocationSite.AGE_summary ) {
+       // remember the summary tuple, but don't add it
+       // we may combine it with the oldest tuple
+       ttSummary = tt;
+
+      } else if( age == AllocationSite.AGE_oldest ) {
+       // found an oldest token, again just remember
+       // for later
+       foundOldest = true;
+
       } else {
-       if( age == AllocationSite.AGE_summary ) {
-         // remember the summary tuple, but don't add it
-         // we may combine it with the oldest tuple
-         ttSummary = tt;
-
-       } else if( age == AllocationSite.AGE_oldest ) {
-         // found an oldest token, again just remember
-         // for later
-         foundOldest = true;
-
-       } else {
-         // otherwise, we change this token to the
-         // next older token
-         Integer tokenToChangeTo = as.getIthOldest(age + 1);
-         TokenTuple ttAged       = tt.changeTokenTo(tokenToChangeTo);
-         ttsOut.tokenTuples.add(ttAged);
-       }
+       assert age == AllocationSite.AGE_in_I;
 
+       Integer I = as.getAge(token);
+       assert I != null;
+
+       // otherwise, we change this token to the
+       // next older token
+       Integer tokenToChangeTo = as.getIthOldest(I + 1);
+       TokenTuple ttAged       = tt.changeTokenTo(tokenToChangeTo);
+       ttsOut.tokenTuples.add(ttAged);
       }
     }
 
@@ -181,6 +210,142 @@ public class TokenTupleSet extends Canonical {
   }
 
 
+  public TokenTupleSet unshadowTokens(AllocationSite as) {
+    assert as != null;
+
+    TokenTupleSet ttsOut = new TokenTupleSet();
+
+    TokenTuple ttSummary = null;
+    boolean foundShadowSummary = false;
+
+    Iterator itrT = this.iterator();
+    while( itrT.hasNext() ) {
+      TokenTuple tt = (TokenTuple) itrT.next();
+
+      Integer token = tt.getToken();
+      int shadowAge = as.getShadowAgeCategory(token);
+
+      if( shadowAge == AllocationSite.AGE_summary ) {
+       // remember the summary tuple, but don't add it
+       // we may combine it with the oldest tuple
+       ttSummary = tt;
+
+      } else if( shadowAge == AllocationSite.SHADOWAGE_notInThisSite ) {
+       ttsOut.tokenTuples.add(tt);
+
+      } else if( shadowAge == AllocationSite.SHADOWAGE_summary ) {
+       // found the shadow summary token, again just remember
+       // for later
+       foundShadowSummary = true;
+
+      } else if( shadowAge == AllocationSite.SHADOWAGE_oldest ) {
+       Integer tokenToChangeTo = as.getOldest();
+       TokenTuple ttNormal = tt.changeTokenTo(tokenToChangeTo);
+       ttsOut.tokenTuples.add(ttNormal);
+
+      } else {
+       assert shadowAge == AllocationSite.SHADOWAGE_in_I;
+
+       Integer I = as.getShadowAge(token);
+       assert I != null;
+
+       Integer tokenToChangeTo = as.getIthOldest(-I);
+       TokenTuple ttNormal = tt.changeTokenTo(tokenToChangeTo);
+       ttsOut.tokenTuples.add(ttNormal);
+      }
+    }
+
+    if       ( ttSummary != null && !foundShadowSummary ) {
+      ttsOut.tokenTuples.add(ttSummary);
+
+    } else if( ttSummary == null &&  foundShadowSummary ) {
+      ttSummary = new TokenTuple(as.getSummary(),
+                                 true,
+                                 TokenTuple.ARITY_ONE).makeCanonical();
+      ttsOut.tokenTuples.add(ttSummary);
+
+    } else if( ttSummary != null &&  foundShadowSummary ) {
+      ttsOut.tokenTuples.add(ttSummary.increaseArity() );
+    }
+
+    return ttsOut.makeCanonical();
+  }
+
+
+  public TokenTupleSet toShadowTokens(AllocationSite as) {
+    assert as != null;
+
+    TokenTupleSet ttsOut = new TokenTupleSet();
+
+    Iterator itrT = this.iterator();
+    while( itrT.hasNext() ) {
+      TokenTuple tt = (TokenTuple) itrT.next();
+
+      Integer token = tt.getToken();
+      int age = as.getAgeCategory(token);
+
+      // summary tokens and tokens not associated with
+      // the site should be left alone
+      if( age == AllocationSite.AGE_notInThisSite ) {
+       ttsOut.tokenTuples.add(tt);
+
+      } else if( age == AllocationSite.AGE_summary ) {
+       ttsOut.tokenTuples.add(tt.changeTokenTo(as.getSummaryShadow() ));
+
+      } else if( age == AllocationSite.AGE_oldest ) {
+       ttsOut.tokenTuples.add(tt.changeTokenTo(as.getOldestShadow() ));
+
+      } else {
+       assert age == AllocationSite.AGE_in_I;
+
+       Integer I = as.getAge(token);
+       assert I != null;
+
+       ttsOut.tokenTuples.add(tt.changeTokenTo(as.getIthOldestShadow(I) ));
+      }
+    }
+
+    return ttsOut.makeCanonical();
+  }
+
+
+  public ReachabilitySet rewriteToken(TokenTuple tokenToRewrite,
+                                      ReachabilitySet replacements,
+                                      boolean makeChangeSet,
+                                      Hashtable<TokenTupleSet, HashSet<TokenTupleSet> > forChangeSet) {
+
+    ReachabilitySet rsOut = new ReachabilitySet().makeCanonical();
+
+    if( !tokenTuples.contains(tokenToRewrite) ) {
+      rsOut = rsOut.add(this);
+
+    } else {
+      TokenTupleSet ttsMinusToken = new TokenTupleSet(this);
+      ttsMinusToken.tokenTuples.remove(tokenToRewrite);
+
+      Iterator<TokenTupleSet> replaceItr = replacements.iterator();
+      while( replaceItr.hasNext() ) {
+       TokenTupleSet replacement = replaceItr.next();
+       TokenTupleSet replaced = new TokenTupleSet(ttsMinusToken);
+       replaced = replaced.unionUpArity(replacement);
+       rsOut = rsOut.add(replaced);
+
+       if( makeChangeSet ) {
+         assert forChangeSet != null;
+         
+         if( forChangeSet.get(this) == null ) {
+           forChangeSet.put(this, new HashSet<TokenTupleSet>() );
+         }
+         
+         forChangeSet.get(this).add(replaced);
+       }
+      }
+    }
+
+    return rsOut.makeCanonical();
+  }
+
+
   public String toString() {
     return tokenTuples.toString();
   }