I have realized that, as long as the bootclass mechanism with the -Xbootclasspath/p:foo.jar
parameter functions the same way with the Apple JVM as with the Sun JVM, I don’t have to instrument Apple’s classes.jar and ui.jar into separate jar files. I should still be able to combine both together into a jar file like I’ve been doing it so far. That means I only have to support multiple input files for Java runtime file instrumentation (“classes.jar:ui.jar” instead of just “rt.jar”)
I digress, but the I have a naming convention for the instrumented rt.jar files, depending on whether I’m recording or replaying, and whether it uses the compact format or the compact debug format:
- record.jar – recording
- rt.record.debug.jar – recording with debug information
- rt.replay.jar – replaying
- rt.replay.debug.jar – replaying with debug info
I’m not sure if I’ve described the compact format recently. Both use an array of longs
. The smallest, most efficient format has records with two longs
per sync point:
- thread ID – 0 or greater
- code – 1= SP_MONITORENTER, 2 = SP_MONITOREXIT, 3 = SP_TRYMONITORENTER, 4 = SP_THREADSTART, 5 = SP_THREADEXIT, 6 = SP_END
This is the bare minimum needed for replay.
The debug format currently needs five longs
per sync point:
- thread ID – 0 or greater
- code – 1= SP_MONITORENTER, 2 = SP_MONITOREXIT, 3 = SP_TRYMONITORENTER, 4 = SP_THREADSTART, 5 = SP_THREADEXIT, 6 = SP_END
- class index – 1 or greater, assigned by the
FileInstrumentor
- method index and program counter – the method index is in the upper 32 bit and is assigned by the
FileInstrumentor
; the PC is in the lowest 16 bit - object ID – -1 if it cannot be determined, 0 if it hasn’t been initialized, 1 or greater for valid IDs
The debug format is useful for me to understand the sync points that have been recorded, because it tells me where a sync point originated from and (at least if my current work with the object IDs will be successful) what objects are involved. If I know what objects are involved, I can detect deadlock.
When calling SyncPointBuffer.compactDebugAdd
, the object ID is actually the first parameter. It worked out better this way; otherwise I would have had to use a local variable to rearrange the stack.