Search code examples
javacode-generationjit

How are exceptions caught and dealt with at the low (assembly) level?


I have this code -

try {
     doSomething();
} catch (Exception e) {
   e.printStackTrace();
}

How will this actually be implemented by the compiler. Where is the check for the exception actually put in the assembly code generated?

Update
I know that how the above code is translated to bytecode. The bytecode only translates the try-catch to corresponding try-handler blocks. I am interested in how it will be translated to assembly/and or handled by the jvm.


Solution

  • The cost of try-catch block

    Roughly speaking try block does not add any exception checking code to the result assembly. It is basically a no-op as long as no exception is thrown. All the slow work is done by exception throwing code.

    When try-catch is JIT-compiled, an exception table is added aside from the code. It maps the address ranges where a handled exception may occur to the address of the corresponding exception handler. Note: these are not the bytecode indices, but the real memory addresses.

    How the exception are thrown in HotSpot?

    1. Implicit exceptions: NullPointerException and StackOverflowError are detected inside signal handler in response to a segmentation fault.
    2. ArrayIndexOutOfBoundsException, ClassCastException etc. are checked explicitly. The corresponding checks are inlined into the compiled code where the array access is done.
    3. OutOfMemoryError and all other exceptions thrown from the native code are checked explicitly whenever a thread state transition is performed (vm->java or native->java).
    4. All user exceptions thrown by athrow bytecode. In a fast path (when a catch handler in the same frame exists), JIT compiles athrow into a simple jump. Otherwise the deoptimization occurs and the exception handling is done inside the VM runtime.

    Well, 'How the exception are caught at assembly level?'

    In no way.
    I mean, exceptions are generally not caught at assembly level - all the heavy stuff (stack walking, handler lookup, deoptimization, monitor unlocking etc.) is done in VM runtime, i.e. in C code.