Backed out changeset aa30bc1b369b (bug 1763076) for causing assertion failure in parser/html/nsHtml5TreeOpExecutor.cpp CLOSED TREE
This commit is contained in:
@@ -12,7 +12,6 @@
|
||||
#include <new>
|
||||
#include <type_traits>
|
||||
#include <utility>
|
||||
#include "ErrorList.h"
|
||||
#include "GeckoProfiler.h"
|
||||
#include "js/GCAPI.h"
|
||||
#include "mozilla/ArrayIterator.h"
|
||||
@@ -776,15 +775,9 @@ nsresult nsHtml5StreamParser::SniffStreamBytes(Span<const uint8_t> aFromSegment,
|
||||
MOZ_ASSERT(mLookingForMetaCharset);
|
||||
|
||||
if (mMode == VIEW_SOURCE_HTML) {
|
||||
auto r = mTokenizer->FlushViewSource();
|
||||
if (r.isErr()) {
|
||||
return r.unwrapErr();
|
||||
}
|
||||
}
|
||||
auto r = mTreeBuilder->Flush();
|
||||
if (r.isErr()) {
|
||||
return r.unwrapErr();
|
||||
mTokenizer->FlushViewSource();
|
||||
}
|
||||
mTreeBuilder->Flush();
|
||||
// Encoding committer flushes the ops on the main thread.
|
||||
|
||||
mozilla::MutexAutoLock speculationAutoLock(mSpeculationMutex);
|
||||
@@ -930,16 +923,10 @@ nsresult nsHtml5StreamParser::WriteStreamBytes(
|
||||
mCharsetSource = source;
|
||||
if (encoding != mEncoding) {
|
||||
mEncoding = encoding;
|
||||
nsresult rv = ReDecodeLocalFile();
|
||||
if (NS_FAILED(rv)) {
|
||||
return rv;
|
||||
}
|
||||
ReDecodeLocalFile();
|
||||
} else {
|
||||
MOZ_ASSERT(mEncoding == UTF_8_ENCODING);
|
||||
nsresult rv = CommitLocalFileToEncoding();
|
||||
if (NS_FAILED(rv)) {
|
||||
return rv;
|
||||
}
|
||||
CommitLocalFileToEncoding();
|
||||
}
|
||||
}
|
||||
return NS_OK;
|
||||
@@ -947,7 +934,7 @@ nsresult nsHtml5StreamParser::WriteStreamBytes(
|
||||
}
|
||||
}
|
||||
|
||||
[[nodiscard]] nsresult nsHtml5StreamParser::ReDecodeLocalFile() {
|
||||
void nsHtml5StreamParser::ReDecodeLocalFile() {
|
||||
MOZ_ASSERT(mDecodingLocalFileWithoutTokenizing && !mLookingForMetaCharset);
|
||||
MOZ_ASSERT(mFirstBufferOfMetaScan);
|
||||
MOZ_ASSERT(mCharsetSource == kCharsetFromFinalAutoDetectionFile ||
|
||||
@@ -981,19 +968,12 @@ nsresult nsHtml5StreamParser::WriteStreamBytes(
|
||||
}
|
||||
|
||||
if (mMode == VIEW_SOURCE_HTML) {
|
||||
auto r = mTokenizer->FlushViewSource();
|
||||
if (r.isErr()) {
|
||||
return r.unwrapErr();
|
||||
}
|
||||
mTokenizer->FlushViewSource();
|
||||
}
|
||||
auto r = mTreeBuilder->Flush();
|
||||
if (r.isErr()) {
|
||||
return r.unwrapErr();
|
||||
}
|
||||
return NS_OK;
|
||||
mTreeBuilder->Flush();
|
||||
}
|
||||
|
||||
[[nodiscard]] nsresult nsHtml5StreamParser::CommitLocalFileToEncoding() {
|
||||
void nsHtml5StreamParser::CommitLocalFileToEncoding() {
|
||||
MOZ_ASSERT(mDecodingLocalFileWithoutTokenizing && !mLookingForMetaCharset);
|
||||
MOZ_ASSERT(mFirstBufferOfMetaScan);
|
||||
mDecodingLocalFileWithoutTokenizing = false;
|
||||
@@ -1019,16 +999,9 @@ nsresult nsHtml5StreamParser::WriteStreamBytes(
|
||||
mForceAutoDetection = false; // To stop feeding the detector
|
||||
mTreeBuilder->SetDocumentCharset(mEncoding, mCharsetSource, true);
|
||||
if (mMode == VIEW_SOURCE_HTML) {
|
||||
auto r = mTokenizer->FlushViewSource();
|
||||
if (r.isErr()) {
|
||||
return r.unwrapErr();
|
||||
}
|
||||
mTokenizer->FlushViewSource();
|
||||
}
|
||||
auto r = mTreeBuilder->Flush();
|
||||
if (r.isErr()) {
|
||||
return r.unwrapErr();
|
||||
}
|
||||
return NS_OK;
|
||||
mTreeBuilder->Flush();
|
||||
}
|
||||
|
||||
class MaybeRunCollector : public Runnable {
|
||||
@@ -1136,10 +1109,7 @@ nsresult nsHtml5StreamParser::OnStartRequest(nsIRequest* aRequest) {
|
||||
mTemplatePushedOrHeadPopped); // Needed to force 1024-byte sniffing
|
||||
// Flush the ops to put them where ContinueAfterScriptsOrEncodingCommitment
|
||||
// can find them.
|
||||
auto r = mTreeBuilder->Flush();
|
||||
if (r.isErr()) {
|
||||
return mExecutor->MarkAsBroken(r.unwrapErr());
|
||||
}
|
||||
mTreeBuilder->Flush();
|
||||
} else if (mMode == VIEW_SOURCE_PLAIN) {
|
||||
nsAutoString viewSourceTitle;
|
||||
CopyUTF8toUTF16(mViewSourceTitle, viewSourceTitle);
|
||||
@@ -1150,10 +1120,7 @@ nsresult nsHtml5StreamParser::OnStartRequest(nsIRequest* aRequest) {
|
||||
mTemplatePushedOrHeadPopped); // Needed to force 1024-byte sniffing
|
||||
// Flush the ops to put them where ContinueAfterScriptsOrEncodingCommitment
|
||||
// can find them.
|
||||
auto r = mTreeBuilder->Flush();
|
||||
if (r.isErr()) {
|
||||
return mExecutor->MarkAsBroken(r.unwrapErr());
|
||||
}
|
||||
mTreeBuilder->Flush();
|
||||
} else if (mMode == VIEW_SOURCE_HTML || mMode == VIEW_SOURCE_XML) {
|
||||
// Generate and flush the View Source document up to and including the
|
||||
// pre element start.
|
||||
@@ -1163,10 +1130,7 @@ nsresult nsHtml5StreamParser::OnStartRequest(nsIRequest* aRequest) {
|
||||
}
|
||||
// Flush the ops to put them where ContinueAfterScriptsOrEncodingCommitment
|
||||
// can find them.
|
||||
auto r = mTokenizer->FlushViewSource();
|
||||
if (r.isErr()) {
|
||||
return mExecutor->MarkAsBroken(r.unwrapErr());
|
||||
}
|
||||
mTokenizer->FlushViewSource();
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -1292,11 +1256,7 @@ void nsHtml5StreamParser::DoStopRequest() {
|
||||
mTreeBuilder->SetDocumentCharset(mEncoding, mCharsetSource, false);
|
||||
|
||||
for (auto&& buffer : mBufferedBytes) {
|
||||
nsresult rv = WriteStreamBytes(buffer);
|
||||
if (NS_FAILED(rv)) {
|
||||
MarkAsBroken(rv);
|
||||
return;
|
||||
}
|
||||
Unused << WriteStreamBytes(buffer);
|
||||
}
|
||||
} else if (!mUnicodeDecoder) {
|
||||
nsresult rv;
|
||||
@@ -1356,20 +1316,12 @@ void nsHtml5StreamParser::DoStopRequest() {
|
||||
mCharsetSource = source;
|
||||
if (encoding != mEncoding) {
|
||||
mEncoding = encoding;
|
||||
nsresult rv = ReDecodeLocalFile();
|
||||
if (NS_FAILED(rv)) {
|
||||
MarkAsBroken(rv);
|
||||
return;
|
||||
}
|
||||
ReDecodeLocalFile();
|
||||
DoStopRequest();
|
||||
return;
|
||||
}
|
||||
MOZ_ASSERT(mEncoding == UTF_8_ENCODING);
|
||||
nsresult rv = CommitLocalFileToEncoding();
|
||||
if (NS_FAILED(rv)) {
|
||||
MarkAsBroken(rv);
|
||||
return;
|
||||
}
|
||||
CommitLocalFileToEncoding();
|
||||
}
|
||||
break;
|
||||
}
|
||||
@@ -1781,23 +1733,6 @@ void nsHtml5StreamParser::PostLoadFlusher() {
|
||||
if (NS_FAILED(DispatchToMain(runnable.forget()))) {
|
||||
NS_WARNING("failed to dispatch load flush event");
|
||||
}
|
||||
|
||||
if ((mMode == VIEW_SOURCE_HTML || mMode == VIEW_SOURCE_XML) &&
|
||||
mTokenizer->ShouldFlushViewSource()) {
|
||||
auto r = mTreeBuilder->Flush(); // delete useless ops
|
||||
MOZ_ASSERT(r.isOk(), "Should have null sink with View Source");
|
||||
r = mTokenizer->FlushViewSource();
|
||||
if (r.isErr()) {
|
||||
MarkAsBroken(r.unwrapErr());
|
||||
return;
|
||||
}
|
||||
if (r.unwrap()) {
|
||||
nsCOMPtr<nsIRunnable> runnable(mExecutorFlusher);
|
||||
if (NS_FAILED(DispatchToMain(runnable.forget()))) {
|
||||
NS_WARNING("failed to dispatch executor flush event");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void nsHtml5StreamParser::FlushTreeOpsAndDisarmTimer() {
|
||||
@@ -1812,15 +1747,9 @@ void nsHtml5StreamParser::FlushTreeOpsAndDisarmTimer() {
|
||||
mFlushTimerArmed = false;
|
||||
}
|
||||
if (mMode == VIEW_SOURCE_HTML || mMode == VIEW_SOURCE_XML) {
|
||||
auto r = mTokenizer->FlushViewSource();
|
||||
if (r.isErr()) {
|
||||
MarkAsBroken(r.unwrapErr());
|
||||
}
|
||||
}
|
||||
auto r = mTreeBuilder->Flush();
|
||||
if (r.isErr()) {
|
||||
MarkAsBroken(r.unwrapErr());
|
||||
mTokenizer->FlushViewSource();
|
||||
}
|
||||
mTreeBuilder->Flush();
|
||||
nsCOMPtr<nsIRunnable> runnable(mExecutorFlusher);
|
||||
if (NS_FAILED(DispatchToMain(runnable.forget()))) {
|
||||
NS_WARNING("failed to dispatch executor flush event");
|
||||
@@ -2235,17 +2164,9 @@ bool nsHtml5StreamParser::ProcessLookingForMetaCharset(bool aEof) {
|
||||
mCharsetSource = mEncodingSwitchSource;
|
||||
|
||||
if (mMode == VIEW_SOURCE_HTML) {
|
||||
auto r = mTokenizer->FlushViewSource();
|
||||
if (r.isErr()) {
|
||||
MarkAsBroken(r.unwrapErr());
|
||||
return false;
|
||||
}
|
||||
}
|
||||
auto r = mTreeBuilder->Flush();
|
||||
if (r.isErr()) {
|
||||
MarkAsBroken(r.unwrapErr());
|
||||
return false;
|
||||
mTokenizer->FlushViewSource();
|
||||
}
|
||||
mTreeBuilder->Flush();
|
||||
|
||||
if (mEncoding != needsEncodingSwitchTo) {
|
||||
// Speculation failed
|
||||
@@ -2284,11 +2205,7 @@ bool nsHtml5StreamParser::ProcessLookingForMetaCharset(bool aEof) {
|
||||
"Must have set mLookingForMetaCharset to false to report data "
|
||||
"to dev tools below");
|
||||
for (auto&& buffer : mBufferedBytes) {
|
||||
nsresult rv = WriteStreamBytes(buffer);
|
||||
if (NS_FAILED(rv)) {
|
||||
MarkAsBroken(rv);
|
||||
return false;
|
||||
}
|
||||
WriteStreamBytes(buffer);
|
||||
}
|
||||
}
|
||||
} else if (!mLookingForMetaCharset && !mDecodingLocalFileWithoutTokenizing) {
|
||||
@@ -2313,17 +2230,9 @@ bool nsHtml5StreamParser::ProcessLookingForMetaCharset(bool aEof) {
|
||||
mBufferedBytes.Clear();
|
||||
mTreeBuilder->SetDocumentCharset(mEncoding, mCharsetSource, true);
|
||||
if (mMode == VIEW_SOURCE_HTML) {
|
||||
auto r = mTokenizer->FlushViewSource();
|
||||
if (r.isErr()) {
|
||||
MarkAsBroken(r.unwrapErr());
|
||||
return false;
|
||||
}
|
||||
}
|
||||
auto r = mTreeBuilder->Flush();
|
||||
if (r.isErr()) {
|
||||
MarkAsBroken(r.unwrapErr());
|
||||
return false;
|
||||
mTokenizer->FlushViewSource();
|
||||
}
|
||||
mTreeBuilder->Flush();
|
||||
}
|
||||
}
|
||||
return rewound;
|
||||
@@ -2446,9 +2355,7 @@ void nsHtml5StreamParser::ParseAvailableData() {
|
||||
} else {
|
||||
mTreeBuilder->StreamEnded();
|
||||
if (mMode == VIEW_SOURCE_HTML || mMode == VIEW_SOURCE_XML) {
|
||||
if (!mTokenizer->EndViewSource()) {
|
||||
MarkAsBroken(NS_ERROR_OUT_OF_MEMORY);
|
||||
}
|
||||
mTokenizer->EndViewSource();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -2489,17 +2396,9 @@ void nsHtml5StreamParser::ParseAvailableData() {
|
||||
speculation->GetStartLineNumber());
|
||||
if (mLookingForMetaCharset) {
|
||||
if (mMode == VIEW_SOURCE_HTML) {
|
||||
auto r = mTokenizer->FlushViewSource();
|
||||
if (r.isErr()) {
|
||||
MarkAsBroken(r.unwrapErr());
|
||||
return;
|
||||
}
|
||||
}
|
||||
auto r = mTreeBuilder->Flush();
|
||||
if (r.isErr()) {
|
||||
MarkAsBroken(r.unwrapErr());
|
||||
return;
|
||||
mTokenizer->FlushViewSource();
|
||||
}
|
||||
mTreeBuilder->Flush();
|
||||
} else {
|
||||
FlushTreeOpsAndDisarmTimer();
|
||||
}
|
||||
@@ -2559,10 +2458,7 @@ void nsHtml5StreamParser::ContinueAfterScriptsOrEncodingCommitment(
|
||||
// XML View Source never needs this kind of encoding commitment.
|
||||
// We need to take the ops here so that they end up in the queue before
|
||||
// the ops that we take from a speculation later in this method.
|
||||
if (!mExecutor->TakeOpsFromStage()) {
|
||||
mExecutor->MarkAsBroken(NS_ERROR_OUT_OF_MEMORY);
|
||||
return;
|
||||
}
|
||||
mExecutor->TakeOpsFromStage();
|
||||
} else {
|
||||
#ifdef DEBUG
|
||||
mExecutor->AssertStageEmpty();
|
||||
@@ -2599,10 +2495,7 @@ void nsHtml5StreamParser::ContinueAfterScriptsOrEncodingCommitment(
|
||||
if (mSpeculations.Length() > 1) {
|
||||
// the first speculation isn't the current speculation, so there's
|
||||
// no need to bother the parser thread.
|
||||
if (!speculation->FlushToSink(mExecutor)) {
|
||||
mExecutor->MarkAsBroken(NS_ERROR_OUT_OF_MEMORY);
|
||||
return;
|
||||
}
|
||||
speculation->FlushToSink(mExecutor);
|
||||
MOZ_ASSERT(!mExecutor->IsScriptExecuting(),
|
||||
"ParseUntilBlocked() was supposed to ensure we don't come "
|
||||
"here when scripts are executing.");
|
||||
@@ -2677,10 +2570,7 @@ void nsHtml5StreamParser::ContinueAfterScriptsOrEncodingCommitment(
|
||||
} else {
|
||||
// We've got a successful speculation and at least a moment ago it was
|
||||
// the current speculation
|
||||
if (!mSpeculations.ElementAt(0)->FlushToSink(mExecutor)) {
|
||||
mExecutor->MarkAsBroken(NS_ERROR_OUT_OF_MEMORY);
|
||||
return;
|
||||
}
|
||||
mSpeculations.ElementAt(0)->FlushToSink(mExecutor);
|
||||
MOZ_ASSERT(!mExecutor->IsScriptExecuting(),
|
||||
"ParseUntilBlocked() was supposed to ensure we don't come "
|
||||
"here when scripts are executing.");
|
||||
@@ -2699,11 +2589,7 @@ void nsHtml5StreamParser::ContinueAfterScriptsOrEncodingCommitment(
|
||||
// any pending ops straight to the executor, because otherwise
|
||||
// they remain unflushed until we get more data from the network.
|
||||
mTreeBuilder->SetOpSink(mExecutor);
|
||||
auto r = mTreeBuilder->Flush(true);
|
||||
if (r.isErr()) {
|
||||
mExecutor->MarkAsBroken(r.unwrapErr());
|
||||
return;
|
||||
}
|
||||
mTreeBuilder->Flush(true);
|
||||
mTreeBuilder->SetOpSink(mExecutor->GetStage());
|
||||
}
|
||||
mExecutor->StartReadingFromStage();
|
||||
@@ -2799,17 +2685,8 @@ void nsHtml5StreamParser::TimerFlush() {
|
||||
}
|
||||
|
||||
if (mMode == VIEW_SOURCE_HTML || mMode == VIEW_SOURCE_XML) {
|
||||
auto r = mTreeBuilder->Flush(); // delete useless ops
|
||||
if (r.isErr()) {
|
||||
MarkAsBroken(r.unwrapErr());
|
||||
return;
|
||||
}
|
||||
r = mTokenizer->FlushViewSource();
|
||||
if (r.isErr()) {
|
||||
MarkAsBroken(r.unwrapErr());
|
||||
return;
|
||||
}
|
||||
if (r.unwrap()) {
|
||||
mTreeBuilder->Flush(); // delete useless ops
|
||||
if (mTokenizer->FlushViewSource()) {
|
||||
nsCOMPtr<nsIRunnable> runnable(mExecutorFlusher);
|
||||
if (NS_FAILED(DispatchToMain(runnable.forget()))) {
|
||||
NS_WARNING("failed to dispatch executor flush event");
|
||||
@@ -2818,12 +2695,7 @@ void nsHtml5StreamParser::TimerFlush() {
|
||||
} else {
|
||||
// we aren't speculating and we don't know when new data is
|
||||
// going to arrive. Send data to the main thread.
|
||||
auto r = mTreeBuilder->Flush(true);
|
||||
if (r.isErr()) {
|
||||
MarkAsBroken(r.unwrapErr());
|
||||
return;
|
||||
}
|
||||
if (r.unwrap()) {
|
||||
if (mTreeBuilder->Flush(true)) {
|
||||
nsCOMPtr<nsIRunnable> runnable(mExecutorFlusher);
|
||||
if (NS_FAILED(DispatchToMain(runnable.forget()))) {
|
||||
NS_WARNING("failed to dispatch executor flush event");
|
||||
@@ -2838,12 +2710,8 @@ void nsHtml5StreamParser::MarkAsBroken(nsresult aRv) {
|
||||
|
||||
Terminate();
|
||||
mTreeBuilder->MarkAsBroken(aRv);
|
||||
auto r = mTreeBuilder->Flush(false);
|
||||
if (r.isOk()) {
|
||||
MOZ_ASSERT(r.unwrap(), "Should have had the markAsBroken op!");
|
||||
} else {
|
||||
MOZ_CRASH("OOM prevents propagation of OOM state");
|
||||
}
|
||||
mozilla::DebugOnly<bool> hadOps = mTreeBuilder->Flush(false);
|
||||
MOZ_ASSERT(hadOps, "Should have had the markAsBroken op!");
|
||||
nsCOMPtr<nsIRunnable> runnable(mExecutorFlusher);
|
||||
if (NS_FAILED(DispatchToMain(runnable.forget()))) {
|
||||
NS_WARNING("failed to dispatch executor flush event");
|
||||
|
||||
Reference in New Issue
Block a user