Bug 1509720 - Inline atom refcounting. r=njn

We're paying two function calls from Gecko_AddRefAtom /
Gecko_ReleaseAtom for no good reason, plus it's simple enough it's probably
worth to inline it anyway for C++ callers.

Differential Revision: https://phabricator.services.mozilla.com/D12860

--HG--
extra : moz-landing-system : lando
This commit is contained in:
Emilio Cobos Álvarez 2018-11-28 15:03:40 +00:00
Родитель aba162bbb6
Коммит b65d0757d1
2 изменённых файлов: 82 добавлений и 79 удалений

Просмотреть файл

@ -9,6 +9,7 @@
#include "nsISupportsImpl.h"
#include "nsString.h"
#include "mozilla/Atomics.h"
#include "mozilla/UniquePtr.h"
namespace mozilla {
@ -50,9 +51,9 @@ public:
bool IsStatic() const { return mIsStatic; }
bool IsDynamic() const { return !IsStatic(); }
const nsStaticAtom* AsStatic() const;
const nsDynamicAtom* AsDynamic() const;
nsDynamicAtom* AsDynamic();
inline const nsStaticAtom* AsStatic() const;
inline const nsDynamicAtom* AsDynamic() const;
inline nsDynamicAtom* AsDynamic();
char16ptr_t GetUTF16String() const;
@ -82,8 +83,8 @@ public:
// We can't use NS_INLINE_DECL_THREADSAFE_REFCOUNTING because the refcounting
// of this type is special.
MozExternalRefCountType AddRef();
MozExternalRefCountType Release();
inline MozExternalRefCountType AddRef();
inline MozExternalRefCountType Release();
typedef mozilla::TrueType HasThreadSafeRefCnt;
@ -157,8 +158,36 @@ class nsDynamicAtom : public nsAtom
public:
// We can't use NS_INLINE_DECL_THREADSAFE_REFCOUNTING because the refcounting
// of this type is special.
MozExternalRefCountType AddRef();
MozExternalRefCountType Release();
MozExternalRefCountType AddRef()
{
MOZ_ASSERT(int32_t(mRefCnt) >= 0, "illegal refcnt");
nsrefcnt count = ++mRefCnt;
if (count == 1) {
gUnusedAtomCount--;
}
return count;
}
MozExternalRefCountType Release()
{
#ifdef DEBUG
// We set a lower GC threshold for atoms in debug builds so that we exercise
// the GC machinery more often.
static const int32_t kAtomGCThreshold = 20;
#else
static const int32_t kAtomGCThreshold = 10000;
#endif
MOZ_ASSERT(int32_t(mRefCnt) > 0, "dup release");
nsrefcnt count = --mRefCnt;
if (count == 0) {
if (++gUnusedAtomCount >= kAtomGCThreshold) {
GCAtomTable();
}
}
return count;
}
const char16_t* String() const
{
@ -173,6 +202,12 @@ public:
private:
friend class nsAtomTable;
friend class nsAtomSubTable;
friend int32_t NS_GetUnusedAtomCount();
static mozilla::Atomic<int32_t,
mozilla::ReleaseAcquire,
mozilla::recordreplay::Behavior::DontPreserve> gUnusedAtomCount;
static void GCAtomTable();
// These shouldn't be used directly, even by friend classes. The
// Create()/Destroy() methods use them.
@ -187,6 +222,39 @@ private:
// The atom's chars are stored at the end of the struct.
};
const nsStaticAtom*
nsAtom::AsStatic() const
{
MOZ_ASSERT(IsStatic());
return static_cast<const nsStaticAtom*>(this);
}
const nsDynamicAtom*
nsAtom::AsDynamic() const
{
MOZ_ASSERT(IsDynamic());
return static_cast<const nsDynamicAtom*>(this);
}
nsDynamicAtom*
nsAtom::AsDynamic()
{
MOZ_ASSERT(IsDynamic());
return static_cast<nsDynamicAtom*>(this);
}
MozExternalRefCountType
nsAtom::AddRef()
{
return IsStatic() ? 2 : AsDynamic()->AddRef();
}
MozExternalRefCountType
nsAtom::Release()
{
return IsStatic() ? 1 : AsDynamic()->Release();
}
// The four forms of NS_Atomize (for use with |RefPtr<nsAtom>|) 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

Просмотреть файл

@ -64,7 +64,8 @@ enum class GCKind {
// This atomic can be accessed during the GC and other places where recorded
// events are not allowed, so its value is not preserved when recording or
// replaying.
static Atomic<int32_t, ReleaseAcquire, recordreplay::Behavior::DontPreserve> gUnusedAtomCount(0);
Atomic<int32_t, ReleaseAcquire, recordreplay::Behavior::DontPreserve>
nsDynamicAtom::gUnusedAtomCount;
nsDynamicAtom::nsDynamicAtom(const nsAString& aString, uint32_t aHash, bool aIsAsciiLowercase)
: nsAtom(aString, aHash, aIsAsciiLowercase)
@ -114,27 +115,6 @@ nsDynamicAtom::Destroy(nsDynamicAtom* aAtom)
free(aAtom);
}
const nsStaticAtom*
nsAtom::AsStatic() const
{
MOZ_ASSERT(IsStatic());
return static_cast<const nsStaticAtom*>(this);
}
const nsDynamicAtom*
nsAtom::AsDynamic() const
{
MOZ_ASSERT(IsDynamic());
return static_cast<const nsDynamicAtom*>(this);
}
nsDynamicAtom*
nsAtom::AsDynamic()
{
MOZ_ASSERT(IsDynamic());
return static_cast<nsDynamicAtom*>(this);
}
void
nsAtom::ToString(nsAString& aString) const
{
@ -450,7 +430,7 @@ void nsAtomTable::GC(GCKind aKind)
// so we won't try to resurrect a zero refcount atom while trying to delete
// it.
MOZ_ASSERT_IF(aKind == GCKind::Shutdown, gUnusedAtomCount == 0);
MOZ_ASSERT_IF(aKind == GCKind::Shutdown, nsDynamicAtom::gUnusedAtomCount == 0);
}
size_t
@ -519,11 +499,11 @@ nsAtomSubTable::GCLocked(GCKind aKind)
NS_ASSERTION(nonZeroRefcountAtomsCount == 0, msg.get());
}
gUnusedAtomCount -= removedCount;
nsDynamicAtom::gUnusedAtomCount -= removedCount;
}
static void
GCAtomTable()
void
nsDynamicAtom::GCAtomTable()
{
MOZ_ASSERT(gAtomTable);
if (NS_IsMainThread()) {
@ -531,51 +511,6 @@ GCAtomTable()
}
}
MOZ_ALWAYS_INLINE MozExternalRefCountType
nsDynamicAtom::AddRef()
{
MOZ_ASSERT(int32_t(mRefCnt) >= 0, "illegal refcnt");
nsrefcnt count = ++mRefCnt;
if (count == 1) {
gUnusedAtomCount--;
}
return count;
}
MOZ_ALWAYS_INLINE MozExternalRefCountType
nsDynamicAtom::Release()
{
#ifdef DEBUG
// We set a lower GC threshold for atoms in debug builds so that we exercise
// the GC machinery more often.
static const int32_t kAtomGCThreshold = 20;
#else
static const int32_t kAtomGCThreshold = 10000;
#endif
MOZ_ASSERT(int32_t(mRefCnt) > 0, "dup release");
nsrefcnt count = --mRefCnt;
if (count == 0) {
if (++gUnusedAtomCount >= kAtomGCThreshold) {
GCAtomTable();
}
}
return count;
}
MozExternalRefCountType
nsAtom::AddRef()
{
return IsStatic() ? 2 : AsDynamic()->AddRef();
}
MozExternalRefCountType
nsAtom::Release()
{
return IsStatic() ? 1 : AsDynamic()->Release();
}
//----------------------------------------------------------------------
// Have the static atoms been inserted into the table?
@ -792,7 +727,7 @@ NS_GetNumberOfAtoms(void)
int32_t
NS_GetUnusedAtomCount(void)
{
return gUnusedAtomCount;
return nsDynamicAtom::gUnusedAtomCount;
}
nsStaticAtom*