Title: [140019] trunk/Source/WebCore
Revision
140019
Author
[email protected]
Date
2013-01-17 11:52:07 -0800 (Thu, 17 Jan 2013)

Log Message

Wire BackgroundHTMLParser to HTMLDocumentParser
https://bugs.webkit.org/show_bug.cgi?id=107140

Reviewed by Adam Barth.

With this patch, we now pass the majority of html5lib and fast/parser tests with threaded HTML parsing enabled.

No new tests because covered by existing fast/parser tests.

* html/parser/BackgroundHTMLParser.cpp:
(WebCore::TokenDelivery::execute):
* html/parser/HTMLDocumentParser.cpp:
(WebCore::HTMLDocumentParser::HTMLDocumentParser):
(WebCore::HTMLDocumentParser::~HTMLDocumentParser):
(WebCore::HTMLDocumentParser::processingData):
(WebCore::HTMLDocumentParser::resumeParsingAfterYield):
(WebCore::HTMLDocumentParser::canTakeNextToken):
(WebCore::HTMLDocumentParser::feedTokens):
(WebCore::HTMLDocumentParser::pumpTokenizer):
(WebCore):
(WebCore::HTMLDocumentParser::startBackgroundParser):
(WebCore::HTMLDocumentParser::stopBackgroundParser):
(WebCore::HTMLDocumentParser::append):
(WebCore::HTMLDocumentParser::end):
(WebCore::HTMLDocumentParser::finish):
(WebCore::HTMLDocumentParser::resumeParsingAfterScriptExecution):
* html/parser/HTMLDocumentParser.h:
(WebCore):
(HTMLDocumentParser):
(WebCore::HTMLDocumentParser::hasPreloadScanner):
(WebCore::HTMLDocumentParser::shouldUseThreading):

Modified Paths

Diff

Modified: trunk/Source/WebCore/ChangeLog (140018 => 140019)


--- trunk/Source/WebCore/ChangeLog	2013-01-17 19:49:24 UTC (rev 140018)
+++ trunk/Source/WebCore/ChangeLog	2013-01-17 19:52:07 UTC (rev 140019)
@@ -1,3 +1,37 @@
+2013-01-17  Tony Gentilcore  <[email protected]>
+
+        Wire BackgroundHTMLParser to HTMLDocumentParser
+        https://bugs.webkit.org/show_bug.cgi?id=107140
+
+        Reviewed by Adam Barth.
+
+        With this patch, we now pass the majority of html5lib and fast/parser tests with threaded HTML parsing enabled.
+
+        No new tests because covered by existing fast/parser tests.
+
+        * html/parser/BackgroundHTMLParser.cpp:
+        (WebCore::TokenDelivery::execute):
+        * html/parser/HTMLDocumentParser.cpp:
+        (WebCore::HTMLDocumentParser::HTMLDocumentParser):
+        (WebCore::HTMLDocumentParser::~HTMLDocumentParser):
+        (WebCore::HTMLDocumentParser::processingData):
+        (WebCore::HTMLDocumentParser::resumeParsingAfterYield):
+        (WebCore::HTMLDocumentParser::canTakeNextToken):
+        (WebCore::HTMLDocumentParser::feedTokens):
+        (WebCore::HTMLDocumentParser::pumpTokenizer):
+        (WebCore):
+        (WebCore::HTMLDocumentParser::startBackgroundParser):
+        (WebCore::HTMLDocumentParser::stopBackgroundParser):
+        (WebCore::HTMLDocumentParser::append):
+        (WebCore::HTMLDocumentParser::end):
+        (WebCore::HTMLDocumentParser::finish):
+        (WebCore::HTMLDocumentParser::resumeParsingAfterScriptExecution):
+        * html/parser/HTMLDocumentParser.h:
+        (WebCore):
+        (HTMLDocumentParser):
+        (WebCore::HTMLDocumentParser::hasPreloadScanner):
+        (WebCore::HTMLDocumentParser::shouldUseThreading):
+
 2013-01-17  Tommy Widenflycht  <[email protected]>
 
         MediaStream API: Move all ExtraDataContainers into anonymous namespaces

Modified: trunk/Source/WebCore/html/parser/HTMLDocumentParser.cpp (140018 => 140019)


--- trunk/Source/WebCore/html/parser/HTMLDocumentParser.cpp	2013-01-17 19:49:24 UTC (rev 140018)
+++ trunk/Source/WebCore/html/parser/HTMLDocumentParser.cpp	2013-01-17 19:52:07 UTC (rev 140019)
@@ -26,6 +26,7 @@
 #include "config.h"
 #include "HTMLDocumentParser.h"
 
+#include "BackgroundHTMLParser.h"
 #include "CompactHTMLToken.h"
 #include "ContentSecurityPolicy.h"
 #include "DocumentFragment.h"
@@ -33,6 +34,7 @@
 #include "Frame.h"
 #include "HTMLNames.h"
 #include "HTMLParserScheduler.h"
+#include "HTMLParserThread.h"
 #include "HTMLTokenizer.h"
 #include "HTMLPreloadScanner.h"
 #include "HTMLScriptRunner.h"
@@ -41,6 +43,7 @@
 #include "InspectorInstrumentation.h"
 #include "NestingLevelIncrementer.h"
 #include "Settings.h"
+#include <wtf/Functional.h>
 
 namespace WebCore {
 
@@ -80,6 +83,7 @@
     , m_parserScheduler(HTMLParserScheduler::create(this))
     , m_xssAuditor(this)
     , m_endWasDelayed(false)
+    , m_haveBackgroundParser(false)
     , m_pumpSessionNestingLevel(0)
 {
 }
@@ -93,6 +97,7 @@
     , m_treeBuilder(HTMLTreeBuilder::create(this, fragment, contextElement, scriptingPermission, m_options))
     , m_xssAuditor(this)
     , m_endWasDelayed(false)
+    , m_haveBackgroundParser(false)
     , m_pumpSessionNestingLevel(0)
 {
     bool reportErrors = false; // For now document fragment parsing never reports errors.
@@ -105,6 +110,7 @@
     ASSERT(!m_pumpSessionNestingLevel);
     ASSERT(!m_preloadScanner);
     ASSERT(!m_insertionPreloadScanner);
+    ASSERT(!m_haveBackgroundParser);
 }
 
 void HTMLDocumentParser::detach()
@@ -164,7 +170,7 @@
 
 bool HTMLDocumentParser::processingData() const
 {
-    return isScheduledForResume() || inPumpSession();
+    return isScheduledForResume() || inPumpSession() || m_haveBackgroundParser;
 }
 
 void HTMLDocumentParser::pumpTokenizerIfPossible(SynchronousMode mode)
@@ -189,6 +195,8 @@
 // Used by HTMLParserScheduler
 void HTMLDocumentParser::resumeParsingAfterYield()
 {
+    ASSERT(!shouldUseThreading());
+
     // pumpTokenizer can cause this parser to be detached from the Document,
     // but we need to ensure it isn't deleted yet.
     RefPtr<HTMLDocumentParser> protect(this);
@@ -213,6 +221,8 @@
     if (isStopped())
         return false;
 
+    ASSERT(!shouldUseThreading() || mode == ForceSynchronous);
+
     if (isWaitingForScripts()) {
         if (mode == AllowYield)
             m_parserScheduler->checkForYieldBeforeScript(session);
@@ -247,7 +257,44 @@
 
 void HTMLDocumentParser::didReceiveTokensFromBackgroundParser(const Vector<CompactHTMLToken>& tokens)
 {
-    // FIXME: Actually consume the tokens.
+    ASSERT(shouldUseThreading());
+
+    // feedTokens can cause this parser to be detached from the Document,
+    // but we need to ensure it isn't deleted yet.
+    RefPtr<HTMLDocumentParser> protect(this);
+
+    // FIXME: Add support for InspectorInstrumentation.
+
+    for (Vector<CompactHTMLToken>::const_iterator it = tokens.begin(); it != tokens.end(); ++it) {
+        ASSERT(!isWaitingForScripts());
+
+        // FIXME: Call m_xssAuditor.filterToken(*it).
+        constructTreeFromCompactHTMLToken(*it);
+
+        if (isStopped())
+            return;
+
+        // FIXME: We'll probably need to check document()->frame()->navigationScheduler()->locationChangePending())
+        // as we do in canTakeNextToken;
+
+        if (isWaitingForScripts()) {
+            runScriptsForPausedTreeBuilder();
+            if (!isWaitingForScripts()) {
+                ParserIdentifier identifier = ParserMap::identifierForParser(this);
+                HTMLParserThread::shared()->postTask(bind(&BackgroundHTMLParser::continuePartial, identifier));
+            }
+        }
+
+        // FIXME: This is too abrupt a way to end parsing because we might
+        // have to wait for deferred scripts. We probably want to call
+        // attemptToRunDeferredScriptsAndEnd(), prepareToStopParsing(), or
+        // attemptToEnd() instead.
+        if (it->type() == HTMLTokenTypes::EndOfFile) {
+            DocumentParser::prepareToStopParsing();
+            document()->setReadyState(Document::Interactive);
+            end();
+        }
+    }
 }
 
 #endif // ENABLE(THREADED_HTML_PARSER)
@@ -259,6 +306,8 @@
     // ASSERT that this object is both attached to the Document and protected.
     ASSERT(refCount() >= 2);
 
+    ASSERT(!shouldUseThreading() || mode == ForceSynchronous);
+
     PumpSession session(m_pumpSessionNestingLevel);
 
     // We tell the InspectorInstrumentation about every pump, even if we
@@ -386,11 +435,49 @@
     endIfDelayed();
 }
 
+#if ENABLE(THREADED_HTML_PARSER)
+
+void HTMLDocumentParser::startBackgroundParser()
+{
+    ASSERT(!m_haveBackgroundParser);
+    m_haveBackgroundParser = true;
+
+    ParserIdentifier identifier = ParserMap::identifierForParser(this);
+    parserMap().mainThreadParsers().set(identifier, this);
+
+    HTMLParserThread::shared()->postTask(bind(&BackgroundHTMLParser::createPartial, identifier, m_options));
+}
+
+void HTMLDocumentParser::stopBackgroundParser()
+{
+    ASSERT(m_haveBackgroundParser);
+    m_haveBackgroundParser = false;
+
+    ParserIdentifier identifier = ParserMap::identifierForParser(this);
+    HTMLParserThread::shared()->postTask(bind(&BackgroundHTMLParser::stopPartial, identifier));
+
+    parserMap().mainThreadParsers().set(identifier, 0);
+    // We will not recieve any messages from the parser after this point.
+}
+
+#endif
+
 void HTMLDocumentParser::append(const SegmentedString& source)
 {
     if (isStopped())
         return;
 
+#if ENABLE(THREADED_HTML_PARSER)
+    if (shouldUseThreading()) {
+        if (!m_haveBackgroundParser)
+            startBackgroundParser();
+
+        ParserIdentifier identifier = ParserMap::identifierForParser(this);
+        HTMLParserThread::shared()->postTask(bind(&BackgroundHTMLParser::appendPartial, identifier, source.toString().isolatedCopy()));
+        return;
+    }
+#endif
+
     // pumpTokenizer can cause this parser to be detached from the Document,
     // but we need to ensure it isn't deleted yet.
     RefPtr<HTMLDocumentParser> protect(this);
@@ -426,6 +513,11 @@
     ASSERT(!isDetached());
     ASSERT(!isScheduledForResume());
 
+#if ENABLE(THREADED_HTML_PARSER)
+    if (m_haveBackgroundParser)
+        stopBackgroundParser();
+#endif
+
     // Informs the the rest of WebCore that parsing is really finished (and deletes this).
     m_treeBuilder->finished();
 }
@@ -466,6 +558,13 @@
 
 void HTMLDocumentParser::finish()
 {
+#if ENABLE(THREADED_HTML_PARSER)
+    if (shouldUseThreading()) {
+        HTMLParserThread::shared()->postTask(bind(&BackgroundHTMLParser::finishPartial, ParserMap::identifierForParser(this)));
+        return;
+    }
+#endif
+
     // FIXME: We should ASSERT(!m_parserStopped) here, since it does not
     // makes sense to call any methods on DocumentParser once it's been stopped.
     // However, FrameLoader::stop calls DocumentParser::finish unconditionally.
@@ -530,6 +629,14 @@
     ASSERT(!isExecutingScript());
     ASSERT(!isWaitingForScripts());
 
+#if ENABLE(THREADED_HTML_PARSER)
+    if (shouldUseThreading()) {
+        ParserIdentifier identifier = ParserMap::identifierForParser(this);
+        HTMLParserThread::shared()->postTask(bind(&BackgroundHTMLParser::continuePartial, identifier));
+        return;
+    }
+#endif
+
     m_insertionPreloadScanner.clear();
     pumpTokenizerIfPossible(AllowYield);
     endIfDelayed();

Modified: trunk/Source/WebCore/html/parser/HTMLDocumentParser.h (140018 => 140019)


--- trunk/Source/WebCore/html/parser/HTMLDocumentParser.h	2013-01-17 19:49:24 UTC (rev 140018)
+++ trunk/Source/WebCore/html/parser/HTMLDocumentParser.h	2013-01-17 19:52:07 UTC (rev 140019)
@@ -113,12 +113,17 @@
     virtual void watchForLoad(CachedResource*);
     virtual void stopWatchingForLoad(CachedResource*);
     virtual HTMLInputStream& inputStream() { return m_input; }
-    virtual bool hasPreloadScanner() const { return m_preloadScanner.get(); }
+    virtual bool hasPreloadScanner() const { return m_preloadScanner.get() && !shouldUseThreading(); }
     virtual void appendCurrentInputStreamToPreloadScannerAndScan();
 
     // CachedResourceClient
     virtual void notifyFinished(CachedResource*);
 
+#if ENABLE(THREADED_HTML_PARSER)
+    void startBackgroundParser();
+    void stopBackgroundParser();
+#endif
+
     enum SynchronousMode {
         AllowYield,
         ForceSynchronous,
@@ -139,6 +144,8 @@
     void attemptToRunDeferredScriptsAndEnd();
     void end();
 
+    bool shouldUseThreading() const { return m_options.useThreading && !isParsingFragment(); }
+
     bool isParsingFragment() const;
     bool isScheduledForResume() const;
     bool inPumpSession() const { return m_pumpSessionNestingLevel > 0; }
@@ -160,6 +167,7 @@
     XSSAuditor m_xssAuditor;
 
     bool m_endWasDelayed;
+    bool m_haveBackgroundParser;
     unsigned m_pumpSessionNestingLevel;
 };
 
_______________________________________________
webkit-changes mailing list
[email protected]
http://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to