Mark Shannon wrote:> Andrew Haley wrote: >> Mark Shannon wrote: >>> Nick Johnson wrote: >>>>> probably there should be a switch to choose whether codegen should turn >>>>> unwind/invoke into dwarf or setjmp/longjmp style code. >>> It seems to me that there is an implicit, and undocumented, assumption >>> that unwinding needs to handle stack-allocated objects. >>> >>> In languages without stack-allocated objects (ie. most languages that >>> support exceptions) there is no need to unwind frame-by-frame, the >>> unwind simply needs to make a single jump to the invoke instruction and >>> restore the context (which in x86 is just 6 registers). >> Not quite. It's also necessary to execute all the pending POSIX >> pthread_cleanup_pop() actions. > > POSIX pthread_cleanup_pop() can only be called directly from C++/C. > C doesn't haven't exceptions.But it does have pthread_exit().> So yet again, this is a C++ issue.No, it isn't: The effect of calling longjmp() or siglongjmp() is undefined if there have been any calls to pthread_cleanup_push() or pthread_cleanup_pop() made without the matching call since the jump buffer was filled. Andrew.
Andrew Haley wrote:> Mark Shannon wrote: >> Andrew Haley wrote: >>> Mark Shannon wrote: >>>> Nick Johnson wrote: >>>>>> probably there should be a switch to choose whether codegen should turn >>>>>> unwind/invoke into dwarf or setjmp/longjmp style code. >>>> It seems to me that there is an implicit, and undocumented, assumption >>>> that unwinding needs to handle stack-allocated objects. >>>> >>>> In languages without stack-allocated objects (ie. most languages that >>>> support exceptions) there is no need to unwind frame-by-frame, the >>>> unwind simply needs to make a single jump to the invoke instruction and >>>> restore the context (which in x86 is just 6 registers). >>> Not quite. It's also necessary to execute all the pending POSIX >>> pthread_cleanup_pop() actions. >> POSIX pthread_cleanup_pop() can only be called directly from C++/C. >> C doesn't haven't exceptions. > > But it does have pthread_exit(). > >> So yet again, this is a C++ issue. > > No, it isn't: > > The effect of calling longjmp() or siglongjmp() is undefined if there > have been any calls to pthread_cleanup_push() or pthread_cleanup_pop() > made without the matching call since the jump buffer was filled. >We are not talking about longjmp() or siglongjmp() we are talking about invoke/unwind!> Andrew. > _______________________________________________ > LLVM Developers mailing list > LLVMdev at cs.uiuc.edu http://llvm.cs.uiuc.edu > http://lists.cs.uiuc.edu/mailman/listinfo/llvmdev >
Mark Shannon wrote:> Andrew Haley wrote: >> Mark Shannon wrote: >>> Andrew Haley wrote: >>>> Mark Shannon wrote: >>>>> Nick Johnson wrote: >>>>>>> probably there should be a switch to choose whether codegen should turn >>>>>>> unwind/invoke into dwarf or setjmp/longjmp style code. >>>>> It seems to me that there is an implicit, and undocumented, assumption >>>>> that unwinding needs to handle stack-allocated objects. >>>>> >>>>> In languages without stack-allocated objects (ie. most languages that >>>>> support exceptions) there is no need to unwind frame-by-frame, the >>>>> unwind simply needs to make a single jump to the invoke instruction and >>>>> restore the context (which in x86 is just 6 registers). >>>> Not quite. It's also necessary to execute all the pending POSIX >>>> pthread_cleanup_pop() actions. >>> POSIX pthread_cleanup_pop() can only be called directly from C++/C. >>> C doesn't haven't exceptions. >> But it does have pthread_exit(). >> >>> So yet again, this is a C++ issue. >> No, it isn't: >> >> The effect of calling longjmp() or siglongjmp() is undefined if there >> have been any calls to pthread_cleanup_push() or pthread_cleanup_pop() >> made without the matching call since the jump buffer was filled. >> > > We are not talking about longjmp() or siglongjmp() we are talking about > invoke/unwind!Let's go back a bit. Your claim is that there is no need to unwind frame-by-frame, an unwind simply needs to make a single jump to an invoke instruction and restore the context (which in x86 is just 6 registers). (This is, more or less, what longjmp() does.) Duncan Sands explained to you why that wouldn't work, saying "if you throw an exception using your proposed unwind implementation, then it wouldn't be caught by dwarf catch/cleanup regions". He's right. You can't just jump to the invoke instruction, you must also pop any cleanups. This is nothing to do with C++, and it has nothing to do with whether a language has stack-allocated objects. Andrew.