Bug 1018486 - Part 6: Changes in parser/, r=peterv, r=hsivonen
authorMichael Layzell <michael@thelayzells.com>
Mon, 18 Jul 2016 12:42:35 -0400
changeset 313045 1cc4e4cbc8ae5817a7c941eb097fa3d701eea40d
parent 313044 3f37edc0d6e1eaa4b108a61355b94c7c99e3a0bc
child 313046 f5ff51f80c2de3d1d8539e9d6041bf0e052c34a4
push id30669
push userkwierso@gmail.com
push dateThu, 08 Sep 2016 00:56:12 +0000
treeherdermozilla-central@77940cbf0c2a [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerspeterv, hsivonen
bugs1018486
milestone51.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
Bug 1018486 - Part 6: Changes in parser/, r=peterv, r=hsivonen MozReview-Commit-ID: EN2yZUn8xj
parser/html/nsHtml5Parser.cpp
parser/html/nsHtml5TreeOpExecutor.cpp
parser/htmlparser/nsParser.cpp
--- a/parser/html/nsHtml5Parser.cpp
+++ b/parser/html/nsHtml5Parser.cpp
@@ -205,50 +205,51 @@ nsHtml5Parser::Parse(const nsAString& aS
 
   // Maintain a reference to ourselves so we don't go away
   // till we're completely done. The old parser grips itself in this method.
   nsCOMPtr<nsIParser> kungFuDeathGrip(this);
   
   // Gripping the other objects just in case, since the other old grip
   // required grips to these, too.
   RefPtr<nsHtml5StreamParser> streamKungFuDeathGrip(GetStreamParser());
-  RefPtr<nsHtml5TreeOpExecutor> treeOpKungFuDeathGrip(mExecutor);
+  mozilla::Unused << streamKungFuDeathGrip; // Not used within function
+  RefPtr<nsHtml5TreeOpExecutor> executor(mExecutor);
 
-  if (!mExecutor->HasStarted()) {
+  if (!executor->HasStarted()) {
     NS_ASSERTION(!GetStreamParser(),
                  "Had stream parser but document.write started life cycle.");
     // This is the first document.write() on a document.open()ed document
-    mExecutor->SetParser(this);
-    mTreeBuilder->setScriptingEnabled(mExecutor->IsScriptEnabled());
+    executor->SetParser(this);
+    mTreeBuilder->setScriptingEnabled(executor->IsScriptEnabled());
 
     bool isSrcdoc = false;
     nsCOMPtr<nsIChannel> channel;
     rv = GetChannel(getter_AddRefs(channel));
     if (NS_SUCCEEDED(rv)) {
       isSrcdoc = NS_IsSrcdocChannel(channel);
     }
     mTreeBuilder->setIsSrcdocDocument(isSrcdoc);
 
     mTokenizer->start();
-    mExecutor->Start();
+    executor->Start();
     if (!aContentType.EqualsLiteral("text/html")) {
       mTreeBuilder->StartPlainText();
       mTokenizer->StartPlainText();
     }
     /*
      * If you move the following line, be very careful not to cause 
      * WillBuildModel to be called before the document has had its 
      * script global object set.
      */
-    rv = mExecutor->WillBuildModel(eDTDMode_unknown);
+    rv = executor->WillBuildModel(eDTDMode_unknown);
     NS_ENSURE_SUCCESS(rv, rv);
   }
 
   // Return early if the parser has processed EOF
-  if (mExecutor->IsComplete()) {
+  if (executor->IsComplete()) {
     return NS_OK;
   }
 
   if (aLastCall && aSourceBuffer.IsEmpty() && !aKey) {
     // document.close()
     NS_ASSERTION(!GetStreamParser(),
                  "Had stream parser but got document.close().");
     if (mDocumentClosed) {
@@ -366,51 +367,51 @@ nsHtml5Parser::Parse(const nsAString& aS
         mTokenizer->setLineNumber(mRootContextLineNumber);
       } else {
         // we aren't the root context, so save the line number on the
         // *stack* so that we can restore it.
         lineNumberSave = mTokenizer->getLineNumber();
       }
 
       if (!mTokenizer->EnsureBufferSpace(stackBuffer.getLength())) {
-        return mExecutor->MarkAsBroken(NS_ERROR_OUT_OF_MEMORY);
+        return executor->MarkAsBroken(NS_ERROR_OUT_OF_MEMORY);
       }
       mLastWasCR = mTokenizer->tokenizeBuffer(&stackBuffer);
       if (NS_FAILED((rv = mTreeBuilder->IsBroken()))) {
-        return mExecutor->MarkAsBroken(rv);
+        return executor->MarkAsBroken(rv);
       }
 
       if (inRootContext) {
         mRootContextLineNumber = mTokenizer->getLineNumber();
       } else {
         mTokenizer->setLineNumber(lineNumberSave);
       }
 
       if (mTreeBuilder->HasScript()) {
         mTreeBuilder->Flush(); // Move ops to the executor
-        rv = mExecutor->FlushDocumentWrite(); // run the ops
+        rv = executor->FlushDocumentWrite(); // run the ops
         NS_ENSURE_SUCCESS(rv, rv);
         // Flushing tree ops can cause all sorts of things.
         // Return early if the parser got terminated.
-        if (mExecutor->IsComplete()) {
+        if (executor->IsComplete()) {
           return NS_OK;
         }
       }
       // Ignore suspension requests
     }
   }
 
   RefPtr<nsHtml5OwningUTF16Buffer> heapBuffer;
   if (stackBuffer.hasMore()) {
     // The buffer wasn't tokenized to completion. Create a copy of the tail
     // on the heap.
     heapBuffer = stackBuffer.FalliblyCopyAsOwningBuffer();
     if (!heapBuffer) {
       // Allocation failed. The parser is now broken.
-      return mExecutor->MarkAsBroken(NS_ERROR_OUT_OF_MEMORY);
+      return executor->MarkAsBroken(NS_ERROR_OUT_OF_MEMORY);
     }
   }
 
   if (heapBuffer) {
     // We have something to insert before the keyholder holding in the non-null
     // aKey case and we have something to swap into firstLevelMarker in the
     // null aKey case.
     if (aKey) {
@@ -441,28 +442,28 @@ nsHtml5Parser::Parse(const nsAString& aS
     }
   }
 
   if (!mBlocked) { // buffer was tokenized to completion
     NS_ASSERTION(!stackBuffer.hasMore(),
       "Buffer wasn't tokenized to completion?");
     // Scripting semantics require a forced tree builder flush here
     mTreeBuilder->Flush(); // Move ops to the executor
-    rv = mExecutor->FlushDocumentWrite(); // run the ops
+    rv = executor->FlushDocumentWrite(); // run the ops
     NS_ENSURE_SUCCESS(rv, rv);
   } else if (stackBuffer.hasMore()) {
     // The buffer wasn't tokenized to completion. Tokenize the untokenized
     // content in order to preload stuff. This content will be retokenized
     // later for normal parsing.
     if (!mDocWriteSpeculatorActive) {
       mDocWriteSpeculatorActive = true;
       if (!mDocWriteSpeculativeTreeBuilder) {
         // Lazily initialize if uninitialized
         mDocWriteSpeculativeTreeBuilder =
-            new nsHtml5TreeBuilder(nullptr, mExecutor->GetStage());
+            new nsHtml5TreeBuilder(nullptr, executor->GetStage());
         mDocWriteSpeculativeTreeBuilder->setScriptingEnabled(
             mTreeBuilder->isScriptingEnabled());
         mDocWriteSpeculativeTokenizer =
             new nsHtml5Tokenizer(mDocWriteSpeculativeTreeBuilder, false);
         mDocWriteSpeculativeTokenizer->setInterner(&mAtomTable);
         mDocWriteSpeculativeTokenizer->start();
       }
       mDocWriteSpeculativeTokenizer->resetToDataState();
@@ -479,52 +480,52 @@ nsHtml5Parser::Parse(const nsAString& aS
     // The buffer position for subsequent non-speculative parsing now lives
     // in heapBuffer, so it's ok to let the buffer position of stackBuffer
     // to be overwritten and not restored below.
     while (stackBuffer.hasMore()) {
       stackBuffer.adjust(mDocWriteSpeculativeLastWasCR);
       if (stackBuffer.hasMore()) {
         if (!mDocWriteSpeculativeTokenizer->EnsureBufferSpace(
             stackBuffer.getLength())) {
-          return mExecutor->MarkAsBroken(NS_ERROR_OUT_OF_MEMORY);
+          return executor->MarkAsBroken(NS_ERROR_OUT_OF_MEMORY);
         }
         mDocWriteSpeculativeLastWasCR =
             mDocWriteSpeculativeTokenizer->tokenizeBuffer(&stackBuffer);
         nsresult rv;
         if (NS_FAILED((rv = mDocWriteSpeculativeTreeBuilder->IsBroken()))) {
-          return mExecutor->MarkAsBroken(rv);
+          return executor->MarkAsBroken(rv);
         }
       }
     }
 
     mDocWriteSpeculativeTreeBuilder->Flush();
     mDocWriteSpeculativeTreeBuilder->DropHandles();
-    mExecutor->FlushSpeculativeLoads();
+    executor->FlushSpeculativeLoads();
   }
 
   return NS_OK;
 }
 
 NS_IMETHODIMP
 nsHtml5Parser::Terminate()
 {
   // We should only call DidBuildModel once, so don't do anything if this is
   // the second time that Terminate has been called.
   if (mExecutor->IsComplete()) {
     return NS_OK;
   }
   // XXX - [ until we figure out a way to break parser-sink circularity ]
   // Hack - Hold a reference until we are completely done...
   nsCOMPtr<nsIParser> kungFuDeathGrip(this);
-  RefPtr<nsHtml5StreamParser> streamKungFuDeathGrip(GetStreamParser());
-  RefPtr<nsHtml5TreeOpExecutor> treeOpKungFuDeathGrip(mExecutor);
-  if (GetStreamParser()) {
-    GetStreamParser()->Terminate();
+  RefPtr<nsHtml5StreamParser> streamParser(GetStreamParser());
+  RefPtr<nsHtml5TreeOpExecutor> executor(mExecutor);
+  if (streamParser) {
+    streamParser->Terminate();
   }
-  return mExecutor->DidBuildModel(true);
+  return executor->DidBuildModel(true);
 }
 
 NS_IMETHODIMP
 nsHtml5Parser::ParseFragment(const nsAString& aSourceBuffer,
                              nsTArray<nsString>& aTagStack)
 {
   return NS_ERROR_NOT_IMPLEMENTED;
 }
--- a/parser/html/nsHtml5TreeOpExecutor.cpp
+++ b/parser/html/nsHtml5TreeOpExecutor.cpp
@@ -345,33 +345,33 @@ nsHtml5TreeOpExecutor::RunFlushLoop()
 
   if (mRunFlushLoopOnStack) {
     // There's already a RunFlushLoop() on the call stack.
     return;
   }
   
   nsHtml5FlushLoopGuard guard(this); // this is also the self-kungfu!
   
-  nsCOMPtr<nsISupports> parserKungFuDeathGrip(mParser);
+  RefPtr<nsParserBase> parserKungFuDeathGrip(mParser);
 
   // Remember the entry time
   (void) nsContentSink::WillParseImpl();
 
   for (;;) {
     if (!mParser) {
       // Parse has terminated.
       mOpQueue.Clear(); // clear in order to be able to assert in destructor
       return;
     }
 
     if (NS_FAILED(IsBroken())) {
       return;
     }
 
-    if (!mParser->IsParserEnabled()) {
+    if (!parserKungFuDeathGrip->IsParserEnabled()) {
       // The parser is blocked.
       return;
     }
   
     if (mFlushState != eNotFlushing) {
       // XXX Can this happen? In case it can, let's avoid crashing.
       return;
     }
@@ -408,16 +408,17 @@ nsHtml5TreeOpExecutor::RunFlushLoop()
         // An extension terminated the parser from a HTTP observer.
         mOpQueue.Clear(); // clear in order to be able to assert in destructor
         return;
       }
       // Not sure if this grip is still needed, but previously, the code
       // gripped before calling ParseUntilBlocked();
       RefPtr<nsHtml5StreamParser> streamKungFuDeathGrip = 
         GetParser()->GetStreamParser();
+      mozilla::Unused << streamKungFuDeathGrip; // Not used within function
       // Now parse content left in the document.write() buffer queue if any.
       // This may generate tree ops on its own or dequeue a speculation.
       nsresult rv = GetParser()->ParseUntilBlocked();
       if (NS_FAILED(rv)) {
         MarkAsBroken(rv);
         return;
       }
     }
@@ -522,16 +523,17 @@ nsHtml5TreeOpExecutor::FlushDocumentWrit
     return rv;
   }
 
   mFlushState = eInFlush;
 
   // avoid crashing near EOF
   RefPtr<nsHtml5TreeOpExecutor> kungFuDeathGrip(this);
   RefPtr<nsParserBase> parserKungFuDeathGrip(mParser);
+  mozilla::Unused << parserKungFuDeathGrip; // Intentionally not used within function
 
   NS_ASSERTION(!mReadingFromStage,
     "Got doc write flush when reading from stage");
 
 #ifdef DEBUG
   mStage.AssertEmpty();
 #endif
   
--- a/parser/htmlparser/nsParser.cpp
+++ b/parser/htmlparser/nsParser.cpp
@@ -1045,18 +1045,18 @@ nsParser::ContinueInterruptedParsing()
     NS_WARNING("Don't call ContinueInterruptedParsing on a blocked parser.");
   }
 #endif
 
   bool isFinalChunk = mParserContext &&
                         mParserContext->mStreamListenerState == eOnStop;
 
   mProcessingNetworkData = true;
-  if (mSink) {
-    mSink->WillParse();
+  if (sinkDeathGrip) {
+    sinkDeathGrip->WillParse();
   }
   result = ResumeParse(true, isFinalChunk); // Ref. bug 57999
   mProcessingNetworkData = false;
 
   if (result != NS_OK) {
     result=mInternalState;
   }
 
@@ -1831,18 +1831,18 @@ nsParser::OnDataAvailable(nsIRequest *re
 
     // Don't bother to start parsing until we've seen some
     // non-whitespace data
     if (IsOkToProcessNetworkData() &&
         theContext->mScanner->FirstNonWhitespacePosition() >= 0) {
       nsCOMPtr<nsIParser> kungFuDeathGrip(this);
       nsCOMPtr<nsIContentSink> sinkDeathGrip(mSink);
       mProcessingNetworkData = true;
-      if (mSink) {
-        mSink->WillParse();
+      if (sinkDeathGrip) {
+        sinkDeathGrip->WillParse();
       }
       rv = ResumeParse();
       mProcessingNetworkData = false;
     }
   } else {
     rv = NS_ERROR_UNEXPECTED;
   }