From d55796be1711fe3344af61f6fb7cb6222e3c0786 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Emilio=20Cobos=20=C3=81lvarez?= Date: Tue, 14 May 2024 14:24:26 +0000 Subject: [PATCH] Bug 1892257 - Move nsStringBuffer to mfbt. r=nika,xpcom-reviewers,glandium Inline Create() and Realloc() so that we don't get negative leaks, since were that code end up in mozglue, it wouldn't have access to the logging machinery. Differential Revision: https://phabricator.services.mozilla.com/D209663 --- caps/nsJSPrincipals.cpp | 1 - dom/base/nsAttrValue.cpp | 49 +++++----- dom/base/nsAttrValue.h | 20 ++-- dom/base/nsAttrValueInlines.h | 14 ++- dom/base/nsContentUtils.cpp | 1 - dom/base/nsContentUtils.h | 1 + dom/base/nsTextFragment.cpp | 18 ++-- dom/base/nsTextFragment.h | 6 +- dom/bindings/DOMString.h | 46 ++++----- dom/bindings/FakeString.h | 28 +++--- dom/bindings/ToJSValue.cpp | 4 +- dom/bindings/test/TestFunctions.cpp | 4 +- dom/docs/webIdlBindings/index.md | 8 +- dom/events/DataTransfer.cpp | 4 +- dom/fetch/FetchUtil.cpp | 2 +- dom/serializers/nsDocumentEncoder.cpp | 8 +- dom/xhr/XMLHttpRequestMainThread.cpp | 1 - dom/xhr/XMLHttpRequestString.cpp | 2 +- .../rootAnalysis/analyzeHeapWrites.js | 6 +- js/xpconnect/src/XPCConvert.cpp | 6 +- js/xpconnect/src/XPCString.cpp | 39 ++++---- js/xpconnect/src/xpcprivate.h | 1 - js/xpconnect/src/xpcpublic.h | 25 ++--- layout/style/StyleAnimationValue.h | 1 - .../nsStringBuffer.h => mfbt/StringBuffer.h | 96 ++++++++++++++----- mfbt/moz.build | 1 + parser/html/nsHtml5String.cpp | 25 ++--- parser/html/nsHtml5String.h | 13 ++- .../manager/ssl/nsCertOverrideService.cpp | 1 - security/manager/ssl/nsClientAuthRemember.cpp | 1 - xpcom/base/CycleCollectedJSContext.cpp | 1 - xpcom/base/CycleCollectedJSRuntime.cpp | 1 - xpcom/base/nsTraceRefcnt.cpp | 15 +-- xpcom/ds/nsAtom.h | 6 +- xpcom/ds/nsAtomTable.cpp | 6 +- xpcom/rust/nsstring/src/conversions.rs | 6 +- xpcom/string/moz.build | 2 - xpcom/string/nsReadableUtils.h | 4 +- xpcom/string/nsStringBuffer.cpp | 70 -------------- xpcom/string/nsTStringRepr.h | 6 +- xpcom/string/nsTSubstring.cpp | 33 +++---- xpcom/string/nsTSubstring.h | 14 ++- xpcom/tests/gtest/TestMoveString.cpp | 1 - xpcom/tests/gtest/TestStrings.cpp | 11 ++- xpcom/tests/gtest/TestUTF.cpp | 1 - 45 files changed, 293 insertions(+), 316 deletions(-) rename xpcom/string/nsStringBuffer.h => mfbt/StringBuffer.h (72%) delete mode 100644 xpcom/string/nsStringBuffer.cpp diff --git a/caps/nsJSPrincipals.cpp b/caps/nsJSPrincipals.cpp index d089bffdf564..7c35eacfcb48 100644 --- a/caps/nsJSPrincipals.cpp +++ b/caps/nsJSPrincipals.cpp @@ -8,7 +8,6 @@ #include "nsString.h" #include "nsJSPrincipals.h" #include "nsCOMPtr.h" -#include "nsStringBuffer.h" #include "mozilla/BasePrincipal.h" #include "mozilla/StaticPtr.h" #include "mozilla/dom/StructuredCloneTags.h" diff --git a/dom/base/nsAttrValue.cpp b/dom/base/nsAttrValue.cpp index e4bf977f5694..4cfb9778b93a 100644 --- a/dom/base/nsAttrValue.cpp +++ b/dom/base/nsAttrValue.cpp @@ -140,7 +140,7 @@ bool MiscContainer::GetString(nsAString& aString) const { return false; } if (isString) { - auto* buffer = static_cast(ptr); + auto* buffer = static_cast(ptr); aString.Assign(buffer, buffer->StorageSize() / sizeof(char16_t) - 1); } else { static_cast(ptr)->ToString(aString); @@ -280,7 +280,7 @@ void nsAttrValue::Shutdown() { void nsAttrValue::Reset() { switch (BaseType()) { case eStringBase: { - if (auto* str = static_cast(GetPtr())) { + if (auto* str = static_cast(GetPtr())) { str->Release(); } break; @@ -318,7 +318,7 @@ void nsAttrValue::SetTo(const nsAttrValue& aOther) { switch (aOther.BaseType()) { case eStringBase: { ResetIfSet(); - if (auto* str = static_cast(aOther.GetPtr())) { + if (auto* str = static_cast(aOther.GetPtr())) { str->AddRef(); SetPtrValueAndType(str, eStringBase); } @@ -395,7 +395,7 @@ void nsAttrValue::SetTo(const nsAttrValue& aOther) { bool isString; if (void* otherPtr = otherCont->GetStringOrAtomPtr(isString)) { if (isString) { - static_cast(otherPtr)->AddRef(); + static_cast(otherPtr)->AddRef(); } else { static_cast(otherPtr)->AddRef(); } @@ -408,7 +408,7 @@ void nsAttrValue::SetTo(const nsAttrValue& aOther) { void nsAttrValue::SetTo(const nsAString& aValue) { ResetIfSet(); - nsStringBuffer* buf = GetStringBuffer(aValue).take(); + mozilla::StringBuffer* buf = GetStringBuffer(aValue).take(); if (buf) { SetPtrValueAndType(buf, eStringBase); } @@ -589,7 +589,7 @@ void nsAttrValue::RemoveDuplicatesFromAtomArray() { if (void* otherPtr = oldCont->GetStringOrAtomPtr(isString)) { stringBits = oldCont->mStringBits; if (isString) { - static_cast(otherPtr)->AddRef(); + static_cast(otherPtr)->AddRef(); } else { static_cast(otherPtr)->AddRef(); } @@ -620,7 +620,7 @@ void nsAttrValue::ToString(nsAString& aResult) const { switch (Type()) { case eString: { - if (auto* str = static_cast(GetPtr())) { + if (auto* str = static_cast(GetPtr())) { aResult.Assign(str, str->StorageSize() / sizeof(char16_t) - 1); } else { aResult.Truncate(); @@ -770,7 +770,7 @@ already_AddRefed nsAttrValue::GetAsAtom() const { const nsCheapString nsAttrValue::GetStringValue() const { MOZ_ASSERT(Type() == eString, "wrong type"); - return nsCheapString(static_cast(GetPtr())); + return nsCheapString(static_cast(GetPtr())); } bool nsAttrValue::GetColorValue(nscolor& aColor) const { @@ -890,7 +890,7 @@ nsAtom* nsAttrValue::AtomAt(int32_t aIndex) const { uint32_t nsAttrValue::HashValue() const { switch (BaseType()) { case eStringBase: { - if (auto* str = static_cast(GetPtr())) { + if (auto* str = static_cast(GetPtr())) { uint32_t len = str->StorageSize() / sizeof(char16_t) - 1; return HashString(static_cast(str->Data()), len); } @@ -1058,9 +1058,9 @@ bool nsAttrValue::Equals(const nsAttrValue& aOther) const { (static_cast(otherCont->mStringBits & NS_ATTRVALUE_BASETYPE_MASK) == eStringBase)) { - return nsCheapString(reinterpret_cast( + return nsCheapString(reinterpret_cast( static_cast(thisCont->mStringBits))) - .Equals(nsCheapString(reinterpret_cast( + .Equals(nsCheapString(reinterpret_cast( static_cast(otherCont->mStringBits)))); } } @@ -1071,7 +1071,7 @@ bool nsAttrValue::Equals(const nsAString& aValue, nsCaseTreatment aCaseSensitive) const { switch (BaseType()) { case eStringBase: { - if (auto* str = static_cast(GetPtr())) { + if (auto* str = static_cast(GetPtr())) { nsDependentString dep(static_cast(str->Data()), str->StorageSize() / sizeof(char16_t) - 1); return aCaseSensitive == eCaseMatters @@ -1117,7 +1117,7 @@ bool nsAttrValue::Equals(const nsAtom* aValue, nsDependentAtomString(atom), nsDependentAtomString(aValue)); } case eStringBase: { - if (auto* str = static_cast(GetPtr())) { + if (auto* str = static_cast(GetPtr())) { size_t strLen = str->StorageSize() / sizeof(char16_t) - 1; if (aValue->GetLength() != strLen) { return false; @@ -1202,7 +1202,7 @@ bool nsAttrValue::SubstringCheck(const nsAString& aValue, nsCaseTreatment aCaseSensitive) const { switch (BaseType()) { case eStringBase: { - if (auto* str = static_cast(GetPtr())) { + if (auto* str = static_cast(GetPtr())) { return F::Check(static_cast(str->Data()), str->StorageSize() / sizeof(char16_t) - 1, aValue, aCaseSensitive); @@ -1518,9 +1518,9 @@ nsAtom* nsAttrValue::GetStoredAtom() const { return nullptr; } -nsStringBuffer* nsAttrValue::GetStoredStringBuffer() const { +mozilla::StringBuffer* nsAttrValue::GetStoredStringBuffer() const { if (BaseType() == eStringBase) { - return static_cast(GetPtr()); + return static_cast(GetPtr()); } if (BaseType() == eOtherBase) { return GetMiscContainer()->GetStoredStringBuffer(); @@ -1829,7 +1829,7 @@ bool nsAttrValue::ParsePositiveIntValue(const nsAString& aString) { } void nsAttrValue::SetColorValue(nscolor aColor, const nsAString& aString) { - nsStringBuffer* buf = GetStringBuffer(aString).take(); + mozilla::StringBuffer* buf = GetStringBuffer(aString).take(); if (!buf) { return; } @@ -1988,7 +1988,7 @@ void nsAttrValue::SetMiscAtomOrString(const nsAString* aValue) { atom->Release(); } } else { - nsStringBuffer* buffer = GetStringBuffer(*aValue).take(); + mozilla::StringBuffer* buffer = GetStringBuffer(*aValue).take(); NS_ENSURE_TRUE_VOID(buffer); uintptr_t bits = reinterpret_cast(buffer) | eStringBase; @@ -2009,7 +2009,7 @@ void nsAttrValue::ResetMiscAtomOrString() { bool isString; if (void* ptr = cont->GetStringOrAtomPtr(isString)) { if (isString) { - static_cast(ptr)->Release(); + static_cast(ptr)->Release(); } else { static_cast(ptr)->Release(); } @@ -2094,19 +2094,19 @@ MiscContainer* nsAttrValue::EnsureEmptyMiscContainer() { return cont; } -already_AddRefed nsAttrValue::GetStringBuffer( +already_AddRefed nsAttrValue::GetStringBuffer( const nsAString& aValue) const { uint32_t len = aValue.Length(); if (!len) { return nullptr; } - if (nsStringBuffer* buf = aValue.GetStringBuffer(); + if (mozilla::StringBuffer* 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 do_AddRef(buf); } - return nsStringBuffer::Create(aValue.Data(), aValue.Length()); + return mozilla::StringBuffer::Create(aValue.Data(), aValue.Length()); } size_t nsAttrValue::SizeOfExcludingThis(MallocSizeOf aMallocSizeOf) const { @@ -2114,7 +2114,8 @@ size_t nsAttrValue::SizeOfExcludingThis(MallocSizeOf aMallocSizeOf) const { switch (BaseType()) { case eStringBase: { - nsStringBuffer* str = static_cast(GetPtr()); + mozilla::StringBuffer* str = + static_cast(GetPtr()); n += str ? str->SizeOfIncludingThisIfUnshared(aMallocSizeOf) : 0; break; } @@ -2134,7 +2135,7 @@ size_t nsAttrValue::SizeOfExcludingThis(MallocSizeOf aMallocSizeOf) const { // We only count the size of the object pointed by otherPtr if it's a // string. When it's an atom, it's counted separatly. - if (nsStringBuffer* buf = container->GetStoredStringBuffer()) { + if (mozilla::StringBuffer* buf = container->GetStoredStringBuffer()) { n += buf->SizeOfIncludingThisIfUnshared(aMallocSizeOf); } diff --git a/dom/base/nsAttrValue.h b/dom/base/nsAttrValue.h index b32dfc98fb64..e757f7fe0f3a 100644 --- a/dom/base/nsAttrValue.h +++ b/dom/base/nsAttrValue.h @@ -16,7 +16,7 @@ #include "nscore.h" #include "nsString.h" -#include "nsStringBuffer.h" +#include "mozilla/StringBuffer.h" #include "nsColor.h" #include "nsCaseTreatment.h" #include "nsMargin.h" @@ -95,19 +95,19 @@ const uintptr_t NS_ATTRVALUE_BASETYPE_MASK = 3; ~NS_ATTRVALUE_ENUMTABLE_VALUE_NEEDS_TO_UPPER))) /** - * A class used to construct a nsString from a nsStringBuffer (we might + * A class used to construct a nsString from a mozilla::StringBuffer (we might * want to move this to nsString at some point). * * WARNING: Note that nsCheapString doesn't take an explicit length -- it - * assumes the string is maximally large, given the nsStringBuffer's storage - * size. This means the given string buffer *must* be sized exactly correctly - * for the string it contains (including one byte for a null terminator). If - * it has any unused storage space, then that will result in bogus characters - * at the end of our nsCheapString. + * assumes the string is maximally large, given the mozilla::StringBuffer's + * storage size. This means the given string buffer *must* be sized exactly + * correctly for the string it contains (including one byte for a null + * terminator). If it has any unused storage space, then that will result in + * bogus characters at the end of our nsCheapString. */ class nsCheapString : public nsString { public: - explicit nsCheapString(nsStringBuffer* aBuf) { + explicit nsCheapString(mozilla::StringBuffer* aBuf) { if (aBuf) { Assign(aBuf, aBuf->StorageSize() / sizeof(char16_t) - 1); } @@ -486,7 +486,7 @@ class nsAttrValue { size_t SizeOfExcludingThis(mozilla::MallocSizeOf aMallocSizeOf) const; nsAtom* GetStoredAtom() const; - nsStringBuffer* GetStoredStringBuffer() const; + mozilla::StringBuffer* GetStoredStringBuffer() const; private: // These have to be the same as in ValueType @@ -532,7 +532,7 @@ class nsAttrValue { // Like ClearMiscContainer, except allocates a new container if one does not // exist already. MiscContainer* EnsureEmptyMiscContainer(); - already_AddRefed GetStringBuffer( + already_AddRefed GetStringBuffer( const nsAString& aValue) const; // Given an enum table and a particular entry in that table, return // the actual integer value we should store. diff --git a/dom/base/nsAttrValueInlines.h b/dom/base/nsAttrValueInlines.h index b15451237c2d..a058c6165447 100644 --- a/dom/base/nsAttrValueInlines.h +++ b/dom/base/nsAttrValueInlines.h @@ -23,10 +23,9 @@ struct MiscContainer final { using ValueType = nsAttrValue::ValueType; ValueType mType; - // mStringBits points to either nsAtom* or nsStringBuffer* and is used when - // mType isn't eCSSDeclaration. - // Note eStringBase and eAtomBase is used also to handle the type of - // mStringBits. + // mStringBits points to either nsAtom* or mozilla::StringBuffer* and is used + // when mType isn't eCSSDeclaration. Note eStringBase and eAtomBase is used + // also to handle the type of mStringBits. // // Note that we use an atomic here so that we can use Compare-And-Swap // to cache the serialization during the parallel servo traversal. This case @@ -102,10 +101,10 @@ struct MiscContainer final { return isString ? nullptr : static_cast(ptr); } - nsStringBuffer* GetStoredStringBuffer() const { + mozilla::StringBuffer* GetStoredStringBuffer() const { bool isString = false; void* ptr = GetStringOrAtomPtr(isString); - return isString ? static_cast(ptr) : nullptr; + return isString ? static_cast(ptr) : nullptr; } void SetStringBitsMainThread(uintptr_t aBits) { @@ -247,8 +246,7 @@ inline nsAtom* nsAttrValue::GetAtomValue() const { inline void nsAttrValue::ToString(mozilla::dom::DOMString& aResult) const { switch (Type()) { case eString: { - nsStringBuffer* str = static_cast(GetPtr()); - if (str) { + if (auto* str = static_cast(GetPtr())) { aResult.SetKnownLiveStringBuffer( str, str->StorageSize() / sizeof(char16_t) - 1); } diff --git a/dom/base/nsContentUtils.cpp b/dom/base/nsContentUtils.cpp index e4f4fadf9cef..da2409be11c5 100644 --- a/dom/base/nsContentUtils.cpp +++ b/dom/base/nsContentUtils.cpp @@ -369,7 +369,6 @@ #include "nsServiceManagerUtils.h" #include "nsStreamUtils.h" #include "nsString.h" -#include "nsStringBuffer.h" #include "nsStringBundle.h" #include "nsStringFlags.h" #include "nsStringFwd.h" diff --git a/dom/base/nsContentUtils.h b/dom/base/nsContentUtils.h index a1f466fa8d88..ccfc2f4668d2 100644 --- a/dom/base/nsContentUtils.h +++ b/dom/base/nsContentUtils.h @@ -142,6 +142,7 @@ class HTMLEditor; class LazyLogModule; class LogModule; class PresShell; +class StringBuffer; class TextEditor; class WidgetDragEvent; class WidgetKeyboardEvent; diff --git a/dom/base/nsTextFragment.cpp b/dom/base/nsTextFragment.cpp index 5cba2577b83a..0ddc91aef49e 100644 --- a/dom/base/nsTextFragment.cpp +++ b/dom/base/nsTextFragment.cpp @@ -106,7 +106,7 @@ nsTextFragment& nsTextFragment::operator=(const nsTextFragment& aOther) { memcpy(const_cast(m1b), aOther.m1b, aOther.mState.mLength); } else { // allocate a buffer for a single REPLACEMENT CHARACTER - m2b = nsStringBuffer::Alloc(sizeof(char16_t) * 2).take(); + m2b = StringBuffer::Alloc(sizeof(char16_t) * 2).take(); if (!m2b) { MOZ_CRASH("OOM!"); } @@ -202,7 +202,7 @@ bool nsTextFragment::SetTo(const char16_t* aBuffer, uint32_t aLength, uint32_t neededSize = aLength * sizeof(char16_t); if (!neededSize) { if (storageSize < AutoStringDefaultStorageSize) { - // If we're storing small enough nsStringBuffer, let's preserve it. + // If we're storing small enough StringBuffer, let's preserve it. static_cast(m2b->Data())[0] = char16_t(0); mState.mLength = 0; @@ -212,7 +212,7 @@ bool nsTextFragment::SetTo(const char16_t* aBuffer, uint32_t aLength, } else if ((neededSize < storageSize) && ((storageSize / 2) < (neededSize + AutoStringDefaultStorageSize))) { - // Don't try to reuse the existing nsStringBuffer, if it would have + // Don't try to reuse the existing StringBuffer, if it would have // lots of unused space. memcpy(m2b->Data(), aBuffer, neededSize); @@ -296,7 +296,7 @@ bool nsTextFragment::SetTo(const char16_t* aBuffer, uint32_t aLength, return false; } - m2b = nsStringBuffer::Alloc(m2bSize.value()).take(); + m2b = StringBuffer::Alloc(m2bSize.value()).take(); if (!m2b) { return false; } @@ -373,10 +373,10 @@ bool nsTextFragment::Append(const char16_t* aBuffer, uint32_t aLength, size *= sizeof(char16_t); // Already a 2-byte string so the result will be too - nsStringBuffer* buff = nullptr; - nsStringBuffer* bufferToRelease = nullptr; + StringBuffer* buff = nullptr; + StringBuffer* bufferToRelease = nullptr; if (m2b->IsReadonly()) { - buff = nsStringBuffer::Alloc(size).take(); + buff = StringBuffer::Alloc(size).take(); if (!buff) { return false; } @@ -384,7 +384,7 @@ bool nsTextFragment::Append(const char16_t* aBuffer, uint32_t aLength, memcpy(static_cast(buff->Data()), m2b->Data(), mState.mLength * sizeof(char16_t)); } else { - buff = nsStringBuffer::Realloc(m2b, size); + buff = StringBuffer::Realloc(m2b, size); if (!buff) { return false; } @@ -418,7 +418,7 @@ bool nsTextFragment::Append(const char16_t* aBuffer, uint32_t aLength, // The old data was 1-byte, but the new is not so we have to expand it // all to 2-byte - nsStringBuffer* buff = nsStringBuffer::Alloc(size).take(); + StringBuffer* buff = StringBuffer::Alloc(size).take(); if (!buff) { return false; } diff --git a/dom/base/nsTextFragment.h b/dom/base/nsTextFragment.h index 91efa49254e9..6f82fb872382 100644 --- a/dom/base/nsTextFragment.h +++ b/dom/base/nsTextFragment.h @@ -18,7 +18,7 @@ #include "nsCharTraits.h" #include "nsString.h" -#include "nsStringBuffer.h" +#include "mozilla/StringBuffer.h" #include "nsReadableUtils.h" #include "nsISupportsImpl.h" @@ -113,7 +113,7 @@ class nsTextFragment final { } ReleaseText(); if (aForce2b && !aUpdateBidi) { - if (nsStringBuffer* buffer = aString.GetStringBuffer()) { + if (mozilla::StringBuffer* buffer = aString.GetStringBuffer()) { NS_ADDREF(m2b = buffer); mState.mInHeap = true; mState.mIs2b = true; @@ -296,7 +296,7 @@ class nsTextFragment final { void UpdateBidiFlag(const char16_t* aBuffer, uint32_t aLength); union { - nsStringBuffer* m2b; + mozilla::StringBuffer* m2b; const char* m1b; // This is const since it can point to shared data }; diff --git a/dom/bindings/DOMString.h b/dom/bindings/DOMString.h index e87d82077723..929da4f53c1c 100644 --- a/dom/bindings/DOMString.h +++ b/dom/bindings/DOMString.h @@ -8,10 +8,10 @@ #define mozilla_dom_DOMString_h #include "nsString.h" -#include "nsStringBuffer.h" #include "mozilla/Assertions.h" #include "mozilla/Attributes.h" #include "mozilla/Maybe.h" +#include "mozilla/StringBuffer.h" #include "nsDOMString.h" #include "nsAtom.h" @@ -36,10 +36,10 @@ namespace mozilla::dom { * It's only OK to call * SetKnownLiveStringBuffer/SetKnownLiveString/SetKnownLiveAtom if the caller of * the method in question plans to keep holding a strong ref to the stringbuffer - * involved, whether it's a raw nsStringBuffer, or stored inside the string or - * atom being passed. In the string/atom cases that means the caller must own - * the string or atom, and not mutate it (in the string case) for the lifetime - * of the DOMString. + * involved, whether it's a raw mozilla::StringBuffer, or stored inside the + * string or atom being passed. In the string/atom cases that means the caller + * must own the string or atom, and not mutate it (in the string case) for the + * lifetime of the DOMString. * * The proper way to extract a value is to check IsNull(). If not null, then * check IsEmpty(). If neither of those is true, check HasStringBuffer(). If @@ -86,9 +86,9 @@ class MOZ_STACK_CLASS DOMString { // Get the stringbuffer. This can only be called if HasStringBuffer() // returned true. If that's true, it will never return null. Note that - // constructing a string from this nsStringBuffer with length given by + // constructing a string from this mozilla::StringBuffer with length given by // StringBufferLength() might give you something that is not null-terminated. - nsStringBuffer* StringBuffer() const { + mozilla::StringBuffer* StringBuffer() const { MOZ_ASSERT(HasStringBuffer(), "Don't ask for the stringbuffer if we don't have it"); MOZ_ASSERT(mStringBuffer, "We better have a stringbuffer if we claim to"); @@ -103,8 +103,8 @@ class MOZ_STACK_CLASS DOMString { return mLength; } - // Tell the DOMString to relinquish ownership of its nsStringBuffer to the - // caller. Can only be called if HasStringBuffer(). + // Tell the DOMString to relinquish ownership of its mozilla::StringBuffer to + // the caller. Can only be called if HasStringBuffer(). void RelinquishBufferOwnership() { MOZ_ASSERT(HasStringBuffer(), "Don't call this if there is no stringbuffer"); @@ -138,10 +138,10 @@ class MOZ_STACK_CLASS DOMString { return mLength; } - // Initialize the DOMString to a (nsStringBuffer, length) pair. The length - // does NOT have to be the full length of the (null-terminated) string in the - // nsStringBuffer. - void SetKnownLiveStringBuffer(nsStringBuffer* aStringBuffer, + // Initialize the DOMString to a (mozilla::StringBuffer, length) pair. The + // length does NOT have to be the full length of the (null-terminated) string + // in the mozilla::StringBuffer. + void SetKnownLiveStringBuffer(mozilla::StringBuffer* aStringBuffer, uint32_t aLength) { MOZ_ASSERT(mState == State::Empty, "We're already set to a value"); if (aLength != 0) { @@ -151,8 +151,9 @@ class MOZ_STACK_CLASS DOMString { // else nothing to do } - // Like SetKnownLiveStringBuffer, but holds a reference to the nsStringBuffer. - void SetStringBuffer(nsStringBuffer* aStringBuffer, uint32_t aLength) { + // Like SetKnownLiveStringBuffer, but holds a reference to the + // mozilla::StringBuffer. + void SetStringBuffer(mozilla::StringBuffer* aStringBuffer, uint32_t aLength) { MOZ_ASSERT(mState == State::Empty, "We're already set to a value"); if (aLength != 0) { SetStringBufferInternal(aStringBuffer, aLength); @@ -169,7 +170,7 @@ class MOZ_STACK_CLASS DOMString { if (MOZ_UNLIKELY(aString.IsVoid())) { SetNull(); } else if (!aString.IsEmpty()) { - if (nsStringBuffer* buf = aString.GetStringBuffer()) { + if (mozilla::StringBuffer* buf = aString.GetStringBuffer()) { SetKnownLiveStringBuffer(buf, aString.Length()); } else if (aString.IsLiteral()) { SetLiteralInternal(aString.BeginReading(), aString.Length()); @@ -228,9 +229,9 @@ class MOZ_STACK_CLASS DOMString { } else if (IsEmpty()) { aString.Truncate(); } else if (HasStringBuffer()) { - // Don't share the nsStringBuffer with aString if the result would not - // be null-terminated. - nsStringBuffer* buf = StringBuffer(); + // Don't share the mozilla::StringBuffer with aString if the result would + // not be null-terminated. + mozilla::StringBuffer* buf = StringBuffer(); uint32_t len = StringBufferLength(); auto chars = static_cast(buf->Data()); if (chars[len] == '\0') { @@ -248,7 +249,7 @@ class MOZ_STACK_CLASS DOMString { } private: - void SetStringBufferInternal(nsStringBuffer* aStringBuffer, + void SetStringBufferInternal(mozilla::StringBuffer* aStringBuffer, uint32_t aLength) { MOZ_ASSERT(mString.isNothing(), "We already have a string?"); MOZ_ASSERT(mState == State::Empty, "We're already set to a value"); @@ -285,8 +286,9 @@ class MOZ_STACK_CLASS DOMString { Maybe mString; union { - // The nsStringBuffer in the OwnedStringBuffer/UnownedStringBuffer cases. - nsStringBuffer* MOZ_UNSAFE_REF( + // The mozilla::StringBuffer in the OwnedStringBuffer/UnownedStringBuffer + // cases. + mozilla::StringBuffer* MOZ_UNSAFE_REF( "The ways in which this can be safe are " "documented above and enforced through " "assertions") mStringBuffer; diff --git a/dom/bindings/FakeString.h b/dom/bindings/FakeString.h index e7221db86872..49a538c7390a 100644 --- a/dom/bindings/FakeString.h +++ b/dom/bindings/FakeString.h @@ -8,7 +8,7 @@ #define mozilla_dom_FakeString_h__ #include "nsString.h" -#include "nsStringBuffer.h" +#include "mozilla/StringBuffer.h" #include "mozilla/RefPtr.h" #include "mozilla/Span.h" #include "js/String.h" @@ -18,7 +18,7 @@ namespace mozilla::dom::binding_detail { // A struct that has a layout compatible with nsAString, so that // reinterpret-casting a FakeString as a const nsAString is safe, but much // faster constructor and destructor behavior. FakeString uses inline storage -// for small strings and an nsStringBuffer for longer strings. It can also +// for small strings and an StringBuffer for longer strings. It can also // point to a literal (static-lifetime) string that's compiled into the binary, // or point at the buffer of an nsAString whose lifetime is longer than that of // the FakeString. @@ -43,7 +43,7 @@ struct FakeString { ~FakeString() { if (mDataFlags & DataFlags::REFCOUNTED) { MOZ_ASSERT(mDataInitialized); - nsStringBuffer::FromData(mData)->Release(); + StringBuffer::FromData(mData)->Release(); } } @@ -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 = aString.GetStringBuffer(); + RefPtr sharedBuffer = aString.GetStringBuffer(); if (!sharedBuffer) { InitData(aString.BeginReading(), aString.Length()); if (!aString.IsTerminated()) { @@ -102,8 +102,8 @@ struct FakeString { InitData(mStorage, aLength); mDataFlags |= DataFlags::INLINE; } else { - RefPtr buf = - nsStringBuffer::Alloc((aLength + 1) * sizeof(char_type)); + RefPtr buf = + StringBuffer::Alloc((aLength + 1) * sizeof(char_type)); if (MOZ_UNLIKELY(!buf)) { return false; } @@ -124,10 +124,10 @@ struct FakeString { return true; } - RefPtr buffer; + RefPtr buffer; if (mDataFlags & DataFlags::REFCOUNTED) { // Make sure we'll drop it when we're done. - buffer = dont_AddRef(nsStringBuffer::FromData(mData)); + buffer = dont_AddRef(StringBuffer::FromData(mData)); // And make sure we don't release it twice by accident. } const char_type* oldChars = mData; @@ -151,7 +151,7 @@ struct FakeString { return true; } - void AssignFromStringBuffer(already_AddRefed aBuffer, + void AssignFromStringBuffer(already_AddRefed aBuffer, size_t aLength) { InitData(static_cast(aBuffer.take()->Data()), aLength); mDataFlags |= DataFlags::REFCOUNTED; @@ -214,7 +214,7 @@ struct FakeString { bool IsMutable() { return (mDataFlags & DataFlags::INLINE) || ((mDataFlags & DataFlags::REFCOUNTED) && - !nsStringBuffer::FromData(mData)->IsReadonly()); + !StringBuffer::FromData(mData)->IsReadonly()); } friend class NonNull; @@ -257,11 +257,15 @@ struct FakeString { }; } // namespace mozilla::dom::binding_detail +namespace mozilla { + template inline void AssignFromStringBuffer( - nsStringBuffer* aBuffer, size_t aLength, - mozilla::dom::binding_detail::FakeString& aDest) { + StringBuffer* aBuffer, size_t aLength, + dom::binding_detail::FakeString& aDest) { aDest.AssignFromStringBuffer(do_AddRef(aBuffer), aLength); } +} // namespace mozilla + #endif /* mozilla_dom_FakeString_h__ */ diff --git a/dom/bindings/ToJSValue.cpp b/dom/bindings/ToJSValue.cpp index 73fc7b1e3348..d0673a2cb2af 100644 --- a/dom/bindings/ToJSValue.cpp +++ b/dom/bindings/ToJSValue.cpp @@ -11,7 +11,7 @@ #include "mozilla/dom/WindowProxyHolder.h" #include "nsAString.h" #include "nsContentUtils.h" -#include "nsStringBuffer.h" +#include "mozilla/StringBuffer.h" #include "xpcpublic.h" namespace mozilla::dom { @@ -23,7 +23,7 @@ bool ToJSValue(JSContext* aCx, const nsAString& aArgument, // XXXkhuey I'd love to use xpc::NonVoidStringToJsval here, but it requires // a non-const nsAString for silly reasons. - nsStringBuffer* sharedBuffer; + mozilla::StringBuffer* sharedBuffer; if (!XPCStringConvert::ReadableToJSVal(aCx, aArgument, &sharedBuffer, aValue)) { return false; diff --git a/dom/bindings/test/TestFunctions.cpp b/dom/bindings/test/TestFunctions.cpp index 59d455402082..e44ac70437dd 100644 --- a/dom/bindings/test/TestFunctions.cpp +++ b/dom/bindings/test/TestFunctions.cpp @@ -10,7 +10,7 @@ #include "mozilla/dom/TestFunctionsBinding.h" #include "mozilla/dom/WindowBinding.h" #include "mozilla/dom/WrapperCachedNonISupportsTestInterface.h" -#include "nsStringBuffer.h" +#include "mozilla/StringBuffer.h" #include "mozITestInterfaceJS.h" #include "nsComponentManagerUtils.h" #include "nsGlobalWindowInner.h" @@ -66,7 +66,7 @@ void TestFunctions::GetStringDataAsDOMString(const Optional& aLength, length = mStringData.Length(); } - if (nsStringBuffer* buf = mStringData.GetStringBuffer()) { + if (StringBuffer* buf = mStringData.GetStringBuffer()) { aString.SetKnownLiveStringBuffer(buf, length); return; } diff --git a/dom/docs/webIdlBindings/index.md b/dom/docs/webIdlBindings/index.md index eb2586210ddc..66d401f27141 100644 --- a/dom/docs/webIdlBindings/index.md +++ b/dom/docs/webIdlBindings/index.md @@ -1999,13 +1999,13 @@ and exported to `mozilla/dom/BindingDeclarations.h` that is used for Web IDL `DOMString` return values. It has a conversion operator to `nsString&` so that it can be passed to methods that take that type or `nsAString&`, but callees that care about performance, have an -`nsStringBuffer` available, and promise to hold on to the -`nsStringBuffer` at least until the binding code comes off the stack +`StringBuffer` available, and promise to hold on to the +`StringBuffer` at least until the binding code comes off the stack can also take a `DOMString` directly for their string return value and -call its `SetStringBuffer` method with the `nsStringBuffer` and its +call its `SetStringBuffer` method with the `StringBuffer` and its length. This allows the binding code to avoid extra reference-counting of the string buffer in many cases, and allows it to take a faster -codepath even if it does end up having to addref the `nsStringBuffer`. +codepath even if it does end up having to addref the `StringBuffer`. ### `GlobalObject` diff --git a/dom/events/DataTransfer.cpp b/dom/events/DataTransfer.cpp index b2f70dab5493..21d5c80e7087 100644 --- a/dom/events/DataTransfer.cpp +++ b/dom/events/DataTransfer.cpp @@ -1068,8 +1068,8 @@ already_AddRefed DataTransfer::GetTransferable( nsCOMPtr inputStream; storageStream->NewInputStream(0, getter_AddRefs(inputStream)); - RefPtr stringBuffer = - nsStringBuffer::Alloc(totalCustomLength); + RefPtr stringBuffer = + StringBuffer::Alloc(totalCustomLength); // Subtract off the null terminator when reading. totalCustomLength--; diff --git a/dom/fetch/FetchUtil.cpp b/dom/fetch/FetchUtil.cpp index 486b58bc37f3..b54a49ee9181 100644 --- a/dom/fetch/FetchUtil.cpp +++ b/dom/fetch/FetchUtil.cpp @@ -652,7 +652,7 @@ void FetchUtil::InitWasmAltDataType() { MOZ_ASSERT(type.IsEmpty()); RunOnShutdown([]() { - // Avoid nsStringBuffer leak tests failures. + // Avoid StringBuffer leak tests failures. const_cast(WasmAltDataType).Truncate(); }); diff --git a/dom/serializers/nsDocumentEncoder.cpp b/dom/serializers/nsDocumentEncoder.cpp index c50a94ea8e4a..351ec6d81b99 100644 --- a/dom/serializers/nsDocumentEncoder.cpp +++ b/dom/serializers/nsDocumentEncoder.cpp @@ -36,7 +36,7 @@ #include "nsTArray.h" #include "nsIFrame.h" #include "nsLayoutUtils.h" -#include "nsStringBuffer.h" +#include "mozilla/StringBuffer.h" #include "mozilla/dom/Comment.h" #include "mozilla/dom/Document.h" #include "mozilla/dom/DocumentType.h" @@ -341,7 +341,7 @@ class nsDocumentEncoder : public nsIDocumentEncoder { // argument of nsIContentSerializer::Init(). bool mNeedsPreformatScanning; bool mIsCopying; // Set to true only while copying - RefPtr mCachedBuffer; + RefPtr mCachedBuffer; class NodeSerializer { public: @@ -1368,7 +1368,7 @@ nsDocumentEncoder::EncodeToStringWithMaxLength(uint32_t aMaxLength, nsString output; static const size_t kStringBufferSizeInBytes = 2048; if (!mCachedBuffer) { - mCachedBuffer = nsStringBuffer::Alloc(kStringBufferSizeInBytes); + mCachedBuffer = StringBuffer::Alloc(kStringBufferSizeInBytes); if (NS_WARN_IF(!mCachedBuffer)) { return NS_ERROR_OUT_OF_MEMORY; } @@ -1406,7 +1406,7 @@ nsDocumentEncoder::EncodeToStringWithMaxLength(uint32_t aMaxLength, bool setOutput = false; MOZ_ASSERT(!mCachedBuffer); // Try to cache the buffer. - if (nsStringBuffer* outputBuffer = output.GetStringBuffer()) { + if (StringBuffer* outputBuffer = output.GetStringBuffer()) { if (outputBuffer->StorageSize() == kStringBufferSizeInBytes && !outputBuffer->IsReadonly()) { mCachedBuffer = outputBuffer; diff --git a/dom/xhr/XMLHttpRequestMainThread.cpp b/dom/xhr/XMLHttpRequestMainThread.cpp index e18800e24a25..c4ad1a2bf7c2 100644 --- a/dom/xhr/XMLHttpRequestMainThread.cpp +++ b/dom/xhr/XMLHttpRequestMainThread.cpp @@ -83,7 +83,6 @@ #include "nsIWindowWatcher.h" #include "nsIConsoleService.h" #include "nsAsyncRedirectVerifyHelper.h" -#include "nsStringBuffer.h" #include "nsIFileChannel.h" #include "mozilla/Telemetry.h" #include "js/ArrayBuffer.h" // JS::{Create,Release}MappedArrayBufferContents,New{,Mapped}ArrayBufferWithContents diff --git a/dom/xhr/XMLHttpRequestString.cpp b/dom/xhr/XMLHttpRequestString.cpp index e0e68f3d2df5..7948ba5c6e4c 100644 --- a/dom/xhr/XMLHttpRequestString.cpp +++ b/dom/xhr/XMLHttpRequestString.cpp @@ -58,7 +58,7 @@ class XMLHttpRequestStringBuffer final { // XXX: Bug 1408793 suggests encapsulating the following sequence within // DOMString. - if (nsStringBuffer* buf = mData.GetStringBuffer()) { + if (StringBuffer* 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/js/src/devtools/rootAnalysis/analyzeHeapWrites.js b/js/src/devtools/rootAnalysis/analyzeHeapWrites.js index 28679676a56f..a4c7df2998bb 100644 --- a/js/src/devtools/rootAnalysis/analyzeHeapWrites.js +++ b/js/src/devtools/rootAnalysis/analyzeHeapWrites.js @@ -286,10 +286,6 @@ function checkFieldWrite(entry, location, fields) if (/\bThreadLocal<\b/.test(field)) return; - - // Debugging check for string corruption. - if (field == "nsStringBuffer.mCanary") - return; } var str = ""; @@ -539,7 +535,7 @@ function ignoreContents(entry) if (entry.isSafeArgument(2)) { var secondArgWhitelist = [ - /nsStringBuffer::ToString/, + /StringBuffer::ToString/, /AppendUTF\d+toUTF\d+/, /AppendASCIItoUTF\d+/, ]; diff --git a/js/xpconnect/src/XPCConvert.cpp b/js/xpconnect/src/XPCConvert.cpp index c11e4ccdfb8a..fdc29abc7d8c 100644 --- a/js/xpconnect/src/XPCConvert.cpp +++ b/js/xpconnect/src/XPCConvert.cpp @@ -165,7 +165,7 @@ bool XPCConvert::NativeData2JS(JSContext* cx, MutableHandleValue d, return true; } - nsStringBuffer* buf; + StringBuffer* buf; if (!XPCStringConvert::ReadableToJSVal(cx, *p, &buf, d)) { return false; } @@ -255,7 +255,7 @@ bool XPCConvert::NativeData2JS(JSContext* cx, MutableHandleValue d, // NOTE: XPCStringConvert::UTF8ToJSVal cannot be used here because // it requires valid UTF-8 sequence. if (mozilla::IsAscii(*utf8String)) { - nsStringBuffer* buf; + StringBuffer* buf; if (!XPCStringConvert::Latin1ToJSVal(cx, *utf8String, &buf, d)) { return false; } @@ -312,7 +312,7 @@ bool XPCConvert::NativeData2JS(JSContext* cx, MutableHandleValue d, } // c-strings (binary blobs) are Latin1 string in JSAPI. - nsStringBuffer* buf; + StringBuffer* buf; if (!XPCStringConvert::Latin1ToJSVal(cx, *cString, &buf, d)) { return false; } diff --git a/js/xpconnect/src/XPCString.cpp b/js/xpconnect/src/XPCString.cpp index 651f3dde9fce..13b4b34f0830 100644 --- a/js/xpconnect/src/XPCString.cpp +++ b/js/xpconnect/src/XPCString.cpp @@ -20,11 +20,12 @@ #include "nscore.h" #include "nsString.h" -#include "nsStringBuffer.h" +#include "mozilla/StringBuffer.h" #include "jsapi.h" #include "xpcpublic.h" using namespace JS; +using mozilla::StringBuffer; const XPCStringConvert::LiteralExternalString XPCStringConvert::sLiteralExternalString; @@ -55,13 +56,13 @@ size_t XPCStringConvert::LiteralExternalString::sizeOfBuffer( void XPCStringConvert::DOMStringExternalString::finalize( JS::Latin1Char* aChars) const { - nsStringBuffer* buf = nsStringBuffer::FromData(aChars); + StringBuffer* buf = StringBuffer::FromData(aChars); buf->Release(); } void XPCStringConvert::DOMStringExternalString::finalize( char16_t* aChars) const { - nsStringBuffer* buf = nsStringBuffer::FromData(aChars); + StringBuffer* buf = StringBuffer::FromData(aChars); buf->Release(); } @@ -70,8 +71,8 @@ size_t XPCStringConvert::DOMStringExternalString::sizeOfBuffer( // We promised the JS engine we would not GC. Enforce that: JS::AutoCheckCannotGC autoCannotGC; - const nsStringBuffer* buf = - nsStringBuffer::FromData(const_cast(aChars)); + const StringBuffer* buf = + StringBuffer::FromData(const_cast(aChars)); // We want sizeof including this, because the entire string buffer is owned by // the external string. But only report here if we're unshared; if we're // shared then we don't know who really owns this data. @@ -83,8 +84,8 @@ size_t XPCStringConvert::DOMStringExternalString::sizeOfBuffer( // We promised the JS engine we would not GC. Enforce that: JS::AutoCheckCannotGC autoCannotGC; - const nsStringBuffer* buf = - nsStringBuffer::FromData(const_cast(aChars)); + const StringBuffer* buf = + StringBuffer::FromData(const_cast(aChars)); // We want sizeof including this, because the entire string buffer is owned by // the external string. But only report here if we're unshared; if we're // shared then we don't know who really owns this data. @@ -94,7 +95,7 @@ size_t XPCStringConvert::DOMStringExternalString::sizeOfBuffer( // convert a readable to a JSString, copying string data // static bool XPCStringConvert::ReadableToJSVal(JSContext* cx, const nsAString& readable, - nsStringBuffer** sharedBuffer, + StringBuffer** sharedBuffer, MutableHandleValue vp) { *sharedBuffer = nullptr; @@ -104,7 +105,7 @@ bool XPCStringConvert::ReadableToJSVal(JSContext* cx, const nsAString& readable, return StringLiteralToJSVal(cx, readable.BeginReading(), length, vp); } - if (nsStringBuffer* buf = readable.GetStringBuffer()) { + if (StringBuffer* buf = readable.GetStringBuffer()) { bool shared; if (!UCStringBufferToJSVal(cx, buf, length, vp, &shared)) { return false; @@ -125,7 +126,7 @@ bool XPCStringConvert::ReadableToJSVal(JSContext* cx, const nsAString& readable, } bool XPCStringConvert::Latin1ToJSVal(JSContext* cx, const nsACString& latin1, - nsStringBuffer** sharedBuffer, + StringBuffer** sharedBuffer, MutableHandleValue vp) { *sharedBuffer = nullptr; @@ -137,7 +138,7 @@ bool XPCStringConvert::Latin1ToJSVal(JSContext* cx, const nsACString& latin1, length, vp); } - if (nsStringBuffer* buf = latin1.GetStringBuffer()) { + if (StringBuffer* buf = latin1.GetStringBuffer()) { bool shared; if (!Latin1StringBufferToJSVal(cx, buf, length, vp, &shared)) { return false; @@ -157,7 +158,7 @@ bool XPCStringConvert::Latin1ToJSVal(JSContext* cx, const nsACString& latin1, } bool XPCStringConvert::UTF8ToJSVal(JSContext* cx, const nsACString& utf8, - nsStringBuffer** sharedBuffer, + StringBuffer** sharedBuffer, MutableHandleValue vp) { *sharedBuffer = nullptr; @@ -168,7 +169,7 @@ bool XPCStringConvert::UTF8ToJSVal(JSContext* cx, const nsACString& utf8, cx, JS::UTF8Chars(utf8.BeginReading(), length), vp); } - if (nsStringBuffer* buf = utf8.GetStringBuffer()) { + if (StringBuffer* buf = utf8.GetStringBuffer()) { bool shared; if (!UTF8StringBufferToJSVal(cx, buf, length, vp, &shared)) { return false; @@ -192,7 +193,7 @@ namespace xpc { bool NonVoidStringToJsval(JSContext* cx, nsAString& str, MutableHandleValue rval) { - nsStringBuffer* sharedBuffer; + StringBuffer* sharedBuffer; if (!XPCStringConvert::ReadableToJSVal(cx, str, &sharedBuffer, rval)) { return false; } @@ -207,7 +208,7 @@ bool NonVoidStringToJsval(JSContext* cx, nsAString& str, bool NonVoidStringToJsval(JSContext* cx, const nsAString& str, MutableHandleValue rval) { - nsStringBuffer* sharedBuffer; + StringBuffer* sharedBuffer; if (!XPCStringConvert::ReadableToJSVal(cx, str, &sharedBuffer, rval)) { return false; } @@ -221,7 +222,7 @@ bool NonVoidStringToJsval(JSContext* cx, const nsAString& str, bool NonVoidLatin1StringToJsval(JSContext* cx, nsACString& str, MutableHandleValue rval) { - nsStringBuffer* sharedBuffer; + StringBuffer* sharedBuffer; if (!XPCStringConvert::Latin1ToJSVal(cx, str, &sharedBuffer, rval)) { return false; } @@ -236,7 +237,7 @@ bool NonVoidLatin1StringToJsval(JSContext* cx, nsACString& str, bool NonVoidLatin1StringToJsval(JSContext* cx, const nsACString& str, MutableHandleValue rval) { - nsStringBuffer* sharedBuffer; + StringBuffer* sharedBuffer; if (!XPCStringConvert::Latin1ToJSVal(cx, str, &sharedBuffer, rval)) { return false; } @@ -250,7 +251,7 @@ bool NonVoidLatin1StringToJsval(JSContext* cx, const nsACString& str, bool NonVoidUTF8StringToJsval(JSContext* cx, nsACString& str, MutableHandleValue rval) { - nsStringBuffer* sharedBuffer; + StringBuffer* sharedBuffer; if (!XPCStringConvert::UTF8ToJSVal(cx, str, &sharedBuffer, rval)) { return false; } @@ -265,7 +266,7 @@ bool NonVoidUTF8StringToJsval(JSContext* cx, nsACString& str, bool NonVoidUTF8StringToJsval(JSContext* cx, const nsACString& str, MutableHandleValue rval) { - nsStringBuffer* sharedBuffer; + StringBuffer* sharedBuffer; if (!XPCStringConvert::UTF8ToJSVal(cx, str, &sharedBuffer, rval)) { return false; } diff --git a/js/xpconnect/src/xpcprivate.h b/js/xpconnect/src/xpcprivate.h index 7b348e35b5fb..38d7516c3619 100644 --- a/js/xpconnect/src/xpcprivate.h +++ b/js/xpconnect/src/xpcprivate.h @@ -138,7 +138,6 @@ #include "nsBaseHashtable.h" #include "nsHashKeys.h" #include "nsWrapperCache.h" -#include "nsStringBuffer.h" #include "nsDeque.h" #include "nsIScriptSecurityManager.h" diff --git a/js/xpconnect/src/xpcpublic.h b/js/xpconnect/src/xpcpublic.h index 28e93a65b429..deddb12284c6 100644 --- a/js/xpconnect/src/xpcpublic.h +++ b/js/xpconnect/src/xpcpublic.h @@ -28,12 +28,12 @@ #include "mozilla/MemoryReporting.h" #include "mozilla/TextUtils.h" #include "mozilla/dom/DOMString.h" +#include "mozilla/StringBuffer.h" #include "mozilla/fallible.h" #include "nsAtom.h" #include "nsCOMPtr.h" #include "nsISupports.h" #include "nsIURI.h" -#include "nsStringBuffer.h" #include "nsStringFwd.h" #include "nsTArray.h" #include "nsWrapperCache.h" @@ -236,11 +236,11 @@ extern bool xpc_DumpJSStack(bool showArgs, bool showLocals, bool showThisProps); extern JS::UniqueChars xpc_PrintJSStack(JSContext* cx, bool showArgs, bool showLocals, bool showThisProps); -inline void AssignFromStringBuffer(nsStringBuffer* buffer, size_t len, +inline void AssignFromStringBuffer(mozilla::StringBuffer* buffer, size_t len, nsAString& dest) { dest.Assign(buffer, len); } -inline void AssignFromStringBuffer(nsStringBuffer* buffer, size_t len, +inline void AssignFromStringBuffer(mozilla::StringBuffer* buffer, size_t len, nsACString& dest) { dest.Assign(buffer, len); } @@ -252,18 +252,18 @@ class XPCStringConvert { // get assigned to *sharedBuffer. Otherwise null will be // assigned. static bool ReadableToJSVal(JSContext* cx, const nsAString& readable, - nsStringBuffer** sharedBuffer, + mozilla::StringBuffer** sharedBuffer, JS::MutableHandle vp); static bool Latin1ToJSVal(JSContext* cx, const nsACString& latin1, - nsStringBuffer** sharedBuffer, + mozilla::StringBuffer** sharedBuffer, JS::MutableHandle vp); static bool UTF8ToJSVal(JSContext* cx, const nsACString& utf8, - nsStringBuffer** sharedBuffer, + mozilla::StringBuffer** sharedBuffer, JS::MutableHandle vp); // Convert the given stringbuffer/length pair to a jsval static MOZ_ALWAYS_INLINE bool UCStringBufferToJSVal( - JSContext* cx, nsStringBuffer* buf, uint32_t length, + JSContext* cx, mozilla::StringBuffer* buf, uint32_t length, JS::MutableHandle rval, bool* sharedBuffer) { JSString* str = JS_NewMaybeExternalUCString( cx, static_cast(buf->Data()), length, @@ -276,7 +276,7 @@ class XPCStringConvert { } static MOZ_ALWAYS_INLINE bool Latin1StringBufferToJSVal( - JSContext* cx, nsStringBuffer* buf, uint32_t length, + JSContext* cx, mozilla::StringBuffer* buf, uint32_t length, JS::MutableHandle rval, bool* sharedBuffer) { JSString* str = JS_NewMaybeExternalStringLatin1( cx, static_cast(buf->Data()), length, @@ -289,7 +289,7 @@ class XPCStringConvert { } static MOZ_ALWAYS_INLINE bool UTF8StringBufferToJSVal( - JSContext* cx, nsStringBuffer* buf, uint32_t length, + JSContext* cx, mozilla::StringBuffer* buf, uint32_t length, JS::MutableHandle rval, bool* sharedBuffer) { JSString* str = JS_NewMaybeExternalStringUTF8( cx, {static_cast(buf->Data()), length}, @@ -387,9 +387,10 @@ class XPCStringConvert { // the whole buffer; otherwise we have to copy. if (chars[len] == '\0') { // NOTE: No need to worry about SrcCharT vs DestCharT, given - // nsStringBuffer::FromData takes void*. + // mozilla::StringBuffer::FromData takes void*. AssignFromStringBuffer( - nsStringBuffer::FromData(const_cast(chars)), len, dest); + mozilla::StringBuffer::FromData(const_cast(chars)), len, + dest); return true; } } else if (callbacks == &sLiteralExternalString) { @@ -504,7 +505,7 @@ inline bool NonVoidStringToJsval(JSContext* cx, mozilla::dom::DOMString& str, if (str.HasStringBuffer()) { uint32_t length = str.StringBufferLength(); - nsStringBuffer* buf = str.StringBuffer(); + mozilla::StringBuffer* buf = str.StringBuffer(); bool shared; if (!XPCStringConvert::UCStringBufferToJSVal(cx, buf, length, rval, &shared)) { diff --git a/layout/style/StyleAnimationValue.h b/layout/style/StyleAnimationValue.h index 04dc48dd90a4..85719ae4f621 100644 --- a/layout/style/StyleAnimationValue.h +++ b/layout/style/StyleAnimationValue.h @@ -17,7 +17,6 @@ #include "mozilla/DbgMacro.h" #include "mozilla/AnimatedPropertyID.h" #include "nsStringFwd.h" -#include "nsStringBuffer.h" #include "nsCoord.h" #include "nsColor.h" #include "nsCSSPropertyID.h" diff --git a/xpcom/string/nsStringBuffer.h b/mfbt/StringBuffer.h similarity index 72% rename from xpcom/string/nsStringBuffer.h rename to mfbt/StringBuffer.h index dad41e48f755..6927b54dfc26 100644 --- a/xpcom/string/nsStringBuffer.h +++ b/mfbt/StringBuffer.h @@ -4,15 +4,18 @@ * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ -#ifndef nsStringBuffer_h__ -#define nsStringBuffer_h__ +#ifndef StringBuffer_h__ +#define StringBuffer_h__ #include +#include #include "mozilla/MemoryReporting.h" #include "mozilla/Assertions.h" #include "mozilla/AlreadyAddRefed.h" #include "mozilla/RefCounted.h" +namespace mozilla { + /** * This structure precedes the string buffers "we" allocate. It may be the * case that nsTAString::mData does not point to one of these special @@ -22,13 +25,13 @@ * tracking. NOTE: A string buffer can be modified only if its reference * count is 1. */ -class nsStringBuffer { +class StringBuffer { private: std::atomic mRefCount; uint32_t mStorageSize; public: - MOZ_DECLARE_REFCOUNTED_TYPENAME(nsStringBuffer) + MOZ_DECLARE_REFCOUNTED_TYPENAME(StringBuffer) /** * Allocates a new string buffer, with given size in bytes and a @@ -47,17 +50,17 @@ class nsStringBuffer { * * @return new string buffer or null if out of memory. */ - static already_AddRefed Alloc(size_t aSize) { + 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, + MOZ_ASSERT(sizeof(StringBuffer) + aSize <= size_t(uint32_t(-1)) && + sizeof(StringBuffer) + aSize > aSize, "mStorageSize will truncate"); - auto* hdr = (nsStringBuffer*)malloc(sizeof(nsStringBuffer) + aSize); + auto* hdr = (StringBuffer*)malloc(sizeof(StringBuffer) + aSize); if (hdr) { hdr->mRefCount = 1; hdr->mStorageSize = aSize; - mozilla::detail::RefCountLogger::logAddRef(hdr, 1); + detail::RefCountLogger::logAddRef(hdr, 1); } return already_AddRefed(hdr); } @@ -68,10 +71,14 @@ class nsStringBuffer { * Note that this will allocate extra space for the trailing null byte, which * this method will add. */ - static already_AddRefed Create(const char16_t* aData, - size_t aLength); - static already_AddRefed Create(const char* aData, - size_t aLength); + static already_AddRefed Create(const char16_t* aData, + size_t aLength) { + return DoCreate(aData, aLength); + } + static already_AddRefed Create(const char* aData, + size_t aLength) { + return DoCreate(aData, aLength); + } /** * Resizes the given string buffer to the specified storage size. This @@ -84,7 +91,31 @@ class nsStringBuffer { * * @see IsReadonly */ - static nsStringBuffer* Realloc(nsStringBuffer* aBuf, size_t aStorageSize); + static StringBuffer* Realloc(StringBuffer* aHdr, size_t aSize) { + MOZ_ASSERT(aSize != 0, "zero capacity allocation not allowed"); + MOZ_ASSERT(sizeof(StringBuffer) + aSize <= size_t(uint32_t(-1)) && + sizeof(StringBuffer) + aSize > aSize, + "mStorageSize will truncate"); + + // no point in trying to save ourselves if we hit this assertion + 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. + { + detail::RefCountLogger::ReleaseLogger logger(aHdr); + logger.logRelease(0); + } + + aHdr = (StringBuffer*)realloc(aHdr, sizeof(StringBuffer) + aSize); + if (aHdr) { + detail::RefCountLogger::logAddRef(aHdr, 1); + aHdr->mStorageSize = aSize; + } + + return aHdr; + } void AddRef() { // Memory synchronization is not required when incrementing a @@ -96,14 +127,14 @@ class nsStringBuffer { // 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); + detail::RefCountLogger::logAddRef(this, count); } 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); + detail::RefCountLogger::ReleaseLogger logger(this); uint32_t count = mRefCount.fetch_sub(1, std::memory_order_release) - 1; logger.logRelease(count); if (count == 0) { @@ -119,10 +150,10 @@ class nsStringBuffer { /** * This method returns the string buffer corresponding to the given data * pointer. The data pointer must have been returned previously by a - * call to the nsStringBuffer::Data method. + * call to the StringBuffer::Data method. */ - static nsStringBuffer* FromData(void* aData) { - return reinterpret_cast(aData) - 1; + static StringBuffer* FromData(void* aData) { + return reinterpret_cast(aData) - 1; } /** @@ -182,8 +213,9 @@ class nsStringBuffer { /** * This measures the size only if the StringBuffer is unshared. */ - size_t SizeOfIncludingThisIfUnshared( - mozilla::MallocSizeOf aMallocSizeOf) const; + size_t SizeOfIncludingThisIfUnshared(MallocSizeOf aMallocSizeOf) const { + return IsReadonly() ? 0 : aMallocSizeOf(this); + } /** * This measures the size regardless of whether the StringBuffer is @@ -194,8 +226,24 @@ class nsStringBuffer { * please explain clearly in a comment why it's safe and won't lead to * double-counting. */ - size_t SizeOfIncludingThisEvenIfShared( - mozilla::MallocSizeOf aMallocSizeOf) const; + size_t SizeOfIncludingThisEvenIfShared(MallocSizeOf aMallocSizeOf) const { + return aMallocSizeOf(this); + } + + private: + template + static already_AddRefed DoCreate(const CharT* aData, + size_t aLength) { + StringBuffer* buffer = Alloc((aLength + 1) * sizeof(CharT)).take(); + if (MOZ_LIKELY(buffer)) { + auto* data = reinterpret_cast(buffer->Data()); + memcpy(data, aData, aLength * sizeof(CharT)); + data[aLength] = 0; + } + return already_AddRefed(buffer); + } }; -#endif /* !defined(nsStringBuffer_h__ */ +} // namespace mozilla + +#endif diff --git a/mfbt/moz.build b/mfbt/moz.build index c1f9a8f92a97..f6fa41c89ecd 100644 --- a/mfbt/moz.build +++ b/mfbt/moz.build @@ -107,6 +107,7 @@ EXPORTS.mozilla = [ "SplayTree.h", "SPSCQueue.h", "StaticAnalysisFunctions.h", + "StringBuffer.h", "TaggedAnonymousMemory.h", "Tainting.h", "TemplateLib.h", diff --git a/parser/html/nsHtml5String.cpp b/parser/html/nsHtml5String.cpp index 7e100806692c..bc01ff344416 100644 --- a/parser/html/nsHtml5String.cpp +++ b/parser/html/nsHtml5String.cpp @@ -5,6 +5,9 @@ #include "nsHtml5String.h" #include "nsCharTraits.h" #include "nsHtml5TreeBuilder.h" +#include "mozilla/StringBuffer.h" + +using mozilla::StringBuffer; void nsHtml5String::ToString(nsAString& aString) { switch (GetKind()) { @@ -104,17 +107,17 @@ nsHtml5String nsHtml5String::FromBuffer(char16_t* aBuffer, int32_t aLength, if (!aLength) { return nsHtml5String(eEmpty); } - // Work with nsStringBuffer directly to make sure that storage is actually - // nsStringBuffer and to make sure the allocation strategy matches + // Work with StringBuffer directly to make sure that storage is actually + // StringBuffer and to make sure the allocation strategy matches // nsAttrValue::GetStringBuffer, so that it doesn't need to reallocate and // copy. - RefPtr buffer = nsStringBuffer::Create(aBuffer, aLength); + RefPtr buffer = StringBuffer::Create(aBuffer, aLength); if (MOZ_UNLIKELY(!buffer)) { if (!aTreeBuilder) { MOZ_CRASH("Out of memory."); } aTreeBuilder->MarkAsBroken(NS_ERROR_OUT_OF_MEMORY); - buffer = nsStringBuffer::Alloc(2 * sizeof(char16_t)); + buffer = StringBuffer::Alloc(2 * sizeof(char16_t)); if (!buffer) { MOZ_CRASH( "Out of memory so badly that couldn't even allocate placeholder."); @@ -133,12 +136,12 @@ nsHtml5String nsHtml5String::FromLiteral(const char* aLiteral) { if (!length) { return nsHtml5String(eEmpty); } - // Work with nsStringBuffer directly to make sure that storage is actually - // nsStringBuffer and to make sure the allocation strategy matches + // Work with StringBuffer directly to make sure that storage is actually + // StringBuffer and to make sure the allocation strategy matches // nsAttrValue::GetStringBuffer, so that it doesn't need to reallocate and // copy. - RefPtr buffer( - nsStringBuffer::Alloc((length + 1) * sizeof(char16_t))); + RefPtr buffer( + StringBuffer::Alloc((length + 1) * sizeof(char16_t))); if (!buffer) { MOZ_CRASH("Out of memory."); } @@ -156,14 +159,14 @@ nsHtml5String nsHtml5String::FromString(const nsAString& aString) { if (!length) { return nsHtml5String(eEmpty); } - if (nsStringBuffer* buffer = aString.GetStringBuffer()) { + if (StringBuffer* buffer = aString.GetStringBuffer()) { if (length == buffer->StorageSize() / sizeof(char16_t) - 1) { buffer->AddRef(); return nsHtml5String(reinterpret_cast(buffer) | eStringBuffer); } } - RefPtr buffer = - nsStringBuffer::Alloc((length + 1) * sizeof(char16_t)); + RefPtr buffer = + StringBuffer::Alloc((length + 1) * sizeof(char16_t)); if (!buffer) { MOZ_CRASH("Out of memory."); } diff --git a/parser/html/nsHtml5String.h b/parser/html/nsHtml5String.h index f725630f9e47..d6864cdbf7bc 100644 --- a/parser/html/nsHtml5String.h +++ b/parser/html/nsHtml5String.h @@ -7,7 +7,10 @@ #include "nsAtom.h" #include "nsString.h" -#include "nsStringBuffer.h" + +namespace mozilla { +class StringBuffer; +} class nsHtml5TreeBuilder; @@ -15,11 +18,11 @@ class nsHtml5TreeBuilder; * A pass-by-value type that can represent * * nullptr * * empty string - * * Non-empty string as exactly-sized (capacity is length) `nsStringBuffer*` + * * Non-empty string as exactly-sized (capacity is length) `StringBuffer*` * * Non-empty string as an nsAtom* * * Holding or passing this type is as unsafe as holding or passing - * `nsStringBuffer*`/`nsAtom*`. + * `StringBuffer*`/`nsAtom*`. */ class nsHtml5String final { private: @@ -36,9 +39,9 @@ class nsHtml5String final { inline Kind GetKind() const { return (Kind)(mBits & kKindMask); } - inline nsStringBuffer* AsStringBuffer() const { + inline mozilla::StringBuffer* AsStringBuffer() const { MOZ_ASSERT(GetKind() == eStringBuffer); - return reinterpret_cast(mBits & kPtrMask); + return reinterpret_cast(mBits & kPtrMask); } inline nsAtom* AsAtom() const { diff --git a/security/manager/ssl/nsCertOverrideService.cpp b/security/manager/ssl/nsCertOverrideService.cpp index b8d0bbc3a12f..fcc2a45e6de8 100644 --- a/security/manager/ssl/nsCertOverrideService.cpp +++ b/security/manager/ssl/nsCertOverrideService.cpp @@ -35,7 +35,6 @@ #include "nsNSSComponent.h" #include "nsNetUtil.h" #include "nsStreamUtils.h" -#include "nsStringBuffer.h" #include "nsThreadUtils.h" using namespace mozilla; diff --git a/security/manager/ssl/nsClientAuthRemember.cpp b/security/manager/ssl/nsClientAuthRemember.cpp index 91fd774c9117..aad233bd0df7 100644 --- a/security/manager/ssl/nsClientAuthRemember.cpp +++ b/security/manager/ssl/nsClientAuthRemember.cpp @@ -17,7 +17,6 @@ #include "nsNetUtil.h" #include "nsPromiseFlatString.h" #include "nsThreadUtils.h" -#include "nsStringBuffer.h" #include "cert.h" #include "nspr.h" #include "pk11pub.h" diff --git a/xpcom/base/CycleCollectedJSContext.cpp b/xpcom/base/CycleCollectedJSContext.cpp index b65acebe2ede..3f3bf9683eb2 100644 --- a/xpcom/base/CycleCollectedJSContext.cpp +++ b/xpcom/base/CycleCollectedJSContext.cpp @@ -41,7 +41,6 @@ #include "nsDOMMutationObserver.h" #include "nsJSUtils.h" #include "nsPIDOMWindow.h" -#include "nsStringBuffer.h" #include "nsThread.h" #include "nsThreadUtils.h" #include "nsWrapperCache.h" diff --git a/xpcom/base/CycleCollectedJSRuntime.cpp b/xpcom/base/CycleCollectedJSRuntime.cpp index 6833dee7914e..3941908ec1e2 100644 --- a/xpcom/base/CycleCollectedJSRuntime.cpp +++ b/xpcom/base/CycleCollectedJSRuntime.cpp @@ -97,7 +97,6 @@ #include "nsDOMJSUtils.h" #include "nsExceptionHandler.h" #include "nsJSUtils.h" -#include "nsStringBuffer.h" #include "nsWrapperCache.h" #include "prenv.h" diff --git a/xpcom/base/nsTraceRefcnt.cpp b/xpcom/base/nsTraceRefcnt.cpp index 41de68eb31d3..f3f156c0e9d3 100644 --- a/xpcom/base/nsTraceRefcnt.cpp +++ b/xpcom/base/nsTraceRefcnt.cpp @@ -353,14 +353,15 @@ static void DumpSerialNumbers(const SerialHash::ConstIterator& aHashEntry, #endif if (aDumpAsStringBuffer) { - // This output will be wrong if the nsStringBuffer was used to + // This output will be wrong if the StringBuffer was used to // store a char16_t string. - auto* buffer = static_cast(aHashEntry.Key()); + auto* buffer = static_cast(aHashEntry.Key()); nsDependentCString bufferString(static_cast(buffer->Data())); - fprintf(outputFile, - "Contents of leaked nsStringBuffer with storage size %d as a " - "char*: %s\n", - buffer->StorageSize(), bufferString.get()); + fprintf( + outputFile, + "Contents of leaked mozilla::StringBuffer with storage size %d as a " + "char*: %s\n", + buffer->StorageSize(), bufferString.get()); } if (!record->allocationStack.empty()) { @@ -449,7 +450,7 @@ nsresult nsTraceRefcnt::DumpStatistics() { if (gSerialNumbers) { bool onlyLoggingStringBuffers = gTypesToLog && gTypesToLog->Count() == 1 && - gTypesToLog->Contains("nsStringBuffer"); + gTypesToLog->Contains("StringBuffer"); fprintf(gBloatLog, "\nSerial Numbers of Leaked Objects:\n"); for (auto iter = gSerialNumbers->ConstIter(); !iter.Done(); iter.Next()) { diff --git a/xpcom/ds/nsAtom.h b/xpcom/ds/nsAtom.h index aa416e81ef49..fb7108c0bbdb 100644 --- a/xpcom/ds/nsAtom.h +++ b/xpcom/ds/nsAtom.h @@ -177,7 +177,7 @@ class nsDynamicAtom : public nsAtom { return count; } - nsStringBuffer* StringBuffer() const { return mStringBuffer; } + mozilla::StringBuffer* StringBuffer() const { return mStringBuffer; } const char16_t* String() const { return reinterpret_cast(mStringBuffer->Data()); @@ -193,7 +193,7 @@ class nsDynamicAtom : public nsAtom { // These shouldn't be used directly, even by friend classes. The // Create()/Destroy() methods use them. - nsDynamicAtom(already_AddRefed, uint32_t aLength, + nsDynamicAtom(already_AddRefed, uint32_t aLength, uint32_t aHash, bool aIsAsciiLowercase); ~nsDynamicAtom() = default; @@ -201,7 +201,7 @@ class nsDynamicAtom : public nsAtom { static void Destroy(nsDynamicAtom* aAtom); mozilla::ThreadSafeAutoRefCnt mRefCnt; - RefPtr mStringBuffer; + RefPtr mStringBuffer; }; const nsStaticAtom* nsAtom::AsStatic() const { diff --git a/xpcom/ds/nsAtomTable.cpp b/xpcom/ds/nsAtomTable.cpp index 379aa647d4c2..cc77fc3fddd0 100644 --- a/xpcom/ds/nsAtomTable.cpp +++ b/xpcom/ds/nsAtomTable.cpp @@ -61,7 +61,7 @@ enum class GCKind { // replaying. Atomic nsDynamicAtom::gUnusedAtomCount; -nsDynamicAtom::nsDynamicAtom(already_AddRefed aBuffer, +nsDynamicAtom::nsDynamicAtom(already_AddRefed aBuffer, uint32_t aLength, uint32_t aHash, bool aIsAsciiLowercase) : nsAtom(aLength, /* aIsStatic = */ false, aHash, aIsAsciiLowercase), @@ -82,9 +82,9 @@ 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 = aString.GetStringBuffer(); + RefPtr buffer = aString.GetStringBuffer(); if (!buffer) { - buffer = nsStringBuffer::Create(aString.Data(), aString.Length()); + buffer = mozilla::StringBuffer::Create(aString.Data(), aString.Length()); if (MOZ_UNLIKELY(!buffer)) { MOZ_CRASH("Out of memory atomizing"); } diff --git a/xpcom/rust/nsstring/src/conversions.rs b/xpcom/rust/nsstring/src/conversions.rs index c72c195c08fb..857615e35369 100644 --- a/xpcom/rust/nsstring/src/conversions.rs +++ b/xpcom/rust/nsstring/src/conversions.rs @@ -146,9 +146,9 @@ macro_rules! constant_conversion { }; } -/// An intermediate check for avoiding a copy and having an `nsStringBuffer` -/// refcount increment instead when both `self` and `other` are `nsACString`s, -/// `other` is entirely ASCII and all old data in `self` is discarded. +/// An intermediate check for avoiding a copy and having an `StringBuffer` refcount increment +/// instead when both `self` and `other` are `nsACString`s, `other` is entirely ASCII and all old +/// data in `self` is discarded. /// /// `$name` is the name of the function to generate /// `$impl` is the underlying conversion that takes a slice and that is used diff --git a/xpcom/string/moz.build b/xpcom/string/moz.build index 1220a16bc8c2..3630658da2f5 100644 --- a/xpcom/string/moz.build +++ b/xpcom/string/moz.build @@ -18,7 +18,6 @@ EXPORTS += [ "nsPromiseFlatString.h", "nsReadableUtils.h", "nsString.h", - "nsStringBuffer.h", "nsStringFlags.h", "nsStringFwd.h", "nsStringIterator.h", @@ -42,7 +41,6 @@ EXPORTS.mozilla += [ UNIFIED_SOURCES += [ "nsASCIIMask.cpp", "nsReadableUtils.cpp", - "nsStringBuffer.cpp", "nsTDependentString.cpp", "nsTDependentSubstring.cpp", "nsTextFormatter.cpp", diff --git a/xpcom/string/nsReadableUtils.h b/xpcom/string/nsReadableUtils.h index 803c6b5d2f27..43c80f92dbd3 100644 --- a/xpcom/string/nsReadableUtils.h +++ b/xpcom/string/nsReadableUtils.h @@ -197,7 +197,7 @@ inline void LossyAppendUTF16toASCII(mozilla::Span aSource, // Latin1 to UTF-8 // Interpret each incoming unsigned byte value as a Unicode scalar value (not // windows-1252!). -// If the input is ASCII, the heap-allocated nsStringBuffer is shared if +// If the input is ASCII, the heap-allocated mozilla::StringBuffer is shared if // possible. [[nodiscard]] inline bool CopyLatin1toUTF8(const nsACString& aSource, @@ -231,7 +231,7 @@ inline void AppendLatin1toUTF8(const nsACString& aSource, nsACString& aDest) { // points above U+00FF, memory-safely produces garbage in release builds and // asserts in debug builds. The nature of the garbage may differ // based on CPU architecture and must not be relied upon. -// If the input is ASCII, the heap-allocated nsStringBuffer is shared if +// If the input is ASCII, the heap-allocated mozilla::StringBuffer is shared if // possible. [[nodiscard]] inline bool LossyCopyUTF8toLatin1(const nsACString& aSource, diff --git a/xpcom/string/nsStringBuffer.cpp b/xpcom/string/nsStringBuffer.cpp deleted file mode 100644 index fbfc91f633a6..000000000000 --- a/xpcom/string/nsStringBuffer.cpp +++ /dev/null @@ -1,70 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* vim: set ts=8 sts=2 et sw=2 tw=80: */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this file, - * You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#include "nsStringBuffer.h" - -#include "mozilla/MemoryReporting.h" -#include "mozilla/RefPtr.h" - -template -static already_AddRefed DoCreate(const CharT* aData, - size_t aLength) { - RefPtr buffer = - nsStringBuffer::Alloc((aLength + 1) * sizeof(CharT)); - if (MOZ_UNLIKELY(!buffer)) { - return nullptr; - } - auto* data = reinterpret_cast(buffer->Data()); - memcpy(data, aData, aLength * sizeof(CharT)); - data[aLength] = 0; - return buffer.forget(); -} - -already_AddRefed nsStringBuffer::Create(const char* aData, - size_t aLength) { - return DoCreate(aData, aLength); -} - -already_AddRefed nsStringBuffer::Create(const char16_t* aData, - size_t aLength) { - return DoCreate(aData, aLength); -} - -nsStringBuffer* nsStringBuffer::Realloc(nsStringBuffer* aHdr, 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"); - - // no point in trying to save ourselves if we hit this assertion - 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. - { - mozilla::detail::RefCountLogger::ReleaseLogger logger(aHdr); - logger.logRelease(0); - } - - aHdr = (nsStringBuffer*)realloc(aHdr, sizeof(nsStringBuffer) + aSize); - if (aHdr) { - mozilla::detail::RefCountLogger::logAddRef(aHdr, 1); - aHdr->mStorageSize = aSize; - } - - return aHdr; -} - -size_t nsStringBuffer::SizeOfIncludingThisIfUnshared( - mozilla::MallocSizeOf aMallocSizeOf) const { - return IsReadonly() ? 0 : aMallocSizeOf(this); -} - -size_t nsStringBuffer::SizeOfIncludingThisEvenIfShared( - mozilla::MallocSizeOf aMallocSizeOf) const { - return aMallocSizeOf(this); -} diff --git a/xpcom/string/nsTStringRepr.h b/xpcom/string/nsTStringRepr.h index 81a01fb4181c..d35a4d23d992 100644 --- a/xpcom/string/nsTStringRepr.h +++ b/xpcom/string/nsTStringRepr.h @@ -14,7 +14,7 @@ #include "mozilla/Char16.h" #include "mozilla/CheckedInt.h" #include "mozilla/fallible.h" -#include "nsStringBuffer.h" +#include "mozilla/StringBuffer.h" #include "nsStringFlags.h" #include "nsStringFwd.h" #include "nsStringIterator.h" @@ -74,9 +74,9 @@ class nsTStringLengthStorage { "nsTString's maximum length, including the trailing null, must fit " "within `int32_t`, as callers will cast to `int32_t` occasionally"); static_assert(((CheckedInt{kMax} + 1) * sizeof(T) + - sizeof(nsStringBuffer)) + sizeof(mozilla::StringBuffer)) .isValid(), - "Math required to allocate a nsStringBuffer for a " + "Math required to allocate a mozilla::StringBuffer for a " "maximum-capacity string must not overflow uint32_t"); // Implicit conversion and assignment from `size_t` which assert that the diff --git a/xpcom/string/nsTSubstring.cpp b/xpcom/string/nsTSubstring.cpp index c89b6773d6ec..0b51e024f08e 100644 --- a/xpcom/string/nsTSubstring.cpp +++ b/xpcom/string/nsTSubstring.cpp @@ -50,7 +50,7 @@ char16_t* const nsCharTraits::sEmptyBuffer = static void ReleaseData(void* aData, nsAString::DataFlags aFlags) { if (aFlags & nsAString::DataFlags::REFCOUNTED) { - nsStringBuffer::FromData(aData)->Release(); + mozilla::StringBuffer::FromData(aData)->Release(); } else if (aFlags & nsAString::DataFlags::OWNED) { // Treat this as destruction of a "StringAdopt" object for leak // tracking purposes. @@ -172,8 +172,8 @@ auto nsTSubstring::StartBulkWriteImpl(size_type aCapacity, // If |aCapacity > kMaxCapacity|, then our doubling algorithm may not be // able to allocate it. Just bail out in cases like that. We don't want // to be allocating 2GB+ strings anyway. - static_assert((sizeof(nsStringBuffer) & 0x1) == 0, - "bad size for nsStringBuffer"); + static_assert((sizeof(mozilla::StringBuffer) & 0x1) == 0, + "bad size for mozilla::StringBuffer"); if (MOZ_UNLIKELY(!this->CheckCapacity(aCapacity))) { return mozilla::Err(NS_ERROR_OUT_OF_MEMORY); } @@ -184,10 +184,10 @@ auto nsTSubstring::StartBulkWriteImpl(size_type aCapacity, // least 1.125, rounding up to the nearest MiB. const size_type slowGrowthThreshold = 8 * 1024 * 1024; - // nsStringBuffer allocates sizeof(nsStringBuffer) + passed size, and - // storageSize below wants extra 1 * sizeof(char_type). + // mozilla::StringBuffer allocates sizeof(mozilla::StringBuffer) + passed + // size, and storageSize below wants extra 1 * sizeof(char_type). const size_type neededExtraSpace = - sizeof(nsStringBuffer) / sizeof(char_type) + 1; + sizeof(mozilla::StringBuffer) / sizeof(char_type) + 1; size_type temp; if (aCapacity >= slowGrowthThreshold) { @@ -196,8 +196,8 @@ auto nsTSubstring::StartBulkWriteImpl(size_type aCapacity, temp = XPCOM_MAX(aCapacity, minNewCapacity) + neededExtraSpace; // Round up to the next multiple of MiB, but ensure the expected - // capacity doesn't include the extra space required by nsStringBuffer - // and null-termination. + // capacity doesn't include the extra space required by + // mozilla::StringBuffer and null-termination. const size_t MiB = 1 << 20; temp = (MiB * ((temp + MiB - 1) / MiB)) - neededExtraSpace; } else { @@ -222,7 +222,8 @@ auto nsTSubstring::StartBulkWriteImpl(size_type aCapacity, // Since we allocate only by powers of 2 we always fit into a full // mozjemalloc bucket, it's not useful to use realloc, which may spend // time uselessly copying too much. - nsStringBuffer* newHdr = nsStringBuffer::Alloc(storageSize).take(); + mozilla::StringBuffer* newHdr = + mozilla::StringBuffer::Alloc(storageSize).take(); if (newHdr) { newData = (char_type*)newHdr->Data(); } else if (shrinking) { @@ -336,7 +337,7 @@ typename nsTSubstring::size_type nsTSubstring::Capacity() const { size_type capacity; if (this->mDataFlags & DataFlags::REFCOUNTED) { // if the string is readonly, then we pretend that it has no capacity. - nsStringBuffer* hdr = nsStringBuffer::FromData(this->mData); + mozilla::StringBuffer* hdr = mozilla::StringBuffer::FromData(this->mData); if (hdr->IsReadonly()) { capacity = 0; } else { @@ -365,7 +366,7 @@ bool nsTSubstring::EnsureMutable(size_type aNewLen) { return true; } if ((this->mDataFlags & DataFlags::REFCOUNTED) && - !nsStringBuffer::FromData(this->mData)->IsReadonly()) { + !mozilla::StringBuffer::FromData(this->mData)->IsReadonly()) { return true; } @@ -404,9 +405,9 @@ void nsTSubstring::Assign(const char_type* aData, size_type aLength) { } template -void nsTSubstring::Assign(already_AddRefed aBuffer, +void nsTSubstring::Assign(already_AddRefed aBuffer, size_type aLength) { - nsStringBuffer* buffer = aBuffer.take(); + mozilla::StringBuffer* buffer = aBuffer.take(); auto* data = reinterpret_cast(buffer->Data()); MOZ_DIAGNOSTIC_ASSERT(data[aLength] == char_type(0), "data should be null terminated"); @@ -517,7 +518,7 @@ bool nsTSubstring::Assign(const self_type& aStr, DataFlags::TERMINATED | DataFlags::REFCOUNTED); // get an owning reference to the this->mData - nsStringBuffer::FromData(this->mData)->AddRef(); + mozilla::StringBuffer::FromData(this->mData)->AddRef(); return true; } if (aStr.mDataFlags & DataFlags::LITERAL) { @@ -1236,7 +1237,7 @@ template size_t nsTSubstring::SizeOfExcludingThisIfUnshared( mozilla::MallocSizeOf aMallocSizeOf) const { if (this->mDataFlags & DataFlags::REFCOUNTED) { - return nsStringBuffer::FromData(this->mData) + return mozilla::StringBuffer::FromData(this->mData) ->SizeOfIncludingThisIfUnshared(aMallocSizeOf); } if (this->mDataFlags & DataFlags::OWNED) { @@ -1260,7 +1261,7 @@ size_t nsTSubstring::SizeOfExcludingThisEvenIfShared( // This is identical to SizeOfExcludingThisIfUnshared except for the // DataFlags::REFCOUNTED case. if (this->mDataFlags & DataFlags::REFCOUNTED) { - return nsStringBuffer::FromData(this->mData) + return mozilla::StringBuffer::FromData(this->mData) ->SizeOfIncludingThisEvenIfShared(aMallocSizeOf); } if (this->mDataFlags & DataFlags::OWNED) { diff --git a/xpcom/string/nsTSubstring.h b/xpcom/string/nsTSubstring.h index 7459333dc0f5..5f6c5a57e0b9 100644 --- a/xpcom/string/nsTSubstring.h +++ b/xpcom/string/nsTSubstring.h @@ -18,7 +18,6 @@ #include "mozilla/Span.h" #include "mozilla/Try.h" #include "mozilla/Unused.h" -#include "nsStringBuffer.h" #include "nsTStringRepr.h" @@ -31,7 +30,6 @@ // memory checking. (Limited to avoid quadratic behavior.) const size_t kNsStringBufferMaxPoison = 16; -class nsStringBuffer; template class nsTSubstringSplitter; template @@ -283,7 +281,7 @@ class BulkWriteHandle final { template class nsTSubstring : public mozilla::detail::nsTStringRepr { friend class mozilla::BulkWriteHandle; - friend class nsStringBuffer; + friend class mozilla::StringBuffer; public: typedef nsTSubstring self_type; @@ -419,11 +417,11 @@ 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) { + void Assign(mozilla::StringBuffer* aBuffer, size_type aLength) { aBuffer->AddRef(); - Assign(already_AddRefed(aBuffer), aLength); + Assign(already_AddRefed(aBuffer), aLength); } - void NS_FASTCALL Assign(already_AddRefed aBuffer, + void NS_FASTCALL Assign(already_AddRefed aBuffer, size_type aLength); #if defined(MOZ_USE_CHAR16_WRAPPER) @@ -1155,9 +1153,9 @@ class nsTSubstring : public mozilla::detail::nsTStringRepr { * If the string uses a reference-counted buffer, this method returns a * pointer to it without incrementing the buffer's refcount. */ - nsStringBuffer* GetStringBuffer() const { + mozilla::StringBuffer* GetStringBuffer() const { if (this->mDataFlags & DataFlags::REFCOUNTED) { - return nsStringBuffer::FromData(this->mData); + return mozilla::StringBuffer::FromData(this->mData); } return nullptr; } diff --git a/xpcom/tests/gtest/TestMoveString.cpp b/xpcom/tests/gtest/TestMoveString.cpp index cdfacdbbac42..62988d341991 100644 --- a/xpcom/tests/gtest/TestMoveString.cpp +++ b/xpcom/tests/gtest/TestMoveString.cpp @@ -8,7 +8,6 @@ #include #include "nsASCIIMask.h" #include "nsString.h" -#include "nsStringBuffer.h" #include "nsReadableUtils.h" #include "nsCRTGlue.h" #include "mozilla/RefPtr.h" diff --git a/xpcom/tests/gtest/TestStrings.cpp b/xpcom/tests/gtest/TestStrings.cpp index 450befc20d8d..4d27b09aad20 100644 --- a/xpcom/tests/gtest/TestStrings.cpp +++ b/xpcom/tests/gtest/TestStrings.cpp @@ -10,7 +10,7 @@ #include "nsCharSeparatedTokenizer.h" #include "nsPrintfCString.h" #include "nsString.h" -#include "nsStringBuffer.h" +#include "mozilla/StringBuffer.h" #include "nsReadableUtils.h" #include "nsCRTGlue.h" #include "mozilla/RefPtr.h" @@ -44,6 +44,7 @@ using mozilla::Maybe; using mozilla::Nothing; using mozilla::Some; using mozilla::Span; +using mozilla::StringBuffer; #define TestExample1 \ "Sed ut perspiciatis unde omnis iste natus error sit voluptatem " \ @@ -1172,12 +1173,12 @@ TEST_F(Strings, rfindcharinset) { TEST_F(Strings, stringbuffer) { const char kData[] = "hello world"; - RefPtr buf; + RefPtr buf; - buf = nsStringBuffer::Alloc(sizeof(kData)); + buf = StringBuffer::Alloc(sizeof(kData)); EXPECT_TRUE(!!buf); - buf = nsStringBuffer::Alloc(sizeof(kData)); + buf = StringBuffer::Alloc(sizeof(kData)); EXPECT_TRUE(!!buf); char* data = (char*)buf->Data(); memcpy(data, kData, sizeof(kData)); @@ -1185,7 +1186,7 @@ TEST_F(Strings, stringbuffer) { nsCString str; str.Assign(buf, sizeof(kData) - 1); - nsStringBuffer* buf2 = str.GetStringBuffer(); + StringBuffer* buf2 = str.GetStringBuffer(); EXPECT_EQ(buf, buf2); } diff --git a/xpcom/tests/gtest/TestUTF.cpp b/xpcom/tests/gtest/TestUTF.cpp index cb574aa8553f..1173dbd6837d 100644 --- a/xpcom/tests/gtest/TestUTF.cpp +++ b/xpcom/tests/gtest/TestUTF.cpp @@ -9,7 +9,6 @@ #include #include #include "nsString.h" -#include "nsStringBuffer.h" #include "nsReadableUtils.h" #include "UTFStrings.h" #include "nsUnicharUtils.h"