Sometimes, javac apparently decides not to be utterly stupid. Sometimes it optimizes. Here’s the special case: When a program locks this
, which is always present in local variable 0 in non-static methods, it does not allocate an additional local variable. I expected the following:
aload\_0 // load this
dup
astore\_1 // store this in local 1
monitorenter // lock this
...
aload\_1 // retrieve this from local 1
monitorexit // unlock this
But in this case, javac is smart enough to realize that aload_0
already contains this
, so it generates
aload\_0 // load this
monitorenter // lock this
...
aload\_0 // load this
monitorexit // unlock this
But, of course, if the user declares a local variable, like in the following example, javac does not recognize this. This Java code
final Object temp = someField;
synchronized(temp) {
...
}
mercilessly generates this bytecode:
aload\_0// load this
getstatic 0004 // load field
astore\_1 // store in local 1
aload\_1 // restore from local 1
dup
astore\_2 // store in local 2
monitorenter // lock
...
aload\_2 // restore from local 2
monitorexit // unlock
Now I have to put more conditionals into my code. Yuck. I hope there aren’t more of these rare optimizations hidden somewhere. All of this gives me a bad feeling about relying on my perception of what javac generates. It would be much more prudent to just rely on the VM specifications, as I did before.