Explicit catches versus bulk catch + type check?
Charles Oliver Nutter
headius at headius.com
Fri Oct 14 14:42:53 PDT 2011
On Fri, Oct 14, 2011 at 7:24 PM, Tom Rodriguez <tom.rodriguez at oracle.com> wrote:
> Are you expecting some performance penalty from doing this? Generally speaking if you are throwing exceptions at all then you've already lost a bunch of performance. The lookups and unwinding are probably negligible in the general case.
Ok, that was my concern. It "felt" like the shape of a single handler
that type-checks would be considerably worse than explicit catches,
but as you describe below that's probably not the case.
> If the exception is thrown from a callee, out of sight of the current compilation, then the only thing that's used for deciding where to dispatch is the exception handler table in the method. There JIT isn't even involved in that case until the exception reaches the current nmethod. Take a look at exception_handler_for_return_address, which finds the PC to dispatch to in the caller frame.
> So in your case you might jump to the exception handler, do the type check and then simply unwind as you would have before. C2 does something similar to what you've done when dispatching exceptions. A single try with multiple catches sends all exceptions to a single entry point in the compiled code which then type checks them and dispatches to the right location, as you've done. catch_inline_exceptions in doCall.cpp does this. C1 relies on the exception handler table and dispatches them individually, with a separate entry point for each type mentioned in a catch. For locally thrown and caught exceptions C2 maybe convert that directly into control flow and possibly simplify type checks along the way. C1 still goes the long route.
> So basically I would be surprised if doing what you're doing would hurt the speed of throwing and catching exceptions by a measurable amount in real programs.
Ok, that's reassuring. Again we're also talking about performance when
an exception *does* happen, which as you point out is already going to
be a hit (backtrace generation, unwinding).
> Where it might hurt you is with compiled code complexity, assuming that you are spreading your try/catch over large blocks of code that might not really need handlers. Remember that every exception handler creates extra control flow edges which can complicate code generation. This is very hard to quantify and may or may not matter but it seemed worth mentioning. Basically it can increase compile time and possibly result in worse register allocations but that's a very vague worry.
> Anyway, if you're worried abut it, I would suggested writing some test cases that match what your usage and see if you can measure differences. There could be pathologies here we're unaware of.
I'll try to do so! There is a fair amount of code involved in these
"catch anything" handlers, so that's a place I can probably improve
(fast checks earlier, shunt as much logic as possible to child
More information about the mlvm-dev