ia64 c++ abi exception handling

Richard Henderson rth@redhat.com
Sun Mar 11 17:39:00 GMT 2001


The following is an initial implementation of the exception 
handling model proposed by the multi-vendor C++ ABI folks.
The specification is targeted at IA-64, but require only 
minor tweeks to be usable on other targets.

The new implementation has a number of advantages:

  * "Personality" routine controls precise exception handling
    semantics.  Rules exist for managing exceptions between
    languages.

  * Two pass structure allows a language to cancel an exception
    and continue from the point of throw.

    For C++, the unhandled exception abort happens from the point
    of throw, as opposed to at the beginning of the call chain,
    so its easier to see what went wrong.

  * Generated code and exception handling data is smaller.
    For instance on alpha-linux, libstdc++.so goes from

				     OLD       NEW
	.rela.eh_frame             28872     37368
	.rela.gcc_except_table    109584      2016
	.text                     445584    418880
	.eh_frame                  49560     59216
	.gcc_except_table          48272     11728

    I expect to be able to reduce the number of dynamic
    relocations further, but this patch is big enough as is.

  * The optimizers need not worry about exception regions at all.
    The strict logical nesting of exception "regions" only exists
    during initial code generation.  Afterward, each instruction
    that is known to throw is tagged with a REG_EH_REGION note
    which records what actions ought to be taken if an exception
    occurs at that location.  Code may now be reordered as the
    optimizers see fit.  Just before emitting assembly, we look
    to see what order things came out and emit sorted tuples 
    containing pc range, landing pad, and action data.

  * Debugging information for catch handlers should be correct.
    The previous "new exceptions" model generated catch clauses
    out of line so that we didn't have to branch around them.
    In the process, it disassociated the code from the debugging
    information.

    This implementation generates the code in line and relies on
    the bb-reorder pass to move it elsewhere and preserve debugging.

There are a number of changes that must be made to targets to
support the new routines.  If a target previously defined
eh_epilogue, then the changes are minimal -- mostly describing
the ABI of the exception handler landing pads.

The old method of using a generic thunk to implement dwarf2
exception return is not supported.  It's not that hard to just
do things properly, and some of the bits involved define the
ABI between throw and catch, so it's a really bad idea for 
generic code to just make something up.

I've not yet re-implemented sjlj exeption handling.  I have a plan
that should greaty reduce the overhead as compared to the existing 
implementation.  I'd really rather deprecate it entirely, but the
non-ability of dwarf2 frame unwind to cope with intermediate
routines not compiled with frame information is probably s show
stopper there.

I have not yet done anything with Java.  I'd been delaying that
until C++ worked.  I'll be talking with them this next week.

This code has been ported to alpha, i386, and powerpc.  It has been
tested on alphaev6-linux, i686-linux, and powerpc-eabisim.  The 
regressions are at an acceptable minimum (IMO):

FAIL: g++.eh/cond1.C (test for excess errors)
FAIL: g++.eh/crash5.C (test for excess errors)
FAIL: g++.other/cond5.C (test for excess errors)

   `({...})' has type `void' and is not a throw-expression

   Before the front end somehow magically recognized a post-template
   expansion throw expression.  The new code doesn't look the same,
   and I'm not sure how to update the check.

FAIL: g++.other/goto3.C jumps (test for errors, line 9)
FAIL: g++.other/goto3.C into catch (test for errors, line 10)
FAIL: g++.other/goto3.C  (test for errors, line 16)
FAIL: g++.other/goto3.C  (test for errors, line 17)

   Failure to notice an illegal branch target inside a catch handler.
   I've not yet examined what the front end had been using to notice
   this condition previously.

FAIL: g++.eh/crash3.C caused compiler crash
FAIL: g++.eh/vbase3.C caused compiler crash

   These tests force -fsjlj-exceptions, which isn't implemented.


Comments welcome.


r~
-------------- next part --------------
A non-text attachment was scrubbed...
Name: d-eh-10.bz2
Type: application/x-bzip2
Size: 123100 bytes
Desc: not available
URL: <http://gcc.gnu.org/pipermail/gcc-patches/attachments/20010311/becca575/attachment.bz2>


More information about the Gcc-patches mailing list