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