Bug 1362338: Make nsIAtom::AddRef and nsIAtom::Release final. r=froydnj
MozReview-Commit-ID: CFWcSNocGIm
--- a/parser/html/nsHtml5Atom.cpp
+++ b/parser/html/nsHtml5Atom.cpp
@@ -35,38 +35,24 @@ nsHtml5Atom::nsHtml5Atom(const nsAString
mozilla::Unused << buf.forget();
}
nsHtml5Atom::~nsHtml5Atom()
{
nsStringBuffer::FromData(mString)->Release();
}
-NS_IMETHODIMP_(MozExternalRefCountType)
-nsHtml5Atom::AddRef()
-{
- NS_NOTREACHED("Attempt to AddRef an nsHtml5Atom.");
- return 2;
-}
-
-NS_IMETHODIMP_(MozExternalRefCountType)
-nsHtml5Atom::Release()
-{
- NS_NOTREACHED("Attempt to Release an nsHtml5Atom.");
- return 1;
-}
-
NS_IMETHODIMP
nsHtml5Atom::QueryInterface(REFNSIID aIID, void** aInstancePtr)
{
NS_NOTREACHED("Attempt to call QueryInterface an nsHtml5Atom.");
return NS_ERROR_UNEXPECTED;
}
-NS_IMETHODIMP
+NS_IMETHODIMP
nsHtml5Atom::ScriptableToString(nsAString& aBuf)
{
NS_NOTREACHED("Should not call ScriptableToString.");
return NS_ERROR_NOT_IMPLEMENTED;
}
NS_IMETHODIMP
nsHtml5Atom::ToUTF8String(nsACString& aReturn)
--- a/parser/html/nsHtml5Atom.h
+++ b/parser/html/nsHtml5Atom.h
@@ -13,16 +13,16 @@
* nsHtml5TreeBuilder owned by one nsHtml5Parser or nsHtml5StreamParser
* instance.
*
* Usage is documented in nsHtml5AtomTable and nsIAtom.
*/
class nsHtml5Atom final : public nsIAtom
{
public:
- NS_DECL_ISUPPORTS
+ NS_IMETHOD QueryInterface(REFNSIID aIID, void** aInstancePtr) final;
NS_DECL_NSIATOM
explicit nsHtml5Atom(const nsAString& aString);
~nsHtml5Atom();
};
#endif // nsHtml5Atom_h
--- a/xpcom/ds/nsAtomTable.cpp
+++ b/xpcom/ds/nsAtomTable.cpp
@@ -123,18 +123,26 @@ private:
}
private:
// We don't need a virtual destructor because we always delete via a
// DynamicAtom* pointer (in GCAtomTable()), not an nsIAtom* pointer.
~DynamicAtom();
public:
- NS_DECL_THREADSAFE_ISUPPORTS
NS_DECL_NSIATOM
+ NS_IMETHOD QueryInterface(REFNSIID aIID, void** aInstancePtr) final;
+ typedef mozilla::TrueType HasThreadSafeRefCnt;
+
+ MozExternalRefCountType DoAddRef();
+ MozExternalRefCountType DoRelease();
+
+protected:
+ ThreadSafeAutoRefCnt mRefCnt;
+ NS_DECL_OWNINGTHREAD
};
#if defined(NS_BUILD_REFCNT_LOGGING)
// nsFakeStringBuffers don't really use the refcounting system, but we
// have to give a coherent series of addrefs and releases to the
// refcount logging system, or we'll hit assertions when running with
// XPCOM_MEM_LOG_CLASSES=nsStringBuffer.
class FakeBufferRefcountHelper
@@ -194,33 +202,21 @@ public:
aStringBuffer->StorageSize() == (mLength + 1) * sizeof(char16_t),
"correct storage");
}
// We don't need a virtual destructor because we always delete via a
// StaticAtom* pointer (in AtomTableClearEntry()), not an nsIAtom* pointer.
~StaticAtom() {}
- NS_DECL_ISUPPORTS
+ NS_IMETHOD QueryInterface(REFNSIID aIID, void** aInstancePtr) final;
NS_DECL_NSIATOM
};
-NS_IMPL_QUERY_INTERFACE(StaticAtom, nsIAtom)
-
-NS_IMETHODIMP_(MozExternalRefCountType)
-StaticAtom::AddRef()
-{
- return 2;
-}
-
-NS_IMETHODIMP_(MozExternalRefCountType)
-StaticAtom::Release()
-{
- return 1;
-}
+NS_IMPL_QUERY_INTERFACE(StaticAtom, nsIAtom);
NS_IMETHODIMP
DynamicAtom::ScriptableToString(nsAString& aBuf)
{
nsStringBuffer::FromData(mString)->ToString(mLength, aBuf);
return NS_OK;
}
@@ -274,16 +270,40 @@ StaticAtom::SizeOfIncludingThis(MallocSi
size_t n = aMallocSizeOf(this);
// Don't measure the string buffer pointed to by the StaticAtom because it's
// in static memory.
return n;
}
//----------------------------------------------------------------------
+NS_IMETHODIMP_(MozExternalRefCountType)
+nsIAtom::AddRef()
+{
+ MOZ_ASSERT(!IsHTML5Atom(), "Attempt to AddRef an nsHtml5Atom");
+ if (!IsDynamicAtom()) {
+ MOZ_ASSERT(IsStaticAtom());
+ return 2;
+ }
+ return static_cast<DynamicAtom*>(this)->DoAddRef();
+}
+
+NS_IMETHODIMP_(MozExternalRefCountType)
+nsIAtom::Release()
+{
+ MOZ_ASSERT(!IsHTML5Atom(), "Attempt to Release an nsHtml5Atom");
+ if (!IsDynamicAtom()) {
+ MOZ_ASSERT(IsStaticAtom());
+ return 1;
+ }
+ return static_cast<DynamicAtom*>(this)->DoRelease();
+}
+
+//----------------------------------------------------------------------
+
/**
* The shared hash table for atom lookups.
*
* Callers must hold gAtomTableLock before manipulating the table.
*/
static PLDHashTable* gAtomTable;
static Mutex* gAtomTableLock;
@@ -479,36 +499,36 @@ DynamicAtom::GCAtomTableLocked(const Mut
MOZ_ASSERT_IF(aKind == GCKind::Shutdown, removedCount == gUnusedAtomCount);
gUnusedAtomCount -= removedCount;
}
NS_IMPL_QUERY_INTERFACE(DynamicAtom, nsIAtom)
-NS_IMETHODIMP_(MozExternalRefCountType)
-DynamicAtom::AddRef(void)
+MozExternalRefCountType
+DynamicAtom::DoAddRef()
{
nsrefcnt count = ++mRefCnt;
if (count == 1) {
gUnusedAtomCount--;
}
return count;
}
#ifdef DEBUG
// We set a lower GC threshold for atoms in debug builds so that we exercise
// the GC machinery more often.
static const uint32_t kAtomGCThreshold = 20;
#else
static const uint32_t kAtomGCThreshold = 10000;
#endif
-NS_IMETHODIMP_(MozExternalRefCountType)
-DynamicAtom::Release(void)
+MozExternalRefCountType
+DynamicAtom::DoRelease()
{
MOZ_ASSERT(mRefCnt > 0);
nsrefcnt count = --mRefCnt;
if (count == 0) {
if (++gUnusedAtomCount >= kAtomGCThreshold) {
GCAtomTable();
}
}
--- a/xpcom/ds/nsIAtom.idl
+++ b/xpcom/ds/nsIAtom.idl
@@ -90,16 +90,19 @@ interface nsIAtom : nsISupports
nsStringBuffer::FromData(mString)->ToString(mLength, aBuf);
}
inline nsStringBuffer* GetStringBuffer() const {
// See the comment on |mString|'s declaration.
return nsStringBuffer::FromData(mString);
}
+ NS_IMETHOD_(MozExternalRefCountType) AddRef() final;
+ NS_IMETHOD_(MozExternalRefCountType) Release() final;
+
/**
* A hashcode that is better distributed than the actual atom
* pointer, for use in situations that need a well-distributed
* hashcode.
*/
inline uint32_t hash() const {
return mHash;
}