7edca4a029617eaf76cc3153872c6269ded8e1aa
[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 {
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 String getDisjointAnalysisId() {
108     return disjointId;
109   }
110
111
112   public int getAllocationDepth() {
113     return allocationDepth;
114   }
115
116   public void setIthOldest( int i, Integer id ) {
117     assert i  >= 0;
118     assert i  <  allocationDepth;
119     assert id != null;
120
121     ithOldest.add( i, id );
122   }
123
124   public Integer getIthOldest( int i ) {
125     assert i >= 0;
126     assert i <  allocationDepth;
127
128     return ithOldest.get( i );
129   }
130
131   public Integer getIthOldestShadow( int i ) {
132     assert i >= 0;
133     assert i <  allocationDepth;
134
135     return -ithOldest.get( i );
136   }
137
138   public Integer getOldest() {
139     return ithOldest.get( allocationDepth - 1 );
140   }
141
142   public Integer getOldestShadow() {
143     return -ithOldest.get( allocationDepth - 1 );
144   }
145
146   public void setSummary( Integer id ) {
147     assert id != null;
148     summary = id;
149   }
150
151   public Integer getSummary() {
152     return summary;
153   }
154
155   public Integer getSummaryShadow() {
156     return -summary;
157   }
158
159   public FlatNew getFlatNew() {
160     return flatNew;
161   }
162
163   public TypeDescriptor getType() {
164     return flatNew.getType();
165   }
166
167   public boolean isFlagged() {
168     return isFlagged;
169   }
170
171   public int getAgeCategory( Integer id ) {
172
173     if( id.equals( summary ) ) {
174       return AGE_summary;
175     }
176
177     if( id.equals( getOldest() ) ) {
178       return AGE_oldest;
179     }
180
181     for( int i = 0; i < allocationDepth - 1; ++i ) {
182       if( id.equals( ithOldest.get( i ) ) ) {
183         return AGE_in_I;
184       }
185     }
186
187     return AGE_notInThisSite;
188   }
189
190   public Integer getAge( Integer id ) {
191     for( int i = 0; i < allocationDepth; ++i ) {
192       if( id.equals( ithOldest.get( i ) ) ) {
193         return new Integer( i );
194       }
195     }
196
197     return null;
198   }
199
200   public int getShadowAgeCategory( Integer id ) {
201     if( id.equals( -summary ) ) {
202       return SHADOWAGE_summary;
203     }
204
205     if( id.equals( getOldestShadow() ) ) {
206       return SHADOWAGE_oldest;
207     }
208
209     for( int i = 0; i < allocationDepth - 1; ++i ) {
210       if( id.equals( getIthOldestShadow( i ) ) ) {
211         return SHADOWAGE_in_I;
212       }
213     }
214
215     return SHADOWAGE_notInThisSite;
216   }
217
218   public Integer getShadowAge( Integer id ) {
219     for( int i = 0; i < allocationDepth - 1; ++i ) {
220       if( id.equals( getIthOldestShadow( i ) ) ) {
221         return new Integer( -i );
222       }
223     }
224
225     return null;
226   }
227
228   public Integer getShadowIDfromID( Integer id ) {
229     int ageCat = getAgeCategory( id );
230     switch( ageCat ) {
231       
232     case AGE_summary:
233     case AGE_oldest:
234     case AGE_in_I:
235       return -id;
236       
237     case AGE_notInThisSite:
238     default:
239       System.out.println( toStringWithIDs() );
240       throw new Error( "ID "+id+" not from this site." );
241     }
242   }
243
244   public String toString() {
245     if( disjointId == null ) {
246       return "allocSite"+id;
247     }
248     return "allocSite "+disjointId+" ("+id+")";
249   }
250
251   public String toStringVerbose() {
252     if( disjointId == null ) {
253       return "allocSite"+id+" "+
254         flatNew.getType().toPrettyString();
255     }
256     return "allocSite "+disjointId+" ("+id+") "+
257       flatNew.getType().toPrettyString();
258   }
259
260   public String toStringForDOT() {
261     if( disjointId != null ) {
262       return "disjoint "+disjointId+"\\n"+toString()+
263         "\\n"+getType().toPrettyString();
264     } else {
265       return                              toString()+
266         "\\n"+getType().toPrettyString();
267     }
268   }
269
270   public String toStringWithIDs() {
271     String s = "allocSite"+id+" ";
272     for( int i = 0; i < ithOldest.size(); ++i ) {
273       s += i+"("+ithOldest.get( i )+") ";
274     }
275     s += "summary("+summary+")";
276     return s;
277   }
278
279   public boolean equalsSpecific( Object o ) {
280     if( o == null ) {
281       return false;
282     }
283
284     if( !(o instanceof AllocSite) ) {
285       return false;
286     }
287
288     AllocSite as = (AllocSite) o;
289
290     return this.id == as.id;
291   }
292
293   public int hashCodeSpecific() {
294     return id;
295   }  
296 }