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 HashSet<MethodDescriptor> containsAtomic;
22 HashSet<MethodDescriptor> containsBarrier;
24 public GlobalFieldType(CallGraph cg, State st, MethodDescriptor root) {
28 this.fields=new Hashtable<MethodDescriptor, Set<FieldDescriptor>>();
29 this.arrays=new Hashtable<MethodDescriptor, Set<TypeDescriptor>>();
30 this.containsAtomic=new HashSet<MethodDescriptor>();
31 this.containsBarrier=new HashSet<MethodDescriptor>();
34 private void doAnalysis() {
35 HashSet toprocess=new HashSet();
37 HashSet discovered=new HashSet();
39 while(!toprocess.isEmpty()) {
40 MethodDescriptor md=(MethodDescriptor)toprocess.iterator().next();
43 Set callees=cg.getCalleeSet(md);
44 for(Iterator it=callees.iterator();it.hasNext();) {
45 MethodDescriptor md2=(MethodDescriptor)it.next();
46 if (!discovered.contains(md2)) {
51 if (md.getClassDesc().getSymbol().equals(TypeUtil.ThreadClass)&&
52 md.getSymbol().equals("start")&&!md.getModifiers().isStatic()&&
53 md.numParameters()==0) {
55 MethodDescriptor runmd=null;
56 for(Iterator methodit=md.getClassDesc().getMethodTable().getSet("run").iterator(); methodit.hasNext();) {
57 MethodDescriptor mdrun=(MethodDescriptor) methodit.next();
58 if (mdrun.numParameters()!=0||mdrun.getModifiers().isStatic())
64 Set runmethodset=cg.getMethods(runmd);
65 for(Iterator it=runmethodset.iterator();it.hasNext();) {
66 MethodDescriptor md2=(MethodDescriptor)it.next();
67 if (!discovered.contains(md2)) {
72 } else throw new Error("Can't find run method");
78 for(Iterator it=discovered.iterator();it.hasNext();) {
79 MethodDescriptor md=(MethodDescriptor)it.next();
80 Set callees=cg.getCalleeSet(md);
81 for(Iterator cit=callees.iterator();cit.hasNext();) {
82 MethodDescriptor md2=(MethodDescriptor)cit.next();
83 if (fields.get(md).addAll(fields.get(md2)))
85 if (arrays.get(md).addAll(arrays.get(md2)))
87 if (containsAtomic.contains(md2)) {
88 if (containsAtomic.add(md))
91 if (containsBarrier.contains(md2)) {
92 if (containsBarrier.add(md))
100 public boolean containsAtomic(MethodDescriptor md) {
101 return containsAtomic.contains(md);
104 public boolean containsBarrier(MethodDescriptor md) {
105 return containsBarrier.contains(md);
108 public Set<FieldDescriptor> getFields(MethodDescriptor md) {
109 return fields.get(md);
112 public Set<TypeDescriptor> getArrays(MethodDescriptor md) {
113 return arrays.get(md);
116 public void analyzeMethod(MethodDescriptor md) {
117 fields.put(md, new HashSet<FieldDescriptor>());
118 arrays.put(md, new HashSet<TypeDescriptor>());
120 FlatMethod fm=st.getMethodFlat(md);
121 for(Iterator it=fm.getNodeSet().iterator();it.hasNext();) {
122 FlatNode fn=(FlatNode)it.next();
123 if (fn.kind()==FKind.FlatSetElementNode) {
124 FlatSetElementNode fsen=(FlatSetElementNode)fn;
125 arrays.get(md).add(fsen.getDst().getType());
126 } else if (fn.kind()==FKind.FlatSetFieldNode) {
127 FlatSetFieldNode fsfn=(FlatSetFieldNode)fn;
128 fields.get(md).add(fsfn.getField());
129 } else if (fn.kind()==FKind.FlatAtomicEnterNode) {
130 containsAtomic.add(md);
131 } else if (fn.kind()==FKind.FlatCall) {
132 MethodDescriptor mdcall=((FlatCall)fn).getMethod();
133 if (mdcall.getSymbol().equals("enterBarrier")&&
134 mdcall.getClassDesc().getSymbol().equals("Barrier"))
135 containsBarrier.add(md);