I just expanded the method to block instrumentation to the entire runtime, and unfortunately I’m getting an java.lang.IllegalMonitorStateException
at sun.misc.URLClassPath.getLoader(Unknown Source)
. So something’s still wrong… :(
Fortunately, the source code in question has been released under the JRL, so now I’m doing a “Java source” vs. “uninstrumented” vs. “instrumented synchronized blocks” vs. “synchronized methods converted to blocks and instrumented synchronized blocks” comparison… that’ll be fun.
Update
By stepping through the bytecode of the fully instrumented getLoader
method I’ve found at least one thing that’s wrong. Since the actual code is released under the JRL, I’ll show simplified code here. The method contains a while
loop that begins at line 1, and a continue
statement:
synchronized void getLoader() {
while(<1st condition>) {
...
if (<2nd condition>) continue;
...
}
...
}
In bytecode, it looks roughly like this:
if??? 12
...
if??? 8
// 2nd condition met!
goto 1 // goto top of while loop
// 2nd condition not met!
...
goto 1 // goto top of while loop
// code after while loop
...
This got instrumented and turned into bytecode similar to this:
aload\_0
invokestatic (SynchronizedMonitor.tryEnterBlock)
aload\_0
monitorenter
aload\_0
invokestatic (SynchronizedMonitor.enterBlock)
if??? 18
...
if??? 14
// 2nd condition met!
goto 1 // goto top of while loop
// 2nd condition not met!
...
goto 1 // goto top of while loop
// code after while loop
...
aload\_0
invokestatic (SynchronizedMonitor.leaveBlock)
aload\_0
monitorexit
return
// exception handler for all exceptions
aload\_0
invokestatic (SynchronizedMonitor.leaveBlock)
aload\_0
monitorexit
athrow // rethrow
The problem is the goto 1
. When the code loops, the aload\_0; invokestatic; aload_0; monitorenter; aload\_0 invokestatic
code is executed again. I don't know if that's what's causing the exception, but it's definitely wrong. It's quite clear that the goto
must be to the line after this code. It's not clear to me yet if that's always the case, though.