This is the mail archive of the
gcc@gcc.gnu.org
mailing list for the GCC project.
Re: EH Performance
- To: eboling at mirrorfinish dot com
- Subject: Re: EH Performance
- From: "Martin v. Loewis" <martin at loewis dot home dot cs dot tu-berlin dot de>
- Date: Fri, 25 Feb 2000 09:02:13 +0100
- CC: gcc at gcc dot gnu dot org
- References: <3.0.6.32.20000224160323.007ea6f0@pop.texas.net>
> Can anyone give me any history on this topic?
I can't give you very early history, but I can tell you that it used
to be worse :-)
Specifically, libgcc is sorting the FDEs in order of increasing
address, to allow a binary search during unwinding. In egcs 1.0 (and
gcc 2.8), the sort algorithm was *very* slow, resulting in a huge time
consumption on throwing the first exception.
A solution to that problem was contributed by Bruno Haible; see the
patch logged as
Sun Mar 1 18:25:37 1998 Bruno Haible <bruno@linuix.mathematik.uni-karlsruhe.de>
* frame.c (start_fde_sort, fde_split, heapsort, fde_merge,
end_fde_sort): New functions for fast sorting of an FDE array.
(fde_insert): Simplified.
(add_fdes): Change argument list.
(frame_init): Use the new functions.
for details. At that time, it was also discussed that the linker could
do the sorting, thus removing the need for runtime sorting. However,
that approach was never implemented. I guess if users are *really*
interested in such a change, that would be an option.
Also, your assertion that the mechanism initializes *all* of the
shared objects (DSO) in the entire application; it does not. It only
processes them in list order until it finds the DSO in which the PC
currently lives. It is necessary to initialize all those DSOs even if
they are not the origin of the exception because there is no run-time
information where the shared library lives in address space. If it was
possible to find out the exact range of all code segments of a DSO at
run time (or find out lower and upper boundaries), then DSOs could be
skipped if they clearly are not the origin of the exception. I'm not
sure what kind of magic that involves, but it seems that the dynamic
linker would have to play a role here.
> First of all, the eh_frame section is marked as read/write in the
> image and, in the case of C++ auto destructor support, this section
> contains flat pointers into the .gcc_except_table section. This
> causes relocations to be emitted when you build a shared object,
> which will cause the eh_frame section to be paged in at application
> load time.
AFAIK, this is the first time this has been reported as a problem. I
assume you are referring to constructs like
.LSCIE1:
.4byte 0x0
.byte 0x1
.string "eh"
.4byte __EXCEPTION_TABLE__
It may be possible to use a relative offset from the CIE to the
exception table, which could be filled-in by the linker, i.e.
.4byte __EXCEPTION_TABLE__ - .LSCIE1
The linker experts would need to comment whether that can be done with
proper relocations; the simple approach above fails as the symbols are
from different sections. If that can be solved in some way, then the
runtime could certainly interpret the value as a delta; it probably
needs a different magic string to do so.
Anyway, it seems to me that any solution to that would be highly
platform-specific. You didn't say what platform you are using; on
Linux, changing the dynamic loader might be an option, on Solaris, it
would not.
Also note that a new C++ ABI is currently underway, which also
includes a new unwinding mechanism. Even though the ABI is primarily
designed for ia64, g++ will likely use it on other platforms as well.
Regards,
Martin