add option to graph visualization that supresses reachability subsets, for improved...
[IRC.git] / Robust / src / Analysis / OwnershipAnalysis / ReferenceEdge.java
1 package Analysis.OwnershipAnalysis;
2
3 import IR.*;
4 import IR.Flat.*;
5
6
7 public class ReferenceEdge {
8
9   // null descriptors mean "any field"
10   protected TypeDescriptor type;
11   protected String field;
12
13   protected boolean isInitialParam;
14
15   protected ReachabilitySet beta;
16   protected ReachabilitySet betaNew;
17
18   protected OwnershipNode src;
19   protected HeapRegionNode dst;
20   private int taintIdentifier;
21
22
23   public ReferenceEdge(OwnershipNode src,
24                        HeapRegionNode dst,
25                        TypeDescriptor type,
26                        String field,
27                        boolean isInitialParam,
28                        ReachabilitySet beta) {
29
30     this.src                     = src;
31     this.dst                     = dst;
32     this.type                    = type;
33     this.field                   = field;
34     this.isInitialParam = isInitialParam;
35     this.taintIdentifier = 0;
36
37     if( beta != null ) {
38       this.beta = beta;
39     } else {
40       this.beta = new ReachabilitySet().makeCanonical();
41     }
42
43     // when edges are not undergoing a transitional operation
44     // that is changing beta info, betaNew is always empty
45     betaNew = new ReachabilitySet().makeCanonical();
46   }
47
48
49   public ReferenceEdge copy() {
50           ReferenceEdge copy= new ReferenceEdge(src,
51                              dst,
52                              type,
53                              field,
54                              isInitialParam,
55                              beta);
56           copy.setTaintIdentifier(this.taintIdentifier);
57           return copy;
58   }
59
60
61   public boolean equals(Object o) {
62     if( o == null ) {
63       return false;
64     }
65
66     if( !(o instanceof ReferenceEdge) ) {
67       return false;
68     }
69
70     ReferenceEdge edge = (ReferenceEdge) o;
71
72     if( !typeEquals( edge.type ) ) {
73       return false;
74     }
75
76     if( !fieldEquals( edge.field ) ) {
77       return false;
78     }
79
80     // Equality of edges is only valid within a graph, so
81     // compare src and dst by reference
82     if( !(src == edge.src) ||
83         !(dst == edge.dst)   ) {
84       return false;
85     }
86
87     return true;
88   }
89
90
91   public boolean equalsIncludingBeta(ReferenceEdge edge) {
92     return equals(edge) && beta.equals(edge.beta);
93   }
94
95
96   public int hashCode() {
97     int hash = 0;
98
99     if( type != null ) {
100       hash += type.hashCode()*17;
101     }
102
103     if( field != null ) {
104       hash += field.hashCode()*7;
105     }
106
107     hash += src.hashCode()*11;
108     hash += dst.hashCode();
109
110     return hash;
111   }
112
113
114   public OwnershipNode getSrc() {
115     return src;
116   }
117
118   public void setSrc(OwnershipNode on) {
119     assert on != null;
120     src = on;
121   }
122
123   public HeapRegionNode getDst() {
124     return dst;
125   }
126
127   public void setDst(HeapRegionNode hrn) {
128     assert hrn != null;
129     dst = hrn;
130   }
131
132
133   public TypeDescriptor getType() {
134     return type;
135   }
136
137   public void setType( TypeDescriptor td ) {
138     type = td;
139   }
140
141   public String getField() {
142     return field;
143   }
144
145   public void setField( String s ) {
146     field = s;
147   }
148
149
150   public boolean typeEquals( TypeDescriptor td ) {
151     if( type == null && td == null ) {
152       return true;
153     }
154     if( type == null ) {
155       return false;
156     }
157     return type.equals( td );
158   }
159
160   public boolean fieldEquals( String s ) {
161     if( field == null && s == null ) {
162       return true;
163     }
164     if( field == null ) {
165       return false;
166     }
167     return field.equals( s );
168   }
169
170   public boolean typeAndFieldEquals( ReferenceEdge e ) {
171     return typeEquals ( e.getType()  ) &&
172            fieldEquals( e.getField() );
173   }
174
175
176   public boolean isInitialParam() {
177     return isInitialParam;
178   }
179
180   public void setIsInitialParam(boolean isInitialParam) {
181     this.isInitialParam = isInitialParam;
182   }
183
184
185   public ReachabilitySet getBeta() {
186     return beta;
187   }
188
189   public void setBeta(ReachabilitySet beta) {
190     assert beta != null;
191     this.beta = beta;
192   }
193
194   public ReachabilitySet getBetaNew() {
195     return betaNew;
196   }
197
198   public void setBetaNew(ReachabilitySet beta) {
199     assert beta != null;
200     this.betaNew = beta;
201   }
202
203   public void applyBetaNew() {
204     assert betaNew != null;
205
206     beta    = betaNew;
207     betaNew = new ReachabilitySet().makeCanonical();
208   }
209
210
211   public String toGraphEdgeString( boolean hideSubsetReachability ) {
212     String edgeLabel = "";
213
214     if( type != null ) {
215       edgeLabel += type.toPrettyString()+"\\n";
216     }
217
218     if( field != null ) {
219       edgeLabel += field+"\\n";
220     }
221
222     if( isInitialParam ) {
223       edgeLabel += "*init*\\n";
224     }
225     
226     edgeLabel+="*taint*="+Integer.toBinaryString(taintIdentifier)+"\\n";
227
228     edgeLabel += beta.toStringEscapeNewline(hideSubsetReachability);
229
230     return edgeLabel;
231   }
232
233   public String toString() {
234     if( type != null ) {
235       return new String("("+src+"->"+type.toPrettyString()+" "+field+"->"+dst+")");
236     }
237
238     return new String("("+src+"->"+type+" "+field+"->"+dst+")");
239   }
240   
241   public void tainedBy(Integer paramIdx){
242           int newTaint=(int) Math.pow(2, paramIdx.intValue());
243           taintIdentifier=taintIdentifier | newTaint;
244   }
245   
246   public void setTaintIdentifier(int newTaint){
247           taintIdentifier=newTaint;
248   }
249   
250   public void unionTaintIdentifier(int newTaint){
251           taintIdentifier=taintIdentifier | newTaint;
252   }
253   
254   public void minusTaintIdentifier(int removedTaint){
255           taintIdentifier = taintIdentifier & (~removedTaint);
256   }
257   
258   public int getTaintIdentifier(){
259           return taintIdentifier;
260   }
261   
262 }