Bug 458440 - Don't create a speculative parser for an empty string. Also, avoid doing work that the scanner will happily do for us. r+sr=jst
authorBlake Kaplan <mrbkap@gmail.com>
Fri, 03 Oct 2008 14:11:12 -0700
changeset 20076 5f519a29afec46c045931493a132e10a673924dc
parent 20075 184ad4f909cd4f3e17df7a91bfbf5732b0c4bc7d
child 20077 0c1ec80708a16cf2c83c26e9f860f86234b330c0
push idunknown
push userunknown
push dateunknown
bugs458440
milestone1.9.1b1pre
Bug 458440 - Don't create a speculative parser for an empty string. Also, avoid doing work that the scanner will happily do for us. r+sr=jst
parser/htmlparser/src/nsParser.cpp
--- a/parser/htmlparser/src/nsParser.cpp
+++ b/parser/htmlparser/src/nsParser.cpp
@@ -201,16 +201,17 @@ class nsSpeculativeScriptThread : public
 public:
   nsSpeculativeScriptThread()
     : mLock(PR_DestroyLock),
       mCVar(PR_DestroyCondVar),
       mKeepParsing(0),
       mCurrentlyParsing(0),
       mNumURIs(0),
       mNumConsumed(0),
+      mContext(nsnull),
       mTerminated(PR_FALSE) {
   }
 
   ~nsSpeculativeScriptThread() {
     NS_ASSERTION(NS_IsMainThread() || !mDocument,
                  "Destroying the document on the wrong thread");
   }
 
@@ -367,41 +368,40 @@ nsPreloadURIs::PreloadURIs(const nsAutoT
   }
 }
 
 NS_IMPL_THREADSAFE_ISUPPORTS1(nsSpeculativeScriptThread, nsIRunnable)
 
 NS_IMETHODIMP
 nsSpeculativeScriptThread::Run()
 {
-  nsScannerIterator start;
-  mScanner->CurrentPosition(start);
+  NS_ASSERTION(!NS_IsMainThread(), "Speculative parsing on the main thread?");
+
+  mNumConsumed = 0;
+
   mTokenizer->WillTokenize(PR_FALSE, &mTokenAllocator);
   while (mKeepParsing) {
     PRBool flushTokens = PR_FALSE;
     nsresult rv = mTokenizer->ConsumeToken(*mScanner, flushTokens);
     if (rv == kEOF) {
       break;
     }
 
+    mNumConsumed += mScanner->Mark();
+
     // TODO Don't pop the tokens.
     CToken *token;
     while (mKeepParsing && NS_SUCCEEDED(rv) && (token = mTokenizer->PopToken())) {
       rv = ProcessToken(token);
     }
   }
   mTokenizer->DidTokenize(PR_FALSE);
 
   nsAutoLock al(mLock.get());
 
-  nsScannerIterator end;
-  mScanner->CurrentPosition(end);
-
-  mNumConsumed = Distance(start, end);
-
   mCurrentlyParsing = 0;
   PR_NotifyCondVar(mCVar.get());
   return NS_OK;
 }
 
 nsresult
 nsSpeculativeScriptThread::StartParsing(nsParser *aParser)
 {
@@ -441,16 +441,19 @@ nsSpeculativeScriptThread::StartParsing(
 
     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);