diff --git a/dom/base/nsAttrValue.cpp b/dom/base/nsAttrValue.cpp index 01efef2eb9d1..e4bf977f5694 100644 --- a/dom/base/nsAttrValue.cpp +++ b/dom/base/nsAttrValue.cpp @@ -141,7 +141,7 @@ bool MiscContainer::GetString(nsAString& aString) const { } if (isString) { auto* buffer = static_cast(ptr); - buffer->ToString(buffer->StorageSize() / sizeof(char16_t) - 1, aString); + aString.Assign(buffer, buffer->StorageSize() / sizeof(char16_t) - 1); } else { static_cast(ptr)->ToString(aString); } @@ -280,11 +280,9 @@ void nsAttrValue::Shutdown() { void nsAttrValue::Reset() { switch (BaseType()) { case eStringBase: { - nsStringBuffer* str = static_cast(GetPtr()); - if (str) { + if (auto* str = static_cast(GetPtr())) { str->Release(); } - break; } case eOtherBase: { @@ -320,8 +318,7 @@ void nsAttrValue::SetTo(const nsAttrValue& aOther) { switch (aOther.BaseType()) { case eStringBase: { ResetIfSet(); - nsStringBuffer* str = static_cast(aOther.GetPtr()); - if (str) { + if (auto* str = static_cast(aOther.GetPtr())) { str->AddRef(); SetPtrValueAndType(str, eStringBase); } @@ -623,18 +620,16 @@ void nsAttrValue::ToString(nsAString& aResult) const { switch (Type()) { case eString: { - nsStringBuffer* str = static_cast(GetPtr()); - if (str) { - str->ToString(str->StorageSize() / sizeof(char16_t) - 1, aResult); + if (auto* str = static_cast(GetPtr())) { + aResult.Assign(str, str->StorageSize() / sizeof(char16_t) - 1); } else { aResult.Truncate(); } break; } case eAtom: { - nsAtom* atom = static_cast(GetPtr()); + auto* atom = static_cast(GetPtr()); atom->ToString(aResult); - break; } case eInteger: { @@ -895,8 +890,7 @@ nsAtom* nsAttrValue::AtomAt(int32_t aIndex) const { uint32_t nsAttrValue::HashValue() const { switch (BaseType()) { case eStringBase: { - nsStringBuffer* str = static_cast(GetPtr()); - if (str) { + if (auto* str = static_cast(GetPtr())) { uint32_t len = str->StorageSize() / sizeof(char16_t) - 1; return HashString(static_cast(str->Data()), len); } @@ -1208,8 +1202,7 @@ bool nsAttrValue::SubstringCheck(const nsAString& aValue, nsCaseTreatment aCaseSensitive) const { switch (BaseType()) { case eStringBase: { - auto str = static_cast(GetPtr()); - if (str) { + if (auto* str = static_cast(GetPtr())) { return F::Check(static_cast(str->Data()), str->StorageSize() / sizeof(char16_t) - 1, aValue, aCaseSensitive); @@ -1217,7 +1210,7 @@ bool nsAttrValue::SubstringCheck(const nsAString& aValue, return aValue.IsEmpty(); } case eAtomBase: { - auto atom = static_cast(GetPtr()); + auto* atom = static_cast(GetPtr()); return F::Check(atom->GetUTF16String(), atom->GetLength(), aValue, aCaseSensitive); } @@ -2107,12 +2100,11 @@ already_AddRefed nsAttrValue::GetStringBuffer( if (!len) { return nullptr; } - - RefPtr buf = nsStringBuffer::FromString(aValue); - if (buf && (buf->StorageSize() / sizeof(char16_t) - 1) == len) { + if (nsStringBuffer* buf = aValue.GetStringBuffer(); + buf && (buf->StorageSize() / sizeof(char16_t) - 1) == len) { // We can only reuse the buffer if it's exactly sized, since we rely on // StorageSize() to get the string length in ToString(). - return buf.forget(); + return do_AddRef(buf); } return nsStringBuffer::Create(aValue.Data(), aValue.Length()); } diff --git a/dom/base/nsAttrValue.h b/dom/base/nsAttrValue.h index 4ef63c287f6a..b32dfc98fb64 100644 --- a/dom/base/nsAttrValue.h +++ b/dom/base/nsAttrValue.h @@ -108,7 +108,9 @@ const uintptr_t NS_ATTRVALUE_BASETYPE_MASK = 3; class nsCheapString : public nsString { public: explicit nsCheapString(nsStringBuffer* aBuf) { - if (aBuf) aBuf->ToString(aBuf->StorageSize() / sizeof(char16_t) - 1, *this); + if (aBuf) { + Assign(aBuf, aBuf->StorageSize() / sizeof(char16_t) - 1); + } } }; diff --git a/dom/base/nsContentUtils.cpp b/dom/base/nsContentUtils.cpp index 1e03c6b79485..e4f4fadf9cef 100644 --- a/dom/base/nsContentUtils.cpp +++ b/dom/base/nsContentUtils.cpp @@ -7010,25 +7010,6 @@ bool nsContentUtils::PlatformToDOMLineBreaks(nsString& aString, return true; } -void nsContentUtils::PopulateStringFromStringBuffer(nsStringBuffer* aBuf, - nsAString& aResultString) { - MOZ_ASSERT(aBuf, "Expecting a non-null string buffer"); - - uint32_t stringLen = NS_strlen(static_cast(aBuf->Data())); - - // SANITY CHECK: In case the nsStringBuffer isn't correctly - // null-terminated, let's clamp its length using the allocated size, to be - // sure the resulting string doesn't sample past the end of the the buffer. - // (Note that StorageSize() is in units of bytes, so we have to convert that - // to units of PRUnichars, and subtract 1 for the null-terminator.) - uint32_t allocStringLen = (aBuf->StorageSize() / sizeof(char16_t)) - 1; - MOZ_ASSERT(stringLen <= allocStringLen, - "string buffer lacks null terminator!"); - stringLen = std::min(stringLen, allocStringLen); - - aBuf->ToString(stringLen, aResultString); -} - already_AddRefed nsContentUtils::GetElementsByClassName( nsINode* aRootNode, const nsAString& aClasses) { MOZ_ASSERT(aRootNode, "Must have root node"); diff --git a/dom/base/nsContentUtils.h b/dom/base/nsContentUtils.h index e7c3a36da104..a1f466fa8d88 100644 --- a/dom/base/nsContentUtils.h +++ b/dom/base/nsContentUtils.h @@ -115,7 +115,6 @@ class nsNodeInfoManager; class nsParser; class nsPIWindowRoot; class nsPresContext; -class nsStringBuffer; class nsTextFragment; class nsView; class nsWrapperCache; @@ -2446,14 +2445,6 @@ class nsContentUtils { [[nodiscard]] static bool PlatformToDOMLineBreaks(nsString& aString, const mozilla::fallible_t&); - /** - * Populates aResultString with the contents of the string-buffer aBuf, up - * to aBuf's null-terminator. aBuf must not be null. Ownership of the string - * is not transferred. - */ - static void PopulateStringFromStringBuffer(nsStringBuffer* aBuf, - nsAString& aResultString); - static bool IsHandlingKeyBoardEvent() { return sIsHandlingKeyBoardEvent; } static void SetIsHandlingKeyBoardEvent(bool aHandling) { diff --git a/dom/base/nsTextFragment.h b/dom/base/nsTextFragment.h index 53308156837b..91efa49254e9 100644 --- a/dom/base/nsTextFragment.h +++ b/dom/base/nsTextFragment.h @@ -113,8 +113,7 @@ class nsTextFragment final { } ReleaseText(); if (aForce2b && !aUpdateBidi) { - nsStringBuffer* buffer = nsStringBuffer::FromString(aString); - if (buffer) { + if (nsStringBuffer* buffer = aString.GetStringBuffer()) { NS_ADDREF(m2b = buffer); mState.mInHeap = true; mState.mIs2b = true; @@ -154,19 +153,13 @@ class nsTextFragment final { const mozilla::fallible_t& aFallible) const { if (mState.mIs2b) { if (aString.IsEmpty()) { - m2b->ToString(mState.mLength, aString); + aString.Assign(m2b, mState.mLength); return true; } - bool ok = aString.Append(Get2b(), mState.mLength, aFallible); - if (!ok) { - return false; - } - - return true; - } else { - return AppendASCIItoUTF16(Substring(m1b, mState.mLength), aString, - aFallible); + return aString.Append(Get2b(), mState.mLength, aFallible); } + return AppendASCIItoUTF16(Substring(m1b, mState.mLength), aString, + aFallible); } /** diff --git a/dom/bindings/DOMString.h b/dom/bindings/DOMString.h index c5404f53511a..e87d82077723 100644 --- a/dom/bindings/DOMString.h +++ b/dom/bindings/DOMString.h @@ -169,8 +169,7 @@ class MOZ_STACK_CLASS DOMString { if (MOZ_UNLIKELY(aString.IsVoid())) { SetNull(); } else if (!aString.IsEmpty()) { - nsStringBuffer* buf = nsStringBuffer::FromString(aString); - if (buf) { + if (nsStringBuffer* buf = aString.GetStringBuffer()) { SetKnownLiveStringBuffer(buf, aString.Length()); } else if (aString.IsLiteral()) { SetLiteralInternal(aString.BeginReading(), aString.Length()); @@ -236,7 +235,7 @@ class MOZ_STACK_CLASS DOMString { auto chars = static_cast(buf->Data()); if (chars[len] == '\0') { // Safe to share the buffer. - buf->ToString(len, aString); + aString.Assign(buf, len); } else { // We need to copy, unfortunately. aString.Assign(chars, len); diff --git a/dom/bindings/FakeString.h b/dom/bindings/FakeString.h index f51f7890d9cd..e7221db86872 100644 --- a/dom/bindings/FakeString.h +++ b/dom/bindings/FakeString.h @@ -51,7 +51,7 @@ struct FakeString { // depend upon aString's data. aString should outlive this instance of // FakeString. void ShareOrDependUpon(const AString& aString) { - RefPtr sharedBuffer = nsStringBuffer::FromString(aString); + RefPtr sharedBuffer = aString.GetStringBuffer(); if (!sharedBuffer) { InitData(aString.BeginReading(), aString.Length()); if (!aString.IsTerminated()) { diff --git a/dom/bindings/test/TestFunctions.cpp b/dom/bindings/test/TestFunctions.cpp index a91121eaa76e..59d455402082 100644 --- a/dom/bindings/test/TestFunctions.cpp +++ b/dom/bindings/test/TestFunctions.cpp @@ -66,8 +66,7 @@ void TestFunctions::GetStringDataAsDOMString(const Optional& aLength, length = mStringData.Length(); } - nsStringBuffer* buf = nsStringBuffer::FromString(mStringData); - if (buf) { + if (nsStringBuffer* buf = mStringData.GetStringBuffer()) { aString.SetKnownLiveStringBuffer(buf, length); return; } @@ -134,7 +133,7 @@ StringType TestFunctions::GetStringType(const nsAString& aString) { return StringType::Literal; } - if (nsStringBuffer::FromString(aString)) { + if (aString.GetStringBuffer()) { return StringType::Stringbuffer; } @@ -146,9 +145,8 @@ StringType TestFunctions::GetStringType(const nsAString& aString) { } bool TestFunctions::StringbufferMatchesStored(const nsAString& aString) { - return nsStringBuffer::FromString(aString) && - nsStringBuffer::FromString(aString) == - nsStringBuffer::FromString(mStringData); + return aString.GetStringBuffer() && + aString.GetStringBuffer() == mStringData.GetStringBuffer(); } void TestFunctions::TestThrowNsresult(ErrorResult& aError) { diff --git a/dom/events/DataTransfer.cpp b/dom/events/DataTransfer.cpp index 70409799f0ca..b2f70dab5493 100644 --- a/dom/events/DataTransfer.cpp +++ b/dom/events/DataTransfer.cpp @@ -1083,7 +1083,7 @@ already_AddRefed DataTransfer::GetTransferable( static_cast(stringBuffer->Data())[amountRead] = 0; nsCString str; - stringBuffer->ToString(totalCustomLength, str); + str.Assign(stringBuffer, totalCustomLength); nsCOMPtr strSupports( do_CreateInstance(NS_SUPPORTS_CSTRING_CONTRACTID)); strSupports->SetData(str); diff --git a/dom/media/MediaResult.h b/dom/media/MediaResult.h index 58e3bf76719d..9b4031e95cd8 100644 --- a/dom/media/MediaResult.h +++ b/dom/media/MediaResult.h @@ -9,7 +9,7 @@ #include "nsString.h" // Required before 'mozilla/ErrorNames.h'!? #include "mozilla/ErrorNames.h" -#include "mozilla/TimeStamp.h" +#include "mozilla/IntegerPrintfMacros.h" #include "nsError.h" #include "nsPrintfCString.h" diff --git a/dom/media/doctor/DDLifetime.cpp b/dom/media/doctor/DDLifetime.cpp index 2d4c6cb96625..c1d2a01a1c32 100644 --- a/dom/media/doctor/DDLifetime.cpp +++ b/dom/media/doctor/DDLifetime.cpp @@ -5,6 +5,7 @@ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ #include "DDLifetime.h" +#include "mozilla/IntegerPrintfMacros.h" namespace mozilla { diff --git a/dom/media/gmp/CDMStorageIdProvider.cpp b/dom/media/gmp/CDMStorageIdProvider.cpp index 52255879b384..9af4580d9e3e 100644 --- a/dom/media/gmp/CDMStorageIdProvider.cpp +++ b/dom/media/gmp/CDMStorageIdProvider.cpp @@ -6,7 +6,7 @@ #include "CDMStorageIdProvider.h" #include "GMPLog.h" #include "nsCOMPtr.h" -#include "nsComponentManagerUtils.h" +#include "mozilla/IntegerPrintfMacros.h" #include "nsICryptoHash.h" #ifdef SUPPORT_STORAGE_ID diff --git a/dom/serializers/nsDocumentEncoder.cpp b/dom/serializers/nsDocumentEncoder.cpp index 46ea15feccca..c50a94ea8e4a 100644 --- a/dom/serializers/nsDocumentEncoder.cpp +++ b/dom/serializers/nsDocumentEncoder.cpp @@ -341,7 +341,7 @@ class nsDocumentEncoder : public nsIDocumentEncoder { // argument of nsIContentSerializer::Init(). bool mNeedsPreformatScanning; bool mIsCopying; // Set to true only while copying - nsStringBuffer* mCachedBuffer; + RefPtr mCachedBuffer; class NodeSerializer { public: @@ -701,11 +701,7 @@ nsresult nsDocumentEncoder::SerializeWholeDocument(uint32_t aMaxLength) { return rv; } -nsDocumentEncoder::~nsDocumentEncoder() { - if (mCachedBuffer) { - mCachedBuffer->Release(); - } -} +nsDocumentEncoder::~nsDocumentEncoder() = default; NS_IMETHODIMP nsDocumentEncoder::Init(Document* aDocument, const nsAString& aMimeType, @@ -1372,7 +1368,7 @@ nsDocumentEncoder::EncodeToStringWithMaxLength(uint32_t aMaxLength, nsString output; static const size_t kStringBufferSizeInBytes = 2048; if (!mCachedBuffer) { - mCachedBuffer = nsStringBuffer::Alloc(kStringBufferSizeInBytes).take(); + mCachedBuffer = nsStringBuffer::Alloc(kStringBufferSizeInBytes); if (NS_WARN_IF(!mCachedBuffer)) { return NS_ERROR_OUT_OF_MEMORY; } @@ -1381,9 +1377,7 @@ nsDocumentEncoder::EncodeToStringWithMaxLength(uint32_t aMaxLength, !mCachedBuffer->IsReadonly(), "nsIDocumentEncoder shouldn't keep reference to non-readonly buffer!"); static_cast(mCachedBuffer->Data())[0] = char16_t(0); - mCachedBuffer->ToString(0, output, true); - // output owns the buffer now! - mCachedBuffer = nullptr; + output.Assign(mCachedBuffer.forget(), 0); if (!mSerializer) { nsAutoCString progId(NS_CONTENTSERIALIZER_CONTRACTID_PREFIX); @@ -1407,21 +1401,18 @@ nsDocumentEncoder::EncodeToStringWithMaxLength(uint32_t aMaxLength, rv = mSerializer->FlushAndFinish(); - mCachedBuffer = nsStringBuffer::FromString(output); // We have to be careful how we set aOutputString, because we don't // want it to end up sharing mCachedBuffer if we plan to reuse it. bool setOutput = false; + MOZ_ASSERT(!mCachedBuffer); // Try to cache the buffer. - if (mCachedBuffer) { - if ((mCachedBuffer->StorageSize() == kStringBufferSizeInBytes) && - !mCachedBuffer->IsReadonly()) { - mCachedBuffer->AddRef(); - } else { - if (NS_SUCCEEDED(rv)) { - mCachedBuffer->ToString(output.Length(), aOutputString); - setOutput = true; - } - mCachedBuffer = nullptr; + if (nsStringBuffer* outputBuffer = output.GetStringBuffer()) { + if (outputBuffer->StorageSize() == kStringBufferSizeInBytes && + !outputBuffer->IsReadonly()) { + mCachedBuffer = outputBuffer; + } else if (NS_SUCCEEDED(rv)) { + aOutputString.Assign(outputBuffer, output.Length()); + setOutput = true; } } diff --git a/dom/webgpu/Adapter.h b/dom/webgpu/Adapter.h index 4156588e8e3b..1daede6119e7 100644 --- a/dom/webgpu/Adapter.h +++ b/dom/webgpu/Adapter.h @@ -11,6 +11,7 @@ #include "mozilla/AlreadyAddRefed.h" #include "mozilla/dom/NonRefcountedDOMObject.h" #include "mozilla/webgpu/WebGPUTypes.h" +#include "mozilla/IntegerPrintfMacros.h" #include "nsPrintfCString.h" #include "nsString.h" #include "ObjectModel.h" diff --git a/dom/xhr/XMLHttpRequestString.cpp b/dom/xhr/XMLHttpRequestString.cpp index 8f9092243ad2..e0e68f3d2df5 100644 --- a/dom/xhr/XMLHttpRequestString.cpp +++ b/dom/xhr/XMLHttpRequestString.cpp @@ -58,8 +58,7 @@ class XMLHttpRequestStringBuffer final { // XXX: Bug 1408793 suggests encapsulating the following sequence within // DOMString. - nsStringBuffer* buf = nsStringBuffer::FromString(mData); - if (buf) { + if (nsStringBuffer* buf = mData.GetStringBuffer()) { // We have to use SetStringBuffer, because once we release our mutex mData // can get mutated from some other thread while the DOMString is still // alive. diff --git a/gfx/layers/ScrollableLayerGuid.cpp b/gfx/layers/ScrollableLayerGuid.cpp index 914a8ad124d4..42a8a4824f3b 100644 --- a/gfx/layers/ScrollableLayerGuid.cpp +++ b/gfx/layers/ScrollableLayerGuid.cpp @@ -8,7 +8,8 @@ #include #include "mozilla/HashFunctions.h" // for HashGeneric -#include "nsPrintfCString.h" // for nsPrintfCString +#include "mozilla/IntegerPrintfMacros.h" +#include "nsPrintfCString.h" // for nsPrintfCString namespace mozilla { namespace layers { diff --git a/gfx/layers/apz/src/FocusState.cpp b/gfx/layers/apz/src/FocusState.cpp index 0230676e7ef4..84bf0b4570cf 100644 --- a/gfx/layers/apz/src/FocusState.cpp +++ b/gfx/layers/apz/src/FocusState.cpp @@ -7,6 +7,7 @@ #include "FocusState.h" #include "mozilla/Logging.h" +#include "mozilla/IntegerPrintfMacros.h" #include "mozilla/layers/APZThreadUtils.h" static mozilla::LazyLogModule sApzFstLog("apz.focusstate"); diff --git a/js/xpconnect/src/XPCString.cpp b/js/xpconnect/src/XPCString.cpp index 5d784a02fd0f..651f3dde9fce 100644 --- a/js/xpconnect/src/XPCString.cpp +++ b/js/xpconnect/src/XPCString.cpp @@ -104,8 +104,7 @@ bool XPCStringConvert::ReadableToJSVal(JSContext* cx, const nsAString& readable, return StringLiteralToJSVal(cx, readable.BeginReading(), length, vp); } - nsStringBuffer* buf = nsStringBuffer::FromString(readable); - if (buf) { + if (nsStringBuffer* buf = readable.GetStringBuffer()) { bool shared; if (!UCStringBufferToJSVal(cx, buf, length, vp, &shared)) { return false; @@ -138,8 +137,7 @@ bool XPCStringConvert::Latin1ToJSVal(JSContext* cx, const nsACString& latin1, length, vp); } - nsStringBuffer* buf = nsStringBuffer::FromString(latin1); - if (buf) { + if (nsStringBuffer* buf = latin1.GetStringBuffer()) { bool shared; if (!Latin1StringBufferToJSVal(cx, buf, length, vp, &shared)) { return false; @@ -170,8 +168,7 @@ bool XPCStringConvert::UTF8ToJSVal(JSContext* cx, const nsACString& utf8, cx, JS::UTF8Chars(utf8.BeginReading(), length), vp); } - nsStringBuffer* buf = nsStringBuffer::FromString(utf8); - if (buf) { + if (nsStringBuffer* buf = utf8.GetStringBuffer()) { bool shared; if (!UTF8StringBufferToJSVal(cx, buf, length, vp, &shared)) { return false; diff --git a/js/xpconnect/src/xpcpublic.h b/js/xpconnect/src/xpcpublic.h index 08da56e2fc9a..28e93a65b429 100644 --- a/js/xpconnect/src/xpcpublic.h +++ b/js/xpconnect/src/xpcpublic.h @@ -238,11 +238,11 @@ extern JS::UniqueChars xpc_PrintJSStack(JSContext* cx, bool showArgs, inline void AssignFromStringBuffer(nsStringBuffer* buffer, size_t len, nsAString& dest) { - buffer->ToString(len, dest); + dest.Assign(buffer, len); } inline void AssignFromStringBuffer(nsStringBuffer* buffer, size_t len, nsACString& dest) { - buffer->ToString(len, dest); + dest.Assign(buffer, len); } // readable string conversions, static methods and members only diff --git a/netwerk/cache2/CacheFileInputStream.cpp b/netwerk/cache2/CacheFileInputStream.cpp index 99302baf546f..564a08fd2ba6 100644 --- a/netwerk/cache2/CacheFileInputStream.cpp +++ b/netwerk/cache2/CacheFileInputStream.cpp @@ -8,6 +8,7 @@ #include "CacheFile.h" #include "nsStreamUtils.h" #include "nsThreadUtils.h" +#include "mozilla/IntegerPrintfMacros.h" #include namespace mozilla::net { diff --git a/netwerk/cache2/CacheFileOutputStream.cpp b/netwerk/cache2/CacheFileOutputStream.cpp index 985082efbaf0..b541132bd98f 100644 --- a/netwerk/cache2/CacheFileOutputStream.cpp +++ b/netwerk/cache2/CacheFileOutputStream.cpp @@ -9,7 +9,7 @@ #include "CacheEntry.h" #include "nsStreamUtils.h" #include "nsThreadUtils.h" -#include "mozilla/DebugOnly.h" +#include "mozilla/IntegerPrintfMacros.h" #include namespace mozilla::net { diff --git a/netwerk/system/android/nsAndroidNetworkLinkService.cpp b/netwerk/system/android/nsAndroidNetworkLinkService.cpp index 850ac5b565db..a3d0328d8b20 100644 --- a/netwerk/system/android/nsAndroidNetworkLinkService.cpp +++ b/netwerk/system/android/nsAndroidNetworkLinkService.cpp @@ -9,6 +9,7 @@ #include "nsIObserverService.h" #include "mozilla/StaticPrefs_network.h" +#include "mozilla/IntegerPrintfMacros.h" #include "mozilla/Services.h" #include "mozilla/Logging.h" diff --git a/netwerk/system/linux/nsNetworkLinkService.cpp b/netwerk/system/linux/nsNetworkLinkService.cpp index 363b058eed71..59894ba1fa54 100644 --- a/netwerk/system/linux/nsNetworkLinkService.cpp +++ b/netwerk/system/linux/nsNetworkLinkService.cpp @@ -8,6 +8,7 @@ #include "nsNetworkLinkService.h" #include "nsString.h" #include "mozilla/Logging.h" +#include "mozilla/IntegerPrintfMacros.h" #include "nsNetAddr.h" #include "mozilla/StaticPrefs_network.h" diff --git a/parser/html/nsHtml5String.cpp b/parser/html/nsHtml5String.cpp index 5fa9415f0682..7e100806692c 100644 --- a/parser/html/nsHtml5String.cpp +++ b/parser/html/nsHtml5String.cpp @@ -5,12 +5,11 @@ #include "nsHtml5String.h" #include "nsCharTraits.h" #include "nsHtml5TreeBuilder.h" -#include "nsUTF8Utils.h" void nsHtml5String::ToString(nsAString& aString) { switch (GetKind()) { case eStringBuffer: - return AsStringBuffer()->ToString(Length(), aString); + return aString.Assign(AsStringBuffer(), Length()); case eAtom: return AsAtom()->ToString(aString); case eEmpty: @@ -157,12 +156,14 @@ nsHtml5String nsHtml5String::FromString(const nsAString& aString) { if (!length) { return nsHtml5String(eEmpty); } - RefPtr buffer = nsStringBuffer::FromString(aString); - if (buffer && (length == buffer->StorageSize() / sizeof(char16_t) - 1)) { - return nsHtml5String(reinterpret_cast(buffer.forget().take()) | - eStringBuffer); + if (nsStringBuffer* buffer = aString.GetStringBuffer()) { + if (length == buffer->StorageSize() / sizeof(char16_t) - 1) { + buffer->AddRef(); + return nsHtml5String(reinterpret_cast(buffer) | eStringBuffer); + } } - buffer = nsStringBuffer::Alloc((length + 1) * sizeof(char16_t)); + RefPtr buffer = + nsStringBuffer::Alloc((length + 1) * sizeof(char16_t)); if (!buffer) { MOZ_CRASH("Out of memory."); } diff --git a/security/manager/ssl/EnterpriseRoots.cpp b/security/manager/ssl/EnterpriseRoots.cpp index 7fd9126ec70f..940037cfc898 100644 --- a/security/manager/ssl/EnterpriseRoots.cpp +++ b/security/manager/ssl/EnterpriseRoots.cpp @@ -7,6 +7,7 @@ #include "EnterpriseRoots.h" #include "mozilla/ArrayUtils.h" +#include "mozilla/IntegerPrintfMacros.h" #include "mozilla/Casting.h" #include "mozilla/Logging.h" #include "mozilla/Unused.h" diff --git a/storage/VacuumManager.cpp b/storage/VacuumManager.cpp index 63eb0f89b4a1..f8513d5eab49 100644 --- a/storage/VacuumManager.cpp +++ b/storage/VacuumManager.cpp @@ -15,17 +15,12 @@ #include "nsIFile.h" #include "nsThreadUtils.h" #include "mozilla/Logging.h" +#include "mozilla/IntegerPrintfMacros.h" #include "prtime.h" -#include "mozilla/StaticPrefs_storage.h" #include "mozStorageConnection.h" #include "mozStoragePrivateHelpers.h" -#include "mozIStorageStatement.h" #include "mozIStorageCompletionCallback.h" -#include "mozIStorageAsyncStatement.h" -#include "mozIStoragePendingStatement.h" -#include "mozIStorageError.h" -#include "mozStorageHelper.h" #include "nsXULAppAPI.h" #include "xpcpublic.h" diff --git a/toolkit/components/antitracking/bouncetrackingprotection/BounceTrackingProtectionStorage.cpp b/toolkit/components/antitracking/bouncetrackingprotection/BounceTrackingProtectionStorage.cpp index 9d8b1364e972..d3a7cb90621d 100644 --- a/toolkit/components/antitracking/bouncetrackingprotection/BounceTrackingProtectionStorage.cpp +++ b/toolkit/components/antitracking/bouncetrackingprotection/BounceTrackingProtectionStorage.cpp @@ -15,9 +15,8 @@ #include "mozStorageCID.h" #include "mozilla/Components.h" #include "mozilla/Monitor.h" -#include "mozilla/AppShutdown.h" +#include "mozilla/IntegerPrintfMacros.h" #include "mozilla/Services.h" -#include "mozilla/ShutdownPhase.h" #include "nsCOMPtr.h" #include "nsDirectoryServiceUtils.h" #include "nsIObserverService.h" diff --git a/toolkit/components/antitracking/bouncetrackingprotection/BounceTrackingStateGlobal.cpp b/toolkit/components/antitracking/bouncetrackingprotection/BounceTrackingStateGlobal.cpp index fc35e96e2fc2..bcd9e57bd8e2 100644 --- a/toolkit/components/antitracking/bouncetrackingprotection/BounceTrackingStateGlobal.cpp +++ b/toolkit/components/antitracking/bouncetrackingprotection/BounceTrackingStateGlobal.cpp @@ -9,6 +9,7 @@ #include "ErrorList.h" #include "mozilla/Assertions.h" #include "mozilla/Logging.h" +#include "mozilla/IntegerPrintfMacros.h" #include "nsIPrincipal.h" namespace mozilla { diff --git a/toolkit/components/glean/bindings/jog/JOG.cpp b/toolkit/components/glean/bindings/jog/JOG.cpp index 56119cef0e72..c5b2bad6b759 100644 --- a/toolkit/components/glean/bindings/jog/JOG.cpp +++ b/toolkit/components/glean/bindings/jog/JOG.cpp @@ -12,6 +12,7 @@ #include "mozilla/ClearOnShutdown.h" #include "mozilla/glean/bindings/jog/jog_ffi_generated.h" #include "mozilla/Logging.h" +#include "mozilla/IntegerPrintfMacros.h" #include "mozilla/StaticPrefs_telemetry.h" #include "mozilla/AppShutdown.h" #include "nsDirectoryServiceDefs.h" @@ -22,8 +23,7 @@ namespace mozilla::glean { -using mozilla::LogLevel; -static mozilla::LazyLogModule sLog("jog"); +static LazyLogModule sLog("jog"); // Storage // Thread Safety: Only used on the main thread. diff --git a/xpcom/base/nsMemoryImpl.cpp b/xpcom/base/nsMemoryImpl.cpp index 4996d27c7a13..1529455da21c 100644 --- a/xpcom/base/nsMemoryImpl.cpp +++ b/xpcom/base/nsMemoryImpl.cpp @@ -15,6 +15,7 @@ #include "nsCOMPtr.h" #include "mozilla/Services.h" #include "mozilla/Atomics.h" +#include "mozilla/IntegerPrintfMacros.h" #ifdef ANDROID # include diff --git a/xpcom/ds/nsAtomTable.cpp b/xpcom/ds/nsAtomTable.cpp index a03fdcce532d..379aa647d4c2 100644 --- a/xpcom/ds/nsAtomTable.cpp +++ b/xpcom/ds/nsAtomTable.cpp @@ -82,7 +82,7 @@ nsDynamicAtom* nsDynamicAtom::Create(const nsAString& aString, uint32_t aHash) { // We tack the chars onto the end of the nsDynamicAtom object. const bool isAsciiLower = ::IsAsciiLowercase(aString.Data(), aString.Length()); - RefPtr buffer = nsStringBuffer::FromString(aString); + RefPtr buffer = aString.GetStringBuffer(); if (!buffer) { buffer = nsStringBuffer::Create(aString.Data(), aString.Length()); if (MOZ_UNLIKELY(!buffer)) { @@ -111,7 +111,7 @@ void nsAtom::ToString(nsAString& aString) const { // which is what's important. aString.AssignLiteral(AsStatic()->String(), mLength); } else { - AsDynamic()->StringBuffer()->ToString(mLength, aString); + aString.Assign(AsDynamic()->StringBuffer(), mLength); } } @@ -577,7 +577,7 @@ already_AddRefed nsAtomTable::Atomize(const nsACString& aUTF8String) { nsString str; CopyUTF8toUTF16(aUTF8String, str); - MOZ_ASSERT(nsStringBuffer::FromString(str), "Should create a string buffer"); + MOZ_ASSERT(str.GetStringBuffer(), "Should create a string buffer"); RefPtr atom = dont_AddRef(nsDynamicAtom::Create(str, key.mHash)); he->mAtom = atom; diff --git a/xpcom/io/nsInputStreamTee.cpp b/xpcom/io/nsInputStreamTee.cpp index 3c0d32e0cbaf..656f1dcb3840 100644 --- a/xpcom/io/nsInputStreamTee.cpp +++ b/xpcom/io/nsInputStreamTee.cpp @@ -10,6 +10,7 @@ #include "mozilla/Maybe.h" #include "mozilla/Mutex.h" #include "mozilla/Attributes.h" +#include "mozilla/IntegerPrintfMacros.h" #include "nsIInputStreamTee.h" #include "nsIInputStream.h" #include "nsIOutputStream.h" diff --git a/xpcom/string/nsStringBuffer.cpp b/xpcom/string/nsStringBuffer.cpp index 196630dd53a9..fbfc91f633a6 100644 --- a/xpcom/string/nsStringBuffer.cpp +++ b/xpcom/string/nsStringBuffer.cpp @@ -7,64 +7,7 @@ #include "nsStringBuffer.h" #include "mozilla/MemoryReporting.h" -#include "nsISupportsImpl.h" -#include "nsString.h" - -void nsStringBuffer::AddRef() { - // Memory synchronization is not required when incrementing a - // reference count. The first increment of a reference count on a - // thread is not important, since the first use of the object on a - // thread can happen before it. What is important is the transfer - // of the pointer to that thread, which may happen prior to the - // first increment on that thread. The necessary memory - // synchronization is done by the mechanism that transfers the - // pointer between threads. -#ifdef NS_BUILD_REFCNT_LOGGING - uint32_t count = -#endif - mRefCount.fetch_add(1, std::memory_order_relaxed) -#ifdef NS_BUILD_REFCNT_LOGGING - + 1 -#endif - ; - NS_LOG_ADDREF(this, count, "nsStringBuffer", sizeof(*this)); -} - -void nsStringBuffer::Release() { - // Since this may be the last release on this thread, we need - // release semantics so that prior writes on this thread are visible - // to the thread that destroys the object when it reads mValue with - // acquire semantics. - uint32_t count = mRefCount.fetch_sub(1, std::memory_order_release) - 1; - NS_LOG_RELEASE(this, count, "nsStringBuffer"); - if (count == 0) { - // We're going to destroy the object on this thread, so we need - // acquire semantics to synchronize with the memory released by - // the last release on other threads, that is, to ensure that - // writes prior to that release are now visible on this thread. - count = mRefCount.load(std::memory_order_acquire); - - free(this); // we were allocated with |malloc| - } -} - -/** - * Alloc returns a pointer to a new string header with set capacity. - */ -already_AddRefed nsStringBuffer::Alloc(size_t aSize) { - NS_ASSERTION(aSize != 0, "zero capacity allocation not allowed"); - NS_ASSERTION(sizeof(nsStringBuffer) + aSize <= size_t(uint32_t(-1)) && - sizeof(nsStringBuffer) + aSize > aSize, - "mStorageSize will truncate"); - - auto* hdr = (nsStringBuffer*)malloc(sizeof(nsStringBuffer) + aSize); - if (hdr) { - hdr->mRefCount = 1; - hdr->mStorageSize = aSize; - NS_LOG_ADDREF(hdr, 1, "nsStringBuffer", sizeof(*hdr)); - } - return already_AddRefed(hdr); -} +#include "mozilla/RefPtr.h" template static already_AddRefed DoCreate(const CharT* aData, @@ -91,78 +34,31 @@ already_AddRefed nsStringBuffer::Create(const char16_t* aData, } nsStringBuffer* nsStringBuffer::Realloc(nsStringBuffer* aHdr, size_t aSize) { - NS_ASSERTION(aSize != 0, "zero capacity allocation not allowed"); - NS_ASSERTION(sizeof(nsStringBuffer) + aSize <= size_t(uint32_t(-1)) && - sizeof(nsStringBuffer) + aSize > aSize, - "mStorageSize will truncate"); + MOZ_ASSERT(aSize != 0, "zero capacity allocation not allowed"); + MOZ_ASSERT(sizeof(nsStringBuffer) + aSize <= size_t(uint32_t(-1)) && + sizeof(nsStringBuffer) + aSize > aSize, + "mStorageSize will truncate"); // no point in trying to save ourselves if we hit this assertion - NS_ASSERTION(!aHdr->IsReadonly(), "|Realloc| attempted on readonly string"); + MOZ_ASSERT(!aHdr->IsReadonly(), "|Realloc| attempted on readonly string"); // Treat this as a release and addref for refcounting purposes, since we // just asserted that the refcount is 1. If we don't do that, refcount // logging will claim we've leaked all sorts of stuff. - NS_LOG_RELEASE(aHdr, 0, "nsStringBuffer"); + { + mozilla::detail::RefCountLogger::ReleaseLogger logger(aHdr); + logger.logRelease(0); + } aHdr = (nsStringBuffer*)realloc(aHdr, sizeof(nsStringBuffer) + aSize); if (aHdr) { - NS_LOG_ADDREF(aHdr, 1, "nsStringBuffer", sizeof(*aHdr)); + mozilla::detail::RefCountLogger::logAddRef(aHdr, 1); aHdr->mStorageSize = aSize; } return aHdr; } -nsStringBuffer* nsStringBuffer::FromString(const nsAString& aStr) { - if (!(aStr.mDataFlags & nsAString::DataFlags::REFCOUNTED)) { - return nullptr; - } - - return FromData(aStr.mData); -} - -nsStringBuffer* nsStringBuffer::FromString(const nsACString& aStr) { - if (!(aStr.mDataFlags & nsACString::DataFlags::REFCOUNTED)) { - return nullptr; - } - - return FromData(aStr.mData); -} - -void nsStringBuffer::ToString(uint32_t aLen, nsAString& aStr, - bool aMoveOwnership) { - char16_t* data = static_cast(Data()); - - MOZ_DIAGNOSTIC_ASSERT(data[aLen] == char16_t(0), - "data should be null terminated"); - - nsAString::DataFlags flags = - nsAString::DataFlags::REFCOUNTED | nsAString::DataFlags::TERMINATED; - - if (!aMoveOwnership) { - AddRef(); - } - aStr.Finalize(); - aStr.SetData(data, aLen, flags); -} - -void nsStringBuffer::ToString(uint32_t aLen, nsACString& aStr, - bool aMoveOwnership) { - char* data = static_cast(Data()); - - MOZ_DIAGNOSTIC_ASSERT(data[aLen] == char(0), - "data should be null terminated"); - - nsACString::DataFlags flags = - nsACString::DataFlags::REFCOUNTED | nsACString::DataFlags::TERMINATED; - - if (!aMoveOwnership) { - AddRef(); - } - aStr.Finalize(); - aStr.SetData(data, aLen, flags); -} - size_t nsStringBuffer::SizeOfIncludingThisIfUnshared( mozilla::MallocSizeOf aMallocSizeOf) const { return IsReadonly() ? 0 : aMallocSizeOf(this); diff --git a/xpcom/string/nsStringBuffer.h b/xpcom/string/nsStringBuffer.h index 43628d666820..dad41e48f755 100644 --- a/xpcom/string/nsStringBuffer.h +++ b/xpcom/string/nsStringBuffer.h @@ -9,10 +9,9 @@ #include #include "mozilla/MemoryReporting.h" -#include "nsStringFwd.h" - -template -struct already_AddRefed; +#include "mozilla/Assertions.h" +#include "mozilla/AlreadyAddRefed.h" +#include "mozilla/RefCounted.h" /** * This structure precedes the string buffers "we" allocate. It may be the @@ -25,12 +24,12 @@ struct already_AddRefed; */ class nsStringBuffer { private: - friend class CheckStaticAtomSizes; - std::atomic mRefCount; uint32_t mStorageSize; public: + MOZ_DECLARE_REFCOUNTED_TYPENAME(nsStringBuffer) + /** * Allocates a new string buffer, with given size in bytes and a * reference count of one. When the string buffer is no longer needed, @@ -43,12 +42,25 @@ class nsStringBuffer { * (i.e., it is not required that the null terminator appear in the last * storage unit of the string buffer's data). * - * This guarantees that StorageSize() returns aStorageSize if the returned + * This guarantees that StorageSize() returns aSize if the returned * buffer is non-null. Some callers like nsAttrValue rely on it. * * @return new string buffer or null if out of memory. */ - static already_AddRefed Alloc(size_t aStorageSize); + static already_AddRefed Alloc(size_t aSize) { + MOZ_ASSERT(aSize != 0, "zero capacity allocation not allowed"); + MOZ_ASSERT(sizeof(nsStringBuffer) + aSize <= size_t(uint32_t(-1)) && + sizeof(nsStringBuffer) + aSize > aSize, + "mStorageSize will truncate"); + + auto* hdr = (nsStringBuffer*)malloc(sizeof(nsStringBuffer) + aSize); + if (hdr) { + hdr->mRefCount = 1; + hdr->mStorageSize = aSize; + mozilla::detail::RefCountLogger::logAddRef(hdr, 1); + } + return already_AddRefed(hdr); + } /** * Returns a string buffer initialized with the given string on it, or null on @@ -74,16 +86,35 @@ class nsStringBuffer { */ static nsStringBuffer* Realloc(nsStringBuffer* aBuf, size_t aStorageSize); - /** - * Increment the reference count on this string buffer. - */ - void NS_FASTCALL AddRef(); + void AddRef() { + // Memory synchronization is not required when incrementing a + // reference count. The first increment of a reference count on a + // thread is not important, since the first use of the object on a + // thread can happen before it. What is important is the transfer + // of the pointer to that thread, which may happen prior to the + // first increment on that thread. The necessary memory + // synchronization is done by the mechanism that transfers the + // pointer between threads. + uint32_t count = mRefCount.fetch_add(1, std::memory_order_relaxed) + 1; + mozilla::detail::RefCountLogger::logAddRef(this, count); + } - /** - * Decrement the reference count on this string buffer. The string - * buffer will be destroyed when its reference count reaches zero. - */ - void NS_FASTCALL Release(); + void Release() { + // Since this may be the last release on this thread, we need release + // semantics so that prior writes on this thread are visible to the thread + // that destroys the object when it reads mValue with acquire semantics. + mozilla::detail::RefCountLogger::ReleaseLogger logger(this); + uint32_t count = mRefCount.fetch_sub(1, std::memory_order_release) - 1; + logger.logRelease(count); + if (count == 0) { + // We're going to destroy the object on this thread, so we need acquire + // semantics to synchronize with the memory released by the last release + // on other threads, that is, to ensure that writes prior to that release + // are now visible on this thread. + count = mRefCount.load(std::memory_order_acquire); + free(this); // We were allocated with malloc. + } + } /** * This method returns the string buffer corresponding to the given data @@ -148,34 +179,6 @@ class nsStringBuffer { #endif } - /** - * The FromString methods return a string buffer for the given string - * object or null if the string object does not have a string buffer. - * The reference count of the string buffer is NOT incremented by these - * methods. If the caller wishes to hold onto the returned value, then - * the returned string buffer must have its reference count incremented - * via a call to the AddRef method. - */ - static nsStringBuffer* FromString(const nsAString& aStr); - static nsStringBuffer* FromString(const nsACString& aStr); - - /** - * The ToString methods assign this string buffer to a given string - * object. If the string object does not support sharable string - * buffers, then its value will be set to a copy of the given string - * buffer. Otherwise, these methods increment the reference count of the - * given string buffer. It is important to specify the length (in - * storage units) of the string contained in the string buffer since the - * length of the string may be less than its storage size. The string - * must have a null terminator at the offset specified by |len|. - * - * NOTE: storage size is measured in bytes even for wide strings; - * however, string length is always measured in storage units - * (2-byte units for wide strings). - */ - void ToString(uint32_t aLen, nsAString& aStr, bool aMoveOwnership = false); - void ToString(uint32_t aLen, nsACString& aStr, bool aMoveOwnership = false); - /** * This measures the size only if the StringBuffer is unshared. */ diff --git a/xpcom/string/nsTSubstring.cpp b/xpcom/string/nsTSubstring.cpp index fdad8c492c9d..c89b6773d6ec 100644 --- a/xpcom/string/nsTSubstring.cpp +++ b/xpcom/string/nsTSubstring.cpp @@ -403,6 +403,17 @@ void nsTSubstring::Assign(const char_type* aData, size_type aLength) { } } +template +void nsTSubstring::Assign(already_AddRefed aBuffer, + size_type aLength) { + nsStringBuffer* buffer = aBuffer.take(); + auto* data = reinterpret_cast(buffer->Data()); + MOZ_DIAGNOSTIC_ASSERT(data[aLength] == char_type(0), + "data should be null terminated"); + Finalize(); + SetData(data, aLength, DataFlags::REFCOUNTED | DataFlags::TERMINATED); +} + template bool nsTSubstring::Assign(const char_type* aData, const fallible_t& aFallible) { diff --git a/xpcom/string/nsTSubstring.h b/xpcom/string/nsTSubstring.h index 622b931afb42..7459333dc0f5 100644 --- a/xpcom/string/nsTSubstring.h +++ b/xpcom/string/nsTSubstring.h @@ -8,20 +8,17 @@ #ifndef nsTSubstring_h #define nsTSubstring_h -#include #include -#include "mozilla/Casting.h" +#include "mozilla/Attributes.h" #include "mozilla/DebugOnly.h" -#include "mozilla/IntegerPrintfMacros.h" -#include "mozilla/UniquePtr.h" #include "mozilla/Maybe.h" #include "mozilla/MemoryReporting.h" -#include "mozilla/IntegerTypeTraits.h" #include "mozilla/ResultExtensions.h" #include "mozilla/Span.h" #include "mozilla/Try.h" #include "mozilla/Unused.h" +#include "nsStringBuffer.h" #include "nsTStringRepr.h" @@ -422,6 +419,13 @@ class nsTSubstring : public mozilla::detail::nsTStringRepr { [[nodiscard]] bool NS_FASTCALL Assign(const substring_tuple_type&, const fallible_t&); + void Assign(nsStringBuffer* aBuffer, size_type aLength) { + aBuffer->AddRef(); + Assign(already_AddRefed(aBuffer), aLength); + } + void NS_FASTCALL Assign(already_AddRefed aBuffer, + size_type aLength); + #if defined(MOZ_USE_CHAR16_WRAPPER) template > void Assign(char16ptr_t aData) { @@ -1142,11 +1146,22 @@ class nsTSubstring : public mozilla::detail::nsTStringRepr { * clears the pointer without releasing the buffer. */ void ForgetSharedBuffer() { - if (base_string_type::mDataFlags & DataFlags::REFCOUNTED) { + if (this->mDataFlags & DataFlags::REFCOUNTED) { SetToEmptyBuffer(); } } + /** + * If the string uses a reference-counted buffer, this method returns a + * pointer to it without incrementing the buffer's refcount. + */ + nsStringBuffer* GetStringBuffer() const { + if (this->mDataFlags & DataFlags::REFCOUNTED) { + return nsStringBuffer::FromData(this->mData); + } + return nullptr; + } + protected: void AssertValid() { MOZ_DIAGNOSTIC_ASSERT(!(this->mClassFlags & ClassFlags::INVALID_MASK)); diff --git a/xpcom/tests/TestHarness.h b/xpcom/tests/TestHarness.h index e5754977466e..40f90d988eee 100644 --- a/xpcom/tests/TestHarness.h +++ b/xpcom/tests/TestHarness.h @@ -23,6 +23,7 @@ #include "nsAppDirectoryServiceDefs.h" #include "nsDirectoryServiceDefs.h" #include "nsDirectoryServiceUtils.h" +#include "mozilla/IntegerPrintfMacros.h" #include "nsIDirectoryService.h" #include "nsIFile.h" #include "nsIObserverService.h" diff --git a/xpcom/tests/gtest/TestStrings.cpp b/xpcom/tests/gtest/TestStrings.cpp index a2bf57db9013..450befc20d8d 100644 --- a/xpcom/tests/gtest/TestStrings.cpp +++ b/xpcom/tests/gtest/TestStrings.cpp @@ -1183,11 +1183,9 @@ TEST_F(Strings, stringbuffer) { memcpy(data, kData, sizeof(kData)); nsCString str; - buf->ToString(sizeof(kData) - 1, str); - - nsStringBuffer* buf2; - buf2 = nsStringBuffer::FromString(str); + str.Assign(buf, sizeof(kData) - 1); + nsStringBuffer* buf2 = str.GetStringBuffer(); EXPECT_EQ(buf, buf2); }