From 91fa94823e835c31efa7669fbd3a9d3d4b44eba9 Mon Sep 17 00:00:00 2001 From: "timeless%mozdev.org" Date: Mon, 17 Mar 2003 23:16:16 +0000 Subject: [PATCH] Bug 196506 Excessive inlining in string libs: Substring() patch by mvl@exedo.nl r=dougt sr=alecf --- string/embed/nsEmbedString.cpp | 46 +++++++++++++++ string/public/nsDependentSubstring.h | 64 +++------------------ string/src/nsDependentSubstring.cpp | 65 +++++++++++++++++++++- xpcom/string/embed/nsEmbedString.cpp | 46 +++++++++++++++ xpcom/string/public/nsDependentSubstring.h | 64 +++------------------ xpcom/string/src/nsDependentSubstring.cpp | 65 +++++++++++++++++++++- 6 files changed, 236 insertions(+), 114 deletions(-) diff --git a/string/embed/nsEmbedString.cpp b/string/embed/nsEmbedString.cpp index aed9635305f..a13cfde5373 100644 --- a/string/embed/nsEmbedString.cpp +++ b/string/embed/nsEmbedString.cpp @@ -452,3 +452,49 @@ nsEmbedCString::GrowCapacity(size_type aNewCapacity) return result; } + + +// Copies of Distance() function (and things that it depends on) from +// ../src/nsReadableUtils.cpp. This is needed to make the non-inline +// constructors of nsDependentSubstring work in embed builds. +// See bug 196506 + +template class CalculateLength + { + public: + typedef CharT value_type; + + CalculateLength() : mDistance(0) { } + size_t GetDistance() const { return mDistance; } + + PRUint32 write( const CharT*, PRUint32 N ) + { mDistance += N; return N; } + private: + size_t mDistance; + }; + +template +inline +size_t +Distance_Impl( const nsReadingIterator& aStart, + const nsReadingIterator& aEnd ) + { + CalculateLength sink; + nsReadingIterator fromBegin(aStart); + copy_string(fromBegin, aEnd, sink); + return sink.GetDistance(); + } + +NS_COM +size_t +Distance( const nsAString::const_iterator& aStart, const nsAString::const_iterator& aEnd ) + { + return Distance_Impl(aStart, aEnd); + } + +NS_COM +size_t +Distance( const nsACString::const_iterator& aStart, const nsACString::const_iterator& aEnd ) + { + return Distance_Impl(aStart, aEnd); + } diff --git a/string/public/nsDependentSubstring.h b/string/public/nsDependentSubstring.h index 98463e68ab9..0571d25ee44 100644 --- a/string/public/nsDependentSubstring.h +++ b/string/public/nsDependentSubstring.h @@ -61,22 +61,8 @@ class NS_COM nsDependentSubstring virtual char_type* GetWritableFragment( fragment_type&, nsFragmentRequest, PRUint32 ) { return 0; } public: - nsDependentSubstring( const abstract_string_type& aString, PRUint32 aStartPos, PRUint32 aLength ) - : mString(aString), - mStartPos( NS_MIN(aStartPos, aString.Length()) ), - mLength( NS_MIN(aLength, aString.Length()-mStartPos) ) - { - // nothing else to do here - } - - nsDependentSubstring( const const_iterator& aStart, const const_iterator& aEnd ) - : mString(aStart.string()) - { - const_iterator zeroPoint; - mString.BeginReading(zeroPoint); - mStartPos = Distance(zeroPoint, aStart); - mLength = Distance(aStart, aEnd); - } + nsDependentSubstring( const abstract_string_type& aString, PRUint32 aStartPos, PRUint32 aLength ); + nsDependentSubstring( const const_iterator& aStart, const const_iterator& aEnd ); // nsDependentSubstring( const self_type& ); // auto-generated copy-constructor should be OK // ~nsDependentSubstring(); // auto-generated destructor OK @@ -113,22 +99,8 @@ class NS_COM nsDependentCSubstring virtual char_type* GetWritableFragment( fragment_type&, nsFragmentRequest, PRUint32 ) { return 0; } public: - nsDependentCSubstring( const abstract_string_type& aString, PRUint32 aStartPos, PRUint32 aLength ) - : mString(aString), - mStartPos( NS_MIN(aStartPos, aString.Length()) ), - mLength( NS_MIN(aLength, aString.Length()-mStartPos) ) - { - // nothing else to do here - } - - nsDependentCSubstring( const const_iterator& aStart, const const_iterator& aEnd ) - : mString(aStart.string()) - { - const_iterator zeroPoint; - mString.BeginReading(zeroPoint); - mStartPos = Distance(zeroPoint, aStart); - mLength = Distance(aStart, aEnd); - } + nsDependentCSubstring( const abstract_string_type& aString, PRUint32 aStartPos, PRUint32 aLength ); + nsDependentCSubstring( const const_iterator& aStart, const const_iterator& aEnd ); // nsDependentCSubstring( const self_type& ); // auto-generated copy-constructor should be OK // ~nsDependentCSubstring(); // auto-generated destructor OK @@ -155,20 +127,10 @@ class NS_COM nsDependentSingleFragmentSubstring typedef nsASingleFragmentString abstract_single_fragment_type; void - Rebind( const char_type* aStartPtr, const char_type* aEndPtr ) - { - NS_ASSERTION(aStartPtr && aEndPtr, "nsDependentSingleFragmentString must wrap a non-NULL buffer"); - mHandle.DataStart(aStartPtr); - mHandle.DataEnd(aEndPtr); - } + Rebind( const char_type* aStartPtr, const char_type* aEndPtr ); void - Rebind( const abstract_single_fragment_type& aString, const PRUint32 aStartPos, const PRUint32 aLength ) - { - const_char_iterator iter; - mHandle.DataStart(aString.BeginReading(iter) + NS_MIN(aStartPos, aString.Length())); - mHandle.DataEnd( NS_MIN(mHandle.DataStart() + aLength, aString.EndReading(iter)) ); - } + Rebind( const abstract_single_fragment_type& aString, const PRUint32 aStartPos, const PRUint32 aLength ); nsDependentSingleFragmentSubstring( const char_type* aStartPtr, const char_type* aEndPtr ) { Rebind(aStartPtr, aEndPtr); } nsDependentSingleFragmentSubstring( const abstract_single_fragment_type& aString, const PRUint32 aStartPos, const PRUint32 aLength ) { Rebind(aString, aStartPos, aLength); } @@ -196,20 +158,10 @@ class NS_COM nsDependentSingleFragmentCSubstring typedef nsASingleFragmentCString abstract_single_fragment_type; void - Rebind( const char_type* aStartPtr, const char_type* aEndPtr ) - { - NS_ASSERTION(aStartPtr && aEndPtr, "nsDependentSingleFragmentCString must wrap a non-NULL buffer"); - mHandle.DataStart(aStartPtr); - mHandle.DataEnd(aEndPtr); - } + Rebind( const char_type* aStartPtr, const char_type* aEndPtr ); void - Rebind( const abstract_single_fragment_type& aString, const PRUint32 aStartPos, const PRUint32 aLength ) - { - const_char_iterator iter; - mHandle.DataStart(aString.BeginReading(iter) + NS_MIN(aStartPos, aString.Length())); - mHandle.DataEnd( NS_MIN(mHandle.DataStart() + aLength, aString.EndReading(iter)) ); - } + Rebind( const abstract_single_fragment_type& aString, const PRUint32 aStartPos, const PRUint32 aLength ); nsDependentSingleFragmentCSubstring( const char_type* aStartPtr, const char_type* aEndPtr ) { Rebind(aStartPtr, aEndPtr); } nsDependentSingleFragmentCSubstring( const abstract_single_fragment_type& aString, const PRUint32 aStartPos, const PRUint32 aLength ) { Rebind(aString, aStartPos, aLength); } diff --git a/string/src/nsDependentSubstring.cpp b/string/src/nsDependentSubstring.cpp index a857da7f8cf..43935ef8eaf 100644 --- a/string/src/nsDependentSubstring.cpp +++ b/string/src/nsDependentSubstring.cpp @@ -23,6 +23,23 @@ #include "nsDependentSubstring.h" +nsDependentSubstring::nsDependentSubstring( const abstract_string_type& aString, PRUint32 aStartPos, PRUint32 aLength ) + : mString(aString), + mStartPos( NS_MIN(aStartPos, aString.Length()) ), + mLength( NS_MIN(aLength, aString.Length()-mStartPos) ) + { + // nothing else to do here + } + +nsDependentSubstring::nsDependentSubstring( const const_iterator& aStart, const const_iterator& aEnd ) + : mString(aStart.string()) + { + const_iterator zeroPoint; + mString.BeginReading(zeroPoint); + mStartPos = Distance(zeroPoint, aStart); + mLength = Distance(aStart, aEnd); + } + PRUint32 nsDependentSubstring::Length() const { @@ -71,8 +88,22 @@ nsDependentSubstring::GetReadableFragment( const_fragment_type& aFragment, nsFra return position_ptr; } +nsDependentCSubstring::nsDependentCSubstring( const abstract_string_type& aString, PRUint32 aStartPos, PRUint32 aLength ) + : mString(aString), + mStartPos( NS_MIN(aStartPos, aString.Length()) ), + mLength( NS_MIN(aLength, aString.Length()-mStartPos) ) + { + // nothing else to do here + } - +nsDependentCSubstring::nsDependentCSubstring( const const_iterator& aStart, const const_iterator& aEnd ) + : mString(aStart.string()) + { + const_iterator zeroPoint; + mString.BeginReading(zeroPoint); + mStartPos = Distance(zeroPoint, aStart); + mLength = Distance(aStart, aEnd); + } PRUint32 nsDependentCSubstring::Length() const @@ -121,3 +152,35 @@ nsDependentCSubstring::GetReadableFragment( const_fragment_type& aFragment, nsFr return position_ptr; } + +void +nsDependentSingleFragmentSubstring::Rebind( const char_type* aStartPtr, const char_type* aEndPtr ) + { + NS_ASSERTION(aStartPtr && aEndPtr, "nsDependentSingleFragmentString must wrap a non-NULL buffer"); + mHandle.DataStart(aStartPtr); + mHandle.DataEnd(aEndPtr); + } + +void +nsDependentSingleFragmentSubstring::Rebind( const abstract_single_fragment_type& aString, const PRUint32 aStartPos, const PRUint32 aLength ) + { + const_char_iterator iter; + mHandle.DataStart(aString.BeginReading(iter) + NS_MIN(aStartPos, aString.Length())); + mHandle.DataEnd( NS_MIN(mHandle.DataStart() + aLength, aString.EndReading(iter)) ); + } + +void +nsDependentSingleFragmentCSubstring::Rebind( const char_type* aStartPtr, const char_type* aEndPtr ) + { + NS_ASSERTION(aStartPtr && aEndPtr, "nsDependentSingleFragmentCString must wrap a non-NULL buffer"); + mHandle.DataStart(aStartPtr); + mHandle.DataEnd(aEndPtr); + } + +void +nsDependentSingleFragmentCSubstring::Rebind( const abstract_single_fragment_type& aString, const PRUint32 aStartPos, const PRUint32 aLength ) + { + const_char_iterator iter; + mHandle.DataStart(aString.BeginReading(iter) + NS_MIN(aStartPos, aString.Length())); + mHandle.DataEnd( NS_MIN(mHandle.DataStart() + aLength, aString.EndReading(iter)) ); + } diff --git a/xpcom/string/embed/nsEmbedString.cpp b/xpcom/string/embed/nsEmbedString.cpp index aed9635305f..a13cfde5373 100644 --- a/xpcom/string/embed/nsEmbedString.cpp +++ b/xpcom/string/embed/nsEmbedString.cpp @@ -452,3 +452,49 @@ nsEmbedCString::GrowCapacity(size_type aNewCapacity) return result; } + + +// Copies of Distance() function (and things that it depends on) from +// ../src/nsReadableUtils.cpp. This is needed to make the non-inline +// constructors of nsDependentSubstring work in embed builds. +// See bug 196506 + +template class CalculateLength + { + public: + typedef CharT value_type; + + CalculateLength() : mDistance(0) { } + size_t GetDistance() const { return mDistance; } + + PRUint32 write( const CharT*, PRUint32 N ) + { mDistance += N; return N; } + private: + size_t mDistance; + }; + +template +inline +size_t +Distance_Impl( const nsReadingIterator& aStart, + const nsReadingIterator& aEnd ) + { + CalculateLength sink; + nsReadingIterator fromBegin(aStart); + copy_string(fromBegin, aEnd, sink); + return sink.GetDistance(); + } + +NS_COM +size_t +Distance( const nsAString::const_iterator& aStart, const nsAString::const_iterator& aEnd ) + { + return Distance_Impl(aStart, aEnd); + } + +NS_COM +size_t +Distance( const nsACString::const_iterator& aStart, const nsACString::const_iterator& aEnd ) + { + return Distance_Impl(aStart, aEnd); + } diff --git a/xpcom/string/public/nsDependentSubstring.h b/xpcom/string/public/nsDependentSubstring.h index 98463e68ab9..0571d25ee44 100644 --- a/xpcom/string/public/nsDependentSubstring.h +++ b/xpcom/string/public/nsDependentSubstring.h @@ -61,22 +61,8 @@ class NS_COM nsDependentSubstring virtual char_type* GetWritableFragment( fragment_type&, nsFragmentRequest, PRUint32 ) { return 0; } public: - nsDependentSubstring( const abstract_string_type& aString, PRUint32 aStartPos, PRUint32 aLength ) - : mString(aString), - mStartPos( NS_MIN(aStartPos, aString.Length()) ), - mLength( NS_MIN(aLength, aString.Length()-mStartPos) ) - { - // nothing else to do here - } - - nsDependentSubstring( const const_iterator& aStart, const const_iterator& aEnd ) - : mString(aStart.string()) - { - const_iterator zeroPoint; - mString.BeginReading(zeroPoint); - mStartPos = Distance(zeroPoint, aStart); - mLength = Distance(aStart, aEnd); - } + nsDependentSubstring( const abstract_string_type& aString, PRUint32 aStartPos, PRUint32 aLength ); + nsDependentSubstring( const const_iterator& aStart, const const_iterator& aEnd ); // nsDependentSubstring( const self_type& ); // auto-generated copy-constructor should be OK // ~nsDependentSubstring(); // auto-generated destructor OK @@ -113,22 +99,8 @@ class NS_COM nsDependentCSubstring virtual char_type* GetWritableFragment( fragment_type&, nsFragmentRequest, PRUint32 ) { return 0; } public: - nsDependentCSubstring( const abstract_string_type& aString, PRUint32 aStartPos, PRUint32 aLength ) - : mString(aString), - mStartPos( NS_MIN(aStartPos, aString.Length()) ), - mLength( NS_MIN(aLength, aString.Length()-mStartPos) ) - { - // nothing else to do here - } - - nsDependentCSubstring( const const_iterator& aStart, const const_iterator& aEnd ) - : mString(aStart.string()) - { - const_iterator zeroPoint; - mString.BeginReading(zeroPoint); - mStartPos = Distance(zeroPoint, aStart); - mLength = Distance(aStart, aEnd); - } + nsDependentCSubstring( const abstract_string_type& aString, PRUint32 aStartPos, PRUint32 aLength ); + nsDependentCSubstring( const const_iterator& aStart, const const_iterator& aEnd ); // nsDependentCSubstring( const self_type& ); // auto-generated copy-constructor should be OK // ~nsDependentCSubstring(); // auto-generated destructor OK @@ -155,20 +127,10 @@ class NS_COM nsDependentSingleFragmentSubstring typedef nsASingleFragmentString abstract_single_fragment_type; void - Rebind( const char_type* aStartPtr, const char_type* aEndPtr ) - { - NS_ASSERTION(aStartPtr && aEndPtr, "nsDependentSingleFragmentString must wrap a non-NULL buffer"); - mHandle.DataStart(aStartPtr); - mHandle.DataEnd(aEndPtr); - } + Rebind( const char_type* aStartPtr, const char_type* aEndPtr ); void - Rebind( const abstract_single_fragment_type& aString, const PRUint32 aStartPos, const PRUint32 aLength ) - { - const_char_iterator iter; - mHandle.DataStart(aString.BeginReading(iter) + NS_MIN(aStartPos, aString.Length())); - mHandle.DataEnd( NS_MIN(mHandle.DataStart() + aLength, aString.EndReading(iter)) ); - } + Rebind( const abstract_single_fragment_type& aString, const PRUint32 aStartPos, const PRUint32 aLength ); nsDependentSingleFragmentSubstring( const char_type* aStartPtr, const char_type* aEndPtr ) { Rebind(aStartPtr, aEndPtr); } nsDependentSingleFragmentSubstring( const abstract_single_fragment_type& aString, const PRUint32 aStartPos, const PRUint32 aLength ) { Rebind(aString, aStartPos, aLength); } @@ -196,20 +158,10 @@ class NS_COM nsDependentSingleFragmentCSubstring typedef nsASingleFragmentCString abstract_single_fragment_type; void - Rebind( const char_type* aStartPtr, const char_type* aEndPtr ) - { - NS_ASSERTION(aStartPtr && aEndPtr, "nsDependentSingleFragmentCString must wrap a non-NULL buffer"); - mHandle.DataStart(aStartPtr); - mHandle.DataEnd(aEndPtr); - } + Rebind( const char_type* aStartPtr, const char_type* aEndPtr ); void - Rebind( const abstract_single_fragment_type& aString, const PRUint32 aStartPos, const PRUint32 aLength ) - { - const_char_iterator iter; - mHandle.DataStart(aString.BeginReading(iter) + NS_MIN(aStartPos, aString.Length())); - mHandle.DataEnd( NS_MIN(mHandle.DataStart() + aLength, aString.EndReading(iter)) ); - } + Rebind( const abstract_single_fragment_type& aString, const PRUint32 aStartPos, const PRUint32 aLength ); nsDependentSingleFragmentCSubstring( const char_type* aStartPtr, const char_type* aEndPtr ) { Rebind(aStartPtr, aEndPtr); } nsDependentSingleFragmentCSubstring( const abstract_single_fragment_type& aString, const PRUint32 aStartPos, const PRUint32 aLength ) { Rebind(aString, aStartPos, aLength); } diff --git a/xpcom/string/src/nsDependentSubstring.cpp b/xpcom/string/src/nsDependentSubstring.cpp index a857da7f8cf..43935ef8eaf 100644 --- a/xpcom/string/src/nsDependentSubstring.cpp +++ b/xpcom/string/src/nsDependentSubstring.cpp @@ -23,6 +23,23 @@ #include "nsDependentSubstring.h" +nsDependentSubstring::nsDependentSubstring( const abstract_string_type& aString, PRUint32 aStartPos, PRUint32 aLength ) + : mString(aString), + mStartPos( NS_MIN(aStartPos, aString.Length()) ), + mLength( NS_MIN(aLength, aString.Length()-mStartPos) ) + { + // nothing else to do here + } + +nsDependentSubstring::nsDependentSubstring( const const_iterator& aStart, const const_iterator& aEnd ) + : mString(aStart.string()) + { + const_iterator zeroPoint; + mString.BeginReading(zeroPoint); + mStartPos = Distance(zeroPoint, aStart); + mLength = Distance(aStart, aEnd); + } + PRUint32 nsDependentSubstring::Length() const { @@ -71,8 +88,22 @@ nsDependentSubstring::GetReadableFragment( const_fragment_type& aFragment, nsFra return position_ptr; } +nsDependentCSubstring::nsDependentCSubstring( const abstract_string_type& aString, PRUint32 aStartPos, PRUint32 aLength ) + : mString(aString), + mStartPos( NS_MIN(aStartPos, aString.Length()) ), + mLength( NS_MIN(aLength, aString.Length()-mStartPos) ) + { + // nothing else to do here + } - +nsDependentCSubstring::nsDependentCSubstring( const const_iterator& aStart, const const_iterator& aEnd ) + : mString(aStart.string()) + { + const_iterator zeroPoint; + mString.BeginReading(zeroPoint); + mStartPos = Distance(zeroPoint, aStart); + mLength = Distance(aStart, aEnd); + } PRUint32 nsDependentCSubstring::Length() const @@ -121,3 +152,35 @@ nsDependentCSubstring::GetReadableFragment( const_fragment_type& aFragment, nsFr return position_ptr; } + +void +nsDependentSingleFragmentSubstring::Rebind( const char_type* aStartPtr, const char_type* aEndPtr ) + { + NS_ASSERTION(aStartPtr && aEndPtr, "nsDependentSingleFragmentString must wrap a non-NULL buffer"); + mHandle.DataStart(aStartPtr); + mHandle.DataEnd(aEndPtr); + } + +void +nsDependentSingleFragmentSubstring::Rebind( const abstract_single_fragment_type& aString, const PRUint32 aStartPos, const PRUint32 aLength ) + { + const_char_iterator iter; + mHandle.DataStart(aString.BeginReading(iter) + NS_MIN(aStartPos, aString.Length())); + mHandle.DataEnd( NS_MIN(mHandle.DataStart() + aLength, aString.EndReading(iter)) ); + } + +void +nsDependentSingleFragmentCSubstring::Rebind( const char_type* aStartPtr, const char_type* aEndPtr ) + { + NS_ASSERTION(aStartPtr && aEndPtr, "nsDependentSingleFragmentCString must wrap a non-NULL buffer"); + mHandle.DataStart(aStartPtr); + mHandle.DataEnd(aEndPtr); + } + +void +nsDependentSingleFragmentCSubstring::Rebind( const abstract_single_fragment_type& aString, const PRUint32 aStartPos, const PRUint32 aLength ) + { + const_char_iterator iter; + mHandle.DataStart(aString.BeginReading(iter) + NS_MIN(aStartPos, aString.Length())); + mHandle.DataEnd( NS_MIN(mHandle.DataStart() + aLength, aString.EndReading(iter)) ); + }