author | Henri Sivonen <hsivonen@iki.fi> |
Wed, 11 Jan 2012 17:49:57 +0200 | |
changeset 84274 | 39e49fcaed223e445a19760bb3974a3958b56178 |
parent 84273 | 418f713f7092d824aac7798069886318c1a92259 |
child 84275 | dc3f10e2e734bc0b4dd389d60ad536644f09c74d |
push id | 4802 |
push user | hsivonen@iki.fi |
push date | Wed, 11 Jan 2012 15:50:46 +0000 |
treeherder | mozilla-inbound@39e49fcaed22 [default view] [failures only] |
perfherder | [talos] [build metrics] [platform microbench] (compared to previous push) |
reviewers | mrbkap |
bugs | 717203 |
milestone | 12.0a1 |
first release with | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
last release without | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
parser/htmlparser/src/nsParser.cpp | file | annotate | diff | comparison | revisions | |
parser/htmlparser/src/nsParser.h | file | annotate | diff | comparison | revisions |
--- a/parser/htmlparser/src/nsParser.cpp +++ b/parser/htmlparser/src/nsParser.cpp @@ -157,513 +157,18 @@ public: { mParser->HandleParserContinueEvent(this); return NS_OK; } }; //-------------- End ParseContinue Event Definition ------------------------ -template <class Type> -class Holder { -public: - typedef void (*Reaper)(Type *); - - Holder(Reaper aReaper) - : mHoldee(nsnull), mReaper(aReaper) - { - } - - ~Holder() { - if (mHoldee) { - mReaper(mHoldee); - } - } - - Type *get() { - return mHoldee; - } - const Holder &operator =(Type *aHoldee) { - if (mHoldee && aHoldee != mHoldee) { - mReaper(mHoldee); - } - mHoldee = aHoldee; - return *this; - } - -private: - Type *mHoldee; - Reaper mReaper; -}; - -class nsSpeculativeScriptThread : public nsIRunnable { -public: - nsSpeculativeScriptThread() - : mLock("nsSpeculativeScriptThread.mLock"), - mCVar(mLock, "nsSpeculativeScriptThread.mCVar"), - mKeepParsing(false), - mCurrentlyParsing(false), - mNumConsumed(0), - mContext(nsnull), - mTerminated(false) { - } - - ~nsSpeculativeScriptThread() { - NS_ASSERTION(NS_IsMainThread() || !mDocument, - "Destroying the document on the wrong thread"); - } - - NS_DECL_ISUPPORTS - NS_DECL_NSIRUNNABLE - - nsresult StartParsing(nsParser *aParser); - void StopParsing(bool aFromDocWrite); - - enum PrefetchType { NONE, SCRIPT, STYLESHEET, IMAGE }; - struct PrefetchEntry { - PrefetchType type; - nsString uri; - nsString charset; - nsString elementType; - }; - - nsIDocument *GetDocument() { - NS_ASSERTION(NS_IsMainThread(), "Potential threadsafety hazard"); - return mDocument; - } - - bool Parsing() { - return mCurrentlyParsing; - } - - CParserContext *Context() { - return mContext; - } - - typedef nsDataHashtable<nsCStringHashKey, bool> PreloadedType; - PreloadedType& GetPreloadedURIs() { - return mPreloadedURIs; - } - - void Terminate() { - mTerminated = true; - StopParsing(false); - } - bool Terminated() { - return mTerminated; - } - -private: - - void ProcessToken(CToken *aToken); - - void AddToPrefetchList(const nsAString &src, - const nsAString &charset, - const nsAString &elementType, - PrefetchType type); - - void FlushURIs(); - - // These members are only accessed on the speculatively parsing thread. - nsTokenAllocator mTokenAllocator; - - // The following members are shared across the main thread and the - // speculatively parsing thread. - Mutex mLock; - CondVar mCVar; - - volatile bool mKeepParsing; - volatile bool mCurrentlyParsing; - nsRefPtr<nsHTMLTokenizer> mTokenizer; - nsAutoPtr<nsScanner> mScanner; - - enum { kBatchPrefetchURIs = 5 }; - nsAutoTArray<PrefetchEntry, kBatchPrefetchURIs> mURIs; - - // Number of characters consumed by the last speculative parse. - PRUint32 mNumConsumed; - - // These members are only accessed on the main thread. - nsCOMPtr<nsIDocument> mDocument; - CParserContext *mContext; - PreloadedType mPreloadedURIs; - bool mTerminated; -}; - -class nsPreloadURIs : public nsIRunnable { -public: - nsPreloadURIs(nsAutoTArray<nsSpeculativeScriptThread::PrefetchEntry, 5> &aURIs, - nsSpeculativeScriptThread *aScriptThread) - : mURIs(aURIs), - mScriptThread(aScriptThread) { - } - - NS_DECL_ISUPPORTS - NS_DECL_NSIRUNNABLE - - static void PreloadURIs(const nsAutoTArray<nsSpeculativeScriptThread::PrefetchEntry, 5> &aURIs, - nsSpeculativeScriptThread *aScriptThread); - -private: - nsAutoTArray<nsSpeculativeScriptThread::PrefetchEntry, 5> mURIs; - nsRefPtr<nsSpeculativeScriptThread> mScriptThread; -}; - -NS_IMPL_THREADSAFE_ISUPPORTS1(nsPreloadURIs, nsIRunnable) - -NS_IMETHODIMP -nsPreloadURIs::Run() -{ - PreloadURIs(mURIs, mScriptThread); - return NS_OK; -} - -void -nsPreloadURIs::PreloadURIs(const nsAutoTArray<nsSpeculativeScriptThread::PrefetchEntry, 5> &aURIs, - nsSpeculativeScriptThread *aScriptThread) -{ - NS_ASSERTION(NS_IsMainThread(), "Touching non-threadsafe objects off thread"); - - if (aScriptThread->Terminated()) { - return; - } - - nsIDocument *doc = aScriptThread->GetDocument(); - NS_ASSERTION(doc, "We shouldn't have started preloading without a document"); - - // Note: Per the code in the HTML content sink, we should be keeping track - // of each <base href> as it comes. However, because we do our speculative - // parsing off the main thread, this is hard to emulate. For now, just load - // the URIs using the document's base URI at the potential cost of being - // wrong and having to re-load a given relative URI later. - nsIURI *base = doc->GetDocBaseURI(); - const nsCString &charset = doc->GetDocumentCharacterSet(); - nsSpeculativeScriptThread::PreloadedType &alreadyPreloaded = - aScriptThread->GetPreloadedURIs(); - for (PRUint32 i = 0, e = aURIs.Length(); i < e; ++i) { - const nsSpeculativeScriptThread::PrefetchEntry &pe = aURIs[i]; - nsCOMPtr<nsIURI> uri; - nsresult rv = NS_NewURI(getter_AddRefs(uri), pe.uri, charset.get(), base); - if (NS_FAILED(rv)) { - NS_WARNING("Failed to create a URI"); - continue; - } - - nsCAutoString spec; - uri->GetSpec(spec); - bool answer; - if (alreadyPreloaded.Get(spec, &answer)) { - // Already preloaded. Don't preload again. - continue; - } - - alreadyPreloaded.Put(spec, true); - - switch (pe.type) { - case nsSpeculativeScriptThread::SCRIPT: - doc->ScriptLoader()->PreloadURI(uri, pe.charset, pe.elementType); - break; - case nsSpeculativeScriptThread::IMAGE: - doc->MaybePreLoadImage(uri, EmptyString()); - break; - case nsSpeculativeScriptThread::STYLESHEET: - doc->PreloadStyle(uri, pe.charset); - break; - case nsSpeculativeScriptThread::NONE: - NS_NOTREACHED("Uninitialized preload entry?"); - break; - } - } -} - -NS_IMPL_THREADSAFE_ISUPPORTS1(nsSpeculativeScriptThread, nsIRunnable) - -NS_IMETHODIMP -nsSpeculativeScriptThread::Run() -{ - NS_ASSERTION(!NS_IsMainThread(), "Speculative parsing on the main thread?"); - - mNumConsumed = 0; - - mTokenizer->WillTokenize(false, &mTokenAllocator); - while (mKeepParsing) { - bool flushTokens = false; - nsresult rv = mTokenizer->ConsumeToken(*mScanner, flushTokens); - if (NS_FAILED(rv)) { - break; - } - - mNumConsumed += mScanner->Mark(); - - // TODO Don't pop the tokens. - CToken *token; - while (mKeepParsing && (token = mTokenizer->PopToken())) { - ProcessToken(token); - } - } - mTokenizer->DidTokenize(false); - - if (mKeepParsing) { - // Ran out of room in this part of the document -- flush out the URIs we - // gathered so far so we don't end up waiting for the parser's current - // load to finish. - if (!mURIs.IsEmpty()) { - FlushURIs(); - } - } - - { - MutexAutoLock al(mLock); - - mCurrentlyParsing = false; - mCVar.Notify(); - } - return NS_OK; -} - -nsresult -nsSpeculativeScriptThread::StartParsing(nsParser *aParser) -{ - NS_ASSERTION(NS_IsMainThread(), "Called on the wrong thread"); - NS_ASSERTION(!mCurrentlyParsing, "Bad race happening"); - - if (!aParser->ThreadPool()) { - return NS_OK; - } - - nsIContentSink *sink = aParser->GetContentSink(); - if (!sink) { - return NS_OK; - } - - nsCOMPtr<nsIDocument> doc = do_QueryInterface(sink->GetTarget()); - if (!doc) { - return NS_OK; - } - - nsAutoString toScan; - CParserContext *context = aParser->PeekContext(); - if (!mTokenizer) { - if (!mPreloadedURIs.Init(15)) { - return NS_ERROR_OUT_OF_MEMORY; - } - - mTokenizer = new nsHTMLTokenizer(context->mDTDMode, context->mDocType, - context->mParserCommand, 0); - if (!mTokenizer) { - return NS_ERROR_OUT_OF_MEMORY; - } - mTokenizer->CopyState(context->mTokenizer); - context->mScanner->CopyUnusedData(toScan); - if (toScan.IsEmpty()) { - return NS_OK; - } - } else if (context == mContext) { - // Don't parse the same part of the document twice. - nsScannerIterator end; - context->mScanner->EndReading(end); - - nsScannerIterator start; - context->mScanner->CurrentPosition(start); - - if (mNumConsumed > context->mNumConsumed) { - // We consumed more the last time we tried speculatively parsing than we - // did the last time we actually parsed. - PRUint32 distance = Distance(start, end); - start.advance(NS_MIN(mNumConsumed - context->mNumConsumed, distance)); - } - - if (start == end) { - // We're at the end of this context's buffer, nothing else to do. - return NS_OK; - } - - CopyUnicodeTo(start, end, toScan); - } else { - // Grab all of the context. - context->mScanner->CopyUnusedData(toScan); - if (toScan.IsEmpty()) { - // Nothing to parse, don't do anything. - return NS_OK; - } - } - - nsCAutoString charset; - PRInt32 source; - aParser->GetDocumentCharset(charset, source); - - mScanner = new nsScanner(toScan, charset, source); - if (!mScanner) { - return NS_ERROR_OUT_OF_MEMORY; - } - mScanner->SetIncremental(true); - - mDocument.swap(doc); - mKeepParsing = true; - mCurrentlyParsing = true; - mContext = context; - return aParser->ThreadPool()->Dispatch(this, NS_DISPATCH_NORMAL); -} - -void -nsSpeculativeScriptThread::StopParsing(bool /*aFromDocWrite*/) -{ - NS_ASSERTION(NS_IsMainThread(), "Can't stop parsing from another thread"); - - { - MutexAutoLock al(mLock); - - mKeepParsing = false; - if (mCurrentlyParsing) { - mCVar.Wait(); - NS_ASSERTION(!mCurrentlyParsing, "Didn't actually stop parsing?"); - } - } - - // The thread is now idle. - if (mTerminated) { - // If we're terminated, then we need to ensure that we release our document - // and tokenizer here on the main thread so that our last reference to them - // isn't our alter-ego rescheduled on another thread. - mDocument = nsnull; - mTokenizer = nsnull; - mScanner = nsnull; - } else if (mURIs.Length()) { - // Note: Don't do this if we're terminated. - nsPreloadURIs::PreloadURIs(mURIs, this); - mURIs.Clear(); - } - - // Note: Currently, we pop the tokens off (see the comment in Run) so this - // isn't a problem. If and when we actually use the tokens created - // off-thread, we'll need to use aFromDocWrite for real. -} - -void -nsSpeculativeScriptThread::ProcessToken(CToken *aToken) -{ - // Only called on the speculative script thread. - - CHTMLToken *token = static_cast<CHTMLToken *>(aToken); - switch (static_cast<eHTMLTokenTypes>(token->GetTokenType())) { - case eToken_start: { - CStartToken *start = static_cast<CStartToken *>(aToken); - nsHTMLTag tag = static_cast<nsHTMLTag>(start->GetTypeID()); - PRInt16 attrs = start->GetAttributeCount(); - PRInt16 i = 0; - nsAutoString src; - nsAutoString elementType; - nsAutoString charset; - nsAutoString href; - nsAutoString rel; - PrefetchType ptype = NONE; - - switch (tag) { - case eHTMLTag_link: - ptype = STYLESHEET; - break; - - case eHTMLTag_img: - ptype = IMAGE; - break; - - case eHTMLTag_script: - ptype = SCRIPT; - break; - - default: - break; - } - - // We currently handle the following element/attribute combos : - // <link rel="stylesheet" href= charset= type> - // <script src= charset= type=> - if (ptype != NONE) { - // loop over all attributes to extract relevant info - for (; i < attrs ; ++i) { - CAttributeToken *attr = static_cast<CAttributeToken *>(mTokenizer->PopToken()); - NS_ASSERTION(attr->GetTokenType() == eToken_attribute, "Weird token"); - - if (attr->GetKey().EqualsLiteral("src")) { - src.Assign(attr->GetValue()); - } else if (attr->GetKey().EqualsLiteral("href")) { - href.Assign(attr->GetValue()); - } else if (attr->GetKey().EqualsLiteral("rel")) { - rel.Assign(attr->GetValue()); - } else if (attr->GetKey().EqualsLiteral("charset")) { - charset.Assign(attr->GetValue()); - } else if (attr->GetKey().EqualsLiteral("type")) { - elementType.Assign(attr->GetValue()); - } - - IF_FREE(attr, &mTokenAllocator); - } - - // ensure we have the right kind if it's a link-element - if (ptype == STYLESHEET) { - if (rel.EqualsLiteral("stylesheet")) { - src = href; // src is the important variable below - } else { - src.Truncate(); // clear src if wrong kind of link - } - } - - // add to list if we have a valid src - if (!src.IsEmpty()) { - AddToPrefetchList(src, charset, elementType, ptype); - } - } else { - // Irrelevant tag, but pop and free all its attributes in any case - for (; i < attrs ; ++i) { - CToken *attr = mTokenizer->PopToken(); - IF_FREE(attr, &mTokenAllocator); - } - } - break; - } - - default: - break; - } - - IF_FREE(aToken, &mTokenAllocator); -} - -void -nsSpeculativeScriptThread::AddToPrefetchList(const nsAString &src, - const nsAString &charset, - const nsAString &elementType, - PrefetchType type) -{ - PrefetchEntry *pe = mURIs.AppendElement(); - pe->type = type; - pe->uri = src; - pe->charset = charset; - pe->elementType = elementType; - - if (mURIs.Length() == kBatchPrefetchURIs) { - FlushURIs(); - } -} - -void -nsSpeculativeScriptThread::FlushURIs() -{ - nsCOMPtr<nsIRunnable> r = new nsPreloadURIs(mURIs, this); - if (!r) { - return; - } - - mURIs.Clear(); - NS_DispatchToMainThread(r, NS_DISPATCH_NORMAL); -} - nsICharsetAlias* nsParser::sCharsetAliasService = nsnull; nsICharsetConverterManager* nsParser::sCharsetConverterManager = nsnull; -nsIThreadPool* nsParser::sSpeculativeThreadPool = nsnull; /** * This gets called when the htmlparser module is initialized. */ // static nsresult nsParser::Init() { @@ -675,47 +180,28 @@ nsParser::Init() nsCOMPtr<nsICharsetConverterManager> charsetConverter = do_GetService(NS_CHARSETCONVERTERMANAGER_CONTRACTID, &rv); NS_ENSURE_SUCCESS(rv, rv); charsetAlias.swap(sCharsetAliasService); charsetConverter.swap(sCharsetConverterManager); - nsCOMPtr<nsIThreadPool> threadPool = - do_CreateInstance(NS_THREADPOOL_CONTRACTID, &rv); - NS_ENSURE_SUCCESS(rv, rv); - - rv = threadPool->SetThreadLimit(kSpeculativeThreadLimit); - NS_ENSURE_SUCCESS(rv, rv); - - rv = threadPool->SetIdleThreadLimit(kIdleThreadLimit); - NS_ENSURE_SUCCESS(rv, rv); - - rv = threadPool->SetIdleThreadTimeout(kIdleThreadTimeout); - NS_ENSURE_SUCCESS(rv, rv); - - threadPool.swap(sSpeculativeThreadPool); - return NS_OK; } /** * This gets called when the htmlparser module is shutdown. */ // static void nsParser::Shutdown() { NS_IF_RELEASE(sCharsetAliasService); NS_IF_RELEASE(sCharsetConverterManager); - if (sSpeculativeThreadPool) { - sSpeculativeThreadPool->Shutdown(); - NS_RELEASE(sSpeculativeThreadPool); - } } #ifdef DEBUG static bool gDumpContent=false; #endif /** * default constructor @@ -790,20 +276,16 @@ nsParser::Cleanup() delete mParserContext; mParserContext = pc; } // It should not be possible for this flag to be set when we are getting // destroyed since this flag implies a pending nsParserContinueEvent, which // has an owning reference to |this|. NS_ASSERTION(!(mFlags & NS_PARSER_FLAG_PENDING_CONTINUE_EVENT), "bad"); - if (mSpeculativeScriptThread) { - mSpeculativeScriptThread->Terminate(); - mSpeculativeScriptThread = nsnull; - } } NS_IMPL_CYCLE_COLLECTION_CLASS(nsParser) NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(nsParser) NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mDTD) NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mSink) NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mObserver) @@ -1522,48 +1004,22 @@ nsParser::DidBuildModel(nsresult anError // DTD was to NS_ENSURE_SUCCESS the sink DidBuildModel call, so if the // sink returns failure we should use sinkResult instead of dtdResult, // to preserve the old error handling behavior of the DTD: result = NS_FAILED(sinkResult) ? sinkResult : dtdResult; } //Ref. to bug 61462. mParserContext->mRequest = 0; - - if (mSpeculativeScriptThread) { - mSpeculativeScriptThread->Terminate(); - mSpeculativeScriptThread = nsnull; - } } } return result; } -void -nsParser::SpeculativelyParse() -{ - if (mParserContext->mParserCommand == eViewNormal && - !mParserContext->mMimeType.EqualsLiteral("text/html")) { - return; - } - - if (!mSpeculativeScriptThread) { - mSpeculativeScriptThread = new nsSpeculativeScriptThread(); - if (!mSpeculativeScriptThread) { - return; - } - } - - nsresult rv = mSpeculativeScriptThread->StartParsing(this); - if (NS_FAILED(rv)) { - mSpeculativeScriptThread = nsnull; - } -} - /** * This method adds a new parser context to the list, * pushing the current one to the next position. * * @param ptr to new context */ void nsParser::PushContext(CParserContext& aContext) @@ -1655,20 +1111,16 @@ nsParser::Terminate(void) mInternalState = result = NS_ERROR_HTMLPARSER_STOPPARSING; // CancelParsingEvents must be called to avoid leaking the nsParser object // @see bug 108049 // If NS_PARSER_FLAG_PENDING_CONTINUE_EVENT is set then CancelParsingEvents // will reset it so DidBuildModel will call DidBuildModel on the DTD. Note: // The IsComplete() call inside of DidBuildModel looks at the pendingContinueEvents flag. CancelParsingEvents(); - if (mSpeculativeScriptThread) { - mSpeculativeScriptThread->Terminate(); - mSpeculativeScriptThread = nsnull; - } // If we got interrupted in the middle of a document.write, then we might // have more than one parser context on our parsercontext stack. This has // the effect of making DidBuildModel a no-op, meaning that we never call // our sink's DidBuildModel and break the reference cycle, causing a leak. // Since we're getting terminated, we manually clean up our context stack. while (mParserContext && mParserContext->mPrevContext) { CParserContext *prev = mParserContext->mPrevContext; @@ -1707,20 +1159,16 @@ nsParser::ContinueInterruptedParsing() nsCOMPtr<nsIParser> kungFuDeathGrip(this); #ifdef DEBUG if (!(mFlags & NS_PARSER_FLAG_PARSER_ENABLED)) { NS_WARNING("Don't call ContinueInterruptedParsing on a blocked parser."); } #endif - if (mSpeculativeScriptThread) { - mSpeculativeScriptThread->StopParsing(false); - } - bool isFinalChunk = mParserContext && mParserContext->mStreamListenerState == eOnStop; mProcessingNetworkData = true; if (mSink) { mSink->WillParse(); } result = ResumeParse(true, isFinalChunk); // Ref. bug 57999 @@ -1845,17 +1293,16 @@ nsParser::SetCanInterrupt(bool aCanInter NS_IMETHODIMP nsParser::Parse(nsIURI* aURL, nsIRequestObserver* aListener, void* aKey, nsDTDMode aMode) { NS_PRECONDITION(aURL, "Error: Null URL given"); - NS_ASSERTION(!mSpeculativeScriptThread, "Can't reuse a parser like this"); nsresult result=kBadURL; mObserver = aListener; if (aURL) { nsCAutoString spec; nsresult rv = aURL->GetSpec(spec); if (rv != NS_OK) { @@ -1907,20 +1354,16 @@ nsParser::Parse(const nsAString& aSource // Nothing is being passed to the parser so return // immediately. mUnusedInput will get processed when // some data is actually passed in. // But if this is the last call, make sure to finish up // stuff correctly. return result; } - if (mSpeculativeScriptThread) { - mSpeculativeScriptThread->StopParsing(true); - } - // Hack to pass on to the dtd the caller's desire to // parse a fragment without worrying about containment rules if (aMode == eDTDMode_fragment) mCommand = eViewFragment; // Maintain a reference to ourselves so we don't go away // till we're completely done. nsCOMPtr<nsIParser> kungFuDeathGrip(this); @@ -2022,18 +1465,16 @@ nsParser::ParseFragment(const nsAString& nsresult result = NS_OK; nsAutoString theContext; PRUint32 theCount = aTagStack.Length(); PRUint32 theIndex = 0; // Disable observers for fragments mFlags &= ~NS_PARSER_FLAG_OBSERVERS_ENABLED; - NS_ASSERTION(!mSpeculativeScriptThread, "Can't reuse a parser like this"); - for (theIndex = 0; theIndex < theCount; theIndex++) { theContext.AppendLiteral("<"); theContext.Append(aTagStack[theCount - theIndex - 1]); theContext.AppendLiteral(">"); } if (theCount == 0) { // Ensure that the buffer is not empty. Because none of the DTDs care @@ -2141,18 +1582,16 @@ nsParser::ParseFragment(const nsAString& nsresult nsParser::ResumeParse(bool allowIteration, bool aIsFinalChunk, bool aCanInterrupt) { nsresult result = NS_OK; if ((mFlags & NS_PARSER_FLAG_PARSER_ENABLED) && mInternalState != NS_ERROR_HTMLPARSER_STOPPARSING) { - NS_ASSERTION(!mSpeculativeScriptThread || !mSpeculativeScriptThread->Parsing(), - "Bad races happening, expect to crash!"); result = WillBuildModel(mParserContext->mScanner->GetFilename()); if (NS_FAILED(result)) { mFlags &= ~NS_PARSER_FLAG_CAN_TOKENIZE; return result; } if (mDTD) { @@ -2192,17 +1631,16 @@ nsParser::ResumeParse(bool allowIteratio // If we're told to block the parser, we disable all further parsing // (and cache any data coming in) until the parser is re-enabled. if (NS_ERROR_HTMLPARSER_BLOCK == result) { mSink->WillInterrupt(); if (mFlags & NS_PARSER_FLAG_PARSER_ENABLED) { // If we were blocked by a recursive invocation, don't re-block. BlockParser(); - SpeculativelyParse(); } return NS_OK; } if (NS_ERROR_HTMLPARSER_STOPPARSING == result) { // Note: Parser Terminate() calls DidBuildModel. if (mInternalState != NS_ERROR_HTMLPARSER_STOPPARSING) { DidBuildModel(mStreamStatus); mInternalState = result; @@ -2713,21 +2151,16 @@ nsParser::OnDataAvailable(nsIRequest *re while (theContext && theContext->mRequest != request) { theContext = theContext->mPrevContext; } if (theContext) { theContext->mStreamListenerState = eOnDataAvail; - if ((mFlags & NS_PARSER_FLAG_PARSER_ENABLED) && - mSpeculativeScriptThread) { - mSpeculativeScriptThread->StopParsing(false); - } - if (eInvalidDetect == theContext->mAutoDetectStatus) { if (theContext->mScanner) { nsScannerIterator iter; theContext->mScanner->EndReading(iter); theContext->mScanner->SetPosition(iter, true); } } @@ -2767,21 +2200,16 @@ nsParser::OnDataAvailable(nsIRequest *re * has been collected from the net. */ nsresult nsParser::OnStopRequest(nsIRequest *request, nsISupports* aContext, nsresult status) { nsresult rv = NS_OK; - if ((mFlags & NS_PARSER_FLAG_PARSER_ENABLED) && - mSpeculativeScriptThread) { - mSpeculativeScriptThread->StopParsing(false); - } - CParserContext *pc = mParserContext; while (pc) { if (pc->mRequest == request) { pc->mStreamListenerState = eOnStop; pc->mScanner->SetIncremental(false); break; }
--- a/parser/htmlparser/src/nsParser.h +++ b/parser/htmlparser/src/nsParser.h @@ -87,17 +87,16 @@ #include "nsCOMArray.h" #include "nsCycleCollectionParticipant.h" #include "nsWeakReference.h" class nsICharsetConverterManager; class nsICharsetAlias; class nsIDTD; class nsScanner; -class nsSpeculativeScriptThread; class nsIThreadPool; #ifdef _MSC_VER #pragma warning( disable : 4275 ) #endif class nsParser : public nsIParser, @@ -375,20 +374,16 @@ class nsParser : public nsIParser, return sCharsetConverterManager; } virtual void Reset() { Cleanup(); Initialize(); } - nsIThreadPool* ThreadPool() { - return sSpeculativeThreadPool; - } - bool IsScriptExecuting() { return mSink && mSink->IsScriptExecuting(); } bool IsOkToProcessNetworkData() { return !IsScriptExecuting() && !mProcessingNetworkData; } @@ -408,18 +403,16 @@ class nsParser : public nsIParser, /** * * @update gess5/18/98 * @param * @return */ nsresult DidBuildModel(nsresult anErrorCode); - void SpeculativelyParse(); - private: /******************************************* These are the tokenization methods... *******************************************/ /** * Part of the code sandwich, this gets called right before @@ -460,17 +453,16 @@ protected: //********************************************* CParserContext* mParserContext; nsCOMPtr<nsIDTD> mDTD; nsCOMPtr<nsIRequestObserver> mObserver; nsCOMPtr<nsIContentSink> mSink; nsIRunnable* mContinueEvent; // weak ref - nsRefPtr<nsSpeculativeScriptThread> mSpeculativeScriptThread; nsTokenAllocator mTokenAllocator; eParserCommands mCommand; nsresult mInternalState; PRInt32 mStreamStatus; PRInt32 mCharsetSource; @@ -479,19 +471,12 @@ protected: nsString mUnusedInput; nsCString mCharset; nsCString mCommandStr; bool mProcessingNetworkData; static nsICharsetAlias* sCharsetAliasService; static nsICharsetConverterManager* sCharsetConverterManager; - static nsIThreadPool* sSpeculativeThreadPool; - - enum { - kSpeculativeThreadLimit = 15, - kIdleThreadLimit = 0, - kIdleThreadTimeout = 50 - }; }; #endif