From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 24270 invoked by alias); 6 May 2003 21:24:52 -0000 Mailing-List: contact gcc-help@gcc.gnu.org; run by ezmlm Precedence: bulk List-Archive: List-Post: List-Help: Sender: gcc-owner@gcc.gnu.org Received: (qmail 24230 invoked from network); 6 May 2003 21:24:50 -0000 Received: from unknown (HELO doubledemon.codesourcery.com) (66.60.148.227) by sources.redhat.com with SMTP; 6 May 2003 21:24:50 -0000 Received: from doubledemon.codesourcery.com (doubledemon.codesourcery.com [127.0.0.1]) by doubledemon.codesourcery.com (8.12.8/8.12.8) with ESMTP id h46LOn9X002271; Tue, 6 May 2003 14:24:49 -0700 Subject: Re: __attribute__((cleanup(function)) versus try/finally From: Mark Mitchell To: Jason Merrill Cc: gcc@gcc.gnu.org In-Reply-To: References: <1052245742.2583.315.camel@doubledemon.codesourcery.com> <1052249890.31850.338.camel@doubledemon.codesourcery.com> Content-Type: text/plain Content-Transfer-Encoding: 7bit Date: Tue, 06 May 2003 21:24:00 -0000 Message-Id: <1052256289.2583.412.camel@doubledemon.codesourcery.com> Mime-Version: 1.0 X-SW-Source: 2003-05/txt/msg00534.txt.bz2 > 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