[llvm-dev] Managed Languages BOF @ Dev Meeting

David Chisnall via llvm-dev llvm-dev at lists.llvm.org
Mon Oct 19 01:56:31 PDT 2015

On 18 Oct 2015, at 23:08, Sanjoy Das <sanjoy at playingwithpointers.com> wrote:
> Supporting only basic block level granularity for "try ranges" may not
> be sufficient for Java -- if a basic block has more than one null check
> in it then throwing the NullPtrException for the first null check (if
> it fails) is semantically different from throwing the NullPtrException
> for the second null check (the constructed exceptions will have
> different stack traces attached to them, for instance [1]).  

[ Footnote inlined ]

> [1]: there is a "hot exception" optimization that some JVMs can do
>  that may allow us to get around this
>  (http://jawspeak.com/2010/05/26/hotspot-caused-exceptions-to-lose-their-stack-traces-in-production-and-the-fix/),
>  but that's an _optimization_ that Java programmers should be able to
>  turn off.

There are some quite exciting security vulnerabilities associated with this optimisation (it turns out that running a few instructions after a security-critical check has failed is not always a good thing to do) so I agree that it’s a good idea to avoid depending on it.

> So we'd
> have to do repeat the null checks in the unwind block, like
>  superblock:  # unwinds to unwind_block
>    null_check(ptr_a)
>    do_something
>    null_check(ptr_b)
>    do_something_again
>  unwind_block:
>    ;; either ptr_a is null or ptr_b is null
>    if (ptr_a == null)
>      throw_nullptrexception(bci = 42)
>    else ;; if (ptr_b == null)
>      throw_nullptrexception(bci = 43)
> So the code explosion problem still exists (in unwind_block), and
> we've duplicated a bunch of code.

Does it?  I guess it depends on how you are implementing the exceptions.  I was expecting that the non-call exceptions would be implemented on top of signals (or something SEH-like on Windows), so the trap handler would have some generic code to identify the faulting instruction, map this back to something useful, and then throw the exception.  You wouldn’t be throwing the null pointer exception from the unwind target, that would be generated in the signal handler and the unwind target would only have to do the normal unwinding.

In a JIT environment, the unwind targets could probably also be lazily emitted, so in your initial IR you’d just have a single patchpoint for the unwind target.  My knowledge of common Java idioms is slightly rusty, but my impression was that, while lots of Java code abuses exceptions for non-exceptional behaviour, this is quite rare for null-pointer exceptions.  Is there much (any?) real-world code where the handling of null pointer exceptions is performance critical?

> Having said that, I'd love to take a look at the proposal that was
> made -- will it be easy for you to dig up a link?

It was this mailing list, but your ability to search it is probably as good as mine.  My brain, unfortunately, does not contain a well indexed cross-reference of the archive.  I believe that the general consensus was that something like this would be good to have, but not sufficiently important to anyone with time to spend actively hacking on stuff to do.  Given that people are now seriously using LLVM for languages that are not so C-like, this might be different...


More information about the llvm-dev mailing list