1 package Analysis.OwnershipAnalysis;
9 public class ReachabilitySet extends Canonical {
11 private HashSet<TokenTupleSet> possibleReachabilities;
13 public ReachabilitySet() {
14 possibleReachabilities = new HashSet<TokenTupleSet>();
17 public ReachabilitySet(TokenTupleSet tts) {
20 possibleReachabilities.add(tts);
23 public ReachabilitySet(TokenTuple tt) {
24 // can't assert before calling this(), it will
25 // do the checking though
26 this( new TokenTupleSet(tt).makeCanonical() );
29 public ReachabilitySet(HashSet<TokenTupleSet> possibleReachabilities) {
30 assert possibleReachabilities != null;
31 this.possibleReachabilities = possibleReachabilities;
34 public ReachabilitySet(ReachabilitySet rs) {
36 // okay to clone, ReachabilitySet should be canonical
37 possibleReachabilities = (HashSet<TokenTupleSet>)rs.possibleReachabilities.clone();
41 public ReachabilitySet makeCanonical() {
42 return (ReachabilitySet) Canonical.makeCanonical(this);
45 public Iterator<TokenTupleSet> iterator() {
46 return possibleReachabilities.iterator();
51 return possibleReachabilities.size();
54 public boolean isEmpty() {
55 return possibleReachabilities.isEmpty();
58 public boolean contains(TokenTupleSet tts) {
60 return possibleReachabilities.contains(tts);
63 public boolean containsWithZeroes(TokenTupleSet tts) {
66 if( possibleReachabilities.contains(tts) ) {
70 Iterator itr = iterator();
71 while( itr.hasNext() ) {
72 TokenTupleSet ttsThis = (TokenTupleSet) itr.next();
73 if( ttsThis.containsWithZeroes(tts) ) {
81 public boolean containsSuperSet(TokenTupleSet tts) {
84 if( possibleReachabilities.contains(tts) ) {
88 Iterator itr = iterator();
89 while( itr.hasNext() ) {
90 TokenTupleSet ttsThis = (TokenTupleSet) itr.next();
91 if( tts.isSubset(ttsThis) ) {
100 public boolean containsTuple(TokenTuple tt) {
101 Iterator itr = iterator();
102 while( itr.hasNext() ) {
103 TokenTupleSet tts = (TokenTupleSet) itr.next();
104 if( tts.containsTuple(tt) ) {
111 public boolean containsTupleSetWithBoth(TokenTuple tt1, TokenTuple tt2) {
112 Iterator itr = iterator();
113 while( itr.hasNext() ) {
114 TokenTupleSet tts = (TokenTupleSet) itr.next();
115 if( tts.containsTuple(tt1) && tts.containsTuple(tt2) ) {
122 public ReachabilitySet union(ReachabilitySet rsIn) {
125 ReachabilitySet rsOut = new ReachabilitySet(this);
126 rsOut.possibleReachabilities.addAll(rsIn.possibleReachabilities);
127 return rsOut.makeCanonical();
130 public ReachabilitySet union(TokenTupleSet ttsIn) {
131 assert ttsIn != null;
133 ReachabilitySet rsOut = new ReachabilitySet(this);
134 rsOut.possibleReachabilities.add(ttsIn);
135 return rsOut.makeCanonical();
138 public ReachabilitySet intersection(ReachabilitySet rsIn) {
141 ReachabilitySet rsOut = new ReachabilitySet();
143 Iterator i = this.iterator();
144 while( i.hasNext() ) {
145 TokenTupleSet tts = (TokenTupleSet) i.next();
146 if( rsIn.possibleReachabilities.contains(tts) ) {
147 rsOut.possibleReachabilities.add(tts);
151 return rsOut.makeCanonical();
155 public ReachabilitySet add(TokenTupleSet tts) {
157 ReachabilitySet rsOut = new ReachabilitySet(tts);
158 return rsOut.union(this);
162 public ChangeTupleSet unionUpArityToChangeSet(ReachabilitySet rsIn) {
165 ChangeTupleSet ctsOut = new ChangeTupleSet();
167 Iterator itrO = this.iterator();
168 while( itrO.hasNext() ) {
169 TokenTupleSet o = (TokenTupleSet) itrO.next();
171 Iterator itrR = rsIn.iterator();
172 while( itrR.hasNext() ) {
173 TokenTupleSet r = (TokenTupleSet) itrR.next();
175 TokenTupleSet theUnion = new TokenTupleSet().makeCanonical();
177 Iterator itrRelement = r.iterator();
178 while( itrRelement.hasNext() ) {
179 TokenTuple ttR = (TokenTuple) itrRelement.next();
180 TokenTuple ttO = o.containsToken(ttR.getToken() );
183 theUnion = theUnion.union(new TokenTupleSet(ttR.unionArity(ttO) ) ).makeCanonical();
185 theUnion = theUnion.union(new TokenTupleSet(ttR) ).makeCanonical();
189 Iterator itrOelement = o.iterator();
190 while( itrOelement.hasNext() ) {
191 TokenTuple ttO = (TokenTuple) itrOelement.next();
192 TokenTuple ttR = theUnion.containsToken(ttO.getToken() );
195 theUnion = theUnion.union(new TokenTupleSet(ttO) ).makeCanonical();
199 if( !theUnion.isEmpty() ) {
200 ctsOut = ctsOut.union(new ChangeTupleSet(new ChangeTuple(o, theUnion) ) );
205 return ctsOut.makeCanonical();
209 public ReachabilitySet ageTokens(AllocationSite as) {
212 ReachabilitySet rsOut = new ReachabilitySet();
214 Iterator itrS = this.iterator();
215 while( itrS.hasNext() ) {
216 TokenTupleSet tts = (TokenTupleSet) itrS.next();
217 rsOut.possibleReachabilities.add(tts.ageTokens(as) );
220 return rsOut.makeCanonical();
224 public ReachabilitySet unshadowTokens(AllocationSite as) {
227 ReachabilitySet rsOut = new ReachabilitySet();
229 Iterator itrS = this.iterator();
230 while( itrS.hasNext() ) {
231 TokenTupleSet tts = (TokenTupleSet) itrS.next();
232 rsOut.possibleReachabilities.add(tts.unshadowTokens(as) );
235 return rsOut.makeCanonical();
239 public ReachabilitySet toShadowTokens(AllocationSite as) {
242 ReachabilitySet rsOut = new ReachabilitySet();
244 Iterator itrS = this.iterator();
245 while( itrS.hasNext() ) {
246 TokenTupleSet tts = (TokenTupleSet) itrS.next();
247 rsOut.possibleReachabilities.add(tts.toShadowTokens(as) );
250 return rsOut.makeCanonical();
254 public ReachabilitySet pruneBy(ReachabilitySet rsIn) {
257 ReachabilitySet rsOut = new ReachabilitySet();
259 Iterator itrB = this.iterator();
260 while( itrB.hasNext() ) {
261 TokenTupleSet ttsB = (TokenTupleSet) itrB.next();
263 boolean subsetExists = false;
265 Iterator itrA = rsIn.iterator();
266 while( itrA.hasNext() && !subsetExists ) {
267 TokenTupleSet ttsA = (TokenTupleSet) itrA.next();
269 if( ttsA.isSubset(ttsB) ) {
275 rsOut.possibleReachabilities.add(ttsB);
279 return rsOut.makeCanonical();
283 public ReachabilitySet exhaustiveArityCombinations() {
284 ReachabilitySet rsOut = new ReachabilitySet();
286 int numDimensions = this.possibleReachabilities.size();
288 if( numDimensions > 1 ) {
289 // for problems that are too big, punt and use less
290 // precise arity for reachability information
291 TokenTupleSet ttsImprecise = new TokenTupleSet().makeCanonical();
293 Iterator<TokenTupleSet> itrThis = this.iterator();
294 while( itrThis.hasNext() ) {
295 TokenTupleSet ttsUnit = itrThis.next();
296 ttsImprecise = ttsImprecise.unionUpArity(ttsUnit.makeArityZeroOrMore() );
299 //rsOut = this.union( ttsImprecise );
300 rsOut = rsOut.union(ttsImprecise);
304 // add an extra digit to detect termination
305 int[] digits = new int[numDimensions+1];
310 // start with the minimum possible coordinate
311 for( int i = 0; i < numDimensions+1; ++i ) {
312 digits[i] = minArity;
315 // and stop when the highest-ordered axis rolls above the minimum
316 while( digits[numDimensions] == minArity ) {
318 // spit out a "coordinate" made from these digits
319 TokenTupleSet ttsCoordinate = new TokenTupleSet().makeCanonical();
320 Iterator<TokenTupleSet> ttsItr = this.iterator();
321 for( int i = 0; i < numDimensions; ++i ) {
322 assert ttsItr.hasNext();
323 TokenTupleSet ttsUnit = ttsItr.next();
324 for( int j = 0; j < digits[i]; ++j ) {
325 ttsCoordinate = ttsCoordinate.unionUpArity(ttsUnit);
328 rsOut = rsOut.add(ttsCoordinate.makeCanonical() );
331 for( int i = 0; i < numDimensions+1; ++i ) {
334 if( digits[i] > maxArity ) {
335 // this axis reached its max, so roll it back to min and increment next higher digit
336 digits[i] = minArity;
339 // this axis did not reach its max so we just enumerated a new unique coordinate, stop
345 return rsOut.makeCanonical();
349 public boolean equals(Object o) {
354 if( !(o instanceof ReachabilitySet) ) {
358 ReachabilitySet rs = (ReachabilitySet) o;
359 return possibleReachabilities.equals(rs.possibleReachabilities);
363 private boolean oldHashSet = false;
364 private int oldHash = 0;
365 public int hashCode() {
366 int currentHash = possibleReachabilities.hashCode();
368 if( oldHashSet == false ) {
369 oldHash = currentHash;
372 if( oldHash != currentHash ) {
373 System.out.println("IF YOU SEE THIS A CANONICAL ReachabilitySet CHANGED");
383 public String toStringEscapeNewline() {
386 Iterator i = this.iterator();
387 while( i.hasNext() ) {
398 public String toString() {
401 Iterator i = this.iterator();
402 while( i.hasNext() ) {