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);
53 public boolean containsBoth(TokenTuple tt1, TokenTuple tt2) {
54 return containsTuple(tt1) && containsTuple(tt2);
57 public boolean containsWithZeroes(TokenTupleSet tts) {
60 // first establish that every token tuple from tts is
62 Iterator<TokenTuple> ttItrIn = tts.iterator();
63 while( ttItrIn.hasNext() ) {
64 TokenTuple ttIn = ttItrIn.next();
65 TokenTuple ttThis = this.containsToken(ttIn.getToken() );
67 if( ttThis == null ) {
72 // then establish that anything in this set that is
73 // not in tts is a zero-arity token tuple, which is okay
74 Iterator<TokenTuple> ttItrThis = this.iterator();
75 while( ttItrThis.hasNext() ) {
76 TokenTuple ttThis = ttItrThis.next();
77 TokenTuple ttIn = tts.containsToken(ttThis.getToken() );
80 ttThis.getArity() != TokenTuple.ARITY_ZEROORMORE ) {
85 // if so this set contains tts with zeroes
89 public TokenTupleSet union(TokenTuple ttIn) {
91 TokenTupleSet ttsOut = new TokenTupleSet(this);
92 ttsOut.tokenTuples.add(ttIn);
93 return ttsOut.makeCanonical();
96 public TokenTupleSet union(TokenTupleSet ttsIn) {
98 TokenTupleSet ttsOut = new TokenTupleSet(this);
99 ttsOut.tokenTuples.addAll(ttsIn.tokenTuples);
100 return ttsOut.makeCanonical();
104 public TokenTupleSet unionUpArity(TokenTupleSet ttsIn) {
105 assert ttsIn != null;
106 TokenTupleSet ttsOut = new TokenTupleSet();
108 Iterator<TokenTuple> ttItr = this.iterator();
109 while( ttItr.hasNext() ) {
110 TokenTuple ttThis = ttItr.next();
111 TokenTuple ttIn = ttsIn.containsToken(ttThis.getToken() );
114 ttsOut.tokenTuples.add(ttThis.unionArity(ttIn) );
116 ttsOut.tokenTuples.add(ttThis);
120 ttItr = ttsIn.iterator();
121 while( ttItr.hasNext() ) {
122 TokenTuple ttIn = ttItr.next();
123 TokenTuple ttThis = ttsOut.containsToken(ttIn.getToken() );
125 if( ttThis == null ) {
126 ttsOut.tokenTuples.add(ttIn);
130 return ttsOut.makeCanonical();
134 public TokenTupleSet add(TokenTuple tt) {
136 TokenTupleSet ttsOut = new TokenTupleSet(tt);
137 return ttsOut.union(this);
141 public TokenTupleSet remove(TokenTuple tt) {
143 TokenTupleSet ttsOut = new TokenTupleSet(this);
144 ttsOut.tokenTuples.remove(tt);
145 return ttsOut.makeCanonical();
149 public boolean equals(Object o) {
154 if( !(o instanceof TokenTupleSet) ) {
158 TokenTupleSet tts = (TokenTupleSet) o;
159 return tokenTuples.equals(tts.tokenTuples);
164 private boolean oldHashSet = false;
165 private int oldHash = 0;
166 public int hashCode() {
167 int currentHash = tokenTuples.hashCode();
169 if( oldHashSet == false ) {
170 oldHash = currentHash;
173 if( oldHash != currentHash ) {
174 System.out.println("IF YOU SEE THIS A CANONICAL TokenTupleSet CHANGED");
184 // this should be a hash table so we can do this by key
185 public TokenTuple containsToken(Integer token) {
186 assert token != null;
188 Iterator itr = tokenTuples.iterator();
189 while( itr.hasNext() ) {
190 TokenTuple tt = (TokenTuple) itr.next();
191 if( token.equals(tt.getToken() ) ) {
199 public TokenTupleSet ageTokens(AllocationSite as) {
202 TokenTupleSet ttsOut = new TokenTupleSet();
204 TokenTuple ttSummary = null;
205 TokenTuple ttOldest = null;
207 Iterator itrT = this.iterator();
208 while( itrT.hasNext() ) {
209 TokenTuple tt = (TokenTuple) itrT.next();
211 Integer token = tt.getToken();
212 int age = as.getAgeCategory(token);
214 // tokens not associated with
215 // the site should be left alone
216 if( age == AllocationSite.AGE_notInThisSite ) {
217 ttsOut.tokenTuples.add(tt);
219 } else if( age == AllocationSite.AGE_summary ) {
220 // remember the summary tuple, but don't add it
221 // we may combine it with the oldest tuple
224 } else if( age == AllocationSite.AGE_oldest ) {
225 // found an oldest token, again just remember
230 assert age == AllocationSite.AGE_in_I;
232 Integer I = as.getAge(token);
235 // otherwise, we change this token to the
237 Integer tokenToChangeTo = as.getIthOldest(I + 1);
238 TokenTuple ttAged = tt.changeTokenTo(tokenToChangeTo);
239 ttsOut.tokenTuples.add(ttAged);
243 // there are four cases to consider here
244 // 1. we found a summary tuple and no oldest tuple
245 // Here we just pass the summary unchanged
246 // 2. we found an oldest tuple, no summary
247 // Make a new, arity-one summary tuple
248 // 3. we found both a summary and an oldest
249 // Merge them by arity
250 // 4. (not handled) we found neither, do nothing
251 if ( ttSummary != null && ttOldest == null ) {
252 ttsOut.tokenTuples.add(ttSummary);
254 } else if( ttSummary == null && ttOldest != null ) {
255 ttsOut.tokenTuples.add(new TokenTuple(as.getSummary(),
261 } else if( ttSummary != null && ttOldest != null ) {
262 ttsOut.tokenTuples.add(ttSummary.unionArity(new TokenTuple(as.getSummary(),
270 return ttsOut.makeCanonical();
274 public TokenTupleSet unshadowTokens(AllocationSite as) {
277 TokenTupleSet ttsOut = new TokenTupleSet();
279 TokenTuple ttSummary = null;
280 TokenTuple ttShadowSummary = null;
282 Iterator itrT = this.iterator();
283 while( itrT.hasNext() ) {
284 TokenTuple tt = (TokenTuple) itrT.next();
286 Integer token = tt.getToken();
287 int shadowAge = as.getShadowAgeCategory(token);
289 if( shadowAge == AllocationSite.AGE_summary ) {
290 // remember the summary tuple, but don't add it
291 // we may combine it with the oldest tuple
294 } else if( shadowAge == AllocationSite.SHADOWAGE_notInThisSite ) {
295 ttsOut.tokenTuples.add(tt);
297 } else if( shadowAge == AllocationSite.SHADOWAGE_summary ) {
298 // found the shadow summary token, again just remember
300 ttShadowSummary = tt;
302 } else if( shadowAge == AllocationSite.SHADOWAGE_oldest ) {
303 Integer tokenToChangeTo = as.getOldest();
304 TokenTuple ttNormal = tt.changeTokenTo(tokenToChangeTo);
305 ttsOut.tokenTuples.add(ttNormal);
308 assert shadowAge == AllocationSite.SHADOWAGE_in_I;
310 Integer I = as.getShadowAge(token);
313 Integer tokenToChangeTo = as.getIthOldest(-I);
314 TokenTuple ttNormal = tt.changeTokenTo(tokenToChangeTo);
315 ttsOut.tokenTuples.add(ttNormal);
319 if ( ttSummary != null && ttShadowSummary == null ) {
320 ttsOut.tokenTuples.add(ttSummary);
322 } else if( ttSummary == null && ttShadowSummary != null ) {
323 ttsOut.tokenTuples.add(new TokenTuple(as.getSummary(),
325 ttShadowSummary.getArity()
329 } else if( ttSummary != null && ttShadowSummary != null ) {
330 ttsOut.tokenTuples.add(ttSummary.unionArity(new TokenTuple(as.getSummary(),
332 ttShadowSummary.getArity()
338 return ttsOut.makeCanonical();
342 public TokenTupleSet toShadowTokens(AllocationSite as) {
345 TokenTupleSet ttsOut = new TokenTupleSet().makeCanonical();
347 Iterator itrT = this.iterator();
348 while( itrT.hasNext() ) {
349 TokenTuple tt = (TokenTuple) itrT.next();
351 Integer token = tt.getToken();
352 int age = as.getAgeCategory(token);
354 // summary tokens and tokens not associated with
355 // the site should be left alone
356 if( age == AllocationSite.AGE_notInThisSite ) {
357 ttsOut = ttsOut.union(tt);
359 } else if( age == AllocationSite.AGE_summary ) {
360 ttsOut = ttsOut.union(tt.changeTokenTo(as.getSummaryShadow() ));
362 } else if( age == AllocationSite.AGE_oldest ) {
363 ttsOut = ttsOut.union(tt.changeTokenTo(as.getOldestShadow() ));
366 assert age == AllocationSite.AGE_in_I;
368 Integer I = as.getAge(token);
371 ttsOut = ttsOut.union(tt.changeTokenTo(as.getIthOldestShadow(I) ));
375 return ttsOut.makeCanonical();
379 public ReachabilitySet rewriteToken(TokenTuple tokenToRewrite,
380 ReachabilitySet replacements,
381 boolean makeChangeSet,
382 Hashtable<TokenTupleSet, HashSet<TokenTupleSet> > forChangeSet) {
384 ReachabilitySet rsOut = new ReachabilitySet().makeCanonical();
386 if( !tokenTuples.contains(tokenToRewrite) ) {
387 rsOut = rsOut.add(this);
390 TokenTupleSet ttsMinusToken = new TokenTupleSet(this);
391 ttsMinusToken.tokenTuples.remove(tokenToRewrite);
393 Iterator<TokenTupleSet> replaceItr = replacements.iterator();
394 while( replaceItr.hasNext() ) {
395 TokenTupleSet replacement = replaceItr.next();
396 TokenTupleSet replaced = new TokenTupleSet(ttsMinusToken).makeCanonical();
397 replaced = replaced.unionUpArity(replacement);
398 rsOut = rsOut.add(replaced);
400 if( makeChangeSet ) {
401 assert forChangeSet != null;
403 if( forChangeSet.get(this) == null ) {
404 forChangeSet.put(this, new HashSet<TokenTupleSet>() );
407 forChangeSet.get(this).add(replaced);
412 return rsOut.makeCanonical();
416 public TokenTupleSet makeArityZeroOrMore() {
417 TokenTupleSet ttsOut = new TokenTupleSet().makeCanonical();
419 Iterator<TokenTuple> itrThis = this.iterator();
420 while( itrThis.hasNext() ) {
421 TokenTuple tt = itrThis.next();
423 ttsOut = ttsOut.union(new TokenTuple(tt.getToken(),
425 TokenTuple.ARITY_ZEROORMORE
430 return ttsOut.makeCanonical();
433 public String toString() {
434 return tokenTuples.toString();