View Javadoc

1   // TraceFlags.java, created Mon Feb  5 23:23:21 2001 by joewhaley
2   // Copyright (C) 2001-3 John Whaley <jwhaley@alum.mit.edu>
3   // Licensed under the terms of the GNU LGPL; see COPYING for details.
4   package joeq.Main;
5   
6   import java.util.Collection;
7   import java.util.Iterator;
8   import java.lang.reflect.Field;
9   import joeq.Class.PrimordialClassLoader;
10  import joeq.Class.jq_Array;
11  import joeq.Class.jq_Class;
12  import joeq.Class.jq_Member;
13  import joeq.Class.jq_Primitive;
14  import joeq.Class.jq_StaticField;
15  import joeq.Class.jq_Type;
16  import joeq.Runtime.Debug;
17  import joeq.Runtime.Reflection;
18  import joeq.UTF.Utf8;
19  import jwutil.collections.Filter;
20  import jwutil.reflect.Reflect;
21  import jwutil.util.Assert;
22  
23  /***
24   * @author  John Whaley <jwhaley@alum.mit.edu>
25   * @version $Id: TraceFlags.java 1985 2004-10-08 08:43:02Z joewhaley $
26   */
27  public abstract class TraceFlags {
28  
29      public static int setTraceFlag(String[] args, int i) {
30          if (args[i].equalsIgnoreCase("-TraceCodeAllocator")) {
31              makeTrue("joeq.Allocator.CodeAllocator", "TRACE");
32              makeTrue("joeq.Allocator.RuntimeCodeAllocator", "TRACE");
33              return i+1;
34          }
35          if (args[i].equalsIgnoreCase("-TraceAssembler")) {
36              makeTrue("joeq.Assembler.x86.x86Assembler", "TRACE");
37              return i+1;
38          }
39          if (args[i].equalsIgnoreCase("-TraceBC2Quad")) {
40              makeTrue("joeq.Compiler.Quad.BytecodeToQuad","ALWAYS_TRACE");
41              makeTrue("joeq.Compiler.Quad.BytecodeToQuad.AbstractState","TRACE");
42              return i+1;
43          }
44          if (args[i].equalsIgnoreCase("-TraceLiveRef")) {
45              makeTrue("joeq.Compiler.BytecodeAnalysis.LiveRefAnalysis","ALWAYS_TRACE");
46              return i+1;
47          }
48          if (args[i].equalsIgnoreCase("-TraceBootImage")) {
49              makeTrue("joeq.Bootstrap.SinglePassBootImage","TRACE");
50              return i+1;
51          }
52          if (args[i].equalsIgnoreCase("-TraceObjectTraverser")) {
53              makeTrue("joeq.Runtime.ObjectTraverser","TRACE");
54              return i+1;
55          }
56          if (args[i].equalsIgnoreCase("-TraceClassLoader")) {
57              makeTrue("joeq.Class.PrimordialClassLoader","TRACE");
58              return i+1;
59          }
60          if (args[i].equalsIgnoreCase("-TraceClass")) {
61              makeTrue("joeq.Class.jq_Class","TRACE");
62              makeTrue("joeq.Class.jq_Array","TRACE");
63              return i+1;
64          }
65          if (args[i].equalsIgnoreCase("-TraceConstantPool")) {
66              makeTrue("joeq.Class.jq_ConstantPool","TRACE");
67              return i+1;
68          }
69          if (args[i].equalsIgnoreCase("-TraceExceptions")) {
70              makeTrue("joeq.Class.jq_CompiledCode","TRACE");
71              makeTrue("joeq.Compiler.Reference.x86.x86ReferenceExceptionDeliverer","TRACE");
72              makeTrue("joeq.Runtime.ExceptionDeliverer","TRACE");
73              return i+1;
74          }
75          if (args[i].equalsIgnoreCase("-TraceTrimmer")) {
76              makeTrue("joeq.Compiler.BytecodeAnalysis.Trimmer","TRACE");
77              makeTrue("joeq.Bootstrap.BootstrapRootSet","TRACE");
78              return i+1;
79          }
80          if (args[i].equalsIgnoreCase("-TraceCompiler")) {
81              makeTrue("joeq.Compiler.Reference.x86.x86ReferenceCompiler","ALWAYS_TRACE");
82              return i+1;
83          }
84          if (args[i].equalsIgnoreCase("-TraceCompileStubs")) {
85              makeTrue("joeq.Compiler.Reference.x86.x86ReferenceCompiler","TRACE_STUBS");
86              return i+1;
87          }
88          if (args[i].equalsIgnoreCase("-TraceLinker")) {
89              makeTrue("joeq.Compiler.Reference.x86.x86ReferenceLinker","TRACE");
90              return i+1;
91          }
92          if (args[i].equalsIgnoreCase("-TraceInterpreter")) {
93              makeTrue("joeq.Interpreter.BytecodeInterpreter","ALWAYS_TRACE");
94              return i+1;
95          }
96          if (args[i].equalsIgnoreCase("-TraceQuadInterpreter")) {
97              makeTrue("joeq.Interpreter.QuadInterpreter","TRACE");
98              return i+1;
99          }
100         if (args[i].equalsIgnoreCase("-TraceStackWalker")) {
101             makeTrue("joeq.Runtime.StackCodeWalker","TRACE");
102             return i+1;
103         }
104         if (args[i].equalsIgnoreCase("-TraceUtf8")) {
105             makeTrue("joeq.UTF.Utf8","TRACE");
106             return i+1;
107         }
108         if (args[i].equalsIgnoreCase("-TraceScheduler")) {
109             makeTrue("joeq.Scheduler.jq_NativeThread","TRACE");
110             makeTrue("joeq.Scheduler.jq_InterrupterThread","TRACE");
111             return i+1;
112         }
113         if (args[i].equalsIgnoreCase("-TraceLocks")) {
114             makeTrue("joeq.Runtime.Monitor","TRACE");
115             return i+1;
116         }
117         /* ARGH: Fix this. */
118         if (args[i].equalsIgnoreCase("-TraceByMethodName")) {
119             addReflect("joeq.Compiler.Reference.x86.x86ReferenceCompiler","TraceMethod_MethodNames", args[++i]);
120             return i+1;
121         }
122         if (args[i].equalsIgnoreCase("-TraceByClassName")) {
123             addReflect("joeq.Compiler.Reference.x86.x86ReferenceCompiler","TraceMethod_ClassNames", args[++i]);
124             return i+1;
125         }
126         if (args[i].equalsIgnoreCase("-TraceBCByMethodName")) {
127             addReflect("joeq.Compiler.Reference.x86.x86ReferenceCompiler","TraceBytecode_MethodNames", args[++i]);
128             return i+1;
129         }
130         if (args[i].equalsIgnoreCase("-TraceBCByClassName")) {
131             addReflect("joeq.Compiler.Reference.x86.x86ReferenceCompiler","TraceBytecode_ClassNames", args[++i]);
132             return i+1;
133         }
134         if (args[i].equalsIgnoreCase("-ReplaceClass")) {
135             makeTrue("joeq.Class.jq_Class","REPLACE_CLASS");
136             // collect a list of classes to replace
137             String s = args[++i];
138             for (;;) {
139                 int index1 = s.indexOf(';');
140                 int index2 = s.indexOf(':');
141                 int index = (index1 == -1)?index2:((index2 == -1)?index1:Math.min(index1, index2));
142                 if (index != -1) {
143                     String className = s.substring(0, index);
144                     joeq.Class.jq_Class.classToReplace.add(className);
145                     s = s.substring(index+1);
146                 } else {
147                     joeq.Class.jq_Class.classToReplace.add(s);
148                     break;
149                 }
150             }
151             return i+1;
152         }
153         if (args[i].equalsIgnoreCase("-TraceReplaceClass")) {
154             makeTrue("joeq.Class.jq_Class","TRACE_REPLACE_CLASS");
155             return i+1;
156         }
157         if (args[i].equalsIgnoreCase("-SetCompiler")) {
158             Reflect.invoke("joeq.Class.Delegates", "setDefaultCompiler", new Object[] { args[++i] });
159             return i+1;
160         }
161         if (args[i].equalsIgnoreCase("-UseCompilerForClasses")) {
162             Object d = Reflect.invoke("joeq.Class.Delegates", "getCompiler", new Object[] { args[++i] });
163             Object c = new jq_Member.FilterByShortClassName(args[++i]);
164             Reflect.invoke("joeq.Class.Delegates", "registerCompiler",
165                            new Class[] { Filter.class, 
166                                          joeq.Compiler.CompilerInterface.class },
167                            new Object[] { c, d });
168             return i+1;
169         }
170         if (args[i].equalsIgnoreCase("-UseCompilerForMethods")) {
171             Object d = Reflect.invoke("joeq.Class.Delegates", "getCompiler", new Object[] { args[++i] });
172             Object c = new jq_Member.FilterByName(args[++i]);
173             Reflect.invoke("joeq.Class.Delegates", "registerCompiler",
174                            new Class[] { Filter.class, 
175                                          joeq.Compiler.CompilerInterface.class },
176                            new Object[] { c, d });
177             return i+1;
178         }
179         if (args[i].equalsIgnoreCase("-Set")) {
180             String fullName = args[++i];
181             int b = fullName.lastIndexOf('.') + 1;
182             String fieldName = fullName.substring(b);
183             String className = fullName.substring(0, b - 1);
184             try {
185                 jq_Class c = (jq_Class) jq_Type.parseType(className);
186                 c.cls_initialize();
187                 jq_StaticField m = null;
188                 Utf8 sf_name = Utf8.get(fieldName);
189                 for (Iterator it = java.util.Arrays.asList(c.getDeclaredStaticFields()).iterator(); it.hasNext();) {
190                     jq_StaticField sm = (jq_StaticField) it.next();
191                     if (sm.getName() == sf_name) {
192                         m = sm;
193                         break;
194                     }
195                 }
196                 if (m != null) {
197                     java.lang.reflect.Field f = (java.lang.reflect.Field) Reflection.getJDKMember(m);
198                     f.setAccessible(true);
199                     Object[] o = new Object[1];
200                     i = parseArg(o, 0, m.getType(), args, i);
201                     f.set(null, o[0]);
202                 } else {
203                     System.err.println("Class " + fullName.substring(0, b - 1) + " doesn't contain a static field with name " + fieldName);
204                 }
205             } catch (NoClassDefFoundError x) {
206                 System.err.println("Class " + fullName.substring(0, b - 1) + " (canonical name " + className + ") not found.");
207                 return i;
208             } catch (IllegalAccessException x) {
209                 System.err.println("Cannot access field: " + x);
210                 return i+1;
211             }
212             return i+1;
213         }
214         return i;
215     }
216 
217     public static int parseArg(Object[] args, int m, jq_Type type, String[] s_args, int j) {
218         if (type == PrimordialClassLoader.getJavaLangString())
219             args[m] = s_args[++j];
220         else if (type == jq_Primitive.BOOLEAN)
221             args[m] = Boolean.valueOf(s_args[++j]);
222         else if (type == jq_Primitive.BYTE)
223             args[m] = Byte.valueOf(s_args[++j]);
224         else if (type == jq_Primitive.SHORT)
225             args[m] = Short.valueOf(s_args[++j]);
226         else if (type == jq_Primitive.CHAR)
227             args[m] = new Character(s_args[++j].charAt(0));
228         else if (type == jq_Primitive.INT)
229             args[m] = Integer.valueOf(s_args[++j]);
230         else if (type == jq_Primitive.LONG) {
231             args[m] = Long.valueOf(s_args[++j]);
232         } else if (type == jq_Primitive.FLOAT)
233             args[m] = Float.valueOf(s_args[++j]);
234         else if (type == jq_Primitive.DOUBLE) {
235             args[m] = Double.valueOf(s_args[++j]);
236         } else if (type.isArrayType()) {
237             if (!s_args[++j].equals("{"))
238                 Assert.UNREACHABLE("array parameter doesn't start with {");
239             int count = 0;
240             while (!s_args[++j].equals("}")) ++count;
241             jq_Type elementType = ((jq_Array) type).getElementType();
242             if (elementType == PrimordialClassLoader.getJavaLangString()) {
243                 String[] array = new String[count];
244                 for (int k = 0; k < count; ++k)
245                     array[k] = s_args[j - count + k];
246                 args[m] = array;
247             } else if (elementType == jq_Primitive.BOOLEAN) {
248                 boolean[] array = new boolean[count];
249                 for (int k = 0; k < count; ++k)
250                     array[k] = Boolean.valueOf(s_args[j - count + k]).booleanValue();
251                 args[m] = array;
252             } else if (elementType == jq_Primitive.BYTE) {
253                 byte[] array = new byte[count];
254                 for (int k = 0; k < count; ++k)
255                     array[k] = Byte.parseByte(s_args[j - count + k]);
256                 args[m] = array;
257             } else if (elementType == jq_Primitive.SHORT) {
258                 short[] array = new short[count];
259                 for (int k = 0; k < count; ++k)
260                     array[k] = Short.parseShort(s_args[j - count + k]);
261                 args[m] = array;
262             } else if (elementType == jq_Primitive.CHAR) {
263                 char[] array = new char[count];
264                 for (int k = 0; k < count; ++k)
265                     array[k] = s_args[j - count + k].charAt(0);
266                 args[m] = array;
267             } else if (elementType == jq_Primitive.INT) {
268                 int[] array = new int[count];
269                 for (int k = 0; k < count; ++k)
270                     array[k] = Integer.parseInt(s_args[j - count + k]);
271                 args[m] = array;
272             } else if (elementType == jq_Primitive.LONG) {
273                 long[] array = new long[count];
274                 for (int k = 0; k < count; ++k)
275                     array[k] = Long.parseLong(s_args[j - count + k]);
276                 args[m] = array;
277             } else if (elementType == jq_Primitive.FLOAT) {
278                 float[] array = new float[count];
279                 for (int k = 0; k < count; ++k)
280                     array[k] = Float.parseFloat(s_args[j - count + k]);
281                 args[m] = array;
282             } else if (elementType == jq_Primitive.DOUBLE) {
283                 double[] array = new double[count];
284                 for (int k = 0; k < count; ++k)
285                     array[k] = Double.parseDouble(s_args[j - count + k]);
286                 args[m] = array;
287             } else
288                 Assert.UNREACHABLE("Parsing of type " + type + " is not implemented");
289         } else
290             Assert.UNREACHABLE("Parsing of type " + type + " is not implemented");
291         return j;
292     }
293 
294     public static void addReflect(String classname, String collectionname, Object toadd) {
295         try {
296             Class c = Class.forName(classname);
297             Field f = c.getField(collectionname);
298             Collection col = (Collection)f.get(null);
299             col.add(toadd);
300         } catch (Exception e) {
301             Debug.writeln("Cannot add to collection "+classname+"."+collectionname);
302         }
303     }
304     
305     public static void makeTrue(String className, String fieldName) {
306         Reflect.setBooleanField(className, fieldName, true);
307     }
308     
309 }