implementing
[IRC.git] / Robust / src / Analysis / Disjoint / RefEdge.java
1 package Analysis.Disjoint;
2
3 import IR.*;
4 import IR.Flat.*;
5
6 public class RefEdge {
7
8   // all edges should have a non-null
9   // TypeDescriptor now
10   protected TypeDescriptor type;
11
12   // the field name may be null if this
13   // edge models a variable reference
14   protected String field;
15
16   // clean means that the reference existed
17   // before the current analysis context
18   protected boolean isClean;
19
20   protected ReachSet beta;
21   protected ReachSet betaNew;
22
23   protected RefSrcNode     src;
24   protected HeapRegionNode dst;
25
26   // existence predicates must be true in a caller
27   // context for this edge to transfer from this
28   // callee to that context--NOTE, existence predicates
29   // do not factor into edge comparisons
30   protected ExistPredSet preds;
31
32   
33   public RefEdge( RefSrcNode     src,
34                   HeapRegionNode dst,
35                   TypeDescriptor type,
36                   String         field,
37                   boolean        isClean,
38                   ReachSet       beta,
39                   ExistPredSet   preds ) {
40     assert type != null;
41
42     this.src     = src;
43     this.dst     = dst;
44     this.type    = type;
45     this.field   = field;
46     this.isClean = isClean;
47
48     if( preds != null ) {
49       this.preds = preds;
50     } else {
51       // TODO: do this right?
52       this.preds = new ExistPredSet().makeCanonical();
53     }
54
55     if( beta != null ) {
56       this.beta = beta;
57     } else {
58       this.beta = new ReachSet().makeCanonical();
59     }
60
61     // when edges are not undergoing an operation that
62     // is changing beta info, betaNew is always empty
63     betaNew = new ReachSet().makeCanonical();
64   }
65
66
67   public RefEdge copy() {
68     RefEdge copy = new RefEdge( src,
69                                 dst,
70                                 type,
71                                 field,
72                                 isClean,                               
73                                 beta,
74                                 preds );
75     return copy;
76   }
77
78
79   public boolean equals( Object o ) {
80     if( o == null ) {
81       return false;
82     }
83
84     if( !(o instanceof RefEdge) ) {
85       return false;
86     }
87     
88     RefEdge edge = (RefEdge) o;
89     
90     if( !typeEquals( edge.type ) ) {
91       return false;
92     }
93
94     if( !fieldEquals( edge.field ) ) {
95       return false;
96     }
97
98     // Equality of edges is only valid within a graph, so
99     // compare src and dst by reference
100     if( !(src == edge.src) ||
101         !(dst == edge.dst)   ) {
102       return false;
103     }
104
105     assert isClean == edge.isClean;
106
107     return true;
108   }
109
110
111   // beta and preds contribute towards reaching the
112   // fixed point, so use this method to determine if
113   // an edge is "equal" to some previous visit, basically
114   public boolean equalsIncludingBetaAndPreds( RefEdge edge ) {
115     return equals( edge ) && 
116       beta.equals( edge.beta ) &&
117       preds.equals( edge.preds );
118   }
119
120   public boolean equalsPreds( RefEdge edge ) {
121     return preds.equals( edge.preds );
122   }
123
124
125   public int hashCode() {
126     int hash = 0;
127
128     hash += type.hashCode()*17;
129
130     if( field != null ) {
131       hash += field.hashCode()*7;
132     }
133     
134     hash += src.hashCode()*11;
135     hash += dst.hashCode();
136
137     return hash;
138   }
139
140
141   public RefSrcNode getSrc() {
142     return src;
143   }
144
145   public void setSrc( RefSrcNode rsn ) {
146     assert rsn != null;
147     src = rsn;
148   }
149
150   public HeapRegionNode getDst() {
151     return dst;
152   }
153
154   public void setDst( HeapRegionNode hrn ) {
155     assert hrn != null;
156     dst = hrn;
157   }
158
159
160   public TypeDescriptor getType() {
161     return type;
162   }
163
164   public void setType( TypeDescriptor td ) {
165     assert td != null;
166     type = td;
167   }
168
169   public String getField() {
170     return field;
171   }
172
173   public void setField( String s ) {
174     field = s;
175   }
176
177
178   public boolean typeEquals( TypeDescriptor td ) {
179     return type.equals( td );
180   }
181
182   public boolean fieldEquals( String s ) {
183     if( field == null && s == null ) {
184       return true;
185     }
186     if( field == null ) {
187       return false;
188     }
189     return field.equals( s );
190   }
191
192   public boolean typeAndFieldEquals( RefEdge e ) {
193     return typeEquals ( e.getType()  ) &&
194            fieldEquals( e.getField() );
195   }
196
197
198   public boolean isClean() {
199     return isClean;
200   }
201
202   public void setIsClean( boolean isClean ) {
203     this.isClean = isClean;
204   }
205
206
207   public ReachSet getBeta() {
208     return beta;
209   }
210
211   public void setBeta( ReachSet beta ) {
212     assert beta != null;
213     this.beta = beta;
214   }
215
216   public ReachSet getBetaNew() {
217     return betaNew;
218   }
219
220   public void setBetaNew( ReachSet beta ) {
221     assert beta != null;
222     this.betaNew = beta;
223   }
224   
225   public void applyBetaNew() {
226     assert betaNew != null;
227
228     beta    = betaNew;
229     betaNew = new ReachSet().makeCanonical();
230   }
231
232
233   public String toGraphEdgeString( boolean hideSubsetReachability ) {
234     String edgeLabel = "";
235
236     if( type != null ) {
237       edgeLabel += type.toPrettyString() + "\\n";
238     }
239
240     if( field != null ) {
241       edgeLabel += field + "\\n";
242     }
243
244     if( isClean ) {
245       edgeLabel += "*clean*\\n";
246     }
247
248     edgeLabel += beta.toStringEscapeNewline( hideSubsetReachability ) +
249       "\\n" + preds.toString();
250       
251     return edgeLabel;
252   }
253
254   public String toString() {
255     assert type != null;
256     return new String( "("+src+
257                        "->"+type.toPrettyString()+
258                        " "+field+
259                        "->"+dst+")"
260                        );
261   }  
262 }