Bug 1401873 - Expose nsAtom in nsIAtom.h. r=froydnj. draft
authorNicholas Nethercote <nnethercote@mozilla.com>
Thu, 21 Sep 2017 17:21:02 +1000
changeset 668168 94ddb8d4843f5b5a91ecb72539725b1f74ed62aa
parent 668167 a9623a347803d81761462fd7c3dd1f2552f422e1
child 668169 ab940a6b491f9df162c3a4a322135d0c3ad99cd2
push id80945
push usernnethercote@mozilla.com
push dateThu, 21 Sep 2017 07:22:53 +0000
reviewersfroydnj
bugs1401873
milestone57.0a1
Bug 1401873 - Expose nsAtom in nsIAtom.h. r=froydnj. Because it's going to be used outside of nsAtomTable.cpp in subsequent patches. MozReview-Commit-ID: KKPygeev7Wf
xpcom/ds/nsAtomTable.cpp
xpcom/ds/nsIAtom.h
--- a/xpcom/ds/nsAtomTable.cpp
+++ b/xpcom/ds/nsAtomTable.cpp
@@ -104,114 +104,89 @@ public:
 
 private:
   nsStringBuffer* mBuffer;
 };
 
 UniquePtr<nsTArray<FakeBufferRefcountHelper>> gFakeBuffers;
 #endif
 
