b960398519e8ff95412f7b645e0fa3dabb3929a2
[IRC.git] / Robust / src / Analysis / Disjoint / HeapRegionNode.java
1 package Analysis.Disjoint;
2
3 import IR.*;
4 import IR.Flat.*;
5 import java.util.*;
6 import java.io.*;
7
8 public class HeapRegionNode extends RefSrcNode {
9
10   protected Integer id;
11
12   protected boolean isSingleObject;
13   protected boolean isFlagged;
14   protected boolean isNewSummary;
15
16   // special nodes that represent heap parts
17   // outside of the current method context
18   protected boolean isOutOfContext;
19
20   protected HashSet<RefEdge> referencers;
21
22   protected TypeDescriptor type;
23
24   protected AllocSite allocSite;
25
26   // some reachability states are inherent
27   // to a node by its definition
28   protected ReachSet inherent;
29
30   // use alpha for the current reach states
31   // and alphaNew during iterative calculations
32   // to update alpha
33   protected ReachSet alpha;
34   protected ReachSet alphaNew;
35
36   protected String description;
37
38   // existence predicates must be true in a caller
39   // context for this node to transfer from this
40   // callee to that context
41   protected ExistPredSet preds;
42
43
44   public HeapRegionNode(Integer id,
45                         boolean isSingleObject,
46                         boolean isFlagged,
47                         boolean isNewSummary,
48                         boolean isOutOfContext,
49                         TypeDescriptor type,
50                         AllocSite allocSite,
51                         ReachSet inherent,
52                         ReachSet alpha,
53                         ExistPredSet preds,
54                         String description
55                         ) {
56
57     this.id             = id;
58     this.isSingleObject = isSingleObject;
59     this.isFlagged      = isFlagged;
60     this.isNewSummary   = isNewSummary;
61     this.isOutOfContext = isOutOfContext;
62     this.type           = type;
63     this.allocSite      = allocSite;
64     this.inherent       = inherent;
65     this.alpha          = alpha;
66     this.preds          = preds;
67     this.description    = description;
68
69     referencers = new HashSet<RefEdge>();
70     alphaNew    = ReachSet.factory();
71   }
72
73   public HeapRegionNode copy() {
74     return new HeapRegionNode(id,
75                               isSingleObject,
76                               isFlagged,
77                               isNewSummary,
78                               isOutOfContext,
79                               type,
80                               allocSite,
81                               inherent,
82                               alpha,
83                               preds,
84                               description);
85   }
86
87
88   public Integer getID() {
89     return id;
90   }
91
92
93   // alpha and preds contribute towards reaching the
94   // fixed point, so use this method to determine if
95   // a node is "equal" to some previous visit, basically
96   public boolean equalsIncludingAlphaAndPreds(HeapRegionNode hrn) {
97
98     return equals(hrn) &&
99            alpha.equals(hrn.alpha) &&
100            preds.equals(hrn.preds);
101   }
102
103
104   public boolean equals(Object o) {
105     if( o == null ) {
106       return false;
107     }
108
109     if( !(o instanceof HeapRegionNode) ) {
110       return false;
111     }
112
113     HeapRegionNode hrn = (HeapRegionNode) o;
114
115     if( !id.equals(hrn.getID() ) ) {
116       return false;
117     }
118
119     assert isSingleObject == hrn.isSingleObject();
120     assert isFlagged      == hrn.isFlagged();
121     assert isNewSummary   == hrn.isNewSummary();
122     assert isOutOfContext == hrn.isOutOfContext();
123     //assert description.equals( hrn.getDescription() );
124
125     return true;
126   }
127
128   public int hashCode() {
129     return id.intValue()*17;
130   }
131
132
133   public boolean isSingleObject() {
134     return isSingleObject;
135   }
136
137   public boolean isFlagged() {
138     return isFlagged;
139   }
140
141   public boolean isNewSummary() {
142     return isNewSummary;
143   }
144
145   public boolean isOutOfContext() {
146     return isOutOfContext;
147   }
148
149
150   public Iterator<RefEdge> iteratorToReferencers() {
151     return referencers.iterator();
152   }
153
154   public Iterator<RefEdge> iteratorToReferencersClone() {
155     HashSet<RefEdge> clone = (HashSet<RefEdge>)referencers.clone();
156     return clone.iterator();
157   }
158
159   public int getNumReferencers() {
160     return referencers.size();
161   }
162
163
164   // in other words, this node is not functionally
165   // part of the graph (anymore)
166   public boolean isWiped() {
167     return
168       getNumReferencers() == 0 &&
169       getNumReferencees() == 0;
170   }
171
172
173   public void addReferencer(RefEdge edge) {
174     assert edge != null;
175
176     referencers.add(edge);
177   }
178
179   public void removeReferencer(RefEdge edge) {
180     assert edge != null;
181     assert referencers.contains(edge);
182
183     referencers.remove(edge);
184   }
185
186   public RefEdge getReferenceFrom(RefSrcNode rsn,
187                                   TypeDescriptor type,
188                                   String field
189                                   ) {
190     assert rsn != null;
191
192     Iterator<RefEdge> itrEdge = referencers.iterator();
193     while( itrEdge.hasNext() ) {
194       RefEdge edge = itrEdge.next();
195
196       if( edge.getSrc().equals(rsn) &&
197           edge.typeEquals(type)     &&
198           edge.fieldEquals(field)
199           ) {
200         return edge;
201       }
202     }
203
204     return null;
205   }
206
207
208   public TypeDescriptor getType() {
209     return type;
210   }
211
212   public AllocSite getAllocSite() {
213     return allocSite;
214   }
215
216
217   public ReachSet getInherent() {
218     return inherent;
219   }
220
221   public ReachSet getAlpha() {
222     return alpha;
223   }
224
225   public void setAlpha(ReachSet alpha) {
226     this.alpha = alpha;
227   }
228
229   public ReachSet getAlphaNew() {
230     return alphaNew;
231   }
232
233   public void setAlphaNew(ReachSet alpha) {
234     this.alphaNew = alpha;
235   }
236
237   public void applyAlphaNew() {
238     assert alphaNew != null;
239     alpha = alphaNew;
240     alphaNew = ReachSet.factory();
241   }
242
243
244   public ExistPredSet getPreds() {
245     return preds;
246   }
247
248   public void setPreds(ExistPredSet preds) {
249     this.preds = preds;
250   }
251
252
253   // use this method to assert that an out-of-context
254   // heap region node has only out-of-context symbols
255   // in its reachability
256   public boolean reachHasOnlyOOC() {
257     assert isOutOfContext;
258
259     Iterator<ReachState> stateItr = alpha.iterator();
260     while( stateItr.hasNext() ) {
261       ReachState state = stateItr.next();
262
263       Iterator<ReachTuple> rtItr = state.iterator();
264       while( rtItr.hasNext() ) {
265         ReachTuple rt = rtItr.next();
266
267         if( !rt.isOutOfContext() ) {
268           return false;
269         }
270       }
271     }
272
273     return true;
274   }
275
276
277   public String getIDString() {
278     String s;
279
280     if( id < 0 ) {
281       s = "minus" + new Integer(-id).toString();
282     } else {
283       s = id.toString();
284     }
285
286     return s;
287   }
288
289   public String getDescription() {
290     return description;
291   }
292
293   public String toStringDOT(boolean hideReach,
294                             boolean hideSubsetReach,
295                             boolean hidePreds) {
296     String attributes = "";
297
298     if( isSingleObject ) {
299       attributes += "shape=box";
300     } else {
301       attributes += "shape=Msquare";
302     }
303
304     if( isFlagged ) {
305       attributes += ",style=filled,fillcolor=lightgrey";
306     }
307
308     String typeStr;
309     if( type == null ) {
310       typeStr = "null";
311     } else {
312       typeStr = type.toPrettyString();
313     }
314
315     String s =
316       "["+attributes+
317       ",label=\"ID"+getIDString()+"\\n"+
318       typeStr+"\\n"+
319       description;
320
321     if( !hideReach ) {
322       s += "\\n"+alpha.toStringEscNewline(hideSubsetReach);
323     }
324
325     if( !hidePreds ) {
326       s += "\\n"+preds.toStringEscNewline();
327     }
328
329     return s+"\"]";
330   }
331
332   public String toString() {
333     return "HRN"+getIDString();
334   }
335 }