JVMS2 requires the compiler to call monexit before the exeption is thrown in a synchronized block. But I really found some examples that do not subject to it.  Here in the attachment is one of the examples.

2007/10/12, Pavel Ozhdikhin <pavel.ozhdikhin@gmail.com>:
On 10/12/07, ʷ <icyrong@gmail.com> wrote:

> We know that according to the specification, when an exeption is thrown,
> the
> control flow goes to the handler of the exeption. If the  exeption is
> thrown
> in a synchronized block, the VM must do a "monitorexit" operation to
> release
> the lock. But I took a look at some control flow graphs(HIR) created by
> JIT,
> and didn't find any "monitorexit" instructions when an exeption is thrown
> in
> a synchronized block. Could any one tell me when and how the "monitorexit"
> operation is done when an exeption is thrown in a synchronized block?


A java compiler should use Java exception mechanics to make sure monexit is
called when the exception is thrown in a synchronized block (see section
7.14 "Synchronization" of JVMS2). JIT also emulates this technique when it
inlines a sychronized method.

When an exception is thrown from a synchronized method (not inlined), VM
releases the lock.

If you have an example of unbalanced monitorenter/monitorexit in HIR, please
share the test here so I could take a deeper look.

Thanks,
Pavel