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();
50 public boolean contains(TokenTupleSet tts) {
52 return possibleReachabilities.contains(tts);
55 public boolean containsTuple(TokenTuple tt) {
56 Iterator itr = iterator();
57 while( itr.hasNext() ) {
58 TokenTupleSet tts = (TokenTupleSet) itr.next();
59 if( tts.containsTuple(tt) ) {
66 public boolean containsTupleSetWithBoth(TokenTuple tt1, TokenTuple tt2) {
67 Iterator itr = iterator();
68 while( itr.hasNext() ) {
69 TokenTupleSet tts = (TokenTupleSet) itr.next();
70 if( tts.containsTuple(tt1) && tts.containsTuple(tt2) ) {
77 public ReachabilitySet increaseArity(Integer token) {
80 HashSet<TokenTupleSet> possibleReachabilitiesNew = new HashSet<TokenTupleSet>();
82 Iterator itr = iterator();
83 while( itr.hasNext() ) {
84 TokenTupleSet tts = (TokenTupleSet) itr.next();
85 possibleReachabilitiesNew.add(tts.increaseArity(token) );
88 return new ReachabilitySet(possibleReachabilitiesNew).makeCanonical();
92 public ReachabilitySet union(ReachabilitySet rsIn) {
95 ReachabilitySet rsOut = new ReachabilitySet(this);
96 rsOut.possibleReachabilities.addAll(rsIn.possibleReachabilities);
97 return rsOut.makeCanonical();
100 public ReachabilitySet union(TokenTupleSet ttsIn) {
101 assert ttsIn != null;
103 ReachabilitySet rsOut = new ReachabilitySet(this);
104 rsOut.possibleReachabilities.add(ttsIn);
105 return rsOut.makeCanonical();
108 public ReachabilitySet intersection(ReachabilitySet rsIn) {
111 ReachabilitySet rsOut = new ReachabilitySet();
113 Iterator i = this.iterator();
114 while( i.hasNext() ) {
115 TokenTupleSet tts = (TokenTupleSet) i.next();
116 if( rsIn.possibleReachabilities.contains(tts) ) {
117 rsOut.possibleReachabilities.add(tts);
121 return rsOut.makeCanonical();
125 public ReachabilitySet add(TokenTupleSet tts) {
127 ReachabilitySet rsOut = new ReachabilitySet(tts);
128 return rsOut.union(this);
132 public ChangeTupleSet unionUpArityToChangeSet(ReachabilitySet rsIn) {
135 ChangeTupleSet ctsOut = new ChangeTupleSet();
137 Iterator itrO = this.iterator();
138 while( itrO.hasNext() ) {
139 TokenTupleSet o = (TokenTupleSet) itrO.next();
141 Iterator itrR = rsIn.iterator();
142 while( itrR.hasNext() ) {
143 TokenTupleSet r = (TokenTupleSet) itrR.next();
145 TokenTupleSet theUnion = new TokenTupleSet();
147 Iterator itrRelement = r.iterator();
148 while( itrRelement.hasNext() ) {
149 TokenTuple e = (TokenTuple) itrRelement.next();
151 if( o.containsToken(e.getToken() ) ) {
152 theUnion = theUnion.union(new TokenTupleSet(e.increaseArity() ) ).makeCanonical();
154 theUnion = theUnion.union(new TokenTupleSet(e) ).makeCanonical();
158 Iterator itrOelement = o.iterator();
159 while( itrOelement.hasNext() ) {
160 TokenTuple e = (TokenTuple) itrOelement.next();
162 if( !theUnion.containsToken(e.getToken() ) ) {
163 theUnion = theUnion.union(new TokenTupleSet(e) ).makeCanonical();
167 if( !theUnion.isEmpty() ) {
168 ctsOut = ctsOut.union(
169 new ChangeTupleSet(new ChangeTuple(o, theUnion) )
175 return ctsOut.makeCanonical();
179 public ReachabilitySet ageTokens(AllocationSite as) {
182 ReachabilitySet rsOut = new ReachabilitySet();
184 Iterator itrS = this.iterator();
185 while( itrS.hasNext() ) {
186 TokenTupleSet tts = (TokenTupleSet) itrS.next();
187 rsOut.possibleReachabilities.add(tts.ageTokens(as) );
190 return rsOut.makeCanonical();
194 public ReachabilitySet unshadowTokens(AllocationSite as) {
197 ReachabilitySet rsOut = new ReachabilitySet();
199 Iterator itrS = this.iterator();
200 while( itrS.hasNext() ) {
201 TokenTupleSet tts = (TokenTupleSet) itrS.next();
202 rsOut.possibleReachabilities.add(tts.unshadowTokens(as) );
205 return rsOut.makeCanonical();
209 public ReachabilitySet toShadowTokens(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.toShadowTokens(as) );
220 return rsOut.makeCanonical();
224 public ReachabilitySet pruneBy(ReachabilitySet rsIn) {
227 ReachabilitySet rsOut = new ReachabilitySet();
229 Iterator itrB = this.iterator();
230 while( itrB.hasNext() ) {
231 TokenTupleSet ttsB = (TokenTupleSet) itrB.next();
233 boolean subsetExists = false;
235 Iterator itrA = rsIn.iterator();
236 while( itrA.hasNext() && !subsetExists ) {
237 TokenTupleSet ttsA = (TokenTupleSet) itrA.next();
239 if( ttsA.isSubset(ttsB) ) {
245 rsOut.possibleReachabilities.add(ttsB);
249 return rsOut.makeCanonical();
253 public ReachabilitySet exhaustiveArityCombinations() {
254 ReachabilitySet rsOut = new ReachabilitySet();
256 int numDimensions = this.possibleReachabilities.size();
258 if( numDimensions > 10 ) {
259 System.out.println( "exhaustiveArityCombinations numDimensions = "+numDimensions );
262 // add an extra digit to detect termination
263 int[] digits = new int[numDimensions+1];
268 // start with the minimum possible coordinate
269 for( int i = 0; i < numDimensions+1; ++i ) {
270 digits[i] = minArity;
273 // and stop when the highest-ordered axis rolls above the minimum
274 while( digits[numDimensions] == minArity ) {
276 // spit out a "coordinate" made from these digits
277 TokenTupleSet ttsCoordinate = new TokenTupleSet();
278 Iterator<TokenTupleSet> ttsItr = this.iterator();
279 for( int i = 0; i < numDimensions; ++i ) {
280 assert ttsItr.hasNext();
281 TokenTupleSet ttsUnit = ttsItr.next();
282 for( int j = 0; j < digits[i]; ++j ) {
283 ttsCoordinate = ttsCoordinate.unionUpArity(ttsUnit);
286 rsOut = rsOut.add(ttsCoordinate.makeCanonical() );
289 for( int i = 0; i < numDimensions+1; ++i ) {
294 System.out.print( "x " );
298 System.out.print( "@ " );
302 System.out.print( "# " );
305 if( digits[i] > maxArity ) {
306 // this axis reached its max, so roll it back to min and increment next higher digit
307 digits[i] = minArity;
310 // this axis did not reach its max so we just enumerated a new unique coordinate, stop
316 return rsOut.makeCanonical();
320 public boolean equals(Object o) {
325 if( !(o instanceof ReachabilitySet) ) {
329 ReachabilitySet rs = (ReachabilitySet) o;
330 return possibleReachabilities.equals(rs.possibleReachabilities);
333 public int hashCode() {
334 return possibleReachabilities.hashCode();
338 public String toStringEscapeNewline() {
341 Iterator i = this.iterator();
342 while( i.hasNext() ) {
353 public String toString() {
356 Iterator i = this.iterator();
357 while( i.hasNext() ) {