Excessive exception size cost ...
michael.meeks at suse.com
Thu Mar 8 09:05:08 PST 2012
On Wed, 2012-02-29 at 16:29 +0000, Michael Meeks wrote:
> So - I did some more analysis, and re-compiled all of LibreOffice both
> with and without the attached patch - analysing all 287 shared libraries
> we get:
So - because of the expert skepticism of my estimate of where the
wasteage is: ie. exception unwind tables, I re-ran my relocstats.pl tool
(which I've checked in here):
over the code both with and without those extra bad_alloc exceptions we
spit out on every string allocation (which are used to do nothing more
useful than abort ;-).
Here are the numbers from:
$ relocstat.pl --data-profile *.so # in program/
Section size breakdown # with no string exceptions
code 74126kb - 45%
exceptions 46003kb - 28%
data 20913kb - 13%
linking 15432kb - 9.3%
data relocs 8462kb - 5.1%
Total: 170285850 bytes
Section size breakdown # with string exceptions thrown everywhere
code 75233kb - 44%
exceptions 48131kb - 28%
data 20913kb - 12%
linking 15445kb - 9.1%
data relocs 8462kb - 5%
Total: 173612058 bytes
So - there is the 1.9% size saving ~3.3Mb saved (which is a lower bound
- we can do better by being more complete).
Perhaps what is more frightening, is the sheer weight of the exception
information: we have fourty-eight (48) Mb of exception unwind
information vs. 75Mb of code; that is cf.
from just two section types: .gcc_except_table and .eh_frame.
It appears that for every 10 bytes of .text (ie. code) we create 6+
bytes of exception unwind information.
Given that we then that in (100 - epsilon)% of the generated cases
don't do anything at all useful with the results beyond the crash
handler, this seems rather a high cost to pay.
It is also a markedly higher proportion than mozilla:
Section size breakdown
code 15923kb - 60%
exceptions 4870kb - 18%
data 3226kb - 12%
data relocs 1682kb - 6.3%
linking 460kb - 1.7%
This is compiled with openSUSE 12.1's default: gcc 4.6.2, and operating
on stripped binaries.
We can also see that of the two potential causes of bloat removal of
not doing this:
a) not in-lining:
if (error_return) throw ::std::bad_alloc();
b) not generating huge unwind tables for methods doing pure
The win breaks down thus:
code change: -1107kb
exception change -2128kb
So 2/3rds of the reduction is simply shrinking the unwind tables.
While it shouldn't affect the ultimate numbers, I am using the
--enable-merged-libs feature here (as is obvious from the
autogen.lastrun I posted).
So - there we are: exceptions hurt, they hurt really a lot size-wise,
and they provide us with very little real value since we just abort when
they are thrown in ~all cases. Alternatively, perhaps they are truly a
productivity tool - they certainly let us generate more bytes of output
more quickly ;-)
Feedback appreciated, my relocstat.pl tool is untouched for several
years, possibly it is not adding up right - please do check it out.
michael.meeks at suse.com <><, Pseudo Engineer, itinerant idiot
More information about the LibreOffice