__attribute__((cleanup(function)) versus try/finally
Mark Mitchell
mark@codesourcery.com
Tue May 6 21:24:00 GMT 2003
> Hmm, I suppose you can assume that $sp is linear. I guess that would work,
> except that you can't unwind through C unless the C code has unwind info.
The C code must have unwind info -- but it does not need to have handler
code. Moving the handler code out-of-line is only part of the issue;
the code size is the other issue.
> cancellation exception specially. When you run out of unwind info, rather
> than call terminate you need to hand off to the old pthread_exit.
I had suggested simply having the pthread-launching routine (the first
thing called in the new thread) be written in C++. It can then just
catch the exception and do whatever's required.
> In effect, this means that any library code that does I/O must have unwind
> info. At that point, it seems to me that we might as well always emit it,
> since it only costs us in disk space. That's what Tru64 does. And Irix.
Yes, I don't argue with any of this. It would be nice to avoid unwind
info, but I'm not sure we can. We can avoid handlers, however.
> >> > The try/finally solution cannot be implemented with this same
> >> > performance; it will, in fact, exact a performance price, in terms of
> >> > both code space and the speed at which cleanups are run, on all
> >> > systems. On systems with setjmp/longjmp exceptions, both costs will be
> >> > very high indeed.
>
> I think you're exaggerating the costs. This is the way the C++ frontend
> works, and you only incur the costs when you use the feature. The design
> philosophy of EH has always been that the speed of the normal code is what
> matters, not the cleanups.
With setjmp/longjmp, there are big costs even if you don't use the
feature. With the scheme I propose, you shouldn't need as many setjmps
-- you only need one setjmp at the beginning of the function to be able
to unwind. You never need to land in the middle of the function.
Without setjmp/longjmp, you save mostly code space. You also improve
cleanup time (in that you need not transfer control to the local frame
of the function before running the cleanup), but this is a smaller
advantage.
> > The observation behind this is that pthread cleanups -- unlike C++ catch
> > clauses -- do not need to execute in the frame of the function that
> > pushed them. They just need to execute while the stack is still there,
> > in case the "arg" to the function directly or indirectly references
> > stuff on the stack.
>
> No, they don't need to. Nor do C++ destructors. But they do anyway.
Catch-clauses and destructors are different.
Given:
int i;
try { ... } catch (...) { i = 3; }
the catch-clause had better execute in the frame of this function.
With a destructor or (analogously) a pthread cleanup handler, the
execution just has to take place while the frame is still active.
--
Mark Mitchell
CodeSourcery, LLC
mark@codesourcery.com
More information about the Gcc
mailing list