Harder to Mimic

The last day was a little messed up. On Tuesday, I stayed at my office until 2:30 AM to install Visual Studio 2005 Beta 2 with all bells and whistles. All in all, it took about 12 hours. Since my bike is at the shop right now, I had to walk home, which took another 45 minutes. I was in bed around 5 AM. Today I slept in a little, then was sore as hell. I guess it’s rare that I walk 10 miles on a single day.

I’ve begun comparing the code Java generates and the code that I’m creating through instrumentation. I think it will be a bit harder than expected to exactly mirror what javac does. Here’s an example. This synchronized block

1
2
3
4
5
6
7
8
synchronized(this) {
    try {
        ...
    }
    catch(RuntimeException e) {
        ...
    }
}

gets translated into the following bytecode:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
aload\_0 // this on stack
dup // this, this on stack
astore\_2 // store this in local 2
monitorenter // lock this
...
aload\_2 // retrieve this from local 2
monitorexit // unlock this
return

// exception handler for RuntimeException (line 6)
astore\_3 // store exception in local 3
...
aload\_2 // retrieve this from local 2
monitorexit // unlock this
goto 24 // jump to return

// exception handler to catch any other exception, unlock, and rethrow
// (lines 6-8)
astore 04 // store exception in local 4
aload\_2 // retrieve this from local 4
monitorexit // unlock this
aload 04 // retrieve exception from local 4
athrow // rethrow
return

The interesting thing here is that javac does not reload the reference for monitorexit from the source variable, but that it instead stores it in a local variable before the monitorenter and reloads the reference from there. Mimicking this behavior is harder than reloading: I have to extend the local variable pool correctly and insert more instructions. Mimicking javac’s product exactly might actually be nearly impossible. To establish equality between the code generated by javac and the instrumented code, the numbering of the local variables has to be identical, and I do not know the scheme javac uses. So this sort of is an alpha-equivalence issue. It should be possible to establish equivalence upto the numbering. But now I’m wondering… is this necessary?

While looking at the code and thinking about the local variable pool, I noticed that I need to check the stack size in all instrumentors. Whenever I’m putting values on the stack — and particularly whenever I use dup to duplicate something that’s already there — I have to increase the stack size. This might actually be related to the stack frame problems.

But now I’m logging out. It’s 5:30 AM, and I’m thoroughly out of my newly established normal sleeping pattern again X-(

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, Uncategorized. Bookmark the permalink.

Leave a Reply