зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1351303, add main thread only cache for nsIAtoms to speed up atomization, r=froydnj
--HG-- extra : rebase_source : 9c67cd71c0721329eaeaaa96a295e90abc480042
This commit is contained in:
Родитель
d5caa7c6c0
Коммит
98fff73826
|
@ -1226,7 +1226,7 @@ Element::SetAttribute(const nsAString& aName,
|
|||
nsAutoString nameToUse;
|
||||
const nsAttrName* name = InternalGetAttrNameFromQName(aName, &nameToUse);
|
||||
if (!name) {
|
||||
nsCOMPtr<nsIAtom> nameAtom = NS_Atomize(nameToUse);
|
||||
nsCOMPtr<nsIAtom> nameAtom = NS_AtomizeMainThread(nameToUse);
|
||||
if (!nameAtom) {
|
||||
aError.Throw(NS_ERROR_OUT_OF_MEMORY);
|
||||
return;
|
||||
|
@ -1308,7 +1308,7 @@ Element::GetAttributeNS(const nsAString& aNamespaceURI,
|
|||
return;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIAtom> name = NS_Atomize(aLocalName);
|
||||
nsCOMPtr<nsIAtom> name = NS_AtomizeMainThread(aLocalName);
|
||||
bool hasAttr = GetAttr(nsid, name, aReturn);
|
||||
if (!hasAttr) {
|
||||
SetDOMStringToNull(aReturn);
|
||||
|
@ -1340,7 +1340,7 @@ Element::RemoveAttributeNS(const nsAString& aNamespaceURI,
|
|||
const nsAString& aLocalName,
|
||||
ErrorResult& aError)
|
||||
{
|
||||
nsCOMPtr<nsIAtom> name = NS_Atomize(aLocalName);
|
||||
nsCOMPtr<nsIAtom> name = NS_AtomizeMainThread(aLocalName);
|
||||
int32_t nsid =
|
||||
nsContentUtils::NameSpaceManager()->GetNameSpaceID(aNamespaceURI,
|
||||
nsContentUtils::IsChromeDoc(OwnerDoc()));
|
||||
|
@ -1413,7 +1413,7 @@ Element::HasAttributeNS(const nsAString& aNamespaceURI,
|
|||
return false;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIAtom> name = NS_Atomize(aLocalName);
|
||||
nsCOMPtr<nsIAtom> name = NS_AtomizeMainThread(aLocalName);
|
||||
return HasAttr(nsid, name);
|
||||
}
|
||||
|
||||
|
|
|
@ -750,7 +750,7 @@ nsAttrValue::GetAsAtom() const
|
|||
{
|
||||
switch (Type()) {
|
||||
case eString:
|
||||
return NS_Atomize(GetStringValue());
|
||||
return NS_AtomizeMainThread(GetStringValue());
|
||||
|
||||
case eAtom:
|
||||
{
|
||||
|
@ -762,7 +762,7 @@ nsAttrValue::GetAsAtom() const
|
|||
{
|
||||
nsAutoString val;
|
||||
ToString(val);
|
||||
return NS_Atomize(val);
|
||||
return NS_AtomizeMainThread(val);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1275,7 +1275,7 @@ nsAttrValue::ParseAtomArray(const nsAString& aValue)
|
|||
++iter;
|
||||
} while (iter != end && !nsContentUtils::IsHTMLWhitespace(*iter));
|
||||
|
||||
nsCOMPtr<nsIAtom> classAtom = NS_Atomize(Substring(start, iter));
|
||||
nsCOMPtr<nsIAtom> classAtom = NS_AtomizeMainThread(Substring(start, iter));
|
||||
if (!classAtom) {
|
||||
Reset();
|
||||
return;
|
||||
|
@ -1316,7 +1316,7 @@ nsAttrValue::ParseAtomArray(const nsAString& aValue)
|
|||
++iter;
|
||||
} while (iter != end && !nsContentUtils::IsHTMLWhitespace(*iter));
|
||||
|
||||
classAtom = NS_Atomize(Substring(start, iter));
|
||||
classAtom = NS_AtomizeMainThread(Substring(start, iter));
|
||||
|
||||
if (!array->AppendElement(classAtom)) {
|
||||
Reset();
|
||||
|
@ -1767,7 +1767,7 @@ nsAttrValue::SetMiscAtomOrString(const nsAString* aValue)
|
|||
"Empty string?");
|
||||
MiscContainer* cont = GetMiscContainer();
|
||||
if (len <= NS_ATTRVALUE_MAX_STRINGLENGTH_ATOM) {
|
||||
nsCOMPtr<nsIAtom> atom = NS_Atomize(*aValue);
|
||||
nsCOMPtr<nsIAtom> atom = NS_AtomizeMainThread(*aValue);
|
||||
if (atom) {
|
||||
cont->mStringBits =
|
||||
reinterpret_cast<uintptr_t>(atom.forget().take()) | eAtomBase;
|
||||
|
|
|
@ -3079,11 +3079,11 @@ nsContentUtils::SplitQName(const nsIContent* aNamespaceResolver,
|
|||
if (*aNamespace == kNameSpaceID_Unknown)
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
*aLocalName = NS_Atomize(Substring(colon + 1, end)).take();
|
||||
*aLocalName = NS_AtomizeMainThread(Substring(colon + 1, end)).take();
|
||||
}
|
||||
else {
|
||||
*aNamespace = kNameSpaceID_None;
|
||||
*aLocalName = NS_Atomize(aQName).take();
|
||||
*aLocalName = NS_AtomizeMainThread(aQName).take();
|
||||
}
|
||||
NS_ENSURE_TRUE(aLocalName, NS_ERROR_OUT_OF_MEMORY);
|
||||
return NS_OK;
|
||||
|
@ -3108,7 +3108,8 @@ nsContentUtils::GetNodeInfoFromQName(const nsAString& aNamespaceURI,
|
|||
const char16_t* end;
|
||||
qName.EndReading(end);
|
||||
|
||||
nsCOMPtr<nsIAtom> prefix = NS_Atomize(Substring(qName.get(), colon));
|
||||
nsCOMPtr<nsIAtom> prefix =
|
||||
NS_AtomizeMainThread(Substring(qName.get(), colon));
|
||||
|
||||
rv = aNodeInfoManager->GetNodeInfo(Substring(colon + 1, end), prefix,
|
||||
nsID, aNodeType, aNodeInfo);
|
||||
|
@ -3168,7 +3169,7 @@ nsContentUtils::SplitExpatName(const char16_t *aExpatName, nsIAtom **aPrefix,
|
|||
nameStart = (uriEnd + 1);
|
||||
if (nameEnd) {
|
||||
const char16_t *prefixStart = nameEnd + 1;
|
||||
*aPrefix = NS_Atomize(Substring(prefixStart, pos)).take();
|
||||
*aPrefix = NS_AtomizeMainThread(Substring(prefixStart, pos)).take();
|
||||
}
|
||||
else {
|
||||
nameEnd = pos;
|
||||
|
@ -3181,7 +3182,7 @@ nsContentUtils::SplitExpatName(const char16_t *aExpatName, nsIAtom **aPrefix,
|
|||
nameEnd = pos;
|
||||
*aPrefix = nullptr;
|
||||
}
|
||||
*aLocalName = NS_Atomize(Substring(nameStart, nameEnd)).take();
|
||||
*aLocalName = NS_AtomizeMainThread(Substring(nameStart, nameEnd)).take();
|
||||
}
|
||||
|
||||
// static
|
||||
|
@ -4056,7 +4057,8 @@ nsContentUtils::GetEventMessageAndAtom(const nsAString& aName,
|
|||
}
|
||||
|
||||
*aEventMessage = eUnidentifiedEvent;
|
||||
nsCOMPtr<nsIAtom> atom = NS_Atomize(NS_LITERAL_STRING("on") + aName);
|
||||
nsCOMPtr<nsIAtom> atom =
|
||||
NS_AtomizeMainThread(NS_LITERAL_STRING("on") + aName);
|
||||
sUserDefinedEvents->AppendObject(atom);
|
||||
mapping.mAtom = atom;
|
||||
mapping.mMessage = eUnidentifiedEvent;
|
||||
|
@ -4089,7 +4091,7 @@ nsContentUtils::GetEventMessageAndAtomForListener(const nsAString& aName,
|
|||
if (mapping.mMaybeSpecialSVGorSMILEvent) {
|
||||
// Try the atom version so that we should get the right message for
|
||||
// SVG/SMIL.
|
||||
atom = NS_Atomize(NS_LITERAL_STRING("on") + aName);
|
||||
atom = NS_AtomizeMainThread(NS_LITERAL_STRING("on") + aName);
|
||||
msg = GetEventMessage(atom);
|
||||
} else {
|
||||
atom = mapping.mAtom;
|
||||
|
|
|
@ -358,17 +358,28 @@ static const PLDHashTableOps AtomTableOps = {
|
|||
|
||||
//----------------------------------------------------------------------
|
||||
|
||||
#define RECENTLY_USED_MAIN_THREAD_ATOM_CACHE_SIZE 31
|
||||
static nsIAtom*
|
||||
sRecentlyUsedMainThreadAtoms[RECENTLY_USED_MAIN_THREAD_ATOM_CACHE_SIZE] = {};
|
||||
|
||||
void
|
||||
DynamicAtom::GCAtomTable()
|
||||
{
|
||||
MutexAutoLock lock(*gAtomTableLock);
|
||||
GCAtomTableLocked(lock, GCKind::RegularOperation);
|
||||
if (NS_IsMainThread()) {
|
||||
MutexAutoLock lock(*gAtomTableLock);
|
||||
GCAtomTableLocked(lock, GCKind::RegularOperation);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
DynamicAtom::GCAtomTableLocked(const MutexAutoLock& aProofOfLock,
|
||||
GCKind aKind)
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
for (uint32_t i = 0; i < RECENTLY_USED_MAIN_THREAD_ATOM_CACHE_SIZE; ++i) {
|
||||
sRecentlyUsedMainThreadAtoms[i] = nullptr;
|
||||
}
|
||||
|
||||
uint32_t removedCount = 0; // Use a non-atomic temporary for cheaper increments.
|
||||
nsAutoCString nonZeroRefcountAtoms;
|
||||
uint32_t nonZeroRefcountAtomsCount = 0;
|
||||
|
@ -719,6 +730,40 @@ NS_Atomize(const nsAString& aUTF16String)
|
|||
return atom.forget();
|
||||
}
|
||||
|
||||
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) {
|
||||
uint32_t length = atom->GetLength();
|
||||
if (length == key.mLength &&
|
||||
(memcmp(atom->GetUTF16String(),
|
||||
key.mUTF16String, length * sizeof(char16_t)) == 0)) {
|
||||
retVal = atom;
|
||||
return retVal.forget();
|
||||
}
|
||||
}
|
||||
|
||||
MutexAutoLock lock(*gAtomTableLock);
|
||||
AtomTableEntry* he = static_cast<AtomTableEntry*>(gAtomTable->Add(&key));
|
||||
|
||||
if (he->mAtom) {
|
||||
retVal = he->mAtom;
|
||||
} else {
|
||||
retVal = DynamicAtom::Create(aUTF16String, hash);
|
||||
he->mAtom = retVal;
|
||||
}
|
||||
|
||||
sRecentlyUsedMainThreadAtoms[index] = retVal;
|
||||
return retVal.forget();
|
||||
}
|
||||
|
||||
nsrefcnt
|
||||
NS_GetNumberOfAtoms(void)
|
||||
{
|
||||
|
|
|
@ -125,6 +125,11 @@ extern already_AddRefed<nsIAtom> NS_Atomize(const char16_t* aUTF16String);
|
|||
*/
|
||||
extern already_AddRefed<nsIAtom> NS_Atomize(const nsAString& aUTF16String);
|
||||
|
||||
/**
|
||||
* An optimized version of the method above for the main thread.
|
||||
*/
|
||||
extern already_AddRefed<nsIAtom> NS_AtomizeMainThread(const nsAString& aUTF16String);
|
||||
|
||||
/**
|
||||
* Return a count of the total number of atoms currently
|
||||
* alive in the system.
|
||||
|
|
Загрузка…
Ссылка в новой задаче