How to exit the monitor in bytecode?

I read the JVM specification to try to figure out how to properly handle monitors. The example they give in the corresponding section is as follows:

0 aload_1 // Push f 1 dup // Duplicate it on the stack 2 astore_2 // Store duplicate in local variable 2 3 monitorenter // Enter the monitor associated with f 4 aload_0 // Holding the monitor, pass this and... 5 invokevirtual #5 // ...call Example.doSomething()V 8 aload_2 // Push local variable 2 (f) 9 monitorexit // Exit the monitor associated with f 10 goto 18 // Complete the method normally 13 astore_3 // In case of any throw, end up here 14 aload_2 // Push local variable 2 (f) 15 monitorexit // Be sure to exit the monitor! 16 aload_3 // Push thrown value... 17 athrow // ...and rethrow value to the invoker 18 return // Return in the normal case Exception table: From To Target Type 4 10 13 any 13 16 13 any 

I cannot understand why a second entry in the exception table is needed. If an exception is monitorexit , do I really want to try to exit the monitor again? Possible exceptions that I can tell are NullPointerException and IllegalMonitorStateException .

+6
source share
2 answers

There is a Java error for this, which was closed as "Not a problem" - http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4414101 . (Kudos to Tom Anderson for finding him.)

The error assessment section really enlightens.

It begins by talking about using asynchronous exceptions; those. a ThreadDeath exception that implements the (deprecated!) Thread.stop() method. A mysterious handler ensures that the monitor lock is locked, even if a "thread stop" occurs at a critical point where the JVM is trying to release the lock.

Then Neil Gufter adds that even a hypothetical infinite loop (as described in this Question) is the correct behavior according to JLS. JLS says the monitor will always be released before the stream continues. If this cannot be done, then including the stream in an infinite loop is more correct than anything else.

+5
source

To be clear

 block 0 : 0 - 3 block 1 : 4 - 10 block 2 : 13 - 16/17 block 3 : 18 

I agree that it is confusing to have a / catch attempt in the second block, because this seems like a possible endless loop. that is, if the exception occurs between 13 and 16, it jumps to 13 to handle it. I can only guess

  • there is a safe exception that you can try to protect against.
  • it is retained for an incomprehensible reason for backward compatibility.
  • there is no good reason for this, and it is an artifact of creating byte code.

I suspect that this does nothing useful, and I think that someone at Oracle was just as suspicious, but he did not know for sure that it could be deleted .;)

+1
source

Source: https://habr.com/ru/post/951791/


All Articles