This commit is contained in:
Cameron Kaiser 2017-05-17 21:30:02 -07:00
parent aa6b13c599
commit f7badd24e2
6 changed files with 64 additions and 17 deletions

View File

@ -1197,10 +1197,10 @@ Element::SetAttribute(const nsAString& aName,
if (IsHTMLElement() && IsInHTMLDocument()) { if (IsHTMLElement() && IsInHTMLDocument()) {
nsAutoString lower; nsAutoString lower;
nsContentUtils::ASCIIToLower(aName, lower); nsContentUtils::ASCIIToLower(aName, lower);
nameAtom = do_GetAtom(lower); nameAtom = NS_AtomizeMainThread(lower);
} }
else { else {
nameAtom = do_GetAtom(aName); nameAtom = NS_AtomizeMainThread(aName);
} }
if (!nameAtom) { if (!nameAtom) {
aError.Throw(NS_ERROR_OUT_OF_MEMORY); aError.Throw(NS_ERROR_OUT_OF_MEMORY);
@ -1282,7 +1282,7 @@ Element::GetAttributeNS(const nsAString& aNamespaceURI,
return; return;
} }
nsCOMPtr<nsIAtom> name = do_GetAtom(aLocalName); nsCOMPtr<nsIAtom> name = NS_AtomizeMainThread(aLocalName);
bool hasAttr = GetAttr(nsid, name, aReturn); bool hasAttr = GetAttr(nsid, name, aReturn);
if (!hasAttr) { if (!hasAttr) {
SetDOMStringToNull(aReturn); SetDOMStringToNull(aReturn);
@ -1314,7 +1314,7 @@ Element::RemoveAttributeNS(const nsAString& aNamespaceURI,
const nsAString& aLocalName, const nsAString& aLocalName,
ErrorResult& aError) ErrorResult& aError)
{ {
nsCOMPtr<nsIAtom> name = do_GetAtom(aLocalName); nsCOMPtr<nsIAtom> name = NS_AtomizeMainThread(aLocalName);
int32_t nsid = int32_t nsid =
nsContentUtils::NameSpaceManager()->GetNameSpaceID(aNamespaceURI); nsContentUtils::NameSpaceManager()->GetNameSpaceID(aNamespaceURI);
@ -1400,7 +1400,7 @@ Element::HasAttributeNS(const nsAString& aNamespaceURI,
return false; return false;
} }
nsCOMPtr<nsIAtom> name = do_GetAtom(aLocalName); nsCOMPtr<nsIAtom> name = NS_AtomizeMainThread(aLocalName);
return HasAttr(nsid, name); return HasAttr(nsid, name);
} }

View File

@ -735,7 +735,7 @@ nsAttrValue::GetAsAtom() const
{ {
switch (Type()) { switch (Type()) {
case eString: case eString:
return do_GetAtom(GetStringValue()); return NS_AtomizeMainThread(GetStringValue());
case eAtom: case eAtom:
{ {
@ -747,7 +747,7 @@ nsAttrValue::GetAsAtom() const
{ {
nsAutoString val; nsAutoString val;
ToString(val); ToString(val);
return do_GetAtom(val); return NS_AtomizeMainThread(val);
} }
} }
} }
@ -1260,7 +1260,7 @@ nsAttrValue::ParseAtomArray(const nsAString& aValue)
++iter; ++iter;
} while (iter != end && !nsContentUtils::IsHTMLWhitespace(*iter)); } while (iter != end && !nsContentUtils::IsHTMLWhitespace(*iter));
nsCOMPtr<nsIAtom> classAtom = do_GetAtom(Substring(start, iter)); nsCOMPtr<nsIAtom> classAtom = NS_AtomizeMainThread(Substring(start, iter));
if (!classAtom) { if (!classAtom) {
Reset(); Reset();
return; return;
@ -1301,7 +1301,7 @@ nsAttrValue::ParseAtomArray(const nsAString& aValue)
++iter; ++iter;
} while (iter != end && !nsContentUtils::IsHTMLWhitespace(*iter)); } while (iter != end && !nsContentUtils::IsHTMLWhitespace(*iter));
classAtom = do_GetAtom(Substring(start, iter)); classAtom = NS_AtomizeMainThread(Substring(start, iter));
if (!array->AppendElement(classAtom)) { if (!array->AppendElement(classAtom)) {
Reset(); Reset();
@ -1718,7 +1718,7 @@ nsAttrValue::SetMiscAtomOrString(const nsAString* aValue)
"Empty string?"); "Empty string?");
MiscContainer* cont = GetMiscContainer(); MiscContainer* cont = GetMiscContainer();
if (len <= NS_ATTRVALUE_MAX_STRINGLENGTH_ATOM) { if (len <= NS_ATTRVALUE_MAX_STRINGLENGTH_ATOM) {
nsCOMPtr<nsIAtom> atom = NS_NewAtom(*aValue); nsCOMPtr<nsIAtom> atom = NS_AtomizeMainThread(*aValue);
if (atom) { if (atom) {
cont->mStringBits = cont->mStringBits =
reinterpret_cast<uintptr_t>(atom.forget().take()) | eAtomBase; reinterpret_cast<uintptr_t>(atom.forget().take()) | eAtomBase;

View File

@ -2850,11 +2850,11 @@ nsContentUtils::SplitQName(const nsIContent* aNamespaceResolver,
if (*aNamespace == kNameSpaceID_Unknown) if (*aNamespace == kNameSpaceID_Unknown)
return NS_ERROR_FAILURE; return NS_ERROR_FAILURE;
*aLocalName = NS_NewAtom(Substring(colon + 1, end)).take(); *aLocalName = NS_AtomizeMainThread(Substring(colon + 1, end)).take();
} }
else { else {
*aNamespace = kNameSpaceID_None; *aNamespace = kNameSpaceID_None;
*aLocalName = NS_NewAtom(aQName).take(); *aLocalName = NS_AtomizeMainThread(aQName).take();
} }
NS_ENSURE_TRUE(aLocalName, NS_ERROR_OUT_OF_MEMORY); NS_ENSURE_TRUE(aLocalName, NS_ERROR_OUT_OF_MEMORY);
return NS_OK; return NS_OK;
@ -2879,7 +2879,7 @@ nsContentUtils::GetNodeInfoFromQName(const nsAString& aNamespaceURI,
const char16_t* end; const char16_t* end;
qName.EndReading(end); qName.EndReading(end);
nsCOMPtr<nsIAtom> prefix = do_GetAtom(Substring(qName.get(), colon)); nsCOMPtr<nsIAtom> prefix = NS_AtomizeMainThread(Substring(qName.get(), colon));
rv = aNodeInfoManager->GetNodeInfo(Substring(colon + 1, end), prefix, rv = aNodeInfoManager->GetNodeInfo(Substring(colon + 1, end), prefix,
nsID, aNodeType, aNodeInfo); nsID, aNodeType, aNodeInfo);
@ -2939,7 +2939,7 @@ nsContentUtils::SplitExpatName(const char16_t *aExpatName, nsIAtom **aPrefix,
nameStart = (uriEnd + 1); nameStart = (uriEnd + 1);
if (nameEnd) { if (nameEnd) {
const char16_t *prefixStart = nameEnd + 1; const char16_t *prefixStart = nameEnd + 1;
*aPrefix = NS_NewAtom(Substring(prefixStart, pos)).take(); *aPrefix = NS_AtomizeMainThread(Substring(prefixStart, pos)).take();
} }
else { else {
nameEnd = pos; nameEnd = pos;
@ -2952,7 +2952,7 @@ nsContentUtils::SplitExpatName(const char16_t *aExpatName, nsIAtom **aPrefix,
nameEnd = pos; nameEnd = pos;
*aPrefix = nullptr; *aPrefix = nullptr;
} }
*aLocalName = NS_NewAtom(Substring(nameStart, nameEnd)).take(); *aLocalName = NS_AtomizeMainThread(Substring(nameStart, nameEnd)).take();
} }
// static // static
@ -3708,7 +3708,7 @@ nsContentUtils::GetEventMessageAndAtom(const nsAString& aName,
} }
*aEventMessage = eUnidentifiedEvent; *aEventMessage = eUnidentifiedEvent;
nsCOMPtr<nsIAtom> atom = do_GetAtom(NS_LITERAL_STRING("on") + aName); nsCOMPtr<nsIAtom> atom = NS_AtomizeMainThread(NS_LITERAL_STRING("on") + aName);
sUserDefinedEvents->AppendObject(atom); sUserDefinedEvents->AppendObject(atom);
mapping.mAtom = atom; mapping.mAtom = atom;
mapping.mMessage = eUnidentifiedEvent; mapping.mMessage = eUnidentifiedEvent;

View File

@ -110,7 +110,7 @@ class nsHtml5TreeOperation {
} }
nsAutoString str; nsAutoString str;
aAtom->ToString(str); aAtom->ToString(str);
return do_GetAtom(str); return NS_AtomizeMainThread(str);
} }
static nsresult AppendTextToTextNode(const char16_t* aBuffer, static nsresult AppendTextToTextNode(const char16_t* aBuffer,

View File

@ -298,6 +298,9 @@ static const PLDHashTableOps AtomTableOps = {
AtomTableInitEntry AtomTableInitEntry
}; };
#define RECENTLY_USED_MAIN_THREAD_ATOM_CACHE_SIZE 31
static nsIAtom*
sRecentlyUsedMainThreadAtoms[RECENTLY_USED_MAIN_THREAD_ATOM_CACHE_SIZE] = {};
static inline static inline
void void
@ -651,6 +654,8 @@ NS_NewAtom(const char16_t* aUTF16String)
return NS_NewAtom(nsDependentString(aUTF16String)); return NS_NewAtom(nsDependentString(aUTF16String));
} }
// Equivalent to current NS_Atomize and called by NS_AtomizeMainThread.
// Left as such for legacy callers in our older 45-era codebase.
already_AddRefed<nsIAtom> already_AddRefed<nsIAtom>
NS_NewAtom(const nsAString& aUTF16String) NS_NewAtom(const nsAString& aUTF16String)
{ {
@ -671,6 +676,43 @@ NS_NewAtom(const nsAString& aUTF16String)
return atom.forget(); return atom.forget();
} }
// From bug 1351303, modified for Mozilla 45.
already_AddRefed<nsIAtom>
NS_AtomizeMainThread(const nsAString& aUTF16String)
{
MOZ_ASSERT(NS_IsMainThread());
nsCOMPtr<nsIAtom> retVal;
uint32_t hash;
AtomTableKey key(aUTF16String.Data(), aUTF16String.Length(), &hash);
uint32_t index = hash % RECENTLY_USED_MAIN_THREAD_ATOM_CACHE_SIZE;
nsIAtom* atom = sRecentlyUsedMainThreadAtoms[index];
if (atom) {
// This isn't ideal, but covers for the collision case, I guess.
// The atom names shouldn't be very long in any event.
uint32_t length = atom->GetLength();
if (length == key.mLength &&
(memcmp(atom->GetUTF16String(),
key.mUTF16String, length * sizeof(char16_t)) == 0)) {
retVal = atom;
return retVal.forget();
}
}
// Inline relevant parts of GetAtomHashEntry.
AtomTableEntry* he = static_cast<AtomTableEntry*>(gAtomTable->Add(&key));
if (he->mAtom) {
retVal = he->mAtom;
} else {
RefPtr<AtomImpl> atom = new AtomImpl(aUTF16String, hash);
he->mAtom = atom;
retVal = he->mAtom; // XXX?
}
sRecentlyUsedMainThreadAtoms[index] = retVal;
return retVal.forget();
}
nsIAtom* nsIAtom*
NS_NewPermanentAtom(const nsAString& aUTF16String) NS_NewPermanentAtom(const nsAString& aUTF16String)
{ {

View File

@ -127,6 +127,11 @@ extern nsIAtom* NS_NewPermanentAtom(const nsAString& aUTF16String);
inline already_AddRefed<nsIAtom> do_GetAtom(const nsAString& aUTF16String) inline already_AddRefed<nsIAtom> do_GetAtom(const nsAString& aUTF16String)
{ return NS_NewAtom(aUTF16String); } { return NS_NewAtom(aUTF16String); }
/**
* An optimized version of the method above for the main thread (bug 1351303).
*/
extern already_AddRefed<nsIAtom> NS_AtomizeMainThread(const nsAString& aUTF16String);
/** /**
* Return a count of the total number of atoms currently * Return a count of the total number of atoms currently
* alive in the system. * alive in the system.