1 package Analysis.Loops;
6 import IR.MethodDescriptor;
7 import IR.FieldDescriptor;
8 import IR.TypeDescriptor;
9 import Analysis.CallGraph.*;
10 import java.util.Iterator;
11 import java.util.HashSet;
12 import java.util.Hashtable;
15 public class GlobalFieldType {
18 MethodDescriptor root;
19 Hashtable<MethodDescriptor, Set<FieldDescriptor>> fields;
20 Hashtable<MethodDescriptor, Set<TypeDescriptor>> arrays;
21 Hashtable<MethodDescriptor, Set<FieldDescriptor>> fieldsrd;
22 Hashtable<MethodDescriptor, Set<TypeDescriptor>> arraysrd;
23 HashSet<MethodDescriptor> containsAtomic;
24 HashSet<MethodDescriptor> containsBarrier;
26 public GlobalFieldType(CallGraph cg, State st, MethodDescriptor root) {
30 this.fields=new Hashtable<MethodDescriptor, Set<FieldDescriptor>>();
31 this.arrays=new Hashtable<MethodDescriptor, Set<TypeDescriptor>>();
32 this.fieldsrd=new Hashtable<MethodDescriptor, Set<FieldDescriptor>>();
33 this.arraysrd=new Hashtable<MethodDescriptor, Set<TypeDescriptor>>();
34 this.containsAtomic=new HashSet<MethodDescriptor>();
35 this.containsBarrier=new HashSet<MethodDescriptor>();
38 private void doAnalysis() {
39 HashSet toprocess=new HashSet();
41 HashSet discovered=new HashSet();
43 while(!toprocess.isEmpty()) {
44 MethodDescriptor md=(MethodDescriptor)toprocess.iterator().next();
47 Set callees=cg.getCalleeSet(md);
48 for(Iterator it=callees.iterator();it.hasNext();) {
49 MethodDescriptor md2=(MethodDescriptor)it.next();
50 if (!discovered.contains(md2)) {
55 if (md.getClassDesc().getSymbol().equals(TypeUtil.ThreadClass)&&
56 md.getSymbol().equals("start")&&!md.getModifiers().isStatic()&&
57 md.numParameters()==0) {
59 MethodDescriptor runmd=null;
60 for(Iterator methodit=md.getClassDesc().getMethodTable().getSet("run").iterator(); methodit.hasNext();) {
61 MethodDescriptor mdrun=(MethodDescriptor) methodit.next();
62 if (mdrun.numParameters()!=0||mdrun.getModifiers().isStatic())
68 Set runmethodset=cg.getMethods(runmd);
69 for(Iterator it=runmethodset.iterator();it.hasNext();) {
70 MethodDescriptor md2=(MethodDescriptor)it.next();
71 if (!discovered.contains(md2)) {
76 } else throw new Error("Can't find run method");
82 for(Iterator it=discovered.iterator();it.hasNext();) {
83 MethodDescriptor md=(MethodDescriptor)it.next();
84 Set callees=cg.getCalleeSet(md);
85 for(Iterator cit=callees.iterator();cit.hasNext();) {
86 MethodDescriptor md2=(MethodDescriptor)cit.next();
87 if (fields.get(md).addAll(fields.get(md2)))
89 if (arrays.get(md).addAll(arrays.get(md2)))
91 if (fieldsrd.get(md).addAll(fieldsrd.get(md2)))
93 if (arraysrd.get(md).addAll(arraysrd.get(md2)))
95 if (containsAtomic.contains(md2)) {
96 if (containsAtomic.add(md))
99 if (containsBarrier.contains(md2)) {
100 if (containsBarrier.add(md))
108 public boolean containsAtomic(MethodDescriptor md) {
109 return containsAtomic.contains(md);
112 public boolean containsBarrier(MethodDescriptor md) {
113 return containsBarrier.contains(md);
116 public Set<FieldDescriptor> getFields(MethodDescriptor md) {
117 return fields.get(md);
120 public Set<TypeDescriptor> getArrays(MethodDescriptor md) {
121 return arrays.get(md);
124 public Set<FieldDescriptor> getFieldsRd(MethodDescriptor md) {
125 return fieldsrd.get(md);
128 public Set<TypeDescriptor> getArraysRd(MethodDescriptor md) {
129 return arraysrd.get(md);
132 public boolean containsAtomicAll(MethodDescriptor md) {
133 Set methodset=cg.getMethods(md);
134 for(Iterator it=methodset.iterator();it.hasNext();) {
135 MethodDescriptor md2=(MethodDescriptor)it.next();
136 if (containsAtomic.contains(md2))
142 public boolean containsBarrierAll(MethodDescriptor md) {
143 Set methodset=cg.getMethods(md);
144 for(Iterator it=methodset.iterator();it.hasNext();) {
145 MethodDescriptor md2=(MethodDescriptor)it.next();
146 if (containsBarrier.contains(md2))
152 public Set<FieldDescriptor> getFieldsAll(MethodDescriptor md) {
153 HashSet<FieldDescriptor> s=new HashSet<FieldDescriptor>();
154 Set methodset=cg.getMethods(md);
155 for(Iterator it=methodset.iterator();it.hasNext();) {
156 MethodDescriptor md2=(MethodDescriptor)it.next();
157 if (fields.containsKey(md2))
158 s.addAll(fields.get(md2));
163 public Set<TypeDescriptor> getArraysAll(MethodDescriptor md) {
164 HashSet<TypeDescriptor> s=new HashSet<TypeDescriptor>();
165 Set methodset=cg.getMethods(md);
166 for(Iterator it=methodset.iterator();it.hasNext();) {
167 MethodDescriptor md2=(MethodDescriptor)it.next();
168 if (arrays.containsKey(md2))
169 s.addAll(arrays.get(md2));
174 public Set<FieldDescriptor> getFieldsRdAll(MethodDescriptor md) {
175 HashSet<FieldDescriptor> s=new HashSet<FieldDescriptor>();
176 Set methodset=cg.getMethods(md);
177 for(Iterator it=methodset.iterator();it.hasNext();) {
178 MethodDescriptor md2=(MethodDescriptor)it.next();
179 if (fieldsrd.containsKey(md2))
180 s.addAll(fieldsrd.get(md2));
185 public Set<TypeDescriptor> getArraysRdAll(MethodDescriptor md) {
186 HashSet<TypeDescriptor> s=new HashSet<TypeDescriptor>();
187 Set methodset=cg.getMethods(md);
188 for(Iterator it=methodset.iterator();it.hasNext();) {
189 MethodDescriptor md2=(MethodDescriptor)it.next();
190 if (arraysrd.containsKey(md2))
191 s.addAll(arraysrd.get(md2));
196 public void analyzeMethod(MethodDescriptor md) {
197 fields.put(md, new HashSet<FieldDescriptor>());
198 arrays.put(md, new HashSet<TypeDescriptor>());
199 fieldsrd.put(md, new HashSet<FieldDescriptor>());
200 arraysrd.put(md, new HashSet<TypeDescriptor>());
202 FlatMethod fm=st.getMethodFlat(md);
203 for(Iterator it=fm.getNodeSet().iterator();it.hasNext();) {
204 FlatNode fn=(FlatNode)it.next();
205 if (fn.kind()==FKind.FlatSetElementNode) {
206 FlatSetElementNode fsen=(FlatSetElementNode)fn;
207 arrays.get(md).add(fsen.getDst().getType());
208 } else if (fn.kind()==FKind.FlatElementNode) {
209 FlatElementNode fen=(FlatElementNode)fn;
210 arraysrd.get(md).add(fen.getSrc().getType());
211 } else if (fn.kind()==FKind.FlatSetFieldNode) {
212 FlatSetFieldNode fsfn=(FlatSetFieldNode)fn;
213 fields.get(md).add(fsfn.getField());
214 } else if (fn.kind()==FKind.FlatFieldNode) {
215 FlatFieldNode ffn=(FlatFieldNode)fn;
216 fieldsrd.get(md).add(ffn.getField());
217 } else if (fn.kind()==FKind.FlatAtomicEnterNode) {
218 containsAtomic.add(md);
219 } else if (fn.kind()==FKind.FlatCall) {
220 MethodDescriptor mdcall=((FlatCall)fn).getMethod();
221 if (mdcall.getSymbol().equals("enterBarrier")&&
222 mdcall.getClassDesc().getSymbol().equals("Barrier")) {
223 containsBarrier.add(md);
224 containsBarrier.add(mdcall);