Bug 1392185 - Remove dynamic HTML5 atoms. r=njn,hsivonen

This is a rebase + manual refcounting on some places, + cleanup of the original
patch in the bug.

Co-authored-by: Nicholas Nethercote <nnethercote@mozilla.com>

Differential Revision: https://phabricator.services.mozilla.com/D11035
This commit is contained in:
Emilio Cobos Álvarez 2018-11-09 14:27:10 +01:00
Родитель ed9deed211
Коммит 03ce7b0699
16 изменённых файлов: 113 добавлений и 210 удалений

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

@ -5,24 +5,6 @@
#include "nsHtml5AtomTable.h"
#include "nsThreadUtils.h"
nsHtml5AtomEntry::nsHtml5AtomEntry(KeyTypePointer aStr)
: nsStringHashKey(aStr)
, mAtom(nsDynamicAtom::Create(*aStr))
{
}
nsHtml5AtomEntry::nsHtml5AtomEntry(nsHtml5AtomEntry&& aOther)
: nsStringHashKey(std::move(aOther))
, mAtom(nullptr)
{
MOZ_ASSERT_UNREACHABLE("nsHtml5AtomTable is broken; tried to copy an entry");
}
nsHtml5AtomEntry::~nsHtml5AtomEntry()
{
nsDynamicAtom::Destroy(mAtom);
}
nsHtml5AtomTable::nsHtml5AtomTable()
: mRecentlyUsedParserAtoms{}
{
@ -37,27 +19,18 @@ nsAtom*
nsHtml5AtomTable::GetAtom(const nsAString& aKey)
{
#ifdef DEBUG
{
MOZ_ASSERT(mPermittedLookupEventTarget->IsOnCurrentThread());
}
MOZ_ASSERT(mPermittedLookupEventTarget->IsOnCurrentThread());
#endif
uint32_t index = mozilla::HashString(aKey) % RECENTLY_USED_PARSER_ATOMS_SIZE;
nsAtom* cachedAtom = mRecentlyUsedParserAtoms[index];
if (cachedAtom && cachedAtom->Equals(aKey)) {
return cachedAtom;
if (nsAtom* atom = mRecentlyUsedParserAtoms[index]) {
if (atom->Equals(aKey)) {
return atom;
}
}
nsStaticAtom* atom = NS_GetStaticAtom(aKey);
if (atom) {
mRecentlyUsedParserAtoms[index] = atom;
return atom;
}
nsHtml5AtomEntry* entry = mTable.PutEntry(aKey);
if (!entry) {
return nullptr;
}
mRecentlyUsedParserAtoms[index] = entry->GetAtom();
return entry->GetAtom();
RefPtr<nsAtom> atom = NS_Atomize(aKey);
nsAtom* ret = atom.get();
mRecentlyUsedParserAtoms[index] = atom.forget();
return ret;
}

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

@ -12,18 +12,6 @@
#define RECENTLY_USED_PARSER_ATOMS_SIZE 31
class nsHtml5AtomEntry : public nsStringHashKey
{
public:
explicit nsHtml5AtomEntry(KeyTypePointer aStr);
nsHtml5AtomEntry(nsHtml5AtomEntry&& aOther);
~nsHtml5AtomEntry();
inline nsAtom* GetAtom() { return mAtom; }
private:
nsDynamicAtom* mAtom;
};
/**
* nsHtml5AtomTable provides non-locking lookup and creation of atoms for
* nsHtml5Parser or nsHtml5StreamParser.
@ -74,9 +62,9 @@ public:
nsHtml5AtomTable();
~nsHtml5AtomTable();
/**
* Obtains the atom for the given string in the scope of this atom table.
*/
// NOTE: We rely on mRecentlyUsedParserAtoms keeping alive the returned atom,
// but the caller is responsible to take a reference before calling GetAtom
// again.
nsAtom* GetAtom(const nsAString& aKey);
/**
@ -87,7 +75,6 @@ public:
for (uint32_t i = 0; i < RECENTLY_USED_PARSER_ATOMS_SIZE; ++i) {
mRecentlyUsedParserAtoms[i] = nullptr;
}
mTable.Clear();
}
#ifdef DEBUG
@ -98,8 +85,7 @@ public:
#endif
private:
nsTHashtable<nsHtml5AtomEntry> mTable;
nsAtom* mRecentlyUsedParserAtoms[RECENTLY_USED_PARSER_ATOMS_SIZE];
RefPtr<nsAtom> mRecentlyUsedParserAtoms[RECENTLY_USED_PARSER_ATOMS_SIZE];
#ifdef DEBUG
nsCOMPtr<nsISerialEventTarget> mPermittedLookupEventTarget;
#endif

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

@ -71,7 +71,7 @@ public:
if (!local->IsStatic()) {
nsAutoString str;
local->ToString(str);
local = aInterner->GetAtom(str);
nsAtom* local = aInterner->GetAtom(str);
clone.mLocals[0] = local;
clone.mLocals[1] = local;
clone.mLocals[2] = local;
@ -81,8 +81,8 @@ public:
}
private:
nsAtom* mLocals[3];
nsAtom* mPrefixes[3];
RefPtr<nsAtom> mLocals[3];
RefPtr<nsAtom> mPrefixes[3];
int32_t mUris[3];
int32_t mLine;
nsHtml5String mValue;

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

@ -58,44 +58,44 @@ int32_t* nsHtml5AttributeName::ALL_NO_NS = 0;
int32_t* nsHtml5AttributeName::XMLNS_NS = 0;
int32_t* nsHtml5AttributeName::XML_NS = 0;
int32_t* nsHtml5AttributeName::XLINK_NS = 0;
nsAtom** nsHtml5AttributeName::ALL_NO_PREFIX = 0;
nsAtom** nsHtml5AttributeName::XMLNS_PREFIX = 0;
nsAtom** nsHtml5AttributeName::XLINK_PREFIX = 0;
nsAtom** nsHtml5AttributeName::XML_PREFIX = 0;
nsAtom**
nsStaticAtom** nsHtml5AttributeName::ALL_NO_PREFIX = 0;
nsStaticAtom** nsHtml5AttributeName::XMLNS_PREFIX = 0;
nsStaticAtom** nsHtml5AttributeName::XLINK_PREFIX = 0;
nsStaticAtom** nsHtml5AttributeName::XML_PREFIX = 0;
RefPtr<nsAtom>*
nsHtml5AttributeName::SVG_DIFFERENT(nsAtom* name, nsAtom* camel)
{
nsAtom** arr = new nsAtom*[4];
RefPtr<nsAtom>* arr = new RefPtr<nsAtom>[4];
arr[0] = name;
arr[1] = name;
arr[2] = camel;
return arr;
}
nsAtom**
RefPtr<nsAtom>*
nsHtml5AttributeName::MATH_DIFFERENT(nsAtom* name, nsAtom* camel)
{
nsAtom** arr = new nsAtom*[4];
RefPtr<nsAtom>* arr = new RefPtr<nsAtom>[4];
arr[0] = name;
arr[1] = camel;
arr[2] = name;
return arr;
}
nsAtom**
RefPtr<nsAtom>*
nsHtml5AttributeName::COLONIFIED_LOCAL(nsAtom* name, nsAtom* suffix)
{
nsAtom** arr = new nsAtom*[4];
RefPtr<nsAtom>* arr = new RefPtr<nsAtom>[4];
arr[0] = name;
arr[1] = suffix;
arr[2] = suffix;
return arr;
}
nsAtom**
RefPtr<nsAtom>*
nsHtml5AttributeName::SAME_LOCAL(nsAtom* name)
{
nsAtom** arr = new nsAtom*[4];
RefPtr<nsAtom>* arr = new RefPtr<nsAtom>[4];
arr[0] = name;
arr[1] = name;
arr[2] = name;
@ -103,8 +103,8 @@ nsHtml5AttributeName::SAME_LOCAL(nsAtom* name)
}
nsHtml5AttributeName::nsHtml5AttributeName(int32_t* uri,
nsAtom** local,
nsAtom** prefix)
RefPtr<nsAtom>* local,
nsStaticAtom** prefix)
: uri(uri)
, local(local)
, prefix(prefix)
@ -148,7 +148,7 @@ nsHtml5AttributeName::getLocal(int32_t mode)
return local[mode];
}
nsAtom*
nsStaticAtom*
nsHtml5AttributeName::getPrefix(int32_t mode)
{
return prefix[mode];
@ -767,19 +767,19 @@ nsHtml5AttributeName::initializeStatics()
XLINK_NS[0] = kNameSpaceID_None;
XLINK_NS[1] = kNameSpaceID_XLink;
XLINK_NS[2] = kNameSpaceID_XLink;
ALL_NO_PREFIX = new nsAtom*[3];
ALL_NO_PREFIX = new nsStaticAtom*[3];
ALL_NO_PREFIX[0] = nullptr;
ALL_NO_PREFIX[1] = nullptr;
ALL_NO_PREFIX[2] = nullptr;
XMLNS_PREFIX = new nsAtom*[3];
XMLNS_PREFIX = new nsStaticAtom*[3];
XMLNS_PREFIX[0] = nullptr;
XMLNS_PREFIX[1] = nsGkAtoms::xmlns;
XMLNS_PREFIX[2] = nsGkAtoms::xmlns;
XLINK_PREFIX = new nsAtom*[3];
XLINK_PREFIX = new nsStaticAtom*[3];
XLINK_PREFIX[0] = nullptr;
XLINK_PREFIX[1] = nsGkAtoms::xlink;
XLINK_PREFIX[2] = nsGkAtoms::xlink;
XML_PREFIX = new nsAtom*[3];
XML_PREFIX = new nsStaticAtom*[3];
XML_PREFIX[0] = nullptr;
XML_PREFIX[1] = nsGkAtoms::xml;
XML_PREFIX[2] = nsGkAtoms::xml;

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

@ -63,16 +63,18 @@ private:
static int32_t* XML_NS;
static int32_t* XLINK_NS;
public:
static nsAtom** ALL_NO_PREFIX;
static nsStaticAtom** ALL_NO_PREFIX;
private:
static nsAtom** XMLNS_PREFIX;
static nsAtom** XLINK_PREFIX;
static nsAtom** XML_PREFIX;
static nsAtom** SVG_DIFFERENT(nsAtom* name, nsAtom* camel);
static nsAtom** MATH_DIFFERENT(nsAtom* name, nsAtom* camel);
static nsAtom** COLONIFIED_LOCAL(nsAtom* name, nsAtom* suffix);
static nsStaticAtom** XMLNS_PREFIX;
static nsStaticAtom** XLINK_PREFIX;
static nsStaticAtom** XML_PREFIX;
static RefPtr<nsAtom>* SVG_DIFFERENT(nsAtom* name, nsAtom* camel);
static RefPtr<nsAtom>* MATH_DIFFERENT(nsAtom* name, nsAtom* camel);
static RefPtr<nsAtom>* COLONIFIED_LOCAL(nsAtom* name, nsAtom* suffix);
public:
static nsAtom** SAME_LOCAL(nsAtom* name);
static RefPtr<nsAtom>* SAME_LOCAL(nsAtom* name);
inline static int32_t levelOrderBinarySearch(jArray<int32_t, int32_t> data,
int32_t key)
{
@ -154,10 +156,13 @@ public:
private:
int32_t* uri;
nsAtom** local;
nsAtom** prefix;
RefPtr<nsAtom>* local;
nsStaticAtom** prefix;
bool custom;
nsHtml5AttributeName(int32_t* uri, nsAtom** local, nsAtom** prefix);
nsHtml5AttributeName(int32_t* uri,
RefPtr<nsAtom>* local,
nsStaticAtom** prefix);
public:
nsHtml5AttributeName();
inline bool isInterned() { return !custom; }
@ -174,7 +179,7 @@ public:
~nsHtml5AttributeName();
int32_t getUri(int32_t mode);
nsAtom* getLocal(int32_t mode);
nsAtom* getPrefix(int32_t mode);
nsStaticAtom* getPrefix(int32_t mode);
bool equalsAnother(nsHtml5AttributeName* another);
static nsHtml5AttributeName* ATTR_ALT;
static nsHtml5AttributeName* ATTR_DIR;

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

@ -76,8 +76,8 @@ public:
static const int32_t OPTIONAL_END_TAG = (1 << 23);
private:
nsAtom* name;
nsAtom* camelCaseName;
RefPtr<nsAtom> name;
RefPtr<nsAtom> camelCaseName;
mozilla::dom::HTMLContentCreatorFunction htmlCreator;
mozilla::dom::SVGContentCreatorFunction svgCreator;
public:

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

@ -17,6 +17,14 @@ nsHtml5Portability::newLocalNameFromBuffer(char16_t* buf,
return interner->GetAtom(nsDependentSubstring(buf, buf + length));
}
nsAtom*
nsHtml5Portability::newLocalFromLocal(nsAtom* local,
nsHtml5AtomTable* interner)
{
// FIXME(emilio): This function should be removed.
return local;
}
static bool
ContainsWhiteSpace(mozilla::Span<char16_t> aSpan)
{
@ -86,19 +94,6 @@ nsHtml5Portability::newCharArrayFromString(nsHtml5String string)
return arr;
}
nsAtom*
nsHtml5Portability::newLocalFromLocal(nsAtom* local, nsHtml5AtomTable* interner)
{
MOZ_ASSERT(local, "Atom was null.");
MOZ_ASSERT(interner, "Atom table was null");
if (!local->IsStatic()) {
nsAutoString str;
local->ToString(str);
local = interner->GetAtom(str);
}
return local;
}
bool
nsHtml5Portability::localEqualsBuffer(nsAtom* local,
char16_t* buf,

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

@ -61,8 +61,8 @@ class nsHtml5StackNode
public:
int32_t idxInTreeBuilder;
int32_t flags;
nsAtom* name;
nsAtom* popName;
RefPtr<nsAtom> name;
RefPtr<nsAtom> popName;
int32_t ns;
nsIContentHandle* node;
nsHtml5HtmlAttributes* attributes;

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

@ -282,7 +282,7 @@ protected:
nsHtml5AttributeName* attributeName;
private:
nsHtml5AttributeName* nonInternedAttributeName;
nsAtom* doctypeName;
RefPtr<nsAtom> doctypeName;
nsHtml5String publicIdentifier;
nsHtml5String systemIdentifier;
nsHtml5HtmlAttributes* attributes;

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

@ -293,7 +293,7 @@ private:
bool scriptingEnabled;
bool needToDropLF;
bool fragment;
nsAtom* contextName;
RefPtr<nsAtom> contextName;
int32_t contextNamespace;
nsIContentHandle* contextNode;
autoJArray<int32_t, int32_t> templateModeStack;

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

@ -112,8 +112,6 @@ nsHtml5TreeBuilder::createElement(int32_t aNamespace,
"Bogus namespace.");
if (mBuilder) {
RefPtr<nsAtom> name = nsHtml5TreeOperation::Reget(aName);
nsIContent* intendedParent =
aIntendedParent ? static_cast<nsIContent*>(aIntendedParent) : nullptr;
@ -126,7 +124,7 @@ nsHtml5TreeBuilder::createElement(int32_t aNamespace,
nsIContent* elem;
if (aNamespace == kNameSpaceID_XHTML) {
elem = nsHtml5TreeOperation::CreateHTMLElement(
name,
aName,
aAttributes,
mozilla::dom::FROM_PARSER_FRAGMENT,
nodeInfoManager,
@ -134,7 +132,7 @@ nsHtml5TreeBuilder::createElement(int32_t aNamespace,
aCreator.html);
} else if (aNamespace == kNameSpaceID_SVG) {
elem = nsHtml5TreeOperation::CreateSVGElement(
name,
aName,
aAttributes,
mozilla::dom::FROM_PARSER_FRAGMENT,
nodeInfoManager,
@ -143,7 +141,7 @@ nsHtml5TreeBuilder::createElement(int32_t aNamespace,
} else {
MOZ_ASSERT(aNamespace == kNameSpaceID_MathML);
elem = nsHtml5TreeOperation::CreateMathMLElement(
name, aAttributes, nodeInfoManager, mBuilder);
aName, aAttributes, nodeInfoManager, mBuilder);
}
if (MOZ_UNLIKELY(aAttributes != tokenizer->GetAttributes() &&
aAttributes != nsHtml5HtmlAttributes::EMPTY_ATTRIBUTES)) {
@ -907,9 +905,8 @@ nsHtml5TreeBuilder::appendDoctypeToDocument(nsAtom* aName,
aPublicId.ToString(publicId);
aSystemId.ToString(systemId);
if (mBuilder) {
RefPtr<nsAtom> name = nsHtml5TreeOperation::Reget(aName);
nsresult rv = nsHtml5TreeOperation::AppendDoctypeToDocument(
name, publicId, systemId, mBuilder);
aName, publicId, systemId, mBuilder);
if (NS_FAILED(rv)) {
MarkAsBrokenAndRequestSuspensionWithBuilder(rv);
}

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

@ -102,9 +102,19 @@ nsHtml5TreeOperation::~nsHtml5TreeOperation()
case eTreeOpCreateSVGElementNetwork:
case eTreeOpCreateSVGElementNotNetwork:
case eTreeOpCreateMathMLElement:
mTwo.atom->Release();
delete mThree.attributes;
break;
case eTreeOpAddError:
if (mThree.atom) {
mThree.atom->Release();
}
if (mFour.atom) {
mFour.atom->Release();
}
break;
case eTreeOpAppendDoctypeToDocument:
mOne.atom->Release();
delete mTwo.stringPair;
break;
case eTreeOpFosterParentText:
@ -303,13 +313,9 @@ nsHtml5TreeOperation::AddAttributes(nsIContent* aNode,
int32_t len = aAttributes->getLength();
for (int32_t i = len; i > 0;) {
--i;
// prefix doesn't need regetting. it is always null or a static atom
// local name is never null
RefPtr<nsAtom> localName = Reget(aAttributes->getLocalNameNoBoundsCheck(i));
nsAtom* localName = aAttributes->getLocalNameNoBoundsCheck(i);
int32_t nsuri = aAttributes->getURINoBoundsCheck(i);
if (!node->HasAttr(nsuri, localName)) {
// prefix doesn't need regetting. it is always null or a static atom
// local name is never null
nsString value; // Not Auto, because using it to hold nsStringBuffer*
aAttributes->getValueNoBoundsCheck(i).ToString(value);
node->SetAttr(
@ -333,11 +339,8 @@ nsHtml5TreeOperation::SetHTMLElementAttributes(
if (klass) {
aElement->SetSingleClassFromParser(klass);
} else {
// prefix doesn't need regetting. it is always null or a static atom
// local name is never null
RefPtr<nsAtom> localName =
Reget(aAttributes->getLocalNameNoBoundsCheck(i));
RefPtr<nsAtom> prefix = aAttributes->getPrefixNoBoundsCheck(i);
nsAtom* localName = aAttributes->getLocalNameNoBoundsCheck(i);
nsAtom* prefix = aAttributes->getPrefixNoBoundsCheck(i);
int32_t nsuri = aAttributes->getURINoBoundsCheck(i);
nsString value; // Not Auto, because using it to hold nsStringBuffer*
@ -563,11 +566,8 @@ nsHtml5TreeOperation::CreateSVGElement(
if (klass) {
newContent->SetSingleClassFromParser(klass);
} else {
// prefix doesn't need regetting. it is always null or a static atom
// local name is never null
RefPtr<nsAtom> localName =
Reget(aAttributes->getLocalNameNoBoundsCheck(i));
RefPtr<nsAtom> prefix = aAttributes->getPrefixNoBoundsCheck(i);
nsAtom* localName = aAttributes->getLocalNameNoBoundsCheck(i);
nsAtom* prefix = aAttributes->getPrefixNoBoundsCheck(i);
int32_t nsuri = aAttributes->getURINoBoundsCheck(i);
nsString value; // Not Auto, because using it to hold nsStringBuffer*
@ -617,11 +617,8 @@ nsHtml5TreeOperation::CreateMathMLElement(nsAtom* aName,
if (klass) {
newContent->SetSingleClassFromParser(klass);
} else {
// prefix doesn't need regetting. it is always null or a static atom
// local name is never null
RefPtr<nsAtom> localName =
Reget(aAttributes->getLocalNameNoBoundsCheck(i));
RefPtr<nsAtom> prefix = aAttributes->getPrefixNoBoundsCheck(i);
nsAtom* localName = aAttributes->getLocalNameNoBoundsCheck(i);
nsAtom* prefix = aAttributes->getPrefixNoBoundsCheck(i);
int32_t nsuri = aAttributes->getURINoBoundsCheck(i);
nsString value; // Not Auto, because using it to hold nsStringBuffer*
@ -846,7 +843,7 @@ nsHtml5TreeOperation::Perform(nsHtml5TreeOpExecutor* aBuilder,
case eTreeOpCreateHTMLElementNotNetwork: {
nsIContent** target = mOne.node;
mozilla::dom::HTMLContentCreatorFunction creator = mFour.htmlCreator;
RefPtr<nsAtom> name = Reget(mTwo.atom);
nsAtom* name = mTwo.atom;
nsHtml5HtmlAttributes* attributes = mThree.attributes;
nsIContent* intendedParent = mFive.node ? *(mFive.node) : nullptr;
@ -870,7 +867,7 @@ nsHtml5TreeOperation::Perform(nsHtml5TreeOpExecutor* aBuilder,
case eTreeOpCreateSVGElementNotNetwork: {
nsIContent** target = mOne.node;
mozilla::dom::SVGContentCreatorFunction creator = mFour.svgCreator;
RefPtr<nsAtom> name = Reget(mTwo.atom);
nsAtom* name = mTwo.atom;
nsHtml5HtmlAttributes* attributes = mThree.attributes;
nsIContent* intendedParent = mFive.node ? *(mFive.node) : nullptr;
@ -892,7 +889,7 @@ nsHtml5TreeOperation::Perform(nsHtml5TreeOpExecutor* aBuilder,
}
case eTreeOpCreateMathMLElement: {
nsIContent** target = mOne.node;
RefPtr<nsAtom> name = Reget(mTwo.atom);
nsAtom* name = mTwo.atom;
nsHtml5HtmlAttributes* attributes = mThree.attributes;
nsIContent* intendedParent = mFive.node ? *(mFive.node) : nullptr;
@ -937,7 +934,7 @@ nsHtml5TreeOperation::Perform(nsHtml5TreeOpExecutor* aBuilder,
return AppendCommentToDocument(buffer, length, aBuilder);
}
case eTreeOpAppendDoctypeToDocument: {
RefPtr<nsAtom> name = Reget(mOne.atom);
nsAtom* name = mOne.atom;
nsHtml5TreeOperationStringPair* pair = mTwo.stringPair;
nsString publicId;
nsString systemId;
@ -1147,8 +1144,8 @@ nsHtml5TreeOperation::Perform(nsHtml5TreeOpExecutor* aBuilder,
case eTreeOpAddError: {
Element* element = (*(mOne.node))->AsElement();
char* msgId = mTwo.charPtr;
RefPtr<nsAtom> atom = Reget(mThree.atom);
RefPtr<nsAtom> otherAtom = Reget(mFour.atom);
nsAtom* atom = mThree.atom;
nsAtom* otherAtom = mFour.atom;
// See viewsource.css for the possible classes in addition to "error".
nsAutoString klass;
element->GetAttr(kNameSpaceID_None, nsGkAtoms::_class, klass);

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

@ -106,28 +106,6 @@ class nsHtml5TreeOperation final
using Encoding = mozilla::Encoding;
public:
/**
* Atom is used inside the parser core are either static atoms that are
* the same as Gecko-wide static atoms or they are dynamic atoms scoped by
* both thread and parser to a particular nsHtml5AtomTable. In order to
* such scoped atoms coming into contact with the rest of Gecko, atoms
* that are about to exit the parser must go through this method which
* reobtains dynamic atoms from the Gecko-global atom table.
*
* @param aAtom a potentially parser-scoped atom
* @return an nsAtom that's pointer comparable on the main thread with
* other not-parser atoms.
*/
static inline already_AddRefed<nsAtom> Reget(nsAtom* aAtom)
{
if (!aAtom || aAtom->IsStatic()) {
return dont_AddRef(aAtom);
}
nsAutoString str;
aAtom->ToString(str);
return NS_AtomizeMainThread(str);
}
static nsresult AppendTextToTextNode(const char16_t* aBuffer,
uint32_t aLength,
mozilla::dom::Text* aTextNode,
@ -370,6 +348,7 @@ public:
mFive.node = static_cast<nsIContent**>(aIntendedParent);
mOne.node = static_cast<nsIContent**>(aTarget);
mTwo.atom = aName;
aName->AddRef();
if (aAttributes == nsHtml5HtmlAttributes::EMPTY_ATTRIBUTES) {
mThree.attributes = nullptr;
} else {
@ -434,10 +413,12 @@ public:
const nsAString& aPublicId,
const nsAString& aSystemId)
{
MOZ_ASSERT(aName);
MOZ_ASSERT(mOpCode == eTreeOpUninitialized,
"Op code must be uninitialized when initializing.");
mOpCode = eTreeOpAppendDoctypeToDocument;
mOne.atom = aName;
aName->AddRef();
mTwo.stringPair = new nsHtml5TreeOperationStringPair(aPublicId, aSystemId);
}
@ -453,6 +434,12 @@ public:
mTwo.charPtr = (char*)aMsgId;
mThree.atom = aAtom;
mFour.atom = aOtherAtom;
if (aAtom) {
aAtom->AddRef();
}
if (aOtherAtom) {
aOtherAtom->AddRef();
}
}
inline void Init(nsIContentHandle* aElement,

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

@ -14,7 +14,7 @@ use gecko_bindings::bindings::Gecko_AddRefAtom;
use gecko_bindings::bindings::Gecko_Atomize;
use gecko_bindings::bindings::Gecko_Atomize16;
use gecko_bindings::bindings::Gecko_ReleaseAtom;
use gecko_bindings::structs::{nsAtom, nsAtom_AtomKind, nsDynamicAtom, nsStaticAtom};
use gecko_bindings::structs::{nsAtom, nsDynamicAtom, nsStaticAtom};
use nsstring::{nsAString, nsStr};
use precomputed_hash::PrecomputedHash;
use std::borrow::{Borrow, Cow};
@ -175,7 +175,7 @@ impl WeakAtom {
/// Returns whether this atom is static.
#[inline]
pub fn is_static(&self) -> bool {
unsafe { (*self.as_ptr()).mKind() == nsAtom_AtomKind::Static as u32 }
unsafe { (*self.as_ptr()).mIsStatic() != 0 }
}
/// Returns the length of the atom string.

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

@ -38,16 +38,6 @@ public:
void AddSizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf,
mozilla::AtomsSizes& aSizes) const;
// Dynamic HTML5 atoms are just like vanilla dynamic atoms, but we disallow
// various operations, the most important of which is AddRef/Release.
// XXX: we'd like to get rid of dynamic HTML5 atoms. See bug 1392185 for
// details.
enum class AtomKind : uint8_t {
Static = 0,
DynamicNormal = 1,
DynamicHTML5 = 2,
};
bool Equals(char16ptr_t aString, uint32_t aLength) const
{
return mLength == aLength &&
@ -59,18 +49,8 @@ public:
return Equals(aString.BeginReading(), aString.Length());
}
AtomKind Kind() const { return static_cast<AtomKind>(mKind); }
bool IsStatic() const { return Kind() == AtomKind::Static; }
bool IsDynamic() const
{
return Kind() == AtomKind::DynamicNormal ||
Kind() == AtomKind::DynamicHTML5;
}
bool IsDynamicHTML5() const
{
return Kind() == AtomKind::DynamicHTML5;
}
bool IsStatic() const { return mIsStatic; }
bool IsDynamic() const { return !IsStatic(); }
const nsStaticAtom* AsStatic() const;
const nsDynamicAtom* AsDynamic() const;
@ -93,11 +73,7 @@ public:
// rather than Hash() so we can use mozilla::BloomFilter<N, nsAtom>, because
// BloomFilter requires elements to implement a function called hash().
//
uint32_t hash() const
{
MOZ_ASSERT(!IsDynamicHTML5());
return mHash;
}
uint32_t hash() const { return mHash; }
// We can't use NS_INLINE_DECL_THREADSAFE_REFCOUNTING because the refcounting
// of this type is special.
@ -110,24 +86,23 @@ protected:
// Used by nsStaticAtom.
constexpr nsAtom(uint32_t aLength, uint32_t aHash)
: mLength(aLength)
, mKind(static_cast<uint32_t>(nsAtom::AtomKind::Static))
, mIsStatic(true)
, mHash(aHash)
{}
// Used by nsDynamicAtom.
nsAtom(AtomKind aKind, const nsAString& aString, uint32_t aHash)
nsAtom(const nsAString& aString, uint32_t aHash)
: mLength(aString.Length())
, mKind(static_cast<uint32_t>(aKind))
, mIsStatic(false)
, mHash(aHash)
{
MOZ_ASSERT(aKind == AtomKind::DynamicNormal ||
aKind == AtomKind::DynamicHTML5);
}
~nsAtom() = default;
const uint32_t mLength:30;
const uint32_t mKind:2; // nsAtom::AtomKind
// NOTE: There's one free bit here.
const uint32_t mIsStatic:1;
const uint32_t mHash;
};
@ -189,8 +164,6 @@ public:
private:
friend class nsAtomTable;
friend class nsAtomSubTable;
// XXX: we'd like to remove nsHtml5AtomEntry. See bug 1392185.
friend class nsHtml5AtomEntry;
// These shouldn't be used directly, even by friend classes. The
// Create()/Destroy() methods use them.

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

@ -67,7 +67,7 @@ enum class GCKind {
static Atomic<int32_t, ReleaseAcquire, recordreplay::Behavior::DontPreserve> gUnusedAtomCount(0);
nsDynamicAtom::nsDynamicAtom(const nsAString& aString, uint32_t aHash)
: nsAtom(AtomKind::DynamicNormal, aString, aHash)
: nsAtom(aString, aHash)
, mRefCnt(1)
{
}
@ -149,8 +149,6 @@ nsAtom::ToString(nsAString& aString) const
void
nsAtom::ToUTF8String(nsACString& aBuf) const
{
MOZ_ASSERT(!IsDynamicHTML5(),
"Called ToUTF8String() on a dynamic HTML5 atom");
CopyUTF16toUTF8(nsDependentString(GetUTF16String(), mLength), aBuf);
}
@ -158,9 +156,6 @@ void
nsAtom::AddSizeOfIncludingThis(MallocSizeOf aMallocSizeOf, AtomsSizes& aSizes)
const
{
MOZ_ASSERT(!IsDynamicHTML5(),
"Called AddSizeOfIncludingThis() on a dynamic HTML5 atom");
// Static atoms are in static memory, and so are not measured here.
if (IsDynamic()) {
aSizes.mDynamicAtoms += aMallocSizeOf(this);
@ -495,7 +490,6 @@ nsAtomSubTable::GCLocked(GCKind aKind)
}
nsAtom* atom = entry->mAtom;
MOZ_ASSERT(!atom->IsDynamicHTML5());
if (atom->IsDynamic() && atom->AsDynamic()->mRefCnt == 0) {
i.Remove();
nsDynamicAtom::Destroy(atom->AsDynamic());
@ -574,16 +568,12 @@ nsDynamicAtom::Release()
MozExternalRefCountType
nsAtom::AddRef()
{
MOZ_ASSERT(!IsDynamicHTML5(), "Attempt to AddRef a dynamic HTML5 atom");
return IsStatic() ? 2 : AsDynamic()->AddRef();
}
MozExternalRefCountType
nsAtom::Release()
{
MOZ_ASSERT(!IsDynamicHTML5(), "Attempt to Release a dynamic HTML5 atom");
return IsStatic() ? 1 : AsDynamic()->Release();
}