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


On Thu, 2012-03-08 at 17:05 +0000, Michael Meeks wrote:
      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):

So, here's my numbers.

Firstly x86_64 product-mode, no symbols, code-as-it-is-in-master

 code            140465kb - 40%
 exceptions      49501kb - 14%
 Total: 358418576 bytes

Then with relocstat-no-inline.patch applied to add additional
rtl_string2UString_throw vs rtl_string2UString etc entry points in order
to extract the "if (pData == 0) throw bad_alloc;" out from the inline
OUString constructors and into standalone functions which are allowed to
throw.

 code            140273kb - 40%
 exceptions      49485kb - 14%
 Total: 358116559 bytes

So, a total reduction in size of 294k bytes with that patch applied.
a 192k reduction in code-section-size

Then with relocstat.no-throws.patch applied instead to simply delete the
std::bad_alloc throws

 code            139542kb - 40%
 exceptions      48011kb - 14%
 Total: 356163070 bytes

which makes a far more hefty 2000k over-all reduction with that patch
applied instead. A 923k reduction in code-section-size.

      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 cod

They are frighteningly huge alright. On the other hand, presumably those
sections aren't loaded unless an exception actually gets thrown (?) so
does their presence matter performance-wise.

      It is also a markedly higher proportion than mozilla:

Maybe large bits of mozilla are compiled without exceptions ?,
historically at least given https://developer.mozilla.org/en/C
++_Portability_Guide#Don%27t_use_exceptions exceptions seems to have
been avoided.

      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();

From the no-inlines experiment the effect of removing the throw here is
presumably two-fold, removing the obvious code, but also letting the
compiler additionally know that the constructors now only call
non-throwing methods (e.g. rtl_string2UString is marked as throw()),
making them effectively nothrow as well which is the bigger button.

      They provide us with very little real value since we just abort when
they are thrown in ~all cases.

These specific bad_alloc exceptions or all of our exceptions?, because
trying to e.g. revert to a global -fno-exceptions world seems
impractical.

