Bug 1018486 - Part 6: Changes in parser/. r=peterv, r=hsivonen, a=ritu
authorMichael Layzell <michael@thelayzells.com>
Wed, 21 Sep 2016 22:20:14 -0400
changeset 350353 f6e34311ee43c4bd0e71ec422fb4efa24e31875f
parent 350352 0e7cb9862be7de356c0d828c69ed2094dcd7680b
child 350354 14c91e05c3997988eb50d895dade51f904280021
push id1230
push userjlund@mozilla.com
push dateMon, 31 Oct 2016 18:13:35 +0000
treeherdermozilla-release@5e06e3766db2 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerspeterv, hsivonen, ritu
bugs1018486
milestone50.0
Bug 1018486 - Part 6: Changes in parser/. r=peterv, r=hsivonen, a=ritu 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;
   }