Re: Exception Handling (Doug Landauer)
18 Sep 1998 23:10:48 -0400

          From comp.compilers

Related articles
[7 earlier articles]
Re: Exception Handling (Marco van de Voort) (2002-08-10)
Re: Exception Handling (Maxim Reznik) (2002-08-10)
Re: Exception Handling (Fergus Henderson) (2002-08-14)
Exception Handling (Bernhard Tschirren) (1998-09-13)
Re: Exception Handling (1998-09-18)
Re: Exception Handling (1998-09-18)
Re: Exception Handling (1998-09-18)
Re: Exception Handling (Morten Christensen) (1998-09-26)
| List of all articles for this month |

From: (Doug Landauer)
Newsgroups: comp.compilers
Date: 18 Sep 1998 23:10:48 -0400
Organization: Apple Computer, Inc.
References: 98-09-049
Keywords: errors

Bernhard Tschirren <> wrote:

> Could somebody please explain "zero runtime overhead" exception handling.
> I'm only familiar with the traditional setjmp() / longjmp() methods.

Well, the first thing to understand is that it's not actually "zero".
It's "small", even when no exceptions are thrown. And it can be
considerable overhead when exceptions do occur, but that's OK, because
it is in line with the C++ exception handling philosophy.

I've worked on three C++ compilers in the past four years, and these
three all use an algorithm at least roughly equivalent to the following:

    The compiler generates an "exception table" data structure, where
    each entry has a start address, an end address, the handler address,
    and a code that tells what kind of entry this is, and some other
    info (e.g., the catch type). Some operating systems can leave
    these tables on disk, and never page it in unless an exception actually
    occurs. Some operating systems can't easily do this optimization (*1).

    The linker collects and sorts these exception tables, and maybe
    performs relocation (*2) on them, if the code in question is going
    to be in a shared library.

    The compiler has to notice that any function call within a try
    block can also be a jump to the corresponding handler, and
    accordingly must preserve register values, and possibly inhibit
    code motion / instruction scheduling -- optimizations that might
    be possible when compiling with exceptions disabled (*3).

    Normal code ignores the EH tables, and runs pretty much full speed.
    But when an exception is thrown, the "throw" code has to interpret
    the tables, walk back up the stack to see what "catch" is relevant,
    then copy the thrown object into the catch variable, unwind the
    stack, restoring the state of the function that caught the exception,
    and then transfer control to the handler.

So the marked points:
    (*1) the OS might be unable to avoid loading the EH table data;
    (*2) the linker might need to perform relocation on the tables; and
    (*3) some optimizations are not possible;
are the main contributors to the small overhead that is caused by the
use of exceptions. That small overhead == zero if your OS is smart, your
linker/relocator is smart or very stupid, and your optimizer is weak
(e.g., an optimizer that wouldn't do those optimizations anyway). :-)

        Doug Landauer (work)

Post a followup to this message

Return to the comp.compilers page.
Search the comp.compilers archives again.