Date: prev next · Thread: first prev next last
2012 Archives by date, by thread · List index


On 02/29/2012 05:29 PM, 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:

$ du -b -c ../../without-stripped/program/*.so  | tail
...
171373684       total
$ du -b -c ../../with-stripped/program/*.so  | tail
...
174692100       total
$

        ie. we have as a lower bound a 1.8% size saving. I expect that to grow
as we start to LTO - as we can finally propagate the fact that methods
don't throw exceptions across modules, and across libraries.

I wouldn't expect too much benefit from a potentially better nothrow analysis. Looking at the C++ standard library, there are lots of functions that can throw, not just new. And using exceptions instead of error return codes can also improve performance, by removing the need for explicit return code checks in the code. (Not to mention that using exceptions, especially ones like std::bad_alloc that are typically intended to just abort your application, can simplify the source code, something that is IMO of equal importance to raw code size/performance.)

        Now - the immediate, and expected riposte is that ~2% of our size is
insignificant ( to go along with the 3% of our CPU time at startup
parsing labels we mostly don't need ;-). Personally, I don't think the
approach of ignoring any efficiency win as insignificant if it is less
than 10% across a code-base of our size is sustainable in the long
term :-) the more we ignore the more it adds up.

        So here are the facts, correct me if I'm wrong:

        * often std::bad_alloc is not handled, making the program
          abort, the exception is not caught by main - there is no
          autosave and data is lost - ie. a SEGV would be preferable.

That's wrong (as we already discussed elsewhere), an uncaught exception (leading to std::terminate -> std::abort -> SIGABRT) behaves virtually the same as SIGSEGV wrt our crash handling.

        * often we fail to emit std::bad_alloc in out of memory

Yes, our code base contains errors.  Lots of them.  ;)

          conditions, cf. sal/inc/rtl/allocator.hxx etc. etc.

Cf. the comment at Allocator::allocate. That code probably predates the invention of the #if defined EXCEPTIONS_OFF workaround used elsewhere.

        * it is unarguably the case that there is no consistent
          bad_alloc handling, it is random, ill thought through and
          anything less than aborting that complete document load/save/
          calculate operation will almost certainly lead to (silent)
          data loss / document errors.

Sure, the current code base, grown over decades and written by people with substantially diverging viewpoints, is a mess. One can only hope that exceptions like std::bad_alloc consistently make it to std::terminate without "helpfully" being caught by some clueless catch (...) before, so that they can lead to a nice SIGABRT and following crash handling (see above).

So, pragmatically, reacting on rtl_allocateMemory() == 0 with std::abort is probably ~just as good as reacting with std::bad_alloc (as I already said in this thread). What I object to is simply ignoring the return value of rtl_allocateMemory, and relying on some subsequent pointer dereferencing leading to SIGSEGV (as it complicates crash analysis, gives a wrong impression about our competence, etc.).

(IMO, the advantage of using std::bad_alloc over std::abort in low level building blocks like rtl::OUString is that it /potentially/ allows the call site to decide whether or not to react on it, cf. Caolán's example. But, indeed, that's probably a minor point as long as our overall code base has more pressing problems, and one that can eventually be corrected.)

        * the user experience of: "we're out of memory, by the way we
          prolly lost some of your document, please try to save,
          re-start compare the data etc." is insignificantly less
          painful than taking a crash.

Nobody suggested that OOM should lead to such a more specific user experience than your garden-variety crash. (Again: the std::bad_alloc is intended for consumption by clueful-enough layers -- and whether there can be such, at least in current LO, is of course debatable. All others shall let it pass, leading to SIGABRT and normal crash handling, see above.)

        * in cases where we have a reasonable expectation of an
          allocation failing and the ability to actually do something
          meaningful: loading images perhaps, where we could swapout
          other images, we can (and do) call the allocation ourself
          and handle return values.

        * IMHO for everything else, we just waste 2% of our size, and
          some CPU cost for no good reason at all, and doubly so for
          the case of OUString("foo") const-strings that we allocate
          internally that cannot be that large.

        Ergo, I suggest we discuss this at the ESC tomorrow, with a view to a
pragmatic, top-to-bottom solution that actually has a chance of working
well.

        I've added it to the agenda.

Ah, I should have read this before the call.  ;)

Stephan

Context


Privacy Policy | Impressum (Legal Info) | Copyright information: Unless otherwise specified, all text and images on this website are licensed under the Creative Commons Attribution-Share Alike 3.0 License. This does not include the source code of LibreOffice, which is licensed under the Mozilla Public License (MPLv2). "LibreOffice" and "The Document Foundation" are registered trademarks of their corresponding registered owners or are in actual use as trademarks in one or more countries. Their respective logos and icons are also subject to international copyright laws. Use thereof is explained in our trademark policy.