new write barrier class
[IRC.git] / Robust / src / Analysis / Loops / GlobalFieldType.java
1 package Analysis.Loops;
2
3 import IR.Flat.*;
4 import IR.State;
5 import IR.MethodDescriptor;
6 import IR.FieldDescriptor;
7 import IR.TypeDescriptor;
8 import Analysis.CallGraph.*;
9 import java.util.Iterator;
10 import java.util.HashSet;
11 import java.util.Hashtable;
12 import java.util.Set;
13
14 public class GlobalFieldType {
15   CallGraph cg;
16   State st;
17   MethodDescriptor root;
18   Hashtable<MethodDescriptor, Set<FieldDescriptor>> fields;
19   Hashtable<MethodDescriptor, Set<TypeDescriptor>> arrays;
20   HashSet<MethodDescriptor> containsAtomic;
21   
22   public GlobalFieldType(CallGraph cg, State st, MethodDescriptor root) {
23     this.cg=cg;
24     this.st=st;
25     this.root=root;
26     this.fields=new Hashtable<MethodDescriptor, Set<FieldDescriptor>>();
27     this.arrays=new Hashtable<MethodDescriptor, Set<TypeDescriptor>>();
28     this.containsAtomic=new HashSet<MethodDescriptor>();
29     doAnalysis();
30   }
31   private void doAnalysis() {
32     HashSet toprocess=new HashSet();
33     toprocess.add(root);
34     HashSet discovered=new HashSet();
35     discovered.add(root);
36     while(!toprocess.isEmpty()) {
37       MethodDescriptor md=(MethodDescriptor)toprocess.iterator().next();
38       toprocess.remove(md);
39       analyzeMethod(md);
40       Set callees=cg.getCalleeSet(md);
41       for(Iterator it=callees.iterator();it.hasNext();) {
42         MethodDescriptor md2=(MethodDescriptor)it.next();
43         if (!discovered.contains(md2)) {
44           discovered.add(md2);
45           toprocess.add(md2);
46         }
47       }
48     }
49     boolean changed=true;
50     while(changed) {
51       changed=false;
52       for(Iterator it=discovered.iterator();it.hasNext();) {
53         MethodDescriptor md=(MethodDescriptor)it.next();
54         Set callees=cg.getCalleeSet(md);
55         for(Iterator cit=callees.iterator();cit.hasNext();) {
56           MethodDescriptor md2=(MethodDescriptor)cit.next();
57           if (fields.get(md).addAll(fields.get(md2)))
58             changed=true;
59           if (arrays.get(md).addAll(arrays.get(md2)))
60             changed=true;
61           if (containsAtomic.contains(md2)) {
62             if (containsAtomic.add(md))
63               changed=true;
64           }
65         }
66       }
67     }
68   }
69
70   public boolean containsAtomic(MethodDescriptor md) {
71     return containsAtomic.contains(md);
72   }
73
74   public Set<FieldDescriptor> getFields(MethodDescriptor md) {
75     return fields.get(md);
76   }
77
78   public Set<TypeDescriptor> getArrays(MethodDescriptor md) {
79     return arrays.get(md);
80   }
81
82   public void analyzeMethod(MethodDescriptor md) {
83     fields.put(md, new HashSet<FieldDescriptor>());
84     arrays.put(md, new HashSet<TypeDescriptor>());
85     
86     FlatMethod fm=st.getMethodFlat(md);
87     for(Iterator it=fm.getNodeSet().iterator();it.hasNext();) {
88       FlatNode fn=(FlatNode)it.next();
89       if (fn.kind()==FKind.FlatSetElementNode) {
90         FlatSetElementNode fsen=(FlatSetElementNode)fn;
91         arrays.get(md).add(fsen.getDst().getType());
92       } else if (fn.kind()==FKind.FlatSetFieldNode) {
93         FlatSetFieldNode fsfn=(FlatSetFieldNode)fn;
94         fields.get(md).add(fsfn.getField());
95       } else if (fn.kind()==FKind.FlatAtomicEnterNode) {
96         containsAtomic.add(md);
97       }
98     }
99   }
100 }