Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How does the JVM know where to catch an exception at runtime?

From my understanding, throw is a primative jvm command. When this is called, the JVM "checks if the current call stack can catch it". if it can't, then java simply pops the call stack almost exactly as if a return was called. then the jvm "checks if the current call stack can catch it" and so on recursively.

My question: how is it algorithmically possible for the JVM to know where in the call stack can catch a given exception? Is there metadata stored in each call stack entry mapping exceptions to code blocks? is there a static data structure in the heap that somehow keeps track of this? because somewhere there has to be data keeping track of that.

like image 484
Alexander Bird Avatar asked Oct 31 '12 23:10

Alexander Bird


2 Answers

The JVM specification has details about this.

In particular, section 4.7.3 gives details about the exception table, which is a series of entries saying which exceptions are caught between which instructions. Section 3.12 gives a concrete example of this.

How this metadata is mapped into native code for the JIT is a different matter, of course - and implementation-specific. For example, there could be some mapping back from each instruction location in the native JITted code back to the original bytecode location, at which point the exception table can be consulted to find the right handler.

like image 143
Jon Skeet Avatar answered Sep 23 '22 07:09

Jon Skeet


Generally speaking: When an exception is thrown the JVM extracts the "call stack". This identifies which bytecode or machine instruction was being executed at each level in the call stack, along with the class and method associated with that location.

Then, for each method in the stack (starting with the method where the exception occurred and working backwards), the JVM looks (in the internal class object) at the method's table mapping try/catch ranges to bytecode/machine instruction ranges.

If a "match" is found in the table for a method, and the type of exception being thrown is a class being monitored for in the found range, then control is transferred to the catch entry point, after setting the exception into a sort of parameter location so the catch clause can reference it.

If a "match" is not found in the table then the call stack is effectively "popped", placing the next earlier method on top of the stack, and the above search for a "match" in the earlier method's table of try/catch ranges is repeated.

This of course is an over-simplification. There is a lot of extra logic involved in handling finally ranges, eg, and several "edge" cases.

like image 20
Hot Licks Avatar answered Sep 20 '22 07:09

Hot Licks