I have a question concerning the exception handling tables that we generate. Right now we generate call sites for all of the code in a function, even for code that cannot (or at least shouldn't) throw an exception. E.g., for this code: #include <cstdio> struct Cleanup { ~Cleanup(void) { printf("in cleanup\n"); } }; static void inline_me(void) { Cleanup C; throw 0; } int main(void) { try { inline_me(); } catch (...) { printf("in catch all\n"); } return 0; } (assume it's all been inlined), the EH handling table for "main" goes from Leh_func_begin1 to Leh_func_end1, marking off each region whether it can throw or not. From my reading of the Exception Tables documentation, this is unnecessary – at least for C++. If a call throws and it doesn't have an entry in the unwind table, then the "terminate()" function is called. Is it fair to assume that there is a similar mechanism for other languages? The reason to ask this is that it could make the EH tables smaller and less cluttered if we elide those areas which we know don't throw (the functions called are marked 'nounwind', etc.). -bw
Hi Bill,> Right now we generate call sites for all of the code in a function, > even for code that cannot (or at least shouldn't) throw an exception....> (assume it's all been inlined), the EH handling table for "main" goes > from Leh_func_begin1 to Leh_func_end1, marking off each region whether > it can throw or not. From my reading of the Exception Tables > documentation, this is unnecessary – at least for C++. If a call > throws and it doesn't have an entry in the unwind table, then the > "terminate()" function is called. Is it fair to assume that there is a > similar mechanism for other languages?in Ada these extra table entries are not needed at all: whether you have them or not, an exception will continue to unwind. There is no calling of "terminate". In short: you only need a table entry for invoke calls, i.e. things you want to catch in this function. The reason to ask this is that> it could make the EH tables smaller and less cluttered if we elide > those areas which we know don't throw (the functions called are marked > 'nounwind', etc.).Sure, that's what the SawPotentiallyThrowing boolean is for. It is currently set for any call, but in fact needn't be set for 'nounwind' calls. When I wrote this stuff 'nounwind' information wasn't available at the codegen level, which is why this isn't done. In case you care, doing this would not hurt Ada :) Ciao, Duncan.
On Mon, Sep 14, 2009 at 6:50 AM, Duncan Sands <baldrick at free.fr> wrote:> Hi Bill, > >> Right now we generate call sites for all of the code in a function, even >> for code that cannot (or at least shouldn't) throw an exception. > > ... >> >> (assume it's all been inlined), the EH handling table for "main" goes >> from Leh_func_begin1 to Leh_func_end1, marking off each region whether it >> can throw or not. From my reading of the Exception Tables documentation, >> this is unnecessary – at least for C++. If a call throws and it doesn't >> have an entry in the unwind table, then the "terminate()" function is >> called. Is it fair to assume that there is a similar mechanism for other >> languages? > > in Ada these extra table entries are not needed at all: whether you > have them or not, an exception will continue to unwind. There is no > calling of "terminate". In short: you only need a table entry for > invoke calls, i.e. things you want to catch in this function. > > The reason to ask this is that >> >> it could make the EH tables smaller and less cluttered if we elide those >> areas which we know don't throw (the functions called are marked >> 'nounwind', etc.). > > Sure, that's what the SawPotentiallyThrowing boolean is for. It is > currently set for any call, but in fact needn't be set for 'nounwind' > calls. When I wrote this stuff 'nounwind' information wasn't available > at the codegen level, which is why this isn't done. In case you care, > doing this would not hurt Ada :) >Yay! :-) I'm interested in getting the tables smaller. And it will help debug when things go wrong. Thanks! -bw
Hi Bill,> The reason to ask this is that >> it could make the EH tables smaller and less cluttered if we elide >> those areas which we know don't throw (the functions called are marked >> 'nounwind', etc.). > > Sure, that's what the SawPotentiallyThrowing boolean is for. It is > currently set for any call, but in fact needn't be set for 'nounwind' > calls. When I wrote this stuff 'nounwind' information wasn't available > at the codegen level, which is why this isn't done. In case you care, > doing this would not hurt Ada :)now I think about it further, I guess SawPotentiallyThrowing is not for this exactly, you'll need to add some additional logic near this place. Ciao, Duncan.
On Sep 16, 2009, at 6:50 AM, Duncan Sands wrote:> Hi Bill, > >> The reason to ask this is that >>> it could make the EH tables smaller and less cluttered if we >>> elide those areas which we know don't throw (the functions called >>> are marked 'nounwind', etc.). >> Sure, that's what the SawPotentiallyThrowing boolean is for. It is >> currently set for any call, but in fact needn't be set for 'nounwind' >> calls. When I wrote this stuff 'nounwind' information wasn't >> available >> at the codegen level, which is why this isn't done. In case you >> care, >> doing this would not hurt Ada :) > > now I think about it further, I guess SawPotentiallyThrowing is not > for > this exactly, you'll need to add some additional logic near this > place. >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. If I implement my suggestion, this will likely go away. I think Eric's working on something that will add the _Unwind_resume() call during selection DAG time, where we can place EH labels around it. But it's just another thing I have to worry about when doing this. :-) -bw