setOldThread and isOldThread

The instrumentation should actually be pretty easy. I just looked at the bytecode of this class:

public class Test {
public static boolean isOldThread() {
return true;
}
public static void setOldThread() { }

public static void main(String[] args) {
if (isOldThread()) {
// some code
}
else {
setOldThread();
}
}
}

and the main method contains these instructions:

invokestatic Test.isOldThread()Z
ifeq 5
// some code
goto 6
invokestatic Test.setOldThread()V
return

The invokestatic Test.isOldThread()Z puts the return value on the stack. The ifeq jumps over the then block if the return value was false; the goto in line 4 jumps over the else block if it was true and the then block has already been executed.

This just needs to be turned into

invokestatic java/lang/Thread.currentThread()Ljava/lang/Thread;
getfield java/lang/Thread.$$$oldThread$$$
ifeq 6
// some code
goto 9
iconst_1
invokestatic java/lang/Thread.currentThread()Ljava/lang/Thread;
putfield java/lang/Thread.$$$oldThread$$$
return

The old line 1 gets replaced by the new lines 1 and 2, which get the current thread, and then get its $$$oldThread$$$ field.

The old line 5 gets replaced by the new lines 6 to 8, which put true on the stack, get the current thread, and then set its $$$oldThread$$$ field.

monitorenter and monitorexit are even easier to handle.

// put object ref on stack
invokestatic edu/rice/cs/cunit/SyncPointBuffer/monitorEnter

just has to be changed into

// put object ref on stack
monitorenter

Exactly the same applies for monitorexit. The value on top of the stack isn’t used as first parameter anymore, now it’s directly consumed by the monitorenter or monitorexit instruction.

Share

About Mathias

Software development engineer. Principal developer of DrJava. Recent Ph.D. graduate from the Department of Computer Science at Rice University.
This entry was posted in Concurrent Unit Testing. Bookmark the permalink.

Leave a Reply