-class nsAtom final : public nsIAtom
+// This constructor is for dynamic atoms.
+nsAtom::nsAtom(const nsAString& aString, uint32_t aHash)
+  : mRefCnt(1)
 {
-private:
-  // nsAtom constructors are private because they must be constructed in very
-  // restricted ways. The following functions are those responsible.
-  friend void RegisterStaticAtoms(const nsStaticAtom*, uint32_t);
-  friend already_AddRefed<nsIAtom> NS_Atomize(const nsACString&);
-  friend already_AddRefed<nsIAtom> NS_Atomize(const nsAString&);
-  friend already_AddRefed<nsIAtom> NS_AtomizeMainThread(const nsAString&);
-
-  // This constructor is for dynamic atoms.
-  nsAtom(const nsAString& aString, uint32_t aHash)
-    : mRefCnt(1)
-  {
-    mLength = aString.Length();
-    SetKind(AtomKind::DynamicAtom);
-    RefPtr<nsStringBuffer> buf = nsStringBuffer::FromString(aString);
-    if (buf) {
-      mString = static_cast<char16_t*>(buf->Data());
-    } else {
-      const size_t size = (mLength + 1) * sizeof(char16_t);
-      buf = nsStringBuffer::Alloc(size);
-      if (MOZ_UNLIKELY(!buf)) {
-        // We OOM because atom allocations should be small and it's hard to
-        // handle them more gracefully in a constructor.
-        NS_ABORT_OOM(size);
-      }
-      mString = static_cast<char16_t*>(buf->Data());
-      CopyUnicodeTo(aString, 0, mString, mLength);
-      mString[mLength] = char16_t(0);
+  mLength = aString.Length();
+  SetKind(AtomKind::DynamicAtom);
+  RefPtr<nsStringBuffer> buf = nsStringBuffer::FromString(aString);
+  if (buf) {
+    mString = static_cast<char16_t*>(buf->Data());
+  } else {
+    const size_t size = (mLength + 1) * sizeof(char16_t);
+    buf = nsStringBuffer::Alloc(size);
+    if (MOZ_UNLIKELY(!buf)) {
+      // We OOM because atom allocations should be small and it's hard to
+      // handle them more gracefully in a constructor.
+      NS_ABORT_OOM(size);
     }
-
-    mHash = aHash;
-    MOZ_ASSERT(mHash == HashString(mString, mLength));
-
-    NS_ASSERTION(mString[mLength] == char16_t(0), "null terminated");
-    NS_ASSERTION(buf && buf->StorageSize() >= (mLength + 1) * sizeof(char16_t),
-                 "enough storage");
-    NS_ASSERTION(Equals(aString), "correct data");
-
-    // Take ownership of buffer
-    mozilla::Unused << buf.forget();
+    mString = static_cast<char16_t*>(buf->Data());
+    CopyUnicodeTo(aString, 0, mString, mLength);
+    mString[mLength] = char16_t(0);
   }
 
-  // This constructor is for static atoms.
-  nsAtom(nsStringBuffer* aStringBuffer, uint32_t aLength, uint32_t aHash)
-  {
-    mLength = aLength;
-    SetKind(AtomKind::StaticAtom);
-    mString = static_cast<char16_t*>(aStringBuffer->Data());
+  mHash = aHash;
+  MOZ_ASSERT(mHash == HashString(mString, mLength));
+
+  NS_ASSERTION(mString[mLength] == char16_t(0), "null terminated");
+  NS_ASSERTION(buf && buf->StorageSize() >= (mLength + 1) * sizeof(char16_t),
+               "enough storage");
+  NS_ASSERTION(Equals(aString), "correct data");
+
+  // Take ownership of buffer
+  mozilla::Unused << buf.forget();
+}
+
+// This constructor is for static atoms.
+nsAtom::nsAtom(nsStringBuffer* aStringBuffer, uint32_t aLength, uint32_t aHash)
+{
+  mLength = aLength;
+  SetKind(AtomKind::StaticAtom);
+  mString = static_cast<char16_t*>(aStringBuffer->Data());
 
 #if defined(NS_BUILD_REFCNT_LOGGING)
-    MOZ_ASSERT(NS_IsMainThread());
-    if (!gFakeBuffers) {
-      gFakeBuffers = MakeUnique<nsTArray<FakeBufferRefcountHelper>>();
-    }
-    gFakeBuffers->AppendElement(aStringBuffer);
+  MOZ_ASSERT(NS_IsMainThread());
+  if (!gFakeBuffers) {
+    gFakeBuffers = MakeUnique<nsTArray<FakeBufferRefcountHelper>>();
+  }
+  gFakeBuffers->AppendElement(aStringBuffer);
 #endif
 
-    // Technically we could currently avoid doing this addref by instead making
-    // the static atom buffers have an initial refcount of 2.
-    aStringBuffer->AddRef();
+  // Technically we could currently avoid doing this addref by instead making
+  // the static atom buffers have an initial refcount of 2.
+  aStringBuffer->AddRef();
 
-    mHash = aHash;
-    MOZ_ASSERT(mHash == HashString(mString, mLength));
-
-    MOZ_ASSERT(mString[mLength] == char16_t(0), "null terminated");
-    MOZ_ASSERT(aStringBuffer &&
-               aStringBuffer->StorageSize() == (mLength + 1) * sizeof(char16_t),
-               "correct storage");
-  }
+  mHash = aHash;
+  MOZ_ASSERT(mHash == HashString(mString, mLength));
 
-public:
-  // We don't need a virtual destructor because we always delete via an nsAtom*
-  // pointer (in AtomTableClearEntry() for static atoms, and in
-  // GCAtomTableLocked() for dynamic atoms), not an nsIAtom* pointer.
-  ~nsAtom()
-  {
-    if (IsDynamicAtom()) {
-      nsStringBuffer::FromData(mString)->Release();
-    } else {
-      MOZ_ASSERT(IsStaticAtom());
-    }
-  }
+  MOZ_ASSERT(mString[mLength] == char16_t(0), "null terminated");
+  MOZ_ASSERT(aStringBuffer &&
+             aStringBuffer->StorageSize() == (mLength + 1) * sizeof(char16_t),
+             "correct storage");
+}
 
-  NS_DECL_NSIATOM
-  NS_IMETHOD QueryInterface(REFNSIID aIID, void** aInstancePtr) final;
-  typedef mozilla::TrueType HasThreadSafeRefCnt;
-
-  MozExternalRefCountType DynamicAddRef();
-  MozExternalRefCountType DynamicRelease();
-
-  bool HasRefs() { return mRefCnt > 0; }
-
-protected:
-  ThreadSafeAutoRefCnt mRefCnt;
-  NS_DECL_OWNINGTHREAD
-};
+// We don't need a virtual destructor because we always delete via an nsAtom*
+// pointer (in AtomTableClearEntry() for static atoms, and in
+// GCAtomTableLocked() for dynamic atoms), not an nsIAtom* pointer.
+nsAtom::~nsAtom()
+{
+  if (IsDynamicAtom()) {
+    nsStringBuffer::FromData(mString)->Release();
+  } else {
+    MOZ_ASSERT(IsStaticAtom());
+  }
+}
 
 NS_IMPL_QUERY_INTERFACE(nsAtom, nsIAtom);
 
 NS_IMETHODIMP
 nsAtom::ToUTF8String(nsACString& aBuf)
 {
   CopyUTF16toUTF8(nsDependentString(mString, mLength), aBuf);
   return NS_OK;
--- a/xpcom/ds/nsIAtom.h
+++ b/xpcom/ds/nsIAtom.h
@@ -12,16 +12,18 @@
 #include "nsStringBuffer.h"
 
 #define NS_IATOM_IID_STR "8b8c11d4-3ed5-4079-8974-73c7576cdb34"
 
 #define NS_IATOM_IID \
   {0x8b8c11d4, 0x3ed5, 0x4079, \
     { 0x89, 0x74, 0x73, 0xc7, 0x57, 0x6c, 0xdb, 0x34 }}
 
+struct nsStaticAtom;
+
 class nsIAtom : public nsISupports
 {
 public:
   NS_DECLARE_STATIC_IID_ACCESSOR(NS_IATOM_IID)
 
   NS_IMETHOD ToUTF8String(nsACString& aString) = 0;
 
   NS_IMETHOD_(size_t)
@@ -92,16 +94,45 @@ protected:
 };
 
 NS_DEFINE_STATIC_IID_ACCESSOR(nsIAtom, NS_IATOM_IID)
 
 #define NS_DECL_NSIATOM \
   NS_IMETHOD ToUTF8String(nsACString& _retval) override; \
   NS_IMETHOD_(size_t) SizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf) override;
 
+class nsAtom final : public nsIAtom
+{
+public:
+  ~nsAtom();
+
+  NS_DECL_NSIATOM
+  NS_IMETHOD QueryInterface(REFNSIID aIID, void** aInstancePtr) final;
+  typedef mozilla::TrueType HasThreadSafeRefCnt;
+
+  MozExternalRefCountType DynamicAddRef();
+  MozExternalRefCountType DynamicRelease();
+
+  bool HasRefs() { return mRefCnt > 0; }
+
+private:
+  // nsAtom constructors are private because they must be constructed in very
+  // restricted ways. The following functions are those responsible.
+  friend void RegisterStaticAtoms(const nsStaticAtom*, uint32_t);
+  friend already_AddRefed<nsIAtom> NS_Atomize(const nsACString&);
+  friend already_AddRefed<nsIAtom> NS_Atomize(const nsAString&);
+  friend already_AddRefed<nsIAtom> NS_AtomizeMainThread(const nsAString&);
+
+  nsAtom(const nsAString& aString, uint32_t aHash);
+  nsAtom(nsStringBuffer* aStringBuffer, uint32_t aLength, uint32_t aHash);
+
+  mozilla::ThreadSafeAutoRefCnt mRefCnt;
+  NS_DECL_OWNINGTHREAD
+};
+
 // The four forms of NS_Atomize (for use with |nsCOMPtr<nsIAtom>|) return the
 // atom for the string given. At any given time there will always be one atom
 // representing a given string. Atoms are intended to make string comparison
 // cheaper by simplifying it to pointer equality. A pointer to the atom that
 // does not own a reference is not guaranteed to be valid.
 
 // Find an atom that matches the given UTF-8 string. The string is assumed to
 // be zero terminated. Never returns null.