From e21a2262ee55a6ac8f3231ea47e384bd67fac93c Mon Sep 17 00:00:00 2001 From: "bent.mozilla%gmail.com" Date: Fri, 8 Feb 2008 22:07:53 +0000 Subject: [PATCH] Bug 386769 - "Make setting innerHTML faster". r=jst, sr=peterv, a=blocking1.9. git-svn-id: svn://10.0.0.236/trunk@245266 18797224-902f-48f8-a5cc-f745e15eee43 --- mozilla/content/base/public/nsIDocument.h | 10 +++ mozilla/content/base/src/nsContentSink.cpp | 15 +++-- mozilla/content/base/src/nsContentSink.h | 5 +- mozilla/content/base/src/nsContentUtils.cpp | 60 +++++++++++++---- .../html/document/src/nsHTMLDocument.cpp | 1 + .../html/document/src/nsHTMLDocument.h | 10 +++ .../src/nsHTMLFragmentContentSink.cpp | 25 +++++-- .../xml/document/src/nsXMLContentSink.cpp | 33 +++++++--- .../xml/document/src/nsXMLContentSink.h | 5 +- .../document/src/nsXMLFragmentContentSink.cpp | 20 +++++- mozilla/parser/htmlparser/public/nsIParser.h | 2 + mozilla/parser/htmlparser/src/CNavDTD.cpp | 15 +++-- mozilla/parser/htmlparser/src/CNavDTD.h | 6 +- .../parser/htmlparser/src/nsExpatDriver.cpp | 13 +++- mozilla/parser/htmlparser/src/nsExpatDriver.h | 4 +- mozilla/parser/htmlparser/src/nsParser.cpp | 66 ++++++++++++++----- mozilla/parser/htmlparser/src/nsParser.h | 10 ++- 17 files changed, 235 insertions(+), 65 deletions(-) diff --git a/mozilla/content/base/public/nsIDocument.h b/mozilla/content/base/public/nsIDocument.h index 05c04555395..9410e61ac1e 100644 --- a/mozilla/content/base/public/nsIDocument.h +++ b/mozilla/content/base/public/nsIDocument.h @@ -941,6 +941,16 @@ public: mJSObject = aJSObject; } + // This method should return an addrefed nsIParser* or nsnull. Implementations + // should transfer ownership of the parser to the caller. + virtual already_AddRefed GetFragmentParser() { + return nsnull; + } + + virtual void SetFragmentParser(nsIParser* aParser) { + // Do nothing. + } + protected: ~nsIDocument() { diff --git a/mozilla/content/base/src/nsContentSink.cpp b/mozilla/content/base/src/nsContentSink.cpp index 5edc698fb4e..1b8ae95d9ac 100644 --- a/mozilla/content/base/src/nsContentSink.cpp +++ b/mozilla/content/base/src/nsContentSink.cpp @@ -147,10 +147,17 @@ nsScriptLoaderObserverProxy::ScriptEvaluated(nsresult aResult, } -NS_IMPL_ISUPPORTS3(nsContentSink, - nsICSSLoaderObserver, - nsISupportsWeakReference, - nsIScriptLoaderObserver) +NS_IMPL_CYCLE_COLLECTING_ADDREF(nsContentSink) +NS_IMPL_CYCLE_COLLECTING_RELEASE(nsContentSink) + +NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(nsContentSink) + NS_INTERFACE_MAP_ENTRY(nsICSSLoaderObserver) + NS_INTERFACE_MAP_ENTRY(nsISupportsWeakReference) + NS_INTERFACE_MAP_ENTRY(nsIScriptLoaderObserver) + NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIScriptLoaderObserver) +NS_INTERFACE_MAP_END + +NS_IMPL_CYCLE_COLLECTION_2(nsContentSink, mDocument, mParser) nsContentSink::nsContentSink() { diff --git a/mozilla/content/base/src/nsContentSink.h b/mozilla/content/base/src/nsContentSink.h index fbb55dc391d..820b37cb32c 100644 --- a/mozilla/content/base/src/nsContentSink.h +++ b/mozilla/content/base/src/nsContentSink.h @@ -62,6 +62,7 @@ #include "prlog.h" #include "nsIRequest.h" #include "nsTimer.h" +#include "nsCycleCollectionParticipant.h" class nsIDocument; class nsIURI; @@ -114,7 +115,9 @@ class nsContentSink : public nsICSSLoaderObserver, public nsStubDocumentObserver, public nsITimerCallback { - NS_DECL_ISUPPORTS + NS_DECL_CYCLE_COLLECTING_ISUPPORTS + NS_DECL_CYCLE_COLLECTION_CLASS_AMBIGUOUS(nsContentSink, + nsIScriptLoaderObserver) NS_DECL_NSISCRIPTLOADEROBSERVER // nsITimerCallback diff --git a/mozilla/content/base/src/nsContentUtils.cpp b/mozilla/content/base/src/nsContentUtils.cpp index b55550d3202..ba836e75f83 100644 --- a/mozilla/content/base/src/nsContentUtils.cpp +++ b/mozilla/content/base/src/nsContentUtils.cpp @@ -78,6 +78,8 @@ #include "nsIParser.h" #include "nsIFragmentContentSink.h" #include "nsIContentSink.h" +#include "nsIHTMLContentSink.h" +#include "nsIXMLContentSink.h" #include "nsHTMLParts.h" #include "nsIParserService.h" #include "nsIServiceManager.h" @@ -130,7 +132,6 @@ static NS_DEFINE_CID(kXTFServiceCID, NS_XTFSERVICE_CID); #include "nsIEventListenerManager.h" #include "nsAttrName.h" #include "nsIDOMUserDataHandler.h" -#include "nsIFragmentContentSink.h" #include "nsContentCreatorFunctions.h" #include "nsTPtrArray.h" #include "nsGUIEvent.h" @@ -3325,11 +3326,7 @@ nsContentUtils::CreateContextualFragment(nsIDOMNode* aContextNode, NS_ENSURE_ARG(aContextNode); *aReturn = nsnull; - // Create a new parser for this entire operation nsresult rv; - nsCOMPtr parser = do_CreateInstance(kCParserCID, &rv); - NS_ENSURE_SUCCESS(rv, rv); - nsCOMPtr node = do_QueryInterface(aContextNode); NS_ENSURE_TRUE(node, NS_ERROR_NOT_AVAILABLE); @@ -3402,17 +3399,52 @@ nsContentUtils::CreateContextualFragment(nsIDOMNode* aContextNode, nsCOMPtr htmlDoc(do_QueryInterface(document)); PRBool bHTML = htmlDoc && !bCaseSensitive; - nsCOMPtr sink; - if (bHTML) { - rv = NS_NewHTMLFragmentContentSink(getter_AddRefs(sink)); - } else { - rv = NS_NewXMLFragmentContentSink(getter_AddRefs(sink)); + + // See if the document has a cached fragment parser. nsHTMLDocument is the + // only one that should really have one at the moment. + nsCOMPtr parser = document->GetFragmentParser(); + if (parser) { + // Get the parser ready to use. + parser->Reset(); + } + else { + // Create a new parser for this operation. + parser = do_CreateInstance(kCParserCID, &rv); + NS_ENSURE_SUCCESS(rv, rv); + } + + // See if the parser already has a content sink that we can reuse. + nsCOMPtr sink; + nsCOMPtr contentsink = parser->GetContentSink(); + if (contentsink) { + // Make sure it's the correct type. + if (bHTML) { + nsCOMPtr htmlsink = do_QueryInterface(contentsink); + sink = do_QueryInterface(htmlsink); + } + else { + nsCOMPtr xmlsink = do_QueryInterface(contentsink); + sink = do_QueryInterface(xmlsink); + } + } + + if (!sink) { + // Either there was no cached content sink or it was the wrong type. Make a + // new one. + if (bHTML) { + rv = NS_NewHTMLFragmentContentSink(getter_AddRefs(sink)); + } else { + rv = NS_NewXMLFragmentContentSink(getter_AddRefs(sink)); + } + NS_ENSURE_SUCCESS(rv, rv); + + contentsink = do_QueryInterface(sink); + NS_ASSERTION(contentsink, "Sink doesn't QI to nsIContentSink!"); + + parser->SetContentSink(contentsink); } - NS_ENSURE_SUCCESS(rv, rv); sink->SetTargetDocument(document); - nsCOMPtr contentsink(do_QueryInterface(sink)); - parser->SetContentSink(contentsink); nsDTDMode mode = eDTDMode_autodetect; switch (document->GetCompatibilityMode()) { @@ -3437,6 +3469,8 @@ nsContentUtils::CreateContextualFragment(nsIDOMNode* aContextNode, rv = sink->GetFragment(aReturn); } + document->SetFragmentParser(parser); + return NS_OK; } diff --git a/mozilla/content/html/document/src/nsHTMLDocument.cpp b/mozilla/content/html/document/src/nsHTMLDocument.cpp index a1a4fac7417..b90f7265fdd 100644 --- a/mozilla/content/html/document/src/nsHTMLDocument.cpp +++ b/mozilla/content/html/document/src/nsHTMLDocument.cpp @@ -408,6 +408,7 @@ NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(nsHTMLDocument, nsDocument) NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mEmbeds) NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mLinks) NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mAnchors) + NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mFragmentParser) NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR_AMBIGUOUS(mForms, nsIDOMNodeList) NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR_AMBIGUOUS(mFormControls, nsIDOMNodeList) diff --git a/mozilla/content/html/document/src/nsHTMLDocument.h b/mozilla/content/html/document/src/nsHTMLDocument.h index 68c9387282f..e31f4168110 100644 --- a/mozilla/content/html/document/src/nsHTMLDocument.h +++ b/mozilla/content/html/document/src/nsHTMLDocument.h @@ -216,6 +216,13 @@ public: NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED_NO_UNLINK(nsHTMLDocument, nsDocument) + virtual already_AddRefed GetFragmentParser() { + return mFragmentParser.forget(); + } + virtual void SetFragmentParser(nsIParser* aParser) { + mFragmentParser = aParser; + } + protected: nsresult GetBodySize(PRInt32* aWidth, PRInt32* aHeight); @@ -382,6 +389,9 @@ protected: PRInt32 mDefaultNamespaceID; PRBool mDisableCookieAccess; + + // Parser used for constructing document fragments. + nsCOMPtr mFragmentParser; }; #endif /* nsHTMLDocument_h___ */ diff --git a/mozilla/content/html/document/src/nsHTMLFragmentContentSink.cpp b/mozilla/content/html/document/src/nsHTMLFragmentContentSink.cpp index 06cc327e140..c11d436f5b8 100644 --- a/mozilla/content/html/document/src/nsHTMLFragmentContentSink.cpp +++ b/mozilla/content/html/document/src/nsHTMLFragmentContentSink.cpp @@ -64,6 +64,7 @@ #include "nsIScriptSecurityManager.h" #include "nsContentSink.h" #include "nsTHashtable.h" +#include "nsCycleCollectionParticipant.h" // // XXX THIS IS TEMPORARY CODE @@ -79,7 +80,9 @@ public: virtual ~nsHTMLFragmentContentSink(); // nsISupports - NS_DECL_ISUPPORTS + NS_DECL_CYCLE_COLLECTING_ISUPPORTS + NS_DECL_CYCLE_COLLECTION_CLASS_AMBIGUOUS(nsHTMLFragmentContentSink, + nsIContentSink) NS_DECL_AND_IMPL_ZEROING_OPERATOR_NEW @@ -223,12 +226,22 @@ nsHTMLFragmentContentSink::~nsHTMLFragmentContentSink() } } -NS_IMPL_ISUPPORTS3(nsHTMLFragmentContentSink, - nsIFragmentContentSink, - nsIHTMLContentSink, - nsIContentSink) +NS_IMPL_CYCLE_COLLECTING_ADDREF_AMBIGUOUS(nsHTMLFragmentContentSink, + nsIContentSink) +NS_IMPL_CYCLE_COLLECTING_RELEASE_AMBIGUOUS(nsHTMLFragmentContentSink, + nsIContentSink) -NS_IMETHODIMP +NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(nsHTMLFragmentContentSink) + NS_INTERFACE_MAP_ENTRY(nsIFragmentContentSink) + NS_INTERFACE_MAP_ENTRY(nsIHTMLContentSink) + NS_INTERFACE_MAP_ENTRY(nsIContentSink) + NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIContentSink) +NS_INTERFACE_MAP_END + +NS_IMPL_CYCLE_COLLECTION_3(nsHTMLFragmentContentSink, mParser, mTargetDocument, + mRoot) + +NS_IMETHODIMP nsHTMLFragmentContentSink::WillBuildModel(void) { if (mRoot) { diff --git a/mozilla/content/xml/document/src/nsXMLContentSink.cpp b/mozilla/content/xml/document/src/nsXMLContentSink.cpp index eeaa83ded6a..582dbaa8cbb 100644 --- a/mozilla/content/xml/document/src/nsXMLContentSink.cpp +++ b/mozilla/content/xml/document/src/nsXMLContentSink.cpp @@ -185,15 +185,30 @@ nsXMLContentSink::Init(nsIDocument* aDoc, return NS_OK; } -NS_IMPL_ISUPPORTS_INHERITED7(nsXMLContentSink, - nsContentSink, - nsIContentSink, - nsIXMLContentSink, - nsIExpatSink, - nsITimerCallback, - nsIDocumentObserver, - nsIMutationObserver, - nsITransformObserver) +NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION_INHERITED(nsXMLContentSink) + NS_INTERFACE_MAP_ENTRY(nsIContentSink) + NS_INTERFACE_MAP_ENTRY(nsIXMLContentSink) + NS_INTERFACE_MAP_ENTRY(nsIExpatSink) + NS_INTERFACE_MAP_ENTRY(nsITimerCallback) + NS_INTERFACE_MAP_ENTRY(nsIDocumentObserver) + NS_INTERFACE_MAP_ENTRY(nsIMutationObserver) + NS_INTERFACE_MAP_ENTRY(nsITransformObserver) +NS_INTERFACE_MAP_END_INHERITING(nsContentSink) + +NS_IMPL_ADDREF_INHERITED(nsXMLContentSink, nsContentSink) +NS_IMPL_RELEASE_INHERITED(nsXMLContentSink, nsContentSink) + +NS_IMPL_CYCLE_COLLECTION_CLASS(nsXMLContentSink) + +NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(nsXMLContentSink, + nsContentSink) + NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mCurrentHead) + NS_IMPL_CYCLE_COLLECTION_TRAVERSE_RAWPTR(mDocElement) + for (PRUint32 i = 0, count = tmp->mContentStack.Length(); i < count; i++) { + const StackNode& node = tmp->mContentStack.ElementAt(i); + cb.NoteXPCOMChild(node.mContent); + } +NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END // nsIContentSink NS_IMETHODIMP diff --git a/mozilla/content/xml/document/src/nsXMLContentSink.h b/mozilla/content/xml/document/src/nsXMLContentSink.h index 108ea6b07cf..5861b8985f1 100644 --- a/mozilla/content/xml/document/src/nsXMLContentSink.h +++ b/mozilla/content/xml/document/src/nsXMLContentSink.h @@ -45,7 +45,7 @@ #include "nsTArray.h" #include "nsCOMPtr.h" #include "nsCRT.h" - +#include "nsCycleCollectionParticipant.h" class nsIDocument; class nsIURI; @@ -84,6 +84,9 @@ public: // nsISupports NS_DECL_ISUPPORTS_INHERITED + NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED_NO_UNLINK(nsXMLContentSink, + nsContentSink) + NS_DECL_NSIEXPATSINK // nsIContentSink diff --git a/mozilla/content/xml/document/src/nsXMLFragmentContentSink.cpp b/mozilla/content/xml/document/src/nsXMLFragmentContentSink.cpp index a86dbebbd2d..3e66cbe8e27 100644 --- a/mozilla/content/xml/document/src/nsXMLFragmentContentSink.cpp +++ b/mozilla/content/xml/document/src/nsXMLFragmentContentSink.cpp @@ -60,6 +60,7 @@ #include "nsTHashtable.h" #include "nsHashKeys.h" #include "nsTArray.h" +#include "nsCycleCollectionParticipant.h" class nsXMLFragmentContentSink : public nsXMLContentSink, public nsIFragmentContentSink @@ -72,6 +73,8 @@ public: // nsISupports NS_DECL_ISUPPORTS_INHERITED + NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED_NO_UNLINK(nsXMLFragmentContentSink, + nsXMLContentSink) // nsIExpatSink NS_IMETHOD HandleDoctypeDecl(const nsAString & aSubset, @@ -169,9 +172,20 @@ nsXMLFragmentContentSink::~nsXMLFragmentContentSink() { } -NS_IMPL_ISUPPORTS_INHERITED1(nsXMLFragmentContentSink, - nsXMLContentSink, - nsIFragmentContentSink) +NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION_INHERITED(nsXMLFragmentContentSink) + NS_INTERFACE_MAP_ENTRY(nsIFragmentContentSink) +NS_INTERFACE_MAP_END_INHERITING(nsXMLContentSink) + +NS_IMPL_ADDREF_INHERITED(nsXMLFragmentContentSink, nsXMLContentSink) +NS_IMPL_RELEASE_INHERITED(nsXMLFragmentContentSink, nsXMLContentSink) + +NS_IMPL_CYCLE_COLLECTION_CLASS(nsXMLFragmentContentSink) + +NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(nsXMLFragmentContentSink, + nsXMLContentSink) + NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mTargetDocument) + NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mRoot) +NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END NS_IMETHODIMP nsXMLFragmentContentSink::WillBuildModel(void) diff --git a/mozilla/parser/htmlparser/public/nsIParser.h b/mozilla/parser/htmlparser/public/nsIParser.h index 23ecd3e9462..f4cd93df866 100644 --- a/mozilla/parser/htmlparser/public/nsIParser.h +++ b/mozilla/parser/htmlparser/public/nsIParser.h @@ -287,6 +287,8 @@ class nsIParser : public nsISupports { */ NS_IMETHOD CancelParsingEvents() = 0; + + virtual void Reset() = 0; }; NS_DEFINE_STATIC_IID_ACCESSOR(nsIParser, NS_IPARSER_IID) diff --git a/mozilla/parser/htmlparser/src/CNavDTD.cpp b/mozilla/parser/htmlparser/src/CNavDTD.cpp index f3398e00486..76d2a24a385 100644 --- a/mozilla/parser/htmlparser/src/CNavDTD.cpp +++ b/mozilla/parser/htmlparser/src/CNavDTD.cpp @@ -113,11 +113,18 @@ static const char kInvalidTagStackPos[] = "Error: invalid tag stack position"; #define NS_DTD_FLAG_HAS_MAIN_CONTAINER (NS_DTD_FLAG_HAD_BODY | \ NS_DTD_FLAG_HAD_FRAMESET) -NS_IMPL_ISUPPORTS1(CNavDTD, nsIDTD) +NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(CNavDTD) + NS_INTERFACE_MAP_ENTRY(nsIDTD) + NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIDTD) +NS_INTERFACE_MAP_END + +NS_IMPL_CYCLE_COLLECTING_ADDREF(CNavDTD) +NS_IMPL_CYCLE_COLLECTING_RELEASE(CNavDTD) + +NS_IMPL_CYCLE_COLLECTION_1(CNavDTD, mSink) CNavDTD::CNavDTD() : mMisplacedContent(0), - mSink(0), mTokenAllocator(0), mBodyContext(new nsDTDContext()), mTempContext(0), @@ -181,8 +188,6 @@ CNavDTD::~CNavDTD() } } #endif - - NS_IF_RELEASE(mSink); } nsresult @@ -212,7 +217,7 @@ CNavDTD::WillBuildModel(const CParserContext& aParserContext, START_TIMER(); if (NS_SUCCEEDED(result) && !mSink) { - result = CallQueryInterface(aSink, &mSink); + mSink = do_QueryInterface(aSink, &result); if (NS_FAILED(result)) { mFlags |= NS_DTD_FLAG_STOP_PARSING; return result; diff --git a/mozilla/parser/htmlparser/src/CNavDTD.h b/mozilla/parser/htmlparser/src/CNavDTD.h index 71b643fefde..de6c072cd0f 100644 --- a/mozilla/parser/htmlparser/src/CNavDTD.h +++ b/mozilla/parser/htmlparser/src/CNavDTD.h @@ -106,6 +106,7 @@ #include "nsTime.h" #include "nsDTDUtils.h" #include "nsParser.h" +#include "nsCycleCollectionParticipant.h" class nsIHTMLContentSink; class nsIParserNode; @@ -158,8 +159,9 @@ public: eHTMLTags aTag, nsEntryStack* aStyleStack = nsnull); - NS_DECL_ISUPPORTS + NS_DECL_CYCLE_COLLECTING_ISUPPORTS NS_DECL_NSIDTD + NS_DECL_CYCLE_COLLECTION_CLASS(CNavDTD) private: /** @@ -381,7 +383,7 @@ protected: nsDeque mMisplacedContent; - nsIHTMLContentSink* mSink; + nsCOMPtr mSink; nsTokenAllocator* mTokenAllocator; nsDTDContext* mBodyContext; nsDTDContext* mTempContext; diff --git a/mozilla/parser/htmlparser/src/nsExpatDriver.cpp b/mozilla/parser/htmlparser/src/nsExpatDriver.cpp index 68a9050fc35..fab4e1eaaff 100644 --- a/mozilla/parser/htmlparser/src/nsExpatDriver.cpp +++ b/mozilla/parser/htmlparser/src/nsExpatDriver.cpp @@ -378,9 +378,16 @@ IsLoadableDTD(const nsCatalogData* aCatalogData, nsIURI* aDTD, /***************************** END CATALOG UTILS *****************************/ -NS_IMPL_ISUPPORTS2(nsExpatDriver, - nsITokenizer, - nsIDTD) +NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(nsExpatDriver) + NS_INTERFACE_MAP_ENTRY(nsITokenizer) + NS_INTERFACE_MAP_ENTRY(nsIDTD) + NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIDTD) +NS_INTERFACE_MAP_END + +NS_IMPL_CYCLE_COLLECTING_ADDREF(nsExpatDriver) +NS_IMPL_CYCLE_COLLECTING_RELEASE(nsExpatDriver) + +NS_IMPL_CYCLE_COLLECTION_2(nsExpatDriver, mSink, mExtendedSink) nsExpatDriver::nsExpatDriver() : mExpatParser(nsnull), diff --git a/mozilla/parser/htmlparser/src/nsExpatDriver.h b/mozilla/parser/htmlparser/src/nsExpatDriver.h index de6b98ca6cd..30d7f995b6e 100644 --- a/mozilla/parser/htmlparser/src/nsExpatDriver.h +++ b/mozilla/parser/htmlparser/src/nsExpatDriver.h @@ -46,6 +46,7 @@ #include "nsITokenizer.h" #include "nsIInputStream.h" #include "nsIParser.h" +#include "nsCycleCollectionParticipant.h" class nsIExpatSink; class nsIExtendedExpatSink; @@ -55,9 +56,10 @@ class nsExpatDriver : public nsIDTD, public nsITokenizer { public: - NS_DECL_ISUPPORTS + NS_DECL_CYCLE_COLLECTING_ISUPPORTS NS_DECL_NSIDTD NS_DECL_NSITOKENIZER + NS_DECL_CYCLE_COLLECTION_CLASS_AMBIGUOUS(nsExpatDriver, nsIDTD) nsExpatDriver(); virtual ~nsExpatDriver(); diff --git a/mozilla/parser/htmlparser/src/nsParser.cpp b/mozilla/parser/htmlparser/src/nsParser.cpp index e2badf87525..6ec4b46fa82 100644 --- a/mozilla/parser/htmlparser/src/nsParser.cpp +++ b/mozilla/parser/htmlparser/src/nsParser.cpp @@ -244,6 +244,17 @@ static PRBool gDumpContent=PR_FALSE; * default constructor */ nsParser::nsParser() +{ + Initialize(PR_TRUE); +} + +nsParser::~nsParser() +{ + Cleanup(); +} + +void +nsParser::Initialize(PRBool aConstructor) { #ifdef NS_DEBUG if (!gDumpContent) { @@ -251,13 +262,22 @@ nsParser::nsParser() } #endif + if (aConstructor) { + // Raw pointer + mParserContext = 0; + } + else { + // nsCOMPtrs + mObserver = nsnull; + mParserFilter = nsnull; + } + + mContinueEvent = nsnull; + mCharsetSource = kCharsetUninitialized; mCharset.AssignLiteral("ISO-8859-1"); - mParserContext=0; - mStreamStatus=0; - mCharsetSource=kCharsetUninitialized; - mInternalState=NS_OK; - mContinueEvent=nsnull; - mCommand=eViewNormal; + mInternalState = NS_OK; + mStreamStatus = 0; + mCommand = eViewNormal; mFlags = NS_PARSER_FLAG_OBSERVERS_ENABLED | NS_PARSER_FLAG_PARSER_ENABLED | NS_PARSER_FLAG_CAN_TOKENIZE; @@ -268,12 +288,9 @@ nsParser::nsParser() MOZ_TIMER_RESET(mTokenizeTime); } -/** - * Destructor - */ -nsParser::~nsParser() +void +nsParser::Cleanup() { - #ifdef NS_DEBUG if (gDumpContent) { if (mSink) { @@ -306,14 +323,31 @@ nsParser::~nsParser() NS_ASSERTION(!(mFlags & NS_PARSER_FLAG_PENDING_CONTINUE_EVENT), "bad"); } -NS_IMPL_CYCLE_COLLECTION_2(nsParser, mSink, mObserver) +NS_IMPL_CYCLE_COLLECTION_CLASS(nsParser) + +NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(nsParser) + NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mSink) + NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mObserver) +NS_IMPL_CYCLE_COLLECTION_UNLINK_END + +NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(nsParser) + NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mSink) + NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mObserver) + CParserContext *pc = tmp->mParserContext; + while (pc) { + cb.NoteXPCOMChild(pc->mDTD); + cb.NoteXPCOMChild(pc->mTokenizer); + pc = pc->mPrevContext; + } +NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END + NS_IMPL_CYCLE_COLLECTING_ADDREF_AMBIGUOUS(nsParser, nsIParser) NS_IMPL_CYCLE_COLLECTING_RELEASE_AMBIGUOUS(nsParser, nsIParser) NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(nsParser) - NS_INTERFACE_MAP_ENTRY(nsIStreamListener) - NS_INTERFACE_MAP_ENTRY(nsIParser) - NS_INTERFACE_MAP_ENTRY(nsIRequestObserver) - NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIParser) + NS_INTERFACE_MAP_ENTRY(nsIStreamListener) + NS_INTERFACE_MAP_ENTRY(nsIParser) + NS_INTERFACE_MAP_ENTRY(nsIRequestObserver) + NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIParser) NS_INTERFACE_MAP_END // The parser continue event is posted only if diff --git a/mozilla/parser/htmlparser/src/nsParser.h b/mozilla/parser/htmlparser/src/nsParser.h index e77bb0f0605..a2503ca927b 100644 --- a/mozilla/parser/htmlparser/src/nsParser.h +++ b/mozilla/parser/htmlparser/src/nsParser.h @@ -381,7 +381,15 @@ class nsParser : public nsIParser, return sCharsetConverterManager; } -protected: + virtual void Reset() { + Cleanup(); + Initialize(); + } + + protected: + + void Initialize(PRBool aConstructor = PR_FALSE); + void Cleanup(); /** *