f5e1ca34d80cac51b28cbf12d269af99da00e95f
[IRC.git] / Robust / src / Analysis / Disjoint / AllocSite.java
1 package Analysis.Disjoint;
2
3 import IR.*;
4 import IR.Flat.*;
5 import java.util.*;
6
7 // allocation sites are independent of any particular
8 // reachability graph, unlike most of the other elements
9 // of the reachability analysis.  An allocation site is
10 // simply a collection of heap region identifiers that
11 // are associated with a single allocation site in the
12 // program under analysis.
13
14 // So two different reachability graphs may incorporate
15 // nodes that represent the memory from one allocation
16 // site.  In this case there are two different sets of
17 // HeapRegionNode objects, but they have the same
18 // node identifiers, and there is one AllocSite
19 // object associated with the FlatNew node that gives
20 // the graphs the identifiers in question.
21
22 // note that an allocsite extends Canonical because they
23 // are Canonical, but specifically so an AllocSite can
24 // be an operand to a CanonicalOp
25
26 public class AllocSite extends Canonical implements Alloc {
27
28   static protected int uniqueIDcount = 0;
29
30   public static final int AGE_notInThisSite = 100;
31   public static final int AGE_in_I          = 101;
32   public static final int AGE_oldest        = 102;
33   public static final int AGE_summary       = 103;
34
35   public static final int SHADOWAGE_notInThisSite = -100;
36   public static final int SHADOWAGE_in_I          = -101;
37   public static final int SHADOWAGE_oldest        = -102;
38   public static final int SHADOWAGE_summary       = -103;
39
40   protected Integer         id;
41   protected int             allocationDepth;
42   protected Vector<Integer> ithOldest;
43   protected Integer         summary;
44   protected FlatNew         flatNew;
45   protected String          disjointId;
46   protected boolean         isFlagged;
47
48
49   public static AllocSite factory( int     allocationDepth, 
50                                    FlatNew flatNew, 
51                                    String  disjointId,
52                                    boolean markAsFlagged
53                                    ) {
54     AllocSite out = new AllocSite( allocationDepth,
55                                    flatNew,
56                                    disjointId,
57                                    markAsFlagged );
58     out = (AllocSite) Canonical.makeCanonical( out );
59     return out;
60   }
61
62
63   protected AllocSite( int     allocationDepth, 
64                        FlatNew flatNew, 
65                        String  disjointId,
66                        boolean markAsFlagged
67                        ) {
68
69     assert allocationDepth >= 1;
70
71     this.allocationDepth = allocationDepth;
72     this.flatNew         = flatNew;
73     this.disjointId      = disjointId;
74
75     // mark this allocation site as being flagged
76     // for the analysis if
77     // 1) we have a non-null disjointID (a named flagged site) 
78     // OR
79     // 2) the type is a class with Bamboo-parameter flags 
80     // OR
81     // 3) a client wants to programmatically flag this site,
82     // such as the OoOJava method effects analysis
83     this.isFlagged = false;
84
85     if( disjointId != null ) {
86       this.isFlagged = true;
87
88     } else if( flatNew.getType().isClass() &&
89                flatNew.getType().getClassDesc().hasFlags()
90                ) {
91       this.isFlagged = true;
92
93     } else if( markAsFlagged ) {
94       this.isFlagged = true;
95     }
96
97
98     ithOldest = new Vector<Integer>( allocationDepth );
99     id        = generateUniqueAllocSiteID();
100   }
101
102   static public Integer generateUniqueAllocSiteID() {
103     ++uniqueIDcount;
104     return new Integer( uniqueIDcount );
105   }
106
107   public int getUniqueAllocSiteID() {
108     return id;
109   }
110
111   public String getDisjointAnalysisId() {
112     return disjointId;
113   }
114
115
116   public int getAllocationDepth() {
117     return allocationDepth;
118   }
119
120   public void setIthOldest( int i, Integer id ) {
121     assert i  >= 0;
122     assert i  <  allocationDepth;
123     assert id != null;
124
125     ithOldest.add( i, id );
126   }
127
128   public Integer getIthOldest( int i ) {
129     assert i >= 0;
130     assert i <  allocationDepth;
131
132     return ithOldest.get( i );
133   }
134
135   public Integer getIthOldestShadow( int i ) {
136     assert i >= 0;
137     assert i <  allocationDepth;
138
139     return -ithOldest.get( i );
140   }
141
142   public Integer getOldest() {
143     return ithOldest.get( allocationDepth - 1 );
144   }
145
146   public Integer getOldestShadow() {
147     return -ithOldest.get( allocationDepth - 1 );
148   }
149
150   public void setSummary( Integer id ) {
151     assert id != null;
152     summary = id;
153   }
154
155   public Integer getSummary() {
156     return summary;
157   }
158
159   public Integer getSummaryShadow() {
160     return -summary;
161   }
162
163   public FlatNew getFlatNew() {
164     return flatNew;
165   }
166
167   public TypeDescriptor getType() {
168     return flatNew.getType();
169   }
170
171   public boolean isFlagged() {
172     return isFlagged;
173   }
174
175   public int getAgeCategory( Integer id ) {
176
177     if( id.equals( summary ) ) {
178       return AGE_summary;
179     }
180
181     if( id.equals( getOldest() ) ) {
182       return AGE_oldest;
183     }
184
185     for( int i = 0; i < allocationDepth - 1; ++i ) {
186       if( id.equals( ithOldest.get( i ) ) ) {
187         return AGE_in_I;
188       }
189     }
190
191     return AGE_notInThisSite;
192   }
193
194   public Integer getAge( Integer id ) {
195     for( int i = 0; i < allocationDepth; ++i ) {
196       if( id.equals( ithOldest.get( i ) ) ) {
197         return new Integer( i );
198       }
199     }
200
201     return null;
202   }
203
204   public int getShadowAgeCategory( Integer id ) {
205     if( id.equals( -summary ) ) {
206       return SHADOWAGE_summary;
207     }
208
209     if( id.equals( getOldestShadow() ) ) {
210       return SHADOWAGE_oldest;
211     }
212
213     for( int i = 0; i < allocationDepth - 1; ++i ) {
214       if( id.equals( getIthOldestShadow( i ) ) ) {
215         return SHADOWAGE_in_I;
216       }
217     }
218
219     return SHADOWAGE_notInThisSite;
220   }
221
222   public Integer getShadowAge( Integer id ) {
223     for( int i = 0; i < allocationDepth - 1; ++i ) {
224       if( id.equals( getIthOldestShadow( i ) ) ) {
225         return new Integer( -i );
226       }
227     }
228
229     return null;
230   }
231
232   public Integer getShadowIDfromID( Integer id ) {
233     int ageCat = getAgeCategory( id );
234     switch( ageCat ) {
235       
236     case AGE_summary:
237     case AGE_oldest:
238     case AGE_in_I:
239       return -id;
240       
241     case AGE_notInThisSite:
242     default:
243       System.out.println( toStringWithIDs() );
244       throw new Error( "ID "+id+" not from this site." );
245     }
246   }
247
248   public String toString() {
249     if( disjointId == null ) {
250       return "allocSite"+id;
251     }
252     return "allocSite "+disjointId+" ("+id+")";
253   }
254
255   public String toStringBrief() {
256     return id.toString();
257   }
258
259   public String toStringVerbose() {
260     if( disjointId == null ) {
261       return "allocSite"+id+" "+
262         flatNew.getType().toPrettyString();
263     }
264     return "allocSite "+disjointId+" ("+id+") "+
265       flatNew.getType().toPrettyString();
266   }
267
268   public String toStringForDOT() {
269     if( disjointId != null ) {
270       return "disjoint "+disjointId+"\\n"+toString()+
271         "\\n"+getType().toPrettyString();
272     } else {
273       return                              toString()+
274         "\\n"+getType().toPrettyString();
275     }
276   }
277
278   public String toStringWithIDs() {
279     String s = "allocSite"+id+" ";
280     for( int i = 0; i < ithOldest.size(); ++i ) {
281       s += i+"("+ithOldest.get( i )+") ";
282     }
283     s += "summary("+summary+")";
284     return s;
285   }
286
287   public boolean equalsSpecific( Object o ) {
288     if( o == null ) {
289       return false;
290     }
291
292     if( !(o instanceof AllocSite) ) {
293       return false;
294     }
295
296     AllocSite as = (AllocSite) o;
297
298     return this.id == as.id;
299   }
300
301   public int hashCodeSpecific() {
302     return id.hashCode();
303   }  
304 }