View Javadoc

1   package joeq.Compiler.Analysis.IPSSA.Apps;
2   
3   import java.util.Arrays;
4   import java.util.Collection;
5   import java.util.Collections;
6   import java.util.HashMap;
7   import java.util.HashSet;
8   import java.util.Iterator;
9   import java.util.LinkedList;
10  import java.util.Set;
11  import java.io.BufferedReader;
12  import java.io.FileReader;
13  import java.io.IOException;
14  import joeq.Class.PrimordialClassLoader;
15  import joeq.Class.jq_Class;
16  import joeq.Class.jq_InstanceField;
17  import joeq.Class.jq_Method;
18  import joeq.Class.jq_Type;
19  import joeq.Compiler.Quad.CallGraph;
20  import joeq.Compiler.Quad.CodeCache;
21  import joeq.Compiler.Quad.RootedCHACallGraph;
22  import joeq.Main.HostedVM;
23  import jwutil.collections.AppendIterator;
24  
25  public class DeclarationDepth {
26      static class DeclarationDepthComputation implements Runnable {
27          private Set _classes;
28          LinkedList  worklist = new LinkedList();
29          HashMap     values   = new HashMap(); 
30          
31          private boolean _verbose = false;
32          
33          public DeclarationDepthComputation(Iterator classIter){
34              _classes = new HashSet();
35              Collection roots = new LinkedList();
36              
37              while(classIter.hasNext()) {
38                  jq_Class c = (jq_Class) jq_Type.parseType((String)classIter.next());
39                  c.load();
40                  _classes.add(c);
41                  roots.addAll(Arrays.asList(c.getDeclaredStaticMethods()));
42              }
43              
44              CallGraph cg = new RootedCHACallGraph();
45              cg.setRoots(roots);
46              for(Iterator iter = cg.getAllMethods().iterator(); iter.hasNext(); ) {
47                  jq_Class c = ((jq_Method)iter.next()).getDeclaringClass();
48                  _classes.add(c);
49              }
50              System.out.println("Processing a total of " + _classes.size() + " class(es)");
51          }
52          
53          public static void main(String[] args) {
54              HostedVM.initialize();
55              CodeCache.AlwaysMap = true;
56              ///initPredefinedClasses();
57              //ClassAndMethod.initializeClasses();
58              
59              Iterator i = null;
60              for (int x=0; x<args.length; ++x) {
61                  if (args[x].equals("-file")) {
62                      try {
63                          BufferedReader br = new BufferedReader(new FileReader(args[++x]));
64                          LinkedList list = new LinkedList();
65                          for (;;) {
66                              String s = br.readLine();
67                              if (s == null) break;
68                              if (s.length() == 0) continue;
69                              if (s.startsWith("%")) continue;
70                              if (s.startsWith("#")) continue;
71                              list.add(s);
72                          }
73                          i = new AppendIterator(list.iterator(), i);
74                      }catch(IOException e) {
75                          e.printStackTrace();
76                          System.exit(2);
77                      }
78                      
79                  } else
80                      if (args[x].endsWith("*")) {
81                          i = new AppendIterator(PrimordialClassLoader.loader.listPackage(args[x].substring(0, args[x].length()-1)), i);
82                      } else 
83                          if(args[x].charAt(0) == '-'){
84                              System.exit(2);                    
85                          }else {
86                              String classname = args[x];
87                              i = new AppendIterator(Collections.singleton(classname).iterator(), i);
88                          }
89              }
90  
91              DeclarationDepthComputation finder = new DeclarationDepthComputation(i);
92              finder.run();
93          }
94          
95          public void run() {
96              worklist.addAll(_classes);
97              boolean change = false;
98              int iterCount = 0;
99              do {
100                 change = false;
101                 for(Iterator iter = worklist.iterator(); iter.hasNext();) {
102                     jq_Class c = (jq_Class)iter.next();
103                                     
104                     change |= processClass(c);
105                 }
106                 System.err.println("Done with the worklist, iteration # " + ++iterCount);
107             } while(change && iterCount < 20);
108          
109             System.out.println("Results:");
110             for(Iterator iter = values.keySet().iterator(); iter.hasNext(); ) {
111                 jq_Class c = (jq_Class) iter.next();
112                 Integer i = (Integer) values.get(c);
113                 System.out.println(cutto(c.toString(), 45) + " : " + i);
114             }
115         }
116 
117         private boolean processClass(jq_Class c) {
118             //System.out.println("Processing class " + c);
119             if(values.get(c) == null) values.put(c, new Integer(0));
120             int oldValue = ((Integer)values.get(c)).intValue();
121             
122             int newValue = 0;
123             jq_InstanceField[] fields = c.getDeclaredInstanceFields();
124             for(int i = 0; i < fields.length; i++) {
125                 jq_InstanceField m = fields[i];
126                 if(! (m.getType() instanceof jq_Class) ) continue;
127                 
128                 jq_Class type = (jq_Class) m.getType();
129                 if(type == c) continue;
130                 
131                 if(values.get(type) == null) {
132                     // no information for type -- initialize it
133                     if(newValue < 1) newValue = 1; 
134                 } else {
135                     int d = ((Integer)values.get(type)).intValue();
136                     if(d+1 > newValue) newValue = d+1;  
137                 }
138             }
139             if(newValue != oldValue) {
140                 values.put(c, new Integer(newValue));
141                 System.err.println("Value for " + c + " changed to " + newValue);
142                 return true;
143             } else {            
144                 return false;
145             }
146         }
147         
148         private static String cutto(String string, int to) {
149             return string.length() < to ? 
150                                          string + repeat(" ", to - string.length()) : 
151                                              string.substring(0, to - 3) + "..."; 
152         }
153         private static String repeat(String string, int to) {
154             StringBuffer result = new StringBuffer();
155             for(int i = 0; i < to; i++) {
156                 result.append(string);  
157             }
158             
159             return result.toString();
160         }
161     }
162 }