[LLVMdev] Exception Handling Tables Question
Nick Kledzik
kledzik at apple.com
Thu Sep 17 21:18:38 PDT 2009
On Sep 17, 2009, at 6:03 PM, Duncan Sands wrote:
> Hi Bill,
>
>>>> Yeah. The logic will need tweaking for sure. I'm also concerned
>>>> about the
>>>> _Unwind_resume() call. GCC emits a call site region for it in the
>>>> exception
>>>> table. We...kind of do that. It looks like it's being included in
>>>> one of the
>>>> "this is a region which isn't in a try-catch block, but it has a
>>>> call in it,
>>>> so lets add it to the exception table" areas.
>>> isn't that exactly how it should be? This is a call that will
>>> unwind
>>> out of the function, so C++ requires it to have a call site region
>>> just
>>> like any other call that we want to let unwind out of the
>>> function. I
>>> don't see why it needs any special logic. If I understood right the
>>> change you want to make is that if a call is known not to unwind
>>> then
>>> you want to omit adding a call-site entry if that saves some space
>>> in
>>> the call site table, which seems irrelevant to this, or am I missing
>>> something? By the way, LLVM "nounwind" calls are different to GCC
>>> no
>>> throw regions IIRC. If an exception is thrown in a GCC no throw
>>> region
>>> then it must (C++) result in a call to "terminate". These are not
>>> mapped to "nounwind", instead we create explicit "catch-all" filter
>>> expressions for this (IIRC). In LLVM it is undefined what happens
>>> if
>>> a call is marked "nounwind" but nonetheless an exception unwinds out
>>> of it. Thus you can add call-site entries for nounwind calls,
>>> or not add them, as you like - whatever is most convenient (eg:
>>> saves
>>> the most space). An interesting optimization which we don't do is
>>> to
>>> identify which calls correspond to a "catch-all" filter and not
>>> generate
>>> an entry for them in the call-site table (no need to add the filter
>>> either) - this saves space and the C++ runtime knows to handle this
>>> just like if we added the filter explicitly.
>>>
>> There's a miscommunication here. :-) The _Unwind_resume call isn't
>> marked with "nounwind", however it's not called through an "invoke"
>> instruction, only a regular "call" instruction. From what I can see,
>> the only reason it falls within a call site in the exception table is
>> because we're generating call sites for areas of code without
>> "invokes".
>
> yes, and that's absolutely the right thing to do! Due to a strange
> design choice, if a call does *not* have an entry in the call-site
> table, and the call unwinds, then the runtime calls std::terminate.
> All calls that may throw (like _Unwind_Resume!) must have an entry
> in the call-site table.
But _Unwind_Resume() is special. It never returns. It does not throw.
The purpose of _Unwind_Resume() is for when you have a function with
a destructor that implicitly needs running during exception processing
as the exception unwinds through the stack. The unwinder jumps into
that function's landing pad where the compiler has laid down a call to
the destructor followed by a call to _Unwind_Resume() which then
continues where the unwinding left off in processing the exception.
Therefore, I don't see the point of having a call-site entry for the
_Unwind_Resume() "call".
-Nick
More information about the llvm-dev
mailing list