1 // jq.java, created Fri Aug 16 16:04:04 2002 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.List;
7
8 /***
9 *
10 * @author John Whaley <jwhaley@alum.mit.edu>
11 * @version $Id: jq.java 1448 2004-03-09 01:49:01Z jwhaley $
12 */
13
14 // FIXED BUGS:
15 // off-by-one error jq_Atom
16 // alg error constantpool forward refs
17 // cut & paste error, used old idx rather than new one
18 // misunderstanding of class file descriptor spec
19 // when initializing type descriptors, byte to string converts to int, not char
20 // cut & paste error, forgot to change memcmp in utf8.get
21 // forgot a "break" in big bytecode traverser switch statement
22 // off-by-one error, index should start at -1 in bytecode traverser
23 // parsed array descriptors in constant pool as class descriptors
24 // forgot to set constant_pool_tag to resolved when field is known at load time
25 // forgot to set resolved flag in InstanceField.resolve()
26 // java.lang.Character contains invalid UTF8 (-32,-108,-124), disabled strict checking.
27 // forgot to add root set of classes to Trimmer, so codegen of new jq_Class failed
28 // added default types to Trimmer without preparing them
29 // forgot to recompile Trimmer after change
30 // assumed entrySet() returned set of objects rather than Map.Entry objects
31 // forgot to change result of Class.getName() from '.' delimiters to '/' delimiters
32 // in compiler, direct-bind invokes didn't check if the target method was compiled yet
33 // interleaving trimming and compiling was wrong. we need to trim all classes, then compile.
34 // in trim, forgot to reset field and method offsets to INVALID_OFFSET
35 // in trim, forgot to reset overrides flag for virtual methods
36 // accidentally reversed isConstant test in jq_StaticField
37 // off-by-one error in check to grow array in x86CodeBuffer
38 // cut-and-paste error: forgot to update assertion about instruction length in x86
39 // forgot to initialize address field in ObjectMap.Entry
40 // in trim, forgot to add vtable to root set
41 // cut-and-paste error: shift amounts for writing array elements
42 // in bootstrapper, need to traverse classes even if they are never instantiated
43 // in trimmer, forgot to load classes for getfield/putfield ops
44 // in trimmer, forgot to add root method to necessary member set
45 // in bootstrapper, java/lang/Object static fields were allocated first
46 // in bootstrapper, forgot to initialize static fields
47 // in trimmer, forgot to add current static field values as instantiated types
48 // in trimmer, not only current static field values, but everything reachable from them are instantiated
49 // debugmsg takes byte array, not char array.
50 // cut-and-paste error; writing to object arrays shifted by 3 instead of 2
51 // forgot to initialize vtable after compiling instance methods
52 // compared to 0 instead of INVALID_OFFSET in InstanceMethod.isVirtual
53 // native routines should be marked __stdcall
54 // in assembler, forgot to change endianness of 16 bit constants
55 // vtable entries for inherited methods were not getting initialized
56 // when backpatching forward branches, the pointer points after the site to be branched, rather than before
57 // +/- error when calculating backward branch offsets
58 // when calling Unsafe methods, codegen was assuming it needed to push the return values
59 // reversed the order of the arguments in compilation of Unsafe.poke
60 // SHIFT_ONCE value was incorrect
61 // field offsets were all off by OBJ_HEADER_SIZE
62 // conditional near backward jumps were off by 1 byte (instruction length 6, not 5)
63 // put assertion in the wrong place in UTF8.isBootstrapJavaLang
64 // forgot to update jq_ClassLoader.getType when adding classlib bootstrap support
65 // UTF8.isBootstrapJavaLang test was not robust enough
66 // forgot to add hijack code when using reflection in Trimmer and Bootstrapper
67 // forgot to add fallback to hijack code when using reflection
68 // cut-and-paste error: incorrectly undid hijacking when getting value during getstatic of jq_Method type
69 // bug in UTF8.isValidMethodDescriptor, leading to infinite loop
70 // did isAssignable test in Trimmer on field type without checking if the type was loaded
71 // cut-and-paste error: in BytecodeVisitor, if_icmpne was doing CMP_EQ test
72 // when building vtable, checking superclasses used getMember rather than getVirtualMethod, causing vtable to be incorrect
73 // order of ops with << in invokeinterface
74 // in checkcast/instance_of, reversed arguments of call to isAssignable
75 // off-by-one error: forgot that invokeinterface runtime routine took an extra argument
76 // trimmed interface types by checking against instantiated types, which is wrong
77 // base object was wrong when calling getVirtualMethod when looking up interface methods in Trimmer
78 // calculated address of arguments, but forgot to do a "peek" in invokeinterface
79 // forgot to return value from invokeinterface
80 // fixed typo in Unsafe.getThreadBlock read from FS[14]
81 // cut-and-paste error: method exits were guarded by TraceBytecodes instead of TraceMethods
82 // arguments pushed to call to arraystorecheck were incorrect
83 // forgot to add System.in/out/err as necessary members
84 // need to map java.lang.Class objects to jav_.lang.Class objects during bootstrapping, because they don't have field jq_type
85 // likewise, need to map java.lang.ClassLoader objects to jav_.lang.ClassLoader
86 // sun.io.CharToSingleByteConverter was being created with reflection and therefore Trimmer didn't catch it
87 // forgot to change jq_Initializer and jq_ClassInitializer when adding VOID as a type
88 // when jikes compiles static class references, it puts an "L" at the start of the name, so it wasn't finding the field with reflection.
89 // skipped transient primitive fields caused a null pointer exception when writing their values
90 // forgot to subtract from startAddress in some of the poke() methods in BootImage
91 // calls to Unsafe were not successfully being bypassed in Trimmer (break; -> return;)
92 // forgot to add fields/methods from Unsafe as necessary, leading them to being trimmed and a crash in bytecode traversal
93 // code to trim references in constant pool replaced references with "jq_NameAndDesc" rather than "jq_MemberReference"
94 // accidentally added Unsafe.<clinit> to the necessary method list in Trimmer
95 // compiled_methods should not be a null static field
96 // 0xc001d00d was not causing a hardware trap when dereferenced!
97 // stupid typo in debugmsg(String), was calling itself rather than debugmsg(byte[])
98 // forgot to initialize jq_Type.class_object field during bootstrap
99 // in ObjectTraverser, forgot to add support for arrays/primitive types when mapping between jq_Type and Class objects
100 // primitive types use Integer.TYPE, not Integer.class
101 // __stdcall has arguments in reverse order on stack! changed SystemInterface to match.
102 // we can't actually skip transient fields (ArrayList.elementData is transient)
103 // can't use Integer to represent code locations, as Integer.compareTo throws a ClassCastException
104 // reversed the cases in jq_CompiledCode.compareTo, so it was never finding anything.
105 // problem when Object or x86ReferenceLinker contains a native or abstract method, because during compilation it recursively tries to initialize itself.
106 // adding compiled code when using bogus remapper crashes because the addresses are the same. disabled compilation during bogus remapping.
107 // confused order of reflective interpreter stack -> grows up, sp points to empty space
108 // accidently shifted getParamWords left by 2, causing the interpreter to crash
109 // forgot to check for null exception type in exception handling (from finally regions)
110 // forgot to add a 'return' when calling object initializer during interpretation, leading to stack underflow
111 // forgot to set thisptr param when calling getfield in reflective interpreter
112 // problem with trying to interpret abstract method. added assertions so that it will be easier to catch next time.
113 // forgot to roll back to previous state in interpreter when a method doesn't catch an exception
114 // variable assignment bug in reflective interpreter invokehelper, assigned to m rather than f
115 // can't call Thread.interrupt0 reflectively, so we skip over it in the reflective interpreter.
116 // the reflective interpreter was crashing on checkcast/instanceof of null
117 // correction to above- interpreter wasn't calling ANY private methods correctly. changed to use "getDeclaredMethod" rather than "getMethod"
118 // forgot to add fields to ObjectTraverser after adding them to JDK classes
119 // i2l is broken, it reversed the hi and lo words
120 // lcmp/fcmp/dcmp were broken, the branch was off by one so less than returned equals
121 // long shifts were incorrect, invalid instruction for AND_r_i8
122 // bug in transcribing uqdivrem function: misread "1" as "i"
123 // bug in x86CodeBuffer: when generated method overflowed the buffer, it initialized the counter to 0 rather than -1. Manifested as incorrect backpatching.
124 // frem/drem were incorrect because loads pushed the values on the stack, so they got reversed.
125 // left a value on the fp register stack when doing fcmp/dcmp/frem/drem, which eventually caused later FP operations to mysteriously return NaN
126 // in Trimmer, forgot to load/verify/prepare array classes from subarrays created with multinewarray
127 // cut-and-paste error: BytecodeVisitor for LASTORE actually called visitIASTORE
128 // arrayStoreCheck did not check for null before doing a getTypeOf on the object
129 // getJavaLangObject() didn't work, probably because of some incorrect field masking behavior. renamed it to prim_desc2type.
130 // forgot to add a base case to recursion in multinewarray_helper
131 // in compiler, forgot to pop args after call to multinewarray runtime function
132 // in multinewarray, looking up of varargs didn't take into account the two arguments already there
133 // in multinewarray, args were used in reverse order
134 // calculating the branch target in tableswitch was off by 4
135 // f2i/f2l/d2i/d2l were rounding the incorrect way for negative values
136 // used the wrong offset when loading back fp control word
137 // used wrong mask for rounding mode in fp control word (0x0c00 not 0x60)
138 // f2i/f2l/d2i/d2l did not handle exceptional cases (too big, too small, NaN) so I added explicit checks
139 // forgot to free floating point registers in f2i/f2l/d2i/d2l exceptional cases
140 // checking for catch blocks checked absolute ip's rather than offsets from code start, causing exceptions not to work
141 // long-standing bug in Trimmer, addSuperclassVirtualMethods didn't work at all because the loop condition was reversed (c==null vs. c!=null)
142 // bug in exception deliverer, order of operations: x<<2+4 is x<<(2+4) not (x<<2)+4
143 // can't use JMath as replacement for StrictMath because it messes up bootstrapping, so moved to a separate class and made them call it
144 // after bootstrapping, Class objects referred to the old system classloader. fixed objecttraverser to map old classloader to the new one.
145 // primordial classloader parent field referred to itself, leading to infinite recursion.
146 // findBootstrapClass added L...; to the class name twice.
147 // trycatch exception types were never actually being set (parameter name was "extype" rather than "exType")
148 // did a +4 rather than a -4 when setting the exception object when branching to a catch block
149 // looking up methods by ip didn't work if the ip pointed to the end address. changed >= to >.
150 // file open/close were not passing the file names as null-terminated byte strings
151 // bug in exception handler range check, the given offset refers to the instr after the one that threw the exception, so it should check (low,high], not [low,high)
152 // in reflective interpreter stack, popping longs was incorrect (did ++ instead of --)
153 // in interpreter, lcmp2 pushes int, not long
154 // in interpreter, lshift had the order of the two arguments reversed
155 // cut-and-paste error: in BytecodeVisitor, dstore was actually calling visitLSTORE
156 // forgot to load/verify/prepare exception types before doing type checks on them
157 // bug in synchronized hack in reflective interpreter: synchronized methods executed twice because monitorenter also executes them
158 // in reflective interpreter, exiting from a synchronized method didn't revert the state back to the old one.
159 // passing double parameters in reflective interpreter was broken, because it pushed the double value of the long bits, rather than the real double value.
160 // typo: interpreter was comparing FCMP2/DCMP2 arguments to "CMP_LT" rather than "CMP_L", leading it to always do the "CMP_G" case
161 // forgot to redirect Unsafe.getTypeOf in reflective interpreter
162 // forgot to redirect getJavaLangClassObject in reflective interpreter
163 // scratch the last one, getfield/getstatic now all go through the ObjectTraverser
164 // in FileInputStream.readBytes (and FileOutputStream.writeBytes), bounds check was off-by-one (off+len-1, not off+len)
165 // FileInputStream.read was returning the return code from the read() call, rather than the actual byte read
166 // files were being opened in text mode (default), causing reading to stop at the first ^Z character
167 // when a class is dynamically loaded, it may refer to methods/fields that were trimmed. oops!
168 // typo: field in ClassLoader was named _jq_type, rather than _desc2type
169 // typo: poke1 signature was (II)V, instead of (IB)V
170 // passed wrong flag into Trimmer (!TrimAllTypes == AddAllClassMembers)
171 // forgot to load/verify/prepare classes of methods added to the worklist in Trimmer
172 // forgot to redirect fields of java.util.zip.ZipFile after redirecting the class to org.jos.
173 // using reflection on java.lang.ref.Finalizer objects is bad. they change behind our backs.
174 // jq_StaticMethod/jq_StaticField.needsDynamicLink was incorrect. it should have been calling jq_Class.needsDynamicLink.
175 // some of the patch_ routines in x86ReferenceCompiler were patching with poke4 rather than poke2
176 // forgot to add "L" and ";" to class name of main class to load.
177 // had the wrong descriptor when searching for main method (forgot '[')
178 // reversed the order of code offset, bc index when building jq_BytecodeMap in reference compiler
179 // typo in linker: loaded class "_class" rather than class "k"
180 // when heap overflows, forgot to add object size to heapCurrent after allocating new block. caused seemingly random but completely repeatable crashes.
181 // patching invokestatic calls patched the absolute target address, not the relative offset to the target address.
182 // LineNumberTable is an attribute of Code, not of MethodInfo
183 // forgot to set jq_LineNumberBC as Comparable
184 // incorrectly assumed that instance methods never needed dynamic links (if the target method is not compiled, it is necessary)
185 // patch_invokevirtual instructions were incorrect
186 // backpatching assumed retloc was at the end of the backpatch region
187 // forgot to update return values from patch routines to reflect that retloc was not at the end of the backpatch region
188 // in reference compiler, can't assert that a method is an interface until the class is loaded.
189 // forgot to load/verify/prepare subarray types in isAssignable
190 // forgot to cls_initialize when doing newarray
191 // accidently was passing "args" to main, instead of "main_args", so the args included the main class name
192 // when running under win2000, calloc would return memory with a lower address than the boot image memory, messing up exception delivery
193 // forgot that cls_init could recursively call itself if a superclass created an object of a subclass's type in its clinit
194 // during startup, primitive descriptors may not yet be registered in desc2type, so we need to set primitive-typed field descriptors after registering the primitive types.
195 // incorrectly assumed that AllocEnabled in BootImage implied that Class objects would be allocated when doing state changes.
196 // accidentally used abs rather than EA when emitting code for cas4
197 // bug in putfield4 backpatch: was doing 8 bit version of instruction
198 // typo: when growing array in Win32FileSystem.list, did "s2 = s" rather than "s = s2"
199 // forgot to replace '.' with '/' when building descriptor for main class
200 // mixed up the from and to arguments in memcpy
201 // cut-and-paste bug in assembler: emit2_DISP32_SEImm8 was setting DISP8, rather than DISP32. manifested in iinc of large indexed local var.
202 // wrong flags to _open when opening for writing
203 // thought that read() returned 0 at EOF, but it actually returns 1 (because it reroutes through readBytes())
204 // during bootstrapping, class initialization triggered Unsafe.getTypeOf() in an assertion before the remapper was installed
205 // cycle in dependencies for clinit, leading to null pointer exceptions because fields weren't initialized yet
206 // forgot a ; in class descriptor, leading to getStaticField to attempt to check superclasses, leading to load being called recursively.
207 // forgot to skip class initializers when merging static methods from one class into another
208 // forgot to update mirror ClassLoader static methods to have the jq_Class as the first argument
209 // when merging classes, we can't use the state variable from the class anymore, each member needs its own copy.
210 // forgot to initialize state variable to STATE_LOADED when creating bridge methods to merged class
211 // forgot to update mirror Class static methods to have the jq_Class as the first argument
212 // accidentally was making more than one copy of some primitive types, because creating the primitive types triggered jq_Primitive to be clinited, so when we returned they had already been created.
213 // accidentally put "java/lang/Map" rather than "java/util/Map" for a field type descriptor
214 // jq_Class objects for nonexistent mirror classes were sticking around and their class_object fields couldn't be initialized because the classes don't exist.
215 // cut-and-paste bug: forgot to update class descriptor in java.util.zip.ZipFile/ZipEntry
216 // forgot a return statement after finding the right field in putInstanceFieldValue
217 // slight problem: initializing a ZipFile causes ZipEntry to be created reflectively, but there is no no-arg constructor. added explicit check for bootstrapping in ZipFile.
218 // forgot to update constructors in Thread mirror class
219 // forgot to add _class field to java.lang.reflect.Array
220 // was creating a mirror class for an anonymous class in ZipFile. changed to use a different class name.
221 // FileSystem.getFileSystem cannot use java.io.FileSystem in its descriptor because it is not a public class, but we still need it to override correctly.
222 // references to a merged method in other class's constant pools were not referring to the new, merged copy. changed to mutate the old copy.
223 // search/replace bug: Thread.registerNatives got renamed to registerReflections
224 // forgot to reset access_flags (specifically, native flag) when merging methods in classes
225 // forgot to call _umask, so all files were being opened read-only
226 // miscopied constants from C header file (octal, not hex!) leading to files being opened read-only
227 // in Trimmer, can't just set AddAllClassMembers flag to false when we want to not automatically add all class methods, because we still want to add the fields.
228 // in Trimmer, adding a static field by simply being in the same class did not add its value
229 // don't call addStaticFieldValue on a primitive type field!
230 // x86ReferenceCompiler always attempts to get the bytecodes of a method on creation, leading to crashes if the method doesn't have any bytecode
231 // forgot to move initCallPatches call after the cls_initialize calls in Bootstrapper
232 // jq_Method.compile_stub wasn't guaranteeing that compile() was compiled
233 // changing to use Reflection class messed up reflection target prediction hack in Trimmer
234 // Linker.invoke* were not being marked as necessary.
235 // needsDynamicLink of instance fields/methods was not taking into account boot image types, leading all invokespecials to be dynamically linked
236 // compile() of a native/abstract method was calling cls_initialize on x86ReferenceLinker (and therefore java.lang.Object) leading to extra call patches and corruption of code
237 // compiling NEWARRAY caused cls_initialize to be called on the array type, which caused java.lang.Object methods to be compiled
238 // forgot to add Reflection.obj_trav to the list of null static fields
239 // setting jq.Bootstrapping should occur before any class initialization takes place (i.e. before setting trace flags)
240 // Reflection._invokestatic_noargs was referring to nonexisting method
241 // ZipEntry._constructor was referring to nonexisting method
242 // CodeAllocator._compiled_methods had the wrong type signature
243 // forgot that allocateCodeBlock code_reloc and data_reloc could be null, so the addAll call was crashing
244 // BootstrapCodeAllocator corrected by startIndex and then called get1, which also corrected by startIndex
245 // malformed loop: put return in loop rather than after it.
246 // mistyped an offset when outputting the coff file
247 // jq_Member.isFinal was checking the ACC_STATIC flag rather than the ACC_FINAL flag
248 // inverted the section numbers in relocations (0 <-> 1)
249 // forgot to relocate references to addresses of static fields in code
250 // in backpatching, did target-code+4 instead of target-code-4, leading backpatchs to be off by 8
251 // forgot to add relocs for vtable pointers in objects
252 // wasn't adding relocs for external references
253 // symbol table numbers were off by 2 because of inserted entry_0 and trap_handler_8 syments
254 // name match against entry_0 and trap_handler_8 forgot numbers
255 // forgot to skip adding relocs for null static fields
256 // forgot to add jq_CompiledCode.entrypoint to code fields
257 // was adding code relocations in the data segment to a list, but wasn't doing anything with that list
258 // forgot some classes referenced by System.initializeSystemClass in the class list
259 // pushing null constant caused relocation to be created for it
260 // code (.text) section is by default write protected, so backpatching crashed
261 // forgot to add some classes to the class list
262 // forgot to initialize CodeAllocator.DEFAULT
263 // forgot to relocate CodeAllocator.lowAddress and CodeAllocator.highAddress, so stack walking was broken.
264 // CodeAllocator.lowAddress and CodeAllocator.highAddress were being initialized BEFORE anything was compiled!
265 // by putting static field relocs in initStaticField, when initStaticField was called more than once for a field, relocs were being also added more than once
266 // array classes not in list were not being initialized
267 // comparison in CompiledCode.compareTo assertion was using > rather than >=
268 // RuntimeCodeAllocator.endian2 was incorrect
269 // Reflection.invoke were asserting for isClsInitialized, but static methods could be called during clinit
270 // jq_InstanceMethod.needsDynamicLink was incorrect, condition was reversed
271 // printing some floats crashed because f2i was not correct, because double constants were stored in the wrong dword order
272 // in BootstrapCodeAllocator, was updating current_bundle ptr on ensureCapacity
273 // forgot to support path seperator in command line class path
274 // forgot to add padding to the last object in the boot image
275 // in bootstrapper, adding reloc for static field failed because it was in nullStaticFields
276 // in Reflection.putfield_L, wrong endianness
277 // forgot to support path seperator in bootstrap command line class path
278 // typo in ZipFile, used _class.newInstance() when I meant ZipEntry._class.newInstance()
279 // forgot to trigger class loading before type checking when using Class.isAssignableFrom, etc.
280 // tricky! in Utf8, table[getID()] failed because getID() could rewrite table, but the code was using the old table!!
281 // calling keySet() on a TreeMap (compiled_methods) causes its fields to change, messing up bootstrapping.
282 // system also creates an instance of ByteToChar via reflection. added to trimmer.
283 // exception delivery crashed when a non-Java stack frame was on the stack, because the cc had no method or TryCatch
284 // forgot to add code/data relocs to generated cc for compile_stub
285 // flipped assertion in ThreadQueue.enqueue
286 // reversed the arguments in asm.emit2_Reg_Mem
287 // disable/enableThreadSwitch in jq_Thread was a static function, causing it to always operate on the current thread!
288 // forgot to push result in _isEQ, causing the stack to screw up (and isEQ to always return true)
289 // was subtracting 1 instead of LOCK_COUNT_INC in monitorexit
290 // in NativeThread, reallocated CodeAllocator rather than calling init() on it
291 // status flags used 0xf, but Monitors were aligned at an 8 byte alignment
292 // forgot to resume the timer interrupt thread after creating it!
293 // run method of timer interrupt thread was not compiled and the thread block was not set yet, so it couldn't be compiled.
294 // forgot to initialize code/heap allocator for interrupter native thread.
295 // in threadSwitch, the register state pointed to the start of the threadSwitch function, so when we resumed from it, it just reentered the threadSwitch
296 // compare and swap when installing inflated lock was incorrect.
297 // in static synch methods, forgot to use Reflection.getJDKType rather than jq_Type.getJavaLangClassObject (which returns null during bootstrapping)
298 // typo: _putstatic4 was actually pointing to _getstatic4
299 // lock overflow was incorrect, was waiting for lock to be released.
300 // when using LOCK_COUNT_MASK when lock entry count overflowed, forgot to right shift it.
301 // forgot to set jq_RegisterState.ContextFlags before calling get_thread_context in ctrl_break_handler
302 // getClassInitializer was using getStaticMethod instead of getDeclaredStaticMethod, leading to the superclass's <clinit> being invoked
303 // using reflection to get a field object returned a new one on every call, causing the bootstrapping phase to screw up
304 // forgot a k = k.getSuperclass() in a loop in getStaticFields, leading to an infinite loop
305 // allocating arrays that were larger than the threshold didn't work.
306 // in Sun's impl, readBytes/writeBytes doesn't throw an IndexOutOfBoundsException when offset == b.length and length == 0 (a bug on their part)
307 // forgot to call load() in ClassLoader.findLoadedClass
308 // off-by-one errors (too small) in stack walking in various situations. forgot to count the dummy frame from the native stub.
309 // isInSamePackage predicate in String.equals was reversed
310 // instance field lookup was using instance_fields array when it should have done a recursive lookup on declared_instance_fields
311 // overlapping array case in arraycopy was backwards
312 // forgot to check array bounds before copying in arraycopy. the array would get written to even if the bounds were bad.
313 // when doing setLocation for BytecodeVisitor, need to change i_end as well as i_start, because get___() routines use i_end
314 // off-by-one error in BitStringIterator.hasNext
315 // put a "this" instead of a "that" in copy constructor for TypeAnalysis.AnalysisState
316 // forgot to set done=true in SingletonIterator, leading to infinite iteration
317 // in TypeAnalysis.AnalysisSummary copy routine, mixed up this and that
318 // in CFG builder, forgot to add ATHROW as branch connecting to exit
319 // forgot to initialize stack depth in TypeAnalysis visitor
320 // forgot to handle RET in basic block builder
321 // in TypeAnalysis union, mixed up "this" and "that"
322 // in interprocedural matching in TypeAnalysis, was calling "copy_deep" for outside nodes, leading to callee outside edges being matched against inside edges added from callee
323 // in TypeAnalysis when copying using old_to_new map, we were recursive calling before adding to the map, leading to infinite recursion on cycles
324 // with cycle detection in TypeAnalysis union, OutsideProgramLocation.union_deep pushed on the stack and then called supertype ProgramLocation.union_deep, which thought there was a cycle
325 // forgot that astore can store jsr ret addr, leading to nullptr in TypeAnalysis
326 // visitBytecode call relies on i_end being i_start-1. array bounds exception
327 // reversed the order of arrays in arraycopy, so the old array was getting cleared
328 // typo when changing StaticField.sf_initialize, added "address" instead of "offset"
329
330 // TODO:
331 // check if 0x80000000 / -1 works
332 // check if x / 0L works
333
334 public abstract class jq {
335
336 /***
337 * Number of native threads in the system.
338 * This can be set with the "-nt" option at startup.
339 */
340 public static int NumOfNativeThreads = 1;
341
342 /***
343 * Whether joeq is running natively, or within another virtual machine.
344 * This flag is never set explicitly - this flag is flipped on in the output
345 * image during bootstrapping.
346 */
347 public static boolean RunningNative = false;
348
349 /***
350 * Flag to disable method compilation.
351 */
352 public static boolean DontCompile = false;
353
354 /***
355 * Whether we are in the middle of the bootstrapping process.
356 */
357 public static boolean IsBootstrapping = false;
358
359 /***
360 * List of method invocations to perform on joeq startup.
361 */
362 public static List on_vm_startup;
363
364 /***
365 * Whether all joeq-VM specific stuff should be ignored as
366 * non-existent. Setting this to "true" enables only the analysis
367 * framework.
368 */
369 public static /*final*/ boolean nullVM = System.getProperty("joeq.nullvm") != null;
370
371 public static /*final*/ boolean SMP = true;
372
373 }