C.
diff --git a/sal/inc/rtl/ustring.h b/sal/inc/rtl/ustring.h
index b9184e0..cfa191b 100644
--- a/sal/inc/rtl/ustring.h
+++ b/sal/inc/rtl/ustring.h
@@ -1253,6 +1253,8 @@ SAL_DLLPUBLIC void SAL_CALL rtl_uString_newFromAscii(
  */
 SAL_DLLPUBLIC void SAL_CALL rtl_uString_newFromLiteral(
         rtl_uString ** newStr, const sal_Char * value, sal_Int32 len ) SAL_THROW_EXTERN_C();
+SAL_DLLPUBLIC void SAL_CALL rtl_uString_newFromLiteral_throw(
+        rtl_uString ** newStr, const sal_Char * value, sal_Int32 len );
 
 /** Allocate a new string from an array of Unicode code points.
 
@@ -1276,6 +1278,10 @@ SAL_DLLPUBLIC void SAL_CALL rtl_uString_newFromLiteral(
 SAL_DLLPUBLIC void SAL_CALL rtl_uString_newFromCodePoints(
     rtl_uString ** newString, sal_uInt32 const * codePoints,
     sal_Int32 codePointCount) SAL_THROW_EXTERN_C();
+SAL_DLLPUBLIC void SAL_CALL rtl_uString_newFromCodePoints_throw(
+    rtl_uString ** newString, sal_uInt32 const * codePoints,
+    sal_Int32 codePointCount);
+
 
 /** Assign a new value to a string.
 
@@ -1733,6 +1739,9 @@ SAL_DLLPUBLIC sal_Int32 SAL_CALL rtl_uString_getToken(
  */
 SAL_DLLPUBLIC void SAL_CALL rtl_string2UString(
         rtl_uString ** newStr, const sal_Char * str, sal_Int32 len, rtl_TextEncoding encoding, 
sal_uInt32 convertFlags ) SAL_THROW_EXTERN_C();
+SAL_DLLPUBLIC void SAL_CALL rtl_string2UString_throw(
+        rtl_uString ** newStr, const sal_Char * str, sal_Int32 len, rtl_TextEncoding encoding, 
sal_uInt32 convertFlags );
+
 
 /* ======================================================================= */
 /* Interning methods */
@@ -1758,6 +1767,9 @@ SAL_DLLPUBLIC void SAL_CALL rtl_string2UString(
  */
 SAL_DLLPUBLIC void SAL_CALL rtl_uString_intern(
         rtl_uString ** newStr, rtl_uString * str) SAL_THROW_EXTERN_C();
+SAL_DLLPUBLIC void SAL_CALL rtl_uString_intern_throw(
+        rtl_uString ** newStr, rtl_uString * str);
+
 
 /** Return a canonical representation for a string.
 
@@ -1801,6 +1813,14 @@ SAL_DLLPUBLIC void SAL_CALL rtl_uString_internConvert(
                                          rtl_TextEncoding encoding,
                                          sal_uInt32       convertFlags,
                                          sal_uInt32      *pInfo) SAL_THROW_EXTERN_C();
+SAL_DLLPUBLIC void SAL_CALL rtl_uString_internConvert_throw(
+                                         rtl_uString   ** newStr,
+                                         const sal_Char * str,
+                                         sal_Int32        len,
+                                         rtl_TextEncoding encoding,
+                                         sal_uInt32       convertFlags,
+                                         sal_uInt32      *pInfo);
+
 
 /** Iterate through a string based on code points instead of UTF-16 code units.
 
diff --git a/sal/inc/rtl/ustring.hxx b/sal/inc/rtl/ustring.hxx
index ef47be6..1b18dd5 100644
--- a/sal/inc/rtl/ustring.hxx
+++ b/sal/inc/rtl/ustring.hxx
@@ -184,14 +184,14 @@ public:
     OUString( const char (&literal)[ N ] )
     {
         pData = 0;
+#if defined EXCEPTIONS_OFF
         rtl_uString_newFromLiteral( &pData, literal, N - 1 );
         if (pData == 0) {
-#if defined EXCEPTIONS_OFF
             SAL_WARN("sal", "std::bad_alloc but EXCEPTIONS_OFF");
+        }
 #else
-            throw std::bad_alloc();
+        rtl_uString_newFromLiteral_throw( &pData, literal, N - 1 );
 #endif
-        }
 #ifdef RTL_STRING_UNITTEST
         rtl_string_unittest_const_literal = true;
 #endif
@@ -252,14 +252,14 @@ public:
               sal_uInt32 convertFlags = OSTRING_TO_OUSTRING_CVTFLAGS )
     {
         pData = 0;
+#if defined EXCEPTIONS_OFF
         rtl_string2UString( &pData, value, length, encoding, convertFlags );
         if (pData == 0) {
-#if defined EXCEPTIONS_OFF
             SAL_WARN("sal", "std::bad_alloc but EXCEPTIONS_OFF");
+        }
 #else
-            throw std::bad_alloc();
+        rtl_string2UString_throw( &pData, value, length, encoding, convertFlags );
 #endif
-        }
     }
 
     /** Create a new string from an array of Unicode code points.
@@ -282,14 +282,14 @@ public:
         sal_uInt32 const * codePoints, sal_Int32 codePointCount):
         pData(NULL)
     {
+#if defined EXCEPTIONS_OFF
         rtl_uString_newFromCodePoints(&pData, codePoints, codePointCount);
         if (pData == NULL) {
-#if defined EXCEPTIONS_OFF
             abort();
+        }
 #else
-            throw std::bad_alloc();
+        rtl_uString_newFromCodePoints_throw(&pData, codePoints, codePointCount);
 #endif
-        }
     }
 
     /**
@@ -341,14 +341,14 @@ public:
     template< int N >
     OUString& operator=( const char (&literal)[ N ] )
     {
+#if defined EXCEPTIONS_OFF
         rtl_uString_newFromLiteral( &pData, literal, N - 1 );
         if (pData == 0) {
-#if defined EXCEPTIONS_OFF
             SAL_WARN("sal", "std::bad_alloc but EXCEPTIONS_OFF");
+        }
 #else
-            throw std::bad_alloc();
+        rtl_uString_newFromLiteral_throw( &pData, literal, N - 1 );
 #endif
-        }
         return *this;
     }
 
@@ -1870,14 +1870,14 @@ public:
     OUString intern() const
     {
         rtl_uString * pNew = 0;
+#if defined EXCEPTIONS_OFF
         rtl_uString_intern( &pNew, pData );
         if (pNew == 0) {
-#if defined EXCEPTIONS_OFF
             SAL_WARN("sal", "std::bad_alloc but EXCEPTIONS_OFF");
+        }
 #else
-            throw std::bad_alloc();
+        rtl_uString_intern_throw( &pNew, pData );
 #endif
-        }
         return OUString( pNew, (DO_NOT_ACQUIRE *)0 );
     }
 
@@ -1912,15 +1912,16 @@ public:
                             sal_uInt32 *pInfo = NULL )
     {
         rtl_uString * pNew = 0;
+#if defined EXCEPTIONS_OFF
         rtl_uString_internConvert( &pNew, value, length, encoding,
                                    convertFlags, pInfo );
         if (pNew == 0) {
-#if defined EXCEPTIONS_OFF
             SAL_WARN("sal", "std::bad_alloc but EXCEPTIONS_OFF");
+        }
 #else
-            throw std::bad_alloc();
+        rtl_uString_internConvert_throw( &pNew, value, length, encoding,
+                                   convertFlags, pInfo );
 #endif
-        }
         return OUString( pNew, (DO_NOT_ACQUIRE *)0 );
     }
 
diff --git a/sal/rtl/source/strtmpl.cxx b/sal/rtl/source/strtmpl.cxx
index 2d8c44b..61eeff0 100644
--- a/sal/rtl/source/strtmpl.cxx
+++ b/sal/rtl/source/strtmpl.cxx
@@ -1222,6 +1222,15 @@ void SAL_CALL IMPL_RTL_STRINGNAME( newFromLiteral)( IMPL_RTL_STRINGDATA** 
ppThis
     }
 }
 
+void SAL_CALL IMPL_RTL_STRINGNAME( newFromLiteral_throw)( IMPL_RTL_STRINGDATA** ppThis,
+                                                    const sal_Char* pCharStr,
+                                                    sal_Int32 nLen )
+{
+    IMPL_RTL_STRINGNAME( newFromLiteral)( ppThis, pCharStr, nLen );
+    if (*ppThis == NULL)
+        throw std::bad_alloc();
+}
+
 /* ----------------------------------------------------------------------- */
 
 void SAL_CALL IMPL_RTL_STRINGNAME( assign )( IMPL_RTL_STRINGDATA** ppThis,
diff --git a/sal/rtl/source/ustring.cxx b/sal/rtl/source/ustring.cxx
index 7c99758..ed98830 100644
--- a/sal/rtl/source/ustring.cxx
+++ b/sal/rtl/source/ustring.cxx
@@ -549,6 +549,16 @@ void SAL_CALL rtl_uString_newFromCodePoints(
     }
 }
 
+void SAL_CALL rtl_uString_newFromCodePoints_throw(
+    rtl_uString ** newString, sal_uInt32 const * codePoints,
+    sal_Int32 codePointCount)
+{
+    rtl_uString_newFromCodePoints(newString, codePoints, codePointCount);
+    if (*newString == NULL)
+        throw std::bad_alloc();
+}
+
+
 /* ======================================================================= */
 
 static int rtl_ImplGetFastUTF8UnicodeLen( const sal_Char* pStr, sal_Int32 nLen )
@@ -771,6 +781,17 @@ void SAL_CALL rtl_string2UString( rtl_uString** ppThis,
                                nCvtFlags, NULL );
 }
 
+void SAL_CALL rtl_string2UString_throw( rtl_uString** ppThis,
+                                  const sal_Char* pStr,
+                                  sal_Int32 nLen,
+                                  rtl_TextEncoding eTextEncoding,
+                                  sal_uInt32 nCvtFlags )
+{
+    rtl_string2UString(ppThis, pStr, nLen, eTextEncoding, nCvtFlags);
+    if (*ppThis == NULL)
+        throw std::bad_alloc();
+}
+
 /* ----------------------------------------------------------------------- */
 
 enum StrLifecycle {
@@ -842,6 +863,14 @@ void SAL_CALL rtl_uString_intern( rtl_uString ** newStr,
     }
 }
 
+void SAL_CALL rtl_uString_intern_throw( rtl_uString ** newStr,
+                                  rtl_uString  * str)
+{
+    rtl_uString_intern( newStr, str);
+    if (*newStr == NULL)
+        throw std::bad_alloc();
+}
+
 static int rtl_canGuessUOutputLength( int len, rtl_TextEncoding eTextEncoding )
 {
     // FIXME: Maybe we should use a bit flag in the higher bits of the
@@ -939,6 +968,19 @@ void SAL_CALL rtl_uString_internConvert( rtl_uString   ** newStr,
     rtl_ustring_intern_internal( newStr, scratch, CAN_RETURN );
 }
 
+void SAL_CALL rtl_uString_internConvert_throw( rtl_uString   ** newStr,
+                                         const sal_Char * str,
+                                         sal_Int32        len,
+                                         rtl_TextEncoding eTextEncoding,
+                                         sal_uInt32       convertFlags,
+                                         sal_uInt32     * pInfo )
+{
+    rtl_uString_internConvert( newStr, str, len, eTextEncoding,
+                                     convertFlags, pInfo );
+    if (*newStr == NULL)
+        throw std::bad_alloc();
+}
+
 static void
 internRelease (rtl_uString *pThis)
 {
diff --git a/sal/util/sal.map b/sal/util/sal.map
index 2127011..b2d8092 100644
--- a/sal/util/sal.map
+++ b/sal/util/sal.map
@@ -623,6 +623,11 @@ LIBO_UDK_3.6 { # symbols available in >= LibO 3.6
         rtl_uString_newReplaceFirst;
         rtl_uString_newReplaceFirstAsciiL;
         rtl_uString_newReplaceFirstAsciiLAsciiL;
+       rtl_uString_newFromLiteral_throw;
+       rtl_uString_newFromCodePoints_throw;
+       rtl_string2UString_throw;
+       rtl_uString_intern_throw;
+       rtl_uString_internConvert_throw;
 } UDK_3.10;
 
 PRIVATE_1.0 {
diff --git a/sal/inc/rtl/ustring.hxx b/sal/inc/rtl/ustring.hxx
index ef47be6..c4005a9 100644
--- a/sal/inc/rtl/ustring.hxx
+++ b/sal/inc/rtl/ustring.hxx
@@ -186,11 +186,7 @@ public:
         pData = 0;
         rtl_uString_newFromLiteral( &pData, literal, N - 1 );
         if (pData == 0) {
-#if defined EXCEPTIONS_OFF
             SAL_WARN("sal", "std::bad_alloc but EXCEPTIONS_OFF");
-#else
-            throw std::bad_alloc();
-#endif
         }
 #ifdef RTL_STRING_UNITTEST
         rtl_string_unittest_const_literal = true;
@@ -254,11 +250,7 @@ public:
         pData = 0;
         rtl_string2UString( &pData, value, length, encoding, convertFlags );
         if (pData == 0) {
-#if defined EXCEPTIONS_OFF
             SAL_WARN("sal", "std::bad_alloc but EXCEPTIONS_OFF");
-#else
-            throw std::bad_alloc();
-#endif
         }
     }
 
@@ -284,11 +276,7 @@ public:
     {
         rtl_uString_newFromCodePoints(&pData, codePoints, codePointCount);
         if (pData == NULL) {
-#if defined EXCEPTIONS_OFF
             abort();
-#else
-            throw std::bad_alloc();
-#endif
         }
     }
 
@@ -343,11 +331,7 @@ public:
     {
         rtl_uString_newFromLiteral( &pData, literal, N - 1 );
         if (pData == 0) {
-#if defined EXCEPTIONS_OFF
             SAL_WARN("sal", "std::bad_alloc but EXCEPTIONS_OFF");
-#else
-            throw std::bad_alloc();
-#endif
         }
         return *this;
     }
@@ -1872,11 +1856,7 @@ public:
         rtl_uString * pNew = 0;
         rtl_uString_intern( &pNew, pData );
         if (pNew == 0) {
-#if defined EXCEPTIONS_OFF
             SAL_WARN("sal", "std::bad_alloc but EXCEPTIONS_OFF");
-#else
-            throw std::bad_alloc();
-#endif
         }
         return OUString( pNew, (DO_NOT_ACQUIRE *)0 );
     }
@@ -1915,11 +1895,7 @@ public:
         rtl_uString_internConvert( &pNew, value, length, encoding,
                                    convertFlags, pInfo );
         if (pNew == 0) {
-#if defined EXCEPTIONS_OFF
             SAL_WARN("sal", "std::bad_alloc but EXCEPTIONS_OFF");
-#else
-            throw std::bad_alloc();
-#endif
         }
         return OUString( pNew, (DO_NOT_ACQUIRE *)0 );
     }
--- Total summary ---

.data summary:
 vtables: 0 size 0 bytes
 rtti: 0 size 0 bytes
 other: 4039 size 749682 bytes

Section size breakdown
 code            140273kb - 40%
 linking         64456kb - 18%
 exceptions      49485kb - 14%
 data            44872kb - 13%
 misc            31720kb - 9.1%
 symbols         13236kb - 3.8%
 debug           3259kb - 0.93%
 versioning      1362kb - 0.39%
 bss             1025kb - 0.29%
 comment           12kb - 0.0035%
 init/fini         10kb - 0.003%
 c/d-tors           8kb - 0.0026%
 Total: 358116559 bytes
Symbol entry counts:
 ~total .dynsym entries: 748824
 .dynstr size:
    def:    47653051
    undef:  5627387
    (avg len):  71
--- Total summary ---

.data summary:
 vtables: 0 size 0 bytes
 rtti: 0 size 0 bytes
 other: 4039 size 749682 bytes

Section size breakdown
 code            140273kb - 40%
 linking         64456kb - 18%
 exceptions      49485kb - 14%
 data            44872kb - 13%
 misc            31720kb - 9.1%
 symbols         13236kb - 3.8%
 debug           3259kb - 0.93%
 versioning      1362kb - 0.39%
 bss             1025kb - 0.29%
 comment           12kb - 0.0035%
 init/fini         10kb - 0.003%
 c/d-tors           8kb - 0.0026%
 Total: 358116559 bytes
Symbol entry counts:
 ~total .dynsym entries: 748824
 .dynstr size:
    def:    47653051
    undef:  5627387
    (avg len):  71
--- Total summary ---

.data summary:
 vtables: 0 size 0 bytes
 rtti: 0 size 0 bytes
 other: 4039 size 749682 bytes

Section size breakdown
 code            139542kb - 40%
 linking         64453kb - 19%
 exceptions      48011kb - 14%
 data            44923kb - 13%
 misc            31872kb - 9.2%
 symbols         13219kb - 3.8%
 debug           3375kb - 0.97%
 versioning      1359kb - 0.39%
 bss             1025kb - 0.29%
 comment           12kb - 0.0035%
 init/fini         10kb - 0.0031%
 c/d-tors           8kb - 0.0026%
 Total: 356163070 bytes
Symbol entry counts:
 ~total .dynsym entries: 748725
 .dynstr size:
    def:    47644443
    undef:  5626038
    (avg len):  71

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.