From 8c2d114c59c624e37b808c283cfcaa113044ed99 Mon Sep 17 00:00:00 2001 From: "bzbarsky%mit.edu" Date: Wed, 7 Sep 2005 17:04:34 +0000 Subject: [PATCH] Once we've had enough ID lookup misses, make the ID table completely live. Bug 299689, r+sr=jst git-svn-id: svn://10.0.0.236/trunk@179801 18797224-902f-48f8-a5cc-f745e15eee43 --- .../html/document/src/nsHTMLDocument.cpp | 29 ++++++++++++++----- .../html/document/src/nsHTMLDocument.h | 21 ++++++++++++++ 2 files changed, 43 insertions(+), 7 deletions(-) diff --git a/mozilla/content/html/document/src/nsHTMLDocument.cpp b/mozilla/content/html/document/src/nsHTMLDocument.cpp index d5b7a969ffe..3a1a126139f 100644 --- a/mozilla/content/html/document/src/nsHTMLDocument.cpp +++ b/mozilla/content/html/document/src/nsHTMLDocument.cpp @@ -2377,12 +2377,25 @@ nsHTMLDocument::GetElementById(const nsAString& aElementId, } if (!e) { - NS_WARN_IF_FALSE(!aElementId.IsEmpty(), - "getElementById(\"\") called, fix caller?"); + // If IdTableIsLive(), no need to look for the element in the document, + // since we're fully maintaining our table's state as the DOM mutates. + if (!IdTableIsLive()) { + if (IdTableShouldBecomeLive()) { + // Just make sure our table is up to date and call this method again + // to look up in the hashtable. + if (mRootContent) { + RegisterNamedItems(mRootContent); + } + return GetElementById(aElementId, aReturn); + } - if (mRootContent && !aElementId.IsEmpty()) { - e = MatchElementId(mRootContent, NS_ConvertUCS2toUTF8(aElementId), - aElementId); + NS_WARN_IF_FALSE(!aElementId.IsEmpty(), + "getElementById(\"\") called, fix caller?"); + + if (mRootContent && !aElementId.IsEmpty()) { + e = MatchElementId(mRootContent, NS_ConvertUCS2toUTF8(aElementId), + aElementId); + } } if (!e) { @@ -3015,12 +3028,14 @@ nsHTMLDocument::AddToIdTable(const nsAString& aId, nsIContent *aContent) nsresult nsHTMLDocument::UpdateIdTableEntry(const nsAString& aId, nsIContent *aContent) { + PRBool liveTable = IdTableIsLive(); + PLDHashOperator op = liveTable ? PL_DHASH_ADD : PL_DHASH_LOOKUP; IdAndNameMapEntry *entry = NS_STATIC_CAST(IdAndNameMapEntry *, PL_DHashTableOperate(&mIdAndNameHashTable, &aId, - PL_DHASH_LOOKUP)); + op)); - if (PL_DHASH_ENTRY_IS_BUSY(entry)) { + if (entry && (liveTable || PL_DHASH_ENTRY_IS_BUSY(entry))) { entry->mIdContent = aContent; } diff --git a/mozilla/content/html/document/src/nsHTMLDocument.h b/mozilla/content/html/document/src/nsHTMLDocument.h index 46b79d6e616..eb7edce8ec1 100644 --- a/mozilla/content/html/document/src/nsHTMLDocument.h +++ b/mozilla/content/html/document/src/nsHTMLDocument.h @@ -310,6 +310,27 @@ protected: PRPackedBool mIsFrameset; + PRBool IdTableIsLive() const { + // live if we've had over 63 misses + return (mIdMissCount & 0x40) != 0; + } + + PRBool IdTableShouldBecomeLive() { + NS_ASSERTION(!IdTableIsLive(), + "Shouldn't be called if table is already live!"); + ++mIdMissCount; + return IdTableIsLive(); + } + + PRUint8 mIdMissCount; + + /* mIdAndNameHashTable works as follows for IDs: + * 1) Attribute changes affect the table immediately (removing and adding + * entries as needed). + * 2) Removals from the DOM affect the table immediately + * 3) Additions to the DOM always update existing entries, but only add new + * ones if IdTableIsLive() is true. + */ PLDHashTable mIdAndNameHashTable; nsCOMPtr mWyciwygChannel;