major revisions on FlowGraph to have more precise information
[IRC.git] / Robust / src / Analysis / OwnershipAnalysis / TokenTuple.java
index e8fd95a97e39de72058aac9f40ad3801815b3e11..00d9561a2fe6238a03ae574d55a5575af24c1c94 100644 (file)
@@ -11,84 +11,134 @@ import java.io.*;
 
 // THIS CLASS IS IMMUTABLE!
 
-public class TokenTuple extends Canonical
-{
-    private Integer token;
-    private boolean isNewSummary;
-
-    // only summary tokens should have ARITY_MANY?
-    public static final int ARITY_ONE  = 1;
-    public static final int ARITY_MANY = 2;
-    private int arity;
-
-    public TokenTuple( HeapRegionNode hrn ) {
-       token        = hrn.getID();
-       isNewSummary = hrn.isNewSummary();
-       arity        = ARITY_ONE;
+public class TokenTuple extends Canonical {
+
+  private Integer token;
+  private boolean isMultiObject;
+
+  public static final int ARITY_ZEROORMORE = 0;
+  public static final int ARITY_ONE        = 1;
+  public static final int ARITY_ONEORMORE  = 2;
+  private int arity;
+
+
+  public TokenTuple(HeapRegionNode hrn) {
+    assert hrn != null;
+
+    token         = hrn.getID();
+    isMultiObject = !hrn.isSingleObject();
+    arity         = ARITY_ONE;
+    fixStuff();
+  }
+
+  public TokenTuple(Integer token,
+                    boolean isMultiObject,
+                    int arity) {
+    assert token != null;
+
+    this.token         = token;
+    this.isMultiObject = isMultiObject;
+    this.arity         = arity;
+    fixStuff();
+  }
+
+  private void fixStuff() {
+    //This is an evil hack...we should fix this stuff elsewhere...
+    if (!isMultiObject) {
+      arity=ARITY_ONE;
+    } else {
+      if (arity==ARITY_ONEORMORE)
+        arity=ARITY_ZEROORMORE;
     }
+  }
 
-    public TokenTuple( Integer token,
-                      boolean isNewSummary,
-                      int     arity ) {
-       this.token        = token;
-       this.isNewSummary = isNewSummary;
-       this.arity        = arity;
-    }
 
-    public TokenTuple makeCanonical() {
-       return (TokenTuple) Canonical.makeCanonical( this );
-    }
+  public TokenTuple makeCanonical() {
+    return (TokenTuple) Canonical.makeCanonical(this);
+  }
 
-    public Integer getToken() { return token; }
-    public int     getArity() {        return arity; }
 
-    public TokenTuple increaseArity() {
-       if( isNewSummary ) {
-           return (TokenTuple) Canonical.makeCanonical( 
-             new TokenTuple( token, isNewSummary, ARITY_MANY )
-                                                        );
-       }
-       return this;
-    }
+  public Integer getToken() {
+    return token;
+  }
+
+  public boolean isMultiObject() {
+    return isMultiObject;
+  }
+
+  public int getArity() {
+    return arity;
+  }
+
+
+  public TokenTuple unionArity(TokenTuple tt) {
+    assert tt            != null;
+    assert token         == tt.token;
+    assert isMultiObject == tt.isMultiObject;
 
-    public TokenTuple changeTokenTo( Integer tokenToChangeTo ) {
-       assert isNewSummary == false;
+    if( isMultiObject ) {
+      // for multiple objects only zero-or-mores combined are still zero-or-more
+      // when two tokens are present (absence of a token is arity=zero and is
+      // handled outside of this method)
+      if( arity == ARITY_ZEROORMORE && tt.arity == ARITY_ZEROORMORE ) {
+        return new TokenTuple(token, true, ARITY_ZEROORMORE).makeCanonical();
+      } else {
+        return new TokenTuple(token, true, ARITY_ONEORMORE).makeCanonical();
+      }
 
-       return new TokenTuple( tokenToChangeTo,
-                              isNewSummary,
-                              arity ).makeCanonical();
+    } else {
+      // a single object region's token can only have ZEROORMORE or ONE
+      if( arity == ARITY_ZEROORMORE && tt.arity == ARITY_ZEROORMORE ) {
+        return new TokenTuple(token, false, ARITY_ZEROORMORE).makeCanonical();
+      } else {
+        return new TokenTuple(token, false, ARITY_ONE).makeCanonical();
+      }
     }
+  }
 
-    public boolean equals( Object o ) {
-       if( o == null ) {
-           return false;
-       }
 
-       if( !(o instanceof TokenTuple) ) {
-           return false;
-       }
+  public TokenTuple changeTokenTo(Integer tokenToChangeTo) {
+    assert tokenToChangeTo != null;
 
-       TokenTuple tt = (TokenTuple) o;
+    return new TokenTuple(tokenToChangeTo,
+                          isMultiObject,
+                          arity).makeCanonical();
+  }
 
-       return token.equals( tt.getToken() ) &&
-              arity ==      tt.getArity();
+
+  public boolean equals(Object o) {
+    if( o == null ) {
+      return false;
     }
 
-    public int hashCode() {
-       return token.intValue();
+    if( !(o instanceof TokenTuple) ) {
+      return false;
     }
 
-    public String toString() {
-       String s = "";
-       if( isNewSummary ) {
-           s = "S";
-       }
+    TokenTuple tt = (TokenTuple) o;
+
+    return token.equals(tt.getToken() ) &&
+           arity ==     tt.getArity();
+  }
+
+  public int hashCode() {
+    return (token.intValue() << 2) ^ arity;
+  }
+
 
-       String t = "";
-       if( arity == ARITY_MANY ) {
-           t = "*";
-       }
+  public String toString() {
+    String s = token.toString();
 
-       return new String( token+s+t );
+    if( isMultiObject ) {
+      s += "M";
     }
+
+    if( arity == ARITY_ZEROORMORE ) {
+      s += "*";
+    } else if( arity == ARITY_ONEORMORE ) {
+      s += "+";
+    }
+
+    return s;
+  }
 }