running new experiments
[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     return equals(hrn) &&
98            alpha.equals(hrn.alpha) &&
99            preds.equals(hrn.preds);
100   }
101
102
103   public boolean equals(Object o) {
104     if( o == null ) {
105       return false;
106     }
107
108     if( !(o instanceof HeapRegionNode) ) {
109       return false;
110     }
111
112     HeapRegionNode hrn = (HeapRegionNode) o;
113
114     if( !id.equals(hrn.getID() ) ) {
115       return false;
116     }
117
118     assert isSingleObject == hrn.isSingleObject();
119     assert isFlagged      == hrn.isFlagged();
120     assert isNewSummary   == hrn.isNewSummary();
121     assert isOutOfContext == hrn.isOutOfContext();
122     //assert description.equals( hrn.getDescription() );
123
124     return true;
125   }
126
127   public int hashCode() {
128     return id.intValue()*17;
129   }
130
131
132   public boolean isSingleObject() {
133     return isSingleObject;
134   }
135
136   public boolean isFlagged() {
137     return isFlagged;
138   }
139
140   public boolean isNewSummary() {
141     return isNewSummary;
142   }
143
144   public boolean isOutOfContext() {
145     return isOutOfContext;
146   }
147
148
149   public Iterator<RefEdge> iteratorToReferencers() {
150     return referencers.iterator();
151   }
152
153   public Iterator<RefEdge> iteratorToReferencersClone() {
154     HashSet<RefEdge> clone = (HashSet<RefEdge>)referencers.clone();
155     return clone.iterator();
156   }
157
158   public int getNumReferencers() {
159     return referencers.size();
160   }
161
162
163   // in other words, this node is not functionally
164   // part of the graph (anymore)
165   public boolean isWiped() {
166     return
167       getNumReferencers() == 0 &&
168       getNumReferencees() == 0;
169   }
170
171
172   public void addReferencer(RefEdge edge) {
173     assert edge != null;
174
175     referencers.add(edge);
176   }
177
178   public void removeReferencer(RefEdge edge) {
179     assert edge != null;
180     assert referencers.contains(edge);
181
182     referencers.remove(edge);
183   }
184
185   public RefEdge getReferenceFrom(RefSrcNode rsn,
186                                   TypeDescriptor type,
187                                   String field
188                                   ) {
189     assert rsn != null;
190
191     Iterator<RefEdge> itrEdge = referencers.iterator();
192     while( itrEdge.hasNext() ) {
193       RefEdge edge = itrEdge.next();
194
195       if( edge.getSrc().equals(rsn) &&
196           edge.typeEquals(type)     &&
197           edge.fieldEquals(field)
198           ) {
199         return edge;
200       }
201     }
202
203     return null;
204   }
205
206
207   public TypeDescriptor getType() {
208     return type;
209   }
210
211   public AllocSite getAllocSite() {
212     return allocSite;
213   }
214
215
216   public ReachSet getInherent() {
217     return inherent;
218   }
219
220   public ReachSet getAlpha() {
221     return alpha;
222   }
223
224   public void setAlpha(ReachSet alpha) {
225     this.alpha = alpha;
226   }
227
228   public ReachSet getAlphaNew() {
229     return alphaNew;
230   }
231
232   public void setAlphaNew(ReachSet alpha) {
233     this.alphaNew = alpha;
234   }
235
236   public void applyAlphaNew() {
237     assert alphaNew != null;
238     alpha = alphaNew;
239     alphaNew = ReachSet.factory();
240   }
241
242
243   public ExistPredSet getPreds() {
244     return preds;
245   }
246
247   public void setPreds(ExistPredSet preds) {
248     this.preds = preds;
249   }
250
251
252   // use this method to assert that an out-of-context
253   // heap region node has only out-of-context symbols
254   // in its reachability
255   public boolean reachHasOnlyOOC() {
256     assert isOutOfContext;
257
258     Iterator<ReachState> stateItr = alpha.iterator();
259     while( stateItr.hasNext() ) {
260       ReachState state = stateItr.next();
261
262       Iterator<ReachTuple> rtItr = state.iterator();
263       while( rtItr.hasNext() ) {
264         ReachTuple rt = rtItr.next();
265
266         if( !rt.isOutOfContext() ) {
267           return false;
268         }
269       }
270     }
271
272     return true;
273   }
274
275
276   public String getIDString() {
277     String s;
278
279     if( id < 0 ) {
280       s = "minus" + new Integer(-id).toString();
281     } else {
282       s = id.toString();
283     }
284
285     return s;
286   }
287
288   public String getDescription() {
289     return description;
290   }
291
292   public String toStringDOT(boolean hideReach,
293                             boolean hideSubsetReach,
294                             boolean hidePreds) {
295     String attributes = "";
296
297     if( isSingleObject ) {
298       attributes += "shape=box";
299     } else {
300       attributes += "shape=Msquare";
301     }
302
303     if( isFlagged ) {
304       attributes += ",style=filled,fillcolor=lightgrey";
305     }
306
307     String typeStr;
308     if( type == null ) {
309       typeStr = "null";
310     } else {
311       typeStr = type.toPrettyString();
312     }
313
314     String s =
315       "["+attributes+
316       ",label=\"ID"+getIDString()+"\\n"+
317       typeStr+"\\n"+
318       description;
319
320     if( !hideReach ) {
321       s += "\\n"+alpha.toStringEscNewline(hideSubsetReach, hidePreds);
322     }
323
324     if( !hidePreds ) {
325       s += "\\n"+preds.toStringEscNewline();
326     }
327
328     return s+"\"]";
329   }
330
331   public String toString() {
332     return "HRN"+getIDString();
333   }
334 }