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
Re: String literals, ASCII vs UTF-8 · Stephan Bergmann
Re: String literals, ASCII vs UTF-8 · Lubos Lunak
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.