зеркало из https://github.com/mozilla/gecko-dev.git
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:
Родитель
ed9deed211
Коммит
03ce7b0699
|
@ -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();
|
||||
}
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче