Bug 1362338: Take a bit from the atom's length to store a tristate. r?froydnj
MozReview-Commit-ID: Elu9EioSDXk
--- a/parser/html/nsHtml5Atom.cpp
+++ b/parser/html/nsHtml5Atom.cpp
@@ -4,17 +4,17 @@
#include "nsHtml5Atom.h"
#include "nsAutoPtr.h"
#include "mozilla/Unused.h"
nsHtml5Atom::nsHtml5Atom(const nsAString& aString)
{
mLength = aString.Length();
- mIsStatic = false;
+ SetKind(AtomKind::HTML5Atom);
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
--- a/xpcom/ds/nsAtomTable.cpp
+++ b/xpcom/ds/nsAtomTable.cpp
@@ -88,17 +88,17 @@ public:
static void GCAtomTableLocked(const MutexAutoLock& aProofOfLock,
GCKind aKind);
private:
DynamicAtom(const nsAString& aString, uint32_t aHash)
: mRefCnt(1)
{
mLength = aString.Length();
- mIsStatic = false;
+ 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
@@ -166,17 +166,17 @@ UniquePtr<nsTArray<FakeBufferRefcountHel
#endif
class StaticAtom final : public nsIAtom
{
public:
StaticAtom(nsStringBuffer* aStringBuffer, uint32_t aLength, uint32_t aHash)
{
mLength = aLength;
- mIsStatic = true;
+ 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);
--- a/xpcom/ds/nsIAtom.idl
+++ b/xpcom/ds/nsIAtom.idl
@@ -32,29 +32,54 @@ interface nsIAtom : nsISupports
* Note that this will NEVER return/throw an error condition.
*/
[binaryname(ScriptableEquals)] boolean equals(in AString aString);
[noscript, notxpcom]
size_t SizeOfIncludingThis(in MallocSizeOf aMallocSizeOf);
%{C++
+ // The kind of atom we have, in order to be able to devirtualize hot stuff
+ // looking at mKind.
+ enum class AtomKind : uint8_t {
+ DynamicAtom = 0,
+ StaticAtom = 1,
+ HTML5Atom = 2,
+ };
+
// note these are NOT virtual so they won't muck with the vtable!
inline bool Equals(char16ptr_t aString, uint32_t aLength) const
{
return mLength == aLength &&
memcmp(mString, aString, mLength * sizeof(char16_t)) == 0;
}
inline bool Equals(const nsAString& aString) const {
return Equals(aString.BeginReading(), aString.Length());
}
+ inline void SetKind(AtomKind aKind) {
+ mKind = static_cast<uint32_t>(aKind);
+ MOZ_ASSERT(Kind() == aKind);
+ }
+
+ inline AtomKind Kind() const {
+ return static_cast<AtomKind>(mKind);
+ }
+
+ inline bool IsDynamicAtom() const {
+ return Kind() == AtomKind::DynamicAtom;
+ }
+
+ inline bool IsHTML5Atom() const {
+ return Kind() == AtomKind::HTML5Atom;
+ }
+
inline bool IsStaticAtom() const {
- return mIsStatic;
+ return Kind() == AtomKind::StaticAtom;
}
inline char16ptr_t GetUTF16String() const {
return mString;
}
inline uint32_t GetLength() const {
return mLength;
@@ -75,18 +100,18 @@ interface nsIAtom : nsISupports
* pointer, for use in situations that need a well-distributed
* hashcode.
*/
inline uint32_t hash() const {
return mHash;
}
protected:
- uint32_t mLength:31;
- uint32_t mIsStatic:1;
+ uint32_t mLength: 30;
+ uint32_t mKind: 2; // nsIAtom::AtomKind
uint32_t mHash;
/**
* WARNING! There is an invisible constraint on |mString|: the chars it
* points to must belong to an nsStringBuffer. This is so that the
* nsStringBuffer::FromData() calls above are valid.
*/
char16_t* mString;
%}