0565b6f092e18863aa88dd35137252647f21d78b
[IRC.git] / Robust / src / Analysis / Disjoint / Effect.java
1 package Analysis.Disjoint;
2
3 import java.util.*;
4
5 import IR.*;
6 import IR.Flat.*;
7
8 public class Effect {
9
10   // operation type
11   public static final int read = 1;
12   public static final int write = 2;
13   public static final int strongupdate = 4;
14
15   // identify an allocation site of affected object
16   protected Alloc affectedAllocSite;
17
18   // identify operation type
19   protected int type;
20
21   // identify a field
22   protected FieldDescriptor field;
23
24   // for debugging purposes, keep the compilation
25   // unit and line number of this effect--only if state
26   // is non-null later
27   protected int             lineNumber;
28   protected ClassDescriptor compilationUnit;
29   protected static Hashtable<FlatNode, ClassDescriptor> fn2cd =
30     new Hashtable<FlatNode, ClassDescriptor>();
31
32
33   public Effect(Alloc affectedAS, int type, FieldDescriptor field, FlatNode currentProgramPoint) {
34     this.affectedAllocSite = affectedAS;
35     this.type = type;
36     this.field = field;
37
38
39     // NOTE: this line number+compilation unit is collected for debugging,
40     // so we don't want to spend time on this unless OOODEBUG or some new
41     // option controls it.  Disjoint and Pointer analysis use this currently.
42     lineNumber      = -1;
43     compilationUnit = null;
44
45     // find the class the current program point belongs to
46     if( currentProgramPoint == null ) {
47       return;
48     }
49     Set<FlatNode> visited = new HashSet<FlatNode>();
50     Set<FlatNode> toVisit = new HashSet<FlatNode>();
51     toVisit.add( currentProgramPoint );
52     
53     while( !toVisit.isEmpty() ) {
54       FlatNode fn = toVisit.iterator().next();
55       toVisit.remove( fn );
56       visited.add( fn );
57
58       // when we find a flat method, remember every node we visited
59       // belongs to that compilation unit
60       if( fn instanceof FlatMethod ) {
61         MethodDescriptor md = ((FlatMethod)fn).getMethod();
62         if( md != null ) {
63           ClassDescriptor cd = md.getClassDesc();
64           if( cd != null ) {
65             fn2cd.put( fn, cd );
66           }
67         }
68       }
69
70       if( fn2cd.containsKey( fn ) ) {
71         compilationUnit = fn2cd.get( fn );
72
73         for( FlatNode fnKnown: visited ) {
74           fn2cd.put( fnKnown, compilationUnit );
75         }
76         
77         lineNumber = currentProgramPoint.getNumLine();
78         break;
79       }
80
81       for( int i = 0; i < fn.numPrev(); ++i ) {
82         FlatNode prev = fn.getPrev( i );
83         if( !visited.contains( prev ) ) {
84           toVisit.add( prev );
85         }
86       }
87     }
88   }
89
90   public static boolean isWrite(int effect) {
91     return (effect & Effect.write)==Effect.write;
92   }
93
94   public boolean isWrite() {
95     return type==write;
96   }
97
98   public boolean isRead() {
99     return type==read;
100   }
101
102   public Alloc getAffectedAllocSite() {
103     return affectedAllocSite;
104   }
105
106   public void setAffectedAllocSite(Alloc affectedAllocSite) {
107     this.affectedAllocSite = affectedAllocSite;
108   }
109
110   public int getType() {
111     return type;
112   }
113
114   public void setType(int type) {
115     this.type = type;
116   }
117
118   public FieldDescriptor getField() {
119     return field;
120   }
121
122   public void setField(FieldDescriptor field) {
123     this.field = field;
124   }
125
126   public boolean equals(Object o) {
127
128     if (o == null) {
129       return false;
130     }
131
132     if (!(o instanceof Effect)) {
133       return false;
134     }
135
136     Effect in = (Effect) o;
137
138     if (affectedAllocSite.equals(in.getAffectedAllocSite())
139         && type == in.getType()
140         && ((field!=null&&field.equals(in.getField()))||
141             (field==null&&in.getField()==null))) {
142       return true;
143     } else {
144       return false;
145     }
146   }
147
148   public int hashCode() {
149
150     int hash = affectedAllocSite.hashCode();
151
152     hash = hash + type;
153
154     if (field != null) {
155       hash = hash ^ field.hashCode();
156     }
157
158     return hash;
159
160   }
161
162   public String toString() {
163     String s = "(";
164
165     s += affectedAllocSite.toStringBrief();
166     s += ", ";
167     if (type == read) {
168       s += "read";
169     } else if (type == write) {
170       s += "write";
171     } else {
172       s += "SU";
173     }
174
175     if (field==null) {
176       s += ", []";
177     } else {
178       s += ", " + field.toStringBrief();
179     }
180
181     if( compilationUnit != null ) {
182       s += ", "+compilationUnit.getSymbol()+":"+lineNumber;
183     }
184     
185     return s + ")";
186   }
187
188 }