[LLVMdev] Question about implementing exceptions, especially to the VMKit team
Filip Pizlo
fpizlo at apple.com
Thu May 1 14:26:23 PDT 2014
I have some data points on this.
- The style of exception handling employed by VMKit has in the past been used as an optimization. For example, OpenVM switched to this after using C++ exceptions for along time because it was a net performance win. This is because Java-like languages tend to do more exception throwing than the C++ runtime is tuned for and the cost of unwinding in C++ is too great: so paying one branch after every call ends up being cheaper, for many benchmarks, than using C++ exceptions because all benchmarks have some throwing (usually at least internally in the standard library). Such high exception volume may be a Javaism.
- WebKit uses LLVM and does exceptions. The implementation is incomplete (I.e. We won't use the LLVM JIT for some exception code paths) but the basic idea is there: 1) throwing an exception through a function that doesn't catch just means you need to just use unwind meta-data. That's easy with compact_unwind. 2) catching can be done by using either deoptimization (deoptimize the entire catching function) or by ensuring that state live in a catch is spilled. It's best to do both: use deoptimization if profiling tells you that the catch doesn't execute and switch to spilling if it does. The benefit is that the deopt approach is very fast if zero throwing happens and the spilling approach will let you implement very efficient unwinding for when it happens with high volume.
I'm not sure this can completely answer your question. Exception implementation is a tricky subject with many strategies and it's an area where you could easily come up with fresh ideas. :-)
-Filip
> On May 1, 2014, at 2:09 PM, Kevin Modzelewski <kmod at dropbox.com> wrote:
>
> Hi all, I'm working on implementing exceptions in Pyston, and I was hoping to get some guidance from the list. I think I've learned enough about C++-style DWARF exceptions to convince myself I have a workable approach, but then I found this VMKit paper (2010) which says
>
>> The exception manager: To manage exceptions, J3 reserves a
>> word for the pending exception in the local storage of each thread.
>> After each method invocation, the word is tested. If an exception
>> has been raised and the function is able to trap the exception, a
>> branch to the exception handler is executed. Otherwise, the function
>> returns to the caller. This implementation is not optimal because it
>> requires a test and branch after each method invocation. A more
>> efficient implementation would use exception tables. However, at
>> time of writing the paper, the exception tables generated by LLVM
>> rely on the GCC runtime library [19] which is not optimized for
>> dynamically generated tables, at least on Linux.
>
>
> So now I'm reexamining whether C++-style exceptions are a good choice for Python, which I would guess throws more exceptions than Java.
>
> Does anyone have advice on the subject? I'm wary of the costs of having to branch after every function call, but maybe that ends up not being too much of a performance drain if the CPU can predict them correctly? But then again, it looks like VMKit has moved to a setjmp-longjmp approach, which makes me think that there must have been some overhead that they wanted to avoid.
>
> I'm also curious about why libgcc is slow on dynamically generated tables, and if that's still true with MCJIT (I assume the VMKit change was made while on the old JIT).
>
> thanks,
> kmod
> _______________________________________________
> LLVM Developers mailing list
> LLVMdev at cs.uiuc.edu http://llvm.cs.uiuc.edu
> http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20140501/0a1787de/attachment.html>
More information about the llvm-dev
mailing list