From 11ce2e06e83529b73e833db5542b3e656b0babf3 Mon Sep 17 00:00:00 2001 From: Roy Tam Date: Wed, 22 May 2019 21:02:27 +0800 Subject: [PATCH] ported changes from mozilla upstream: bug1351303, bug1352235, bug1371508, bug1430268, bug1352734 --- dom/base/Element.cpp | 8 ++-- dom/base/nsAttrValue.cpp | 10 ++--- dom/base/nsContentUtils.cpp | 16 ++++---- dom/base/nsNodeInfoManager.cpp | 31 ++++++++++++++- dom/base/nsNodeInfoManager.h | 3 ++ layout/base/nsDisplayList.cpp | 4 ++ parser/html/nsHtml5Portability.cpp | 2 +- parser/html/nsHtml5TreeOperation.h | 2 +- security/manager/ssl/nsNSSIOLayer.cpp | 6 +++ xpcom/ds/nsAtomTable.cpp | 57 ++++++++++++++++++++++----- xpcom/ds/nsIAtom.idl | 15 ++++++- 11 files changed, 123 insertions(+), 31 deletions(-) diff --git a/dom/base/Element.cpp b/dom/base/Element.cpp index 5c3277e841..80f78051db 100644 --- a/dom/base/Element.cpp +++ b/dom/base/Element.cpp @@ -1316,7 +1316,7 @@ Element::SetAttribute(const nsAString& aName, nsAutoString nameToUse; const nsAttrName* name = InternalGetAttrNameFromQName(aName, &nameToUse); if (!name) { - nsCOMPtr nameAtom = NS_Atomize(nameToUse); + nsCOMPtr nameAtom = NS_AtomizeMainThread(nameToUse); if (!nameAtom) { aError.Throw(NS_ERROR_OUT_OF_MEMORY); return; @@ -1398,7 +1398,7 @@ Element::GetAttributeNS(const nsAString& aNamespaceURI, return; } - nsCOMPtr name = NS_Atomize(aLocalName); + nsCOMPtr name = NS_AtomizeMainThread(aLocalName); bool hasAttr = GetAttr(nsid, name, aReturn); if (!hasAttr) { SetDOMStringToNull(aReturn); @@ -1430,7 +1430,7 @@ Element::RemoveAttributeNS(const nsAString& aNamespaceURI, const nsAString& aLocalName, ErrorResult& aError) { - nsCOMPtr name = NS_Atomize(aLocalName); + nsCOMPtr name = NS_AtomizeMainThread(aLocalName); int32_t nsid = nsContentUtils::NameSpaceManager()->GetNameSpaceID(aNamespaceURI, nsContentUtils::IsChromeDoc(OwnerDoc())); @@ -1518,7 +1518,7 @@ Element::HasAttributeNS(const nsAString& aNamespaceURI, return false; } - nsCOMPtr name = NS_Atomize(aLocalName); + nsCOMPtr name = NS_AtomizeMainThread(aLocalName); return HasAttr(nsid, name); } diff --git a/dom/base/nsAttrValue.cpp b/dom/base/nsAttrValue.cpp index 8eb1aaf974..ebddcb7edf 100644 --- a/dom/base/nsAttrValue.cpp +++ b/dom/base/nsAttrValue.cpp @@ -742,7 +742,7 @@ nsAttrValue::GetAsAtom() const { switch (Type()) { case eString: - return NS_Atomize(GetStringValue()); + return NS_AtomizeMainThread(GetStringValue()); case eAtom: { @@ -754,7 +754,7 @@ nsAttrValue::GetAsAtom() const { nsAutoString val; ToString(val); - return NS_Atomize(val); + return NS_AtomizeMainThread(val); } } } @@ -1267,7 +1267,7 @@ nsAttrValue::ParseAtomArray(const nsAString& aValue) ++iter; } while (iter != end && !nsContentUtils::IsHTMLWhitespace(*iter)); - nsCOMPtr classAtom = NS_Atomize(Substring(start, iter)); + nsCOMPtr classAtom = NS_AtomizeMainThread(Substring(start, iter)); if (!classAtom) { Reset(); return; @@ -1308,7 +1308,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(); @@ -1757,7 +1757,7 @@ nsAttrValue::SetMiscAtomOrString(const nsAString* aValue) "Empty string?"); MiscContainer* cont = GetMiscContainer(); if (len <= NS_ATTRVALUE_MAX_STRINGLENGTH_ATOM) { - nsCOMPtr atom = NS_Atomize(*aValue); + nsCOMPtr atom = NS_AtomizeMainThread(*aValue); if (atom) { cont->mStringBits = reinterpret_cast(atom.forget().take()) | eAtomBase; diff --git a/dom/base/nsContentUtils.cpp b/dom/base/nsContentUtils.cpp index 3696195ddb..1f9c179472 100644 --- a/dom/base/nsContentUtils.cpp +++ b/dom/base/nsContentUtils.cpp @@ -2947,11 +2947,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; @@ -2976,7 +2976,8 @@ nsContentUtils::GetNodeInfoFromQName(const nsAString& aNamespaceURI, const char16_t* end; qName.EndReading(end); - nsCOMPtr prefix = NS_Atomize(Substring(qName.get(), colon)); + nsCOMPtr prefix = + NS_AtomizeMainThread(Substring(qName.get(), colon)); rv = aNodeInfoManager->GetNodeInfo(Substring(colon + 1, end), prefix, nsID, aNodeType, aNodeInfo); @@ -3036,7 +3037,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; @@ -3049,7 +3050,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 @@ -3887,7 +3888,8 @@ nsContentUtils::GetEventMessageAndAtom(const nsAString& aName, } *aEventMessage = eUnidentifiedEvent; - nsCOMPtr atom = NS_Atomize(NS_LITERAL_STRING("on") + aName); + nsCOMPtr atom = + NS_AtomizeMainThread(NS_LITERAL_STRING("on") + aName); sUserDefinedEvents->AppendObject(atom); mapping.mAtom = atom; mapping.mMessage = eUnidentifiedEvent; @@ -3920,7 +3922,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; diff --git a/dom/base/nsNodeInfoManager.cpp b/dom/base/nsNodeInfoManager.cpp index 80f0aa786b..9a4765a4e6 100644 --- a/dom/base/nsNodeInfoManager.cpp +++ b/dom/base/nsNodeInfoManager.cpp @@ -112,7 +112,8 @@ nsNodeInfoManager::nsNodeInfoManager() mNonDocumentNodeInfos(0), mTextNodeInfo(nullptr), mCommentNodeInfo(nullptr), - mDocumentNodeInfo(nullptr) + mDocumentNodeInfo(nullptr), + mRecentlyUsedNodeInfos{} { nsLayoutStatics::AddRef(); @@ -232,11 +233,19 @@ nsNodeInfoManager::GetNodeInfo(nsIAtom *aName, nsIAtom *aPrefix, NodeInfo::NodeInfoInner tmpKey(aName, aPrefix, aNamespaceID, aNodeType, aExtraName); + uint32_t index = + GetNodeInfoInnerHashValue(&tmpKey) % RECENTLY_USED_NODEINFOS_SIZE; + NodeInfo* ni = mRecentlyUsedNodeInfos[index]; + if (ni && NodeInfoInnerKeyCompare(&(ni->mInner), &tmpKey)) { + RefPtr nodeInfo = ni; + return nodeInfo.forget(); + } + void *node = PL_HashTableLookup(mNodeInfoHash, &tmpKey); if (node) { RefPtr nodeInfo = static_cast(node); - + mRecentlyUsedNodeInfos[index] = nodeInfo; return nodeInfo.forget(); } @@ -254,6 +263,7 @@ nsNodeInfoManager::GetNodeInfo(nsIAtom *aName, nsIAtom *aPrefix, NS_IF_ADDREF(mDocument); } + mRecentlyUsedNodeInfos[index] = newNodeInfo; return newNodeInfo.forget(); } @@ -272,10 +282,20 @@ nsNodeInfoManager::GetNodeInfo(const nsAString& aName, nsIAtom *aPrefix, NodeInfo::NodeInfoInner tmpKey(aName, aPrefix, aNamespaceID, aNodeType); + uint32_t index = + GetNodeInfoInnerHashValue(&tmpKey) % RECENTLY_USED_NODEINFOS_SIZE; + NodeInfo* ni = mRecentlyUsedNodeInfos[index]; + if (ni && NodeInfoInnerKeyCompare(&(ni->mInner), &tmpKey)) { + RefPtr nodeInfo = ni; + nodeInfo.forget(aNodeInfo); + return NS_OK; + } + void *node = PL_HashTableLookup(mNodeInfoHash, &tmpKey); if (node) { RefPtr nodeInfo = static_cast(node); + mRecentlyUsedNodeInfos[index] = nodeInfo; nodeInfo.forget(aNodeInfo); return NS_OK; @@ -297,6 +317,7 @@ nsNodeInfoManager::GetNodeInfo(const nsAString& aName, nsIAtom *aPrefix, NS_IF_ADDREF(mDocument); } + mRecentlyUsedNodeInfos[index] = newNodeInfo; newNodeInfo.forget(aNodeInfo); return NS_OK; @@ -421,6 +442,12 @@ nsNodeInfoManager::RemoveNodeInfo(NodeInfo *aNodeInfo) } } + uint32_t index = + GetNodeInfoInnerHashValue(&aNodeInfo->mInner) % RECENTLY_USED_NODEINFOS_SIZE; + if (mRecentlyUsedNodeInfos[index] == aNodeInfo) { + mRecentlyUsedNodeInfos[index] = nullptr; + } + #ifdef DEBUG bool ret = #endif diff --git a/dom/base/nsNodeInfoManager.h b/dom/base/nsNodeInfoManager.h index 6ece66577d..759dd391eb 100644 --- a/dom/base/nsNodeInfoManager.h +++ b/dom/base/nsNodeInfoManager.h @@ -32,6 +32,8 @@ class NodeInfo; } // namespace dom } // namespace mozilla +#define RECENTLY_USED_NODEINFOS_SIZE 31 + class nsNodeInfoManager final { private: @@ -137,6 +139,7 @@ private: mozilla::dom::NodeInfo * MOZ_NON_OWNING_REF mCommentNodeInfo; // WEAK to avoid circular ownership mozilla::dom::NodeInfo * MOZ_NON_OWNING_REF mDocumentNodeInfo; // WEAK to avoid circular ownership RefPtr mBindingManager; + mozilla::dom::NodeInfo* mRecentlyUsedNodeInfos[RECENTLY_USED_NODEINFOS_SIZE]; }; #endif /* nsNodeInfoManager_h___ */ diff --git a/layout/base/nsDisplayList.cpp b/layout/base/nsDisplayList.cpp index c830891a50..a55ec1e393 100644 --- a/layout/base/nsDisplayList.cpp +++ b/layout/base/nsDisplayList.cpp @@ -3808,12 +3808,14 @@ nsDisplayLayerEventRegions::AddFrame(nsDisplayListBuilder* aBuilder, // region on scrollbar frames that won't be placed in their own layer. See // bug 1213324 for details. mDispatchToContentHitRegion.Or(mDispatchToContentHitRegion, borderBox); + mDispatchToContentHitRegion.SimplifyOutward(8); } else if (aFrame->GetType() == nsGkAtoms::objectFrame) { // If the frame is a plugin frame and wants to handle wheel events as // default action, we should add the frame to dispatch-to-content region. nsPluginFrame* pluginFrame = do_QueryFrame(aFrame); if (pluginFrame && pluginFrame->WantsToHandleWheelEventAsDefaultAction()) { mDispatchToContentHitRegion.Or(mDispatchToContentHitRegion, borderBox); + mDispatchToContentHitRegion.SimplifyOutward(8); } } @@ -3850,6 +3852,7 @@ nsDisplayLayerEventRegions::AddFrame(nsDisplayListBuilder* aBuilder, } if (alreadyHadRegions) { mDispatchToContentHitRegion.OrWith(CombinedTouchActionRegion()); + mDispatchToContentHitRegion.SimplifyOutward(8); } } } @@ -3859,6 +3862,7 @@ nsDisplayLayerEventRegions::AddInactiveScrollPort(const nsRect& aRect) { mHitRegion.Or(mHitRegion, aRect); mDispatchToContentHitRegion.Or(mDispatchToContentHitRegion, aRect); + mDispatchToContentHitRegion.SimplifyOutward(8); } bool diff --git a/parser/html/nsHtml5Portability.cpp b/parser/html/nsHtml5Portability.cpp index 36c7e758a2..0a7c6f845e 100644 --- a/parser/html/nsHtml5Portability.cpp +++ b/parser/html/nsHtml5Portability.cpp @@ -91,7 +91,7 @@ nsHtml5Portability::releaseString(nsString* str) bool nsHtml5Portability::localEqualsBuffer(nsIAtom* local, char16_t* buf, int32_t offset, int32_t length) { - return local->Equals(nsDependentSubstring(buf + offset, buf + offset + length)); + return local->Equals(buf + offset, length); } bool diff --git a/parser/html/nsHtml5TreeOperation.h b/parser/html/nsHtml5TreeOperation.h index 0b2970738e..a93f44c46f 100644 --- a/parser/html/nsHtml5TreeOperation.h +++ b/parser/html/nsHtml5TreeOperation.h @@ -108,7 +108,7 @@ class nsHtml5TreeOperation { } nsAutoString str; aAtom->ToString(str); - return NS_Atomize(str); + return NS_AtomizeMainThread(str); } static nsresult AppendTextToTextNode(const char16_t* aBuffer, diff --git a/security/manager/ssl/nsNSSIOLayer.cpp b/security/manager/ssl/nsNSSIOLayer.cpp index 337ef8b8e6..55313906a4 100644 --- a/security/manager/ssl/nsNSSIOLayer.cpp +++ b/security/manager/ssl/nsNSSIOLayer.cpp @@ -2331,6 +2331,12 @@ nsSSLIOLayerSetOptions(PRFileDesc* fd, bool forSTARTTLS, return NS_ERROR_FAILURE; } + // Set TLS 1.3 compat mode. + if (SECSuccess != SSL_OptionSet(fd, SSL_ENABLE_TLS13_COMPAT_MODE, PR_TRUE)) { + MOZ_LOG(gPIPNSSLog, LogLevel::Error, + ("[%p] nsSSLIOLayerSetOptions: Setting compat mode failed\n", fd)); + } + if ((infoObject->GetProviderFlags() & nsISocketProvider::BE_CONSERVATIVE) && (range.max > SSL_LIBRARY_VERSION_TLS_1_2)) { MOZ_LOG(gPIPNSSLog, LogLevel::Debug, diff --git a/xpcom/ds/nsAtomTable.cpp b/xpcom/ds/nsAtomTable.cpp index 3dd3bd36c1..8f7fb5c64a 100644 --- a/xpcom/ds/nsAtomTable.cpp +++ b/xpcom/ds/nsAtomTable.cpp @@ -325,13 +325,7 @@ AtomTableMatchKey(const PLDHashEntryHdr* aEntry, const void* aKey) nsDependentAtomString(he->mAtom)) == 0; } - uint32_t length = he->mAtom->GetLength(); - if (length != k->mLength) { - return false; - } - - return memcmp(he->mAtom->GetUTF16String(), - k->mUTF16String, length * sizeof(char16_t)) == 0; + return he->mAtom->Equals(k->mUTF16String, k->mLength); } static void @@ -364,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; @@ -712,6 +717,40 @@ NS_Atomize(const nsAString& aUTF16String) return atom.forget(); } +already_AddRefed +NS_AtomizeMainThread(const nsAString& aUTF16String) +{ + MOZ_ASSERT(NS_IsMainThread()); + nsCOMPtr 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(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) { diff --git a/xpcom/ds/nsIAtom.idl b/xpcom/ds/nsIAtom.idl index c025408387..64947bb414 100644 --- a/xpcom/ds/nsIAtom.idl +++ b/xpcom/ds/nsIAtom.idl @@ -37,9 +37,15 @@ interface nsIAtom : nsISupports size_t SizeOfIncludingThis(in MallocSizeOf aMallocSizeOf); %{C++ - // note this is NOT virtual so this won't muck with the vtable! + // 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 aString.Equals(nsDependentString(mString, mLength)); + return Equals(aString.BeginReading(), aString.Length()); } inline bool IsStaticAtom() const { @@ -119,6 +125,11 @@ extern already_AddRefed NS_Atomize(const char16_t* aUTF16String); */ extern already_AddRefed NS_Atomize(const nsAString& aUTF16String); +/** + * An optimized version of the method above for the main thread. + */ +extern already_AddRefed NS_AtomizeMainThread(const nsAString& aUTF16String); + /** * Return a count of the total number of atoms currently * alive in the system.