Related articles |
---|
[2 earlier articles] |
Re: Implementation of C++ exceptions ? mw@ipx2.rz.uni-mannheim.de (1994-04-05) |
Re: Implementation of C++ exceptions ? chase@Think.COM (1994-04-05) |
Re: Implementation of C++ exceptions ? schmidt@tango.ICS.UCI.EDU (Douglas C. Schmidt) (1994-04-06) |
Re: Implementation of C++ exceptions ? mmc@wagner.imada.ou.dk (1994-04-07) |
Implementation of C++ exceptions ? ssimmons@convex.com (1994-04-08) |
Re: Implementation of C++ exceptions ? davis@ilog.ilog.fr (1994-04-11) |
Re: Implementation of C++ exceptions ? chase@Think.COM (1994-04-11) |
Re: Implementation of C++ exceptions ? sean@PICARD.TAMU.EDU (1994-04-12) |
Newsgroups: | comp.compilers |
From: | chase@Think.COM (David Chase) |
Keywords: | C++, performance, design |
Organization: | Thinking Machines Corporation, Cambridge MA, USA |
References: | 94-04-019 94-04-066 |
Date: | Mon, 11 Apr 1994 20:31:24 GMT |
davis@ilog.ilog.fr (Harley Davis) writes:
|> I thought the cost of exception handling in C++ was the need to stack
|> up the code which calls the destructors of automatic variables in all
|> active blocks when unwinding to the handler. I couldn't figure out if
|> David Chase's description eliminated this cost.
[Disclaimer -- what follows is *like* what the SunPro C++ 4.0 compiler
does, but not necessarily what it does.]
My fault -- I described the data structure, but not the algorithm. Given
the tables full of (sorted) self-relative PC-ranges that are assembled by
the linker, and given that the per-binary/library .init section registers
the endpoints of each table, there is no need to stack and unstack
exception handlers in the normal case. When an an exception is thrown,
the run-time dispatcher searches the tables while unwinding the stack.
The protocol looks something like:
recall that an exception range entry is 5 words:
self_rel_rbegin, rlength, rbegin_rel_handler, self_rel_info, reserved
__rt_ex_disp:
save ...
candidate = find_entry(%i7,%i0) ! pass it our return PC, and exception
if (candidate != 0) {
! return into frame.
range_begin = candidate + candidate[0];
handler = range_begin + candidate[2];
jmp handler
restore
} else {
! discard frame and try again
restore %i0, 0, %i0
ba __rt_ex_disp
restore
}
There's some details and monkey business having to do with C++ semantics
(having to do with where the exception object is supposed to be stored,
etc.) Find_entry has to interpret the info field to see if the exception
matches.
The handler for this exception runs in the same context as the other
source code surrounding it. If the exception is rethrown, or if the
handler is really just a bunch of destructors, then at the end of the
code, it does something like:
__rt_ex_disp(exception)
Note (this is important) that this call into the runtime does NOT occur
within the same PC range that invoked this handler. This may invoke
another handler in the same frame, or it may cause the frame to be
discarded.
This all gets much more entertaining when you are trying to debug code,
because then it is not permitted to destroy the stack as you search for a
handler. Note that this also relies heavily on calling *conventions*
(probably not standards -- this are some angels-on-a-pin regarding
behavior of the ABI and compiled code in the presence of setjmp and
longjmp) that are widely followed by compilers for Sparc -- namely, that
an activation record is equivalent to a register window. (Not true for
leaf routines, but then a leaf routine by definition cannot contain a call
to __rt_ex_disp).
In the case of the debugger, what you must do is dump the register windows
to the stack (usual case for debugger) and walk the stack, passing the
return PC's so encountered to "find_entry", hoping to get a hit. The info
data structure (or else debugger information) has to include information
distinguishing true C++ handlers from destructors.
If I get really motivated, I'll try to describe how asynchronous exception
handling (could) work.
David Chase, speaking for myself
Thinking Machines Corp.
--
Return to the
comp.compilers page.
Search the
comp.compilers archives again.