Bug 655682 - Perform discretionary flushes in the HTML parser even if the current node is foster-parenting. r=bzbarsky.

This commit is contained in:
Henri Sivonen 2011-05-19 11:42:01 +03:00
Родитель 59ff6df7b7
Коммит 1b9051c4ac
3 изменённых файлов: 20 добавлений и 29 удалений

Просмотреть файл

@ -1159,13 +1159,11 @@ nsHtml5StreamParser::ContinueAfterScripts(nsHtml5Tokenizer* aTokenizer,
mSpeculations.RemoveElementAt(0);
if (mSpeculations.IsEmpty()) {
// yes, it was still the only speculation. Now stop speculating
if (mTreeBuilder->IsDiscretionaryFlushSafe()) {
// However, before telling the executor to read from stage, flush
// any pending ops straight to the executor, because otherwise
// they remain unflushed until we get more data from the network.
mTreeBuilder->SetOpSink(mExecutor);
mTreeBuilder->Flush();
}
// However, before telling the executor to read from stage, flush
// any pending ops straight to the executor, because otherwise
// they remain unflushed until we get more data from the network.
mTreeBuilder->SetOpSink(mExecutor);
mTreeBuilder->Flush(PR_TRUE);
mTreeBuilder->SetOpSink(mExecutor->GetStage());
mExecutor->StartReadingFromStage();
mSpeculating = PR_FALSE;
@ -1268,15 +1266,9 @@ nsHtml5StreamParser::TimerFlush()
// we aren't speculating and we don't know when new data is
// going to arrive. Send data to the main thread.
// However, don't do if the current element on the stack is a
// foster-parenting element and there's pending text, because flushing in
// that case would make the tree shape dependent on where the flush points
// fall.
if (mTreeBuilder->IsDiscretionaryFlushSafe()) {
if (mTreeBuilder->Flush()) {
if (NS_FAILED(NS_DispatchToMainThread(mExecutorFlusher))) {
NS_WARNING("failed to dispatch executor flush event");
}
if (mTreeBuilder->Flush(PR_TRUE)) {
if (NS_FAILED(NS_DispatchToMainThread(mExecutorFlusher))) {
NS_WARNING("failed to dispatch executor flush event");
}
}
}

Просмотреть файл

@ -602,9 +602,18 @@ nsHtml5TreeBuilder::HasScript()
}
PRBool
nsHtml5TreeBuilder::Flush()
nsHtml5TreeBuilder::Flush(PRBool aDiscretionary)
{
flushCharacters();
if (!aDiscretionary ||
!(charBufferLen &&
currentPtr >= 0 &&
stack[currentPtr]->isFosterParenting())) {
// Don't flush text on discretionary flushes if the current element on
// the stack is a foster-parenting element and there's pending text,
// because flushing in that case would make the tree shape dependent on
// where the flush points fall.
flushCharacters();
}
FlushLoads();
if (mOpSink) {
PRBool hasOps = !mOpQueue.IsEmpty();
@ -667,14 +676,6 @@ nsHtml5TreeBuilder::AddSnapshotToScript(nsAHtml5TreeBuilderState* aSnapshot, PRI
mOpQueue.ElementAt(mOpQueue.Length() - 1).SetSnapshot(aSnapshot, aLine);
}
PRBool
nsHtml5TreeBuilder::IsDiscretionaryFlushSafe()
{
return !(charBufferLen &&
currentPtr >= 0 &&
stack[currentPtr]->isFosterParenting());
}
void
nsHtml5TreeBuilder::DropHandles()
{

Просмотреть файл

@ -72,8 +72,6 @@
~nsHtml5TreeBuilder();
PRBool IsDiscretionaryFlushSafe();
PRBool HasScript();
void SetOpSink(nsAHtml5TreeOpSink* aOpSink) {
@ -84,7 +82,7 @@
mOpQueue.Clear();
}
PRBool Flush();
PRBool Flush(PRBool aDiscretionary = PR_FALSE);
void FlushLoads();