implemented PCLOC annotation.
[IRC.git] / Robust / src / IR / Virtual.java
1 package IR;
2 import java.util.*;
3
4 import Analysis.Locality.LocalityBinding;
5 import Analysis.Locality.LocalityAnalysis;
6 import Analysis.CallGraph.CallGraph;
7
8 public class Virtual {
9   State state;
10   LocalityAnalysis locality;
11   Hashtable<MethodDescriptor, Integer> methodnumber;
12   Hashtable<ClassDescriptor, Integer> classmethodcount;
13   Hashtable<LocalityBinding, Integer> localitynumber;
14   CallGraph callgraph;
15
16   // for interfaces
17   int if_starts;
18   SymbolTable if_methods;
19
20   public Integer getMethodNumber(MethodDescriptor md) {
21     return methodnumber.get(md);
22   }
23
24   public int getMethodCount(ClassDescriptor md) {
25     return classmethodcount.get(md).intValue();
26   }
27
28   public int getLocalityNumber(LocalityBinding lb) {
29     return localitynumber.get(lb).intValue();
30   }
31
32   public Virtual(State state, LocalityAnalysis locality, CallGraph callgraph) {
33     this.state=state;
34     this.locality=locality;
35     this.if_starts = 0;
36     this.if_methods = new SymbolTable();
37     this.callgraph=callgraph;
38     classmethodcount=new Hashtable<ClassDescriptor, Integer>();
39     if (state.DSM||state.SINGLETM)
40       localitynumber=new Hashtable<LocalityBinding, Integer>();
41     else
42       methodnumber=new Hashtable<MethodDescriptor, Integer>();
43     doAnalysis();
44   }
45
46   private void doAnalysis() {
47     Iterator classit=state.getClassSymbolTable().getDescriptorsIterator();
48     while(classit.hasNext()) {
49       ClassDescriptor cd=(ClassDescriptor)classit.next();
50       numberMethodsIF(cd);
51     }
52     classit=state.getClassSymbolTable().getDescriptorsIterator();
53     while(classit.hasNext()) {
54       ClassDescriptor cd=(ClassDescriptor)classit.next();
55       if (state.DSM||state.SINGLETM)
56         numberLocality(cd);
57       else
58         numberMethods(cd);
59     }
60     classit=state.getClassSymbolTable().getDescriptorsIterator();
61     while(classit.hasNext()) {
62       ClassDescriptor cd=(ClassDescriptor)classit.next();
63       if(!cd.isInterface()) {
64         int count = classmethodcount.get(cd).intValue();
65         classmethodcount.put(cd, new Integer(count+this.if_starts));
66       }
67     }
68   }
69
70   private int numberLocality(ClassDescriptor cd) {
71     if (classmethodcount.containsKey(cd))
72       return classmethodcount.get(cd).intValue();
73     ClassDescriptor superdesc=cd.getSuperDesc();
74     int start=0;
75     if (superdesc!=null)
76       start=numberLocality(superdesc);
77
78     if (locality.getClassBindings(cd)!=null)
79       for(Iterator<LocalityBinding> lbit=locality.getClassBindings(cd).iterator(); lbit.hasNext(); ) {
80         LocalityBinding lb=lbit.next();
81         MethodDescriptor md=lb.getMethod();
82         //Is it a static method or constructor
83         if (md.isStatic()||md.getReturnType()==null)
84           continue;
85
86         if (superdesc!=null) {
87           Set possiblematches=superdesc.getMethodTable().getSet(md.getSymbol());
88           boolean foundmatch=false;
89           for(Iterator matchit=possiblematches.iterator(); matchit.hasNext(); ) {
90             MethodDescriptor matchmd=(MethodDescriptor)matchit.next();
91             if (md.matches(matchmd)) {
92               Set<LocalityBinding> lbset=locality.getMethodBindings(matchmd);
93               if (lbset!=null)
94                 for(Iterator<LocalityBinding> suplbit=lbset.iterator(); suplbit.hasNext(); ) {
95                   LocalityBinding suplb=suplbit.next();
96                   if (lb.contextMatches(suplb)) {
97                     foundmatch=true;
98                     localitynumber.put(lb, localitynumber.get(suplb));
99                     break;
100                   }
101                 }
102               break;
103             }
104           }
105           if (!foundmatch)
106             localitynumber.put(lb, new Integer(start++));
107         } else {
108           localitynumber.put(lb, new Integer(start++));
109         }
110       }
111     classmethodcount.put(cd, new Integer(start));
112     return start;
113   }
114
115   private int numberMethodsIF(ClassDescriptor cd) {
116     if(!cd.isInterface()) {
117       return 0;
118     }
119     int mnum = 0;
120     if (classmethodcount.containsKey(cd))
121       return classmethodcount.get(cd).intValue();
122     // check the inherited interfaces
123     Iterator it_sifs = cd.getSuperInterfaces();
124     while(it_sifs.hasNext()) {
125       ClassDescriptor superif = (ClassDescriptor)it_sifs.next();
126       mnum += numberMethodsIF(superif);
127     }
128     for(Iterator it=cd.getMethods(); it.hasNext(); ) {
129       MethodDescriptor md=(MethodDescriptor)it.next();
130       if (md.isStatic()||md.getReturnType()==null)
131         continue;
132
133       if (!callgraph.isCallable(md)&&!callgraph.isCalled(md))
134         continue;
135       boolean foundmatch=false;
136       // check if there is a matched method that has been assigned method num
137       Set possiblematches_if = if_methods.getSet(md.getSymbol());
138       for(Iterator matchit=possiblematches_if.iterator(); matchit.hasNext(); ) {
139         MethodDescriptor matchmd=(MethodDescriptor)matchit.next();
140         if (md.matches(matchmd)) {
141           int num=methodnumber.get(matchmd);
142           methodnumber.put(md, new Integer(num));
143           foundmatch=true;
144           break;
145         }
146       }
147       if (!foundmatch) {
148         methodnumber.put(md, new Integer(if_starts++));
149         if_methods.add(md);
150         mnum++;
151       }
152     }
153     classmethodcount.put(cd, new Integer(mnum));
154     return mnum;
155   }
156
157   private int numberMethods(ClassDescriptor cd) {
158     if (classmethodcount.containsKey(cd))
159       return classmethodcount.get(cd).intValue();
160     ClassDescriptor superdesc=cd.getSuperDesc();
161     int start=if_starts;
162     int mnum = 0;
163     if (superdesc!=null) {
164       mnum = numberMethods(superdesc);
165       start += mnum;
166     }
167 methodit:
168     for(Iterator it=cd.getMethods(); it.hasNext(); ) {
169       MethodDescriptor md=(MethodDescriptor)it.next();
170       if (md.isStatic()||md.getReturnType()==null)
171         continue;
172       if (!callgraph.isCallable(md)&&!callgraph.isCalled(md))
173         continue;
174       // check if there is a matched method in methods defined in interfaces
175       Set possiblematches_if=if_methods.getSet(md.getSymbol());
176       for(Iterator matchit=possiblematches_if.iterator(); matchit.hasNext(); ) {
177         MethodDescriptor matchmd=(MethodDescriptor)matchit.next();
178         if (md.matches(matchmd)) {
179           int num;
180           if (!methodnumber.containsKey(matchmd)) {
181             num=start++;
182             mnum++;
183             methodnumber.put(matchmd,num);
184           } else
185             num = methodnumber.get(matchmd);
186           methodnumber.put(md, new Integer(num));
187           continue methodit;
188         }
189       }
190       if (superdesc!=null) {
191         Set possiblematches=superdesc.getMethodTable().getSet(md.getSymbol());
192         for(Iterator matchit=possiblematches.iterator(); matchit.hasNext(); ) {
193           MethodDescriptor matchmd=(MethodDescriptor)matchit.next();
194           if (md.matches(matchmd)) {
195             int num;
196             if (!methodnumber.containsKey(matchmd)) {
197               num=start++;
198               mnum++;
199               methodnumber.put(matchmd,num);
200             } else
201               num = methodnumber.get(matchmd);
202             methodnumber.put(md, new Integer(num));
203             continue methodit;
204           }
205         }
206       }
207
208       methodnumber.put(md, new Integer(start++));
209       mnum++;
210     }
211     classmethodcount.put(cd, new Integer(mnum));
212     return mnum;
213   }
214 }
215