1 package Analysis.OwnershipAnalysis;
9 public class TokenTupleSet extends Canonical {
11 private HashSet<TokenTuple> tokenTuples;
14 public TokenTupleSet() {
15 tokenTuples = new HashSet<TokenTuple>();
18 public TokenTupleSet(TokenTuple tt) {
24 public TokenTupleSet(TokenTupleSet tts) {
26 // okay to clone, TokenTuple and TokenTupleSet should be canonical
27 tokenTuples = (HashSet<TokenTuple>)tts.tokenTuples.clone();
31 public TokenTupleSet makeCanonical() {
32 return (TokenTupleSet) Canonical.makeCanonical(this);
35 public Iterator iterator() {
36 return tokenTuples.iterator();
39 public boolean isEmpty() {
40 return tokenTuples.isEmpty();
43 public boolean isSubset(TokenTupleSet ttsIn) {
45 return ttsIn.tokenTuples.containsAll(this.tokenTuples);
48 public boolean containsTuple(TokenTuple tt) {
50 return tokenTuples.contains(tt);
54 public TokenTupleSet union(TokenTupleSet ttsIn) {
56 TokenTupleSet ttsOut = new TokenTupleSet(this);
57 ttsOut.tokenTuples.addAll(ttsIn.tokenTuples);
58 return ttsOut.makeCanonical();
62 public TokenTupleSet unionUpArity(TokenTupleSet ttsIn) {
64 TokenTupleSet ttsOut = new TokenTupleSet();
66 Iterator<TokenTuple> ttItr = this.iterator();
67 while( ttItr.hasNext() ) {
68 TokenTuple ttThis = ttItr.next();
69 TokenTuple ttIn = ttsIn.containsToken( ttThis.getToken() );
72 ttsOut.tokenTuples.add( ttThis.unionArity( ttIn ) );
74 ttsOut.tokenTuples.add( ttThis );
78 ttItr = ttsIn.iterator();
79 while( ttItr.hasNext() ) {
80 TokenTuple ttIn = ttItr.next();
81 TokenTuple ttThis = ttsOut.containsToken( ttIn.getToken() );
83 if( ttThis == null ) {
84 ttsOut.tokenTuples.add( ttIn );
88 return ttsOut.makeCanonical();
92 public TokenTupleSet add(TokenTuple tt) {
94 TokenTupleSet ttsOut = new TokenTupleSet(tt);
95 return ttsOut.union(this);
99 public boolean equals(Object o) {
104 if( !(o instanceof TokenTupleSet) ) {
108 TokenTupleSet tts = (TokenTupleSet) o;
109 return tokenTuples.equals(tts.tokenTuples);
112 public int hashCode() {
113 return tokenTuples.hashCode();
117 // this should be a hash table so we can do this by key
118 public TokenTuple containsToken(Integer token) {
119 assert token != null;
121 Iterator itr = tokenTuples.iterator();
122 while( itr.hasNext() ) {
123 TokenTuple tt = (TokenTuple) itr.next();
124 if( token.equals(tt.getToken() ) ) {
132 public TokenTupleSet ageTokens(AllocationSite as) {
135 TokenTupleSet ttsOut = new TokenTupleSet();
137 TokenTuple ttSummary = null;
138 TokenTuple ttOldest = null;
140 Iterator itrT = this.iterator();
141 while( itrT.hasNext() ) {
142 TokenTuple tt = (TokenTuple) itrT.next();
144 Integer token = tt.getToken();
145 int age = as.getAgeCategory(token);
147 // tokens not associated with
148 // the site should be left alone
149 if( age == AllocationSite.AGE_notInThisSite ) {
150 ttsOut.tokenTuples.add(tt);
152 } else if( age == AllocationSite.AGE_summary ) {
153 // remember the summary tuple, but don't add it
154 // we may combine it with the oldest tuple
157 } else if( age == AllocationSite.AGE_oldest ) {
158 // found an oldest token, again just remember
163 assert age == AllocationSite.AGE_in_I;
165 Integer I = as.getAge(token);
168 // otherwise, we change this token to the
170 Integer tokenToChangeTo = as.getIthOldest(I + 1);
171 TokenTuple ttAged = tt.changeTokenTo(tokenToChangeTo);
172 ttsOut.tokenTuples.add(ttAged);
176 // there are four cases to consider here
177 // 1. we found a summary tuple and no oldest tuple
178 // Here we just pass the summary unchanged
179 // 2. we found an oldest tuple, no summary
180 // Make a new, arity-one summary tuple
181 // 3. we found both a summary and an oldest
182 // Merge them by arity
183 // 4. (not handled) we found neither, do nothing
184 if ( ttSummary != null && ttOldest == null ) {
185 ttsOut.tokenTuples.add(ttSummary);
187 } else if( ttSummary == null && ttOldest != null ) {
188 ttsOut.tokenTuples.add(new TokenTuple(as.getSummary(),
194 } else if( ttSummary != null && ttOldest != null ) {
195 ttsOut.tokenTuples.add(ttSummary.unionArity(new TokenTuple(as.getSummary(),
203 return ttsOut.makeCanonical();
207 public TokenTupleSet unshadowTokens(AllocationSite as) {
210 TokenTupleSet ttsOut = new TokenTupleSet();
212 TokenTuple ttSummary = null;
213 TokenTuple ttShadowSummary = null;
215 Iterator itrT = this.iterator();
216 while( itrT.hasNext() ) {
217 TokenTuple tt = (TokenTuple) itrT.next();
219 Integer token = tt.getToken();
220 int shadowAge = as.getShadowAgeCategory(token);
222 if( shadowAge == AllocationSite.AGE_summary ) {
223 // remember the summary tuple, but don't add it
224 // we may combine it with the oldest tuple
227 } else if( shadowAge == AllocationSite.SHADOWAGE_notInThisSite ) {
228 ttsOut.tokenTuples.add(tt);
230 } else if( shadowAge == AllocationSite.SHADOWAGE_summary ) {
231 // found the shadow summary token, again just remember
233 ttShadowSummary = tt;
235 } else if( shadowAge == AllocationSite.SHADOWAGE_oldest ) {
236 Integer tokenToChangeTo = as.getOldest();
237 TokenTuple ttNormal = tt.changeTokenTo(tokenToChangeTo);
238 ttsOut.tokenTuples.add(ttNormal);
241 assert shadowAge == AllocationSite.SHADOWAGE_in_I;
243 Integer I = as.getShadowAge(token);
246 Integer tokenToChangeTo = as.getIthOldest(-I);
247 TokenTuple ttNormal = tt.changeTokenTo(tokenToChangeTo);
248 ttsOut.tokenTuples.add(ttNormal);
252 if ( ttSummary != null && ttShadowSummary == null ) {
253 ttsOut.tokenTuples.add(ttSummary);
255 } else if( ttSummary == null && ttShadowSummary != null ) {
256 ttsOut.tokenTuples.add( new TokenTuple(as.getSummary(),
258 ttShadowSummary.getArity()
262 } else if( ttSummary != null && ttShadowSummary != null ) {
263 ttsOut.tokenTuples.add(ttSummary.unionArity( new TokenTuple(as.getSummary(),
265 ttShadowSummary.getArity()
271 return ttsOut.makeCanonical();
275 public TokenTupleSet toShadowTokens(AllocationSite as) {
278 TokenTupleSet ttsOut = new TokenTupleSet().makeCanonical();
280 Iterator itrT = this.iterator();
281 while( itrT.hasNext() ) {
282 TokenTuple tt = (TokenTuple) itrT.next();
284 Integer token = tt.getToken();
285 int age = as.getAgeCategory(token);
287 // summary tokens and tokens not associated with
288 // the site should be left alone
289 if( age == AllocationSite.AGE_notInThisSite ) {
290 ttsOut.tokenTuples.add(tt);
292 } else if( age == AllocationSite.AGE_summary ) {
293 ttsOut.tokenTuples.add(tt.changeTokenTo(as.getSummaryShadow() ));
295 } else if( age == AllocationSite.AGE_oldest ) {
296 ttsOut.tokenTuples.add(tt.changeTokenTo(as.getOldestShadow() ));
299 assert age == AllocationSite.AGE_in_I;
301 Integer I = as.getAge(token);
304 ttsOut.tokenTuples.add(tt.changeTokenTo(as.getIthOldestShadow(I) ));
308 return ttsOut.makeCanonical();
312 public ReachabilitySet rewriteToken(TokenTuple tokenToRewrite,
313 ReachabilitySet replacements,
314 boolean makeChangeSet,
315 Hashtable<TokenTupleSet, HashSet<TokenTupleSet> > forChangeSet) {
317 ReachabilitySet rsOut = new ReachabilitySet().makeCanonical();
319 if( !tokenTuples.contains(tokenToRewrite) ) {
320 rsOut = rsOut.add(this);
323 TokenTupleSet ttsMinusToken = new TokenTupleSet(this);
324 ttsMinusToken.tokenTuples.remove(tokenToRewrite);
326 Iterator<TokenTupleSet> replaceItr = replacements.iterator();
327 while( replaceItr.hasNext() ) {
328 TokenTupleSet replacement = replaceItr.next();
329 TokenTupleSet replaced = new TokenTupleSet(ttsMinusToken);
330 replaced = replaced.unionUpArity(replacement);
331 rsOut = rsOut.add(replaced);
333 if( makeChangeSet ) {
334 assert forChangeSet != null;
336 if( forChangeSet.get(this) == null ) {
337 forChangeSet.put(this, new HashSet<TokenTupleSet>() );
340 forChangeSet.get(this).add(replaced);
345 return rsOut.makeCanonical();
349 public TokenTupleSet makeArityZeroOrMore() {
350 TokenTupleSet ttsOut = new TokenTupleSet().makeCanonical();
352 Iterator<TokenTuple> itrThis = this.iterator();
353 while( itrThis.hasNext() ) {
354 TokenTuple tt = itrThis.next();
356 ttsOut.tokenTuples.add( new TokenTuple( tt.getToken(),
358 TokenTuple.ARITY_ZEROORMORE
363 return ttsOut.makeCanonical();
367 public String toString() {
368 return tokenTuples.toString();