1
2
3
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
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
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 }