add profile codes for multicore version
[IRC.git] / Robust / src / Analysis / OwnershipAnalysis / TokenTuple.java
1 package Analysis.OwnershipAnalysis;
2
3 import IR.*;
4 import IR.Flat.*;
5 import java.util.*;
6 import java.io.*;
7
8
9 // a token touple is a pair that indicates a
10 // heap region node and an arity
11
12 // THIS CLASS IS IMMUTABLE!
13
14 public class TokenTuple extends Canonical {
15
16   private Integer token;
17   private boolean isMultiObject;
18
19   public static final int ARITY_ZEROORMORE = 0;
20   public static final int ARITY_ONE        = 1;
21   public static final int ARITY_ONEORMORE  = 2;
22   private int arity;
23
24
25   public TokenTuple(HeapRegionNode hrn) {
26     assert hrn != null;
27
28     token         = hrn.getID();
29     isMultiObject = !hrn.isSingleObject();
30     arity         = ARITY_ONE;
31   }
32
33   public TokenTuple(Integer token,
34                     boolean isMultiObject,
35                     int arity) {
36     assert token != null;
37
38     this.token         = token;
39     this.isMultiObject = isMultiObject;
40     this.arity         = arity;
41   }
42
43
44   public TokenTuple makeCanonical() {
45     return (TokenTuple) Canonical.makeCanonical(this);
46   }
47
48
49   public Integer getToken() {
50     return token;
51   }
52
53   public boolean isMultiObject() {
54     return isMultiObject;
55   }
56
57   public int getArity() {
58     return arity;
59   }
60
61
62   public TokenTuple unionArity(TokenTuple tt) {
63     assert tt            != null;
64     assert token         == tt.token;
65     assert isMultiObject == tt.isMultiObject;
66
67     if( isMultiObject ) {
68       // for multiple objects only zero-or-mores combined are still zero-or-more
69       // when two tokens are present (absence of a token is arity=zero and is
70       // handled outside of this method)
71       if( arity == ARITY_ZEROORMORE && tt.arity == ARITY_ZEROORMORE ) {
72         return new TokenTuple(token, true, ARITY_ZEROORMORE).makeCanonical();
73       } else {
74         return new TokenTuple(token, true, ARITY_ONEORMORE).makeCanonical();
75       }
76
77     } else {
78       // a single object region's token can only have ZEROORMORE or ONE
79       if( arity == ARITY_ZEROORMORE && tt.arity == ARITY_ZEROORMORE ) {
80         return new TokenTuple(token, false, ARITY_ZEROORMORE).makeCanonical();
81       } else {
82         return new TokenTuple(token, false, ARITY_ONE).makeCanonical();
83       }
84     }
85   }
86
87
88   public TokenTuple changeTokenTo(Integer tokenToChangeTo) {
89     assert tokenToChangeTo != null;
90
91     return new TokenTuple(tokenToChangeTo,
92                           isMultiObject,
93                           arity).makeCanonical();
94   }
95
96
97   public boolean equals(Object o) {
98     if( o == null ) {
99       return false;
100     }
101
102     if( !(o instanceof TokenTuple) ) {
103       return false;
104     }
105
106     TokenTuple tt = (TokenTuple) o;
107
108     return token.equals(tt.getToken() ) &&
109            arity ==     tt.getArity();
110   }
111
112   private boolean oldHashSet = false;
113   private int oldHash    = 0;
114   public int hashCode() {
115     int currentHash = token.intValue()*31 + arity;
116
117     if( oldHashSet == false ) {
118       oldHash = currentHash;
119       oldHashSet = true;
120     } else {
121       if( oldHash != currentHash ) {
122         System.out.println("IF YOU SEE THIS A CANONICAL TokenTuple CHANGED");
123         Integer x = null;
124         x.toString();
125       }
126     }
127
128     return currentHash;
129   }
130
131
132   public String toString() {
133     String s = token.toString();
134
135     if( isMultiObject ) {
136       s += "M";
137     }
138
139     if( arity == ARITY_ZEROORMORE ) {
140       s += "*";
141     } else if( arity == ARITY_ONEORMORE ) {
142       s += "+";
143     }
144
145     return s;
146   }
147 }