Title: [139497] trunk/Source/WebCore
Revision
139497
Author
to...@chromium.org
Date
2013-01-11 14:20:13 -0800 (Fri, 11 Jan 2013)

Log Message

We should be able to checkpoint and restore the HTMLTokenizer across threads
https://bugs.webkit.org/show_bug.cgi?id=106597

Based on patch by Adam Barth.

This has the ability to create a checkpoint any time the parser is blocked on a script.
We clear m_appropriateEndTagName after each end tag is flushed so that the ASSERT in
canCreateCheckpoint() will pass.

Reviewed by Adam Barth.

No new tests because no new functionality.

* html/parser/HTMLDocumentParser.cpp:
(WebCore::HTMLDocumentParser::HTMLDocumentParser):
(WebCore::HTMLDocumentParser::pumpTokenizer):
* html/parser/HTMLDocumentParser.h:
(WebCore):
(HTMLDocumentParser):
* html/parser/HTMLTokenizer.cpp:
(WebCore):
(WebCore::HTMLTokenizer::canCreateCheckpoint):
(WebCore::HTMLTokenizer::createCheckpoint):
(WebCore::HTMLTokenizer::restoreFromCheckpoint):
* html/parser/HTMLTokenizer.h:
(HTMLTokenizer):
(Checkpoint):
(WebCore::HTMLTokenizer::Checkpoint::Checkpoint):
* xml/parser/MarkupTokenizerBase.h:
(WebCore::MarkupTokenizerBase::InputStreamPreprocessor::InputStreamPreprocessor):
(WebCore::MarkupTokenizerBase::InputStreamPreprocessor::skipNextNewLine):
(InputStreamPreprocessor):
(WebCore::MarkupTokenizerBase::InputStreamPreprocessor::reset):

Modified Paths

Diff

Modified: trunk/Source/WebCore/ChangeLog (139496 => 139497)


--- trunk/Source/WebCore/ChangeLog	2013-01-11 22:18:27 UTC (rev 139496)
+++ trunk/Source/WebCore/ChangeLog	2013-01-11 22:20:13 UTC (rev 139497)
@@ -1,3 +1,39 @@
+2013-01-11  Tony Gentilcore  <to...@chromium.org>
+
+        We should be able to checkpoint and restore the HTMLTokenizer across threads
+        https://bugs.webkit.org/show_bug.cgi?id=106597
+
+        Based on patch by Adam Barth.
+
+        This has the ability to create a checkpoint any time the parser is blocked on a script.
+        We clear m_appropriateEndTagName after each end tag is flushed so that the ASSERT in
+        canCreateCheckpoint() will pass.
+
+        Reviewed by Adam Barth.
+
+        No new tests because no new functionality.
+
+        * html/parser/HTMLDocumentParser.cpp:
+        (WebCore::HTMLDocumentParser::HTMLDocumentParser):
+        (WebCore::HTMLDocumentParser::pumpTokenizer):
+        * html/parser/HTMLDocumentParser.h:
+        (WebCore):
+        (HTMLDocumentParser):
+        * html/parser/HTMLTokenizer.cpp:
+        (WebCore):
+        (WebCore::HTMLTokenizer::canCreateCheckpoint):
+        (WebCore::HTMLTokenizer::createCheckpoint):
+        (WebCore::HTMLTokenizer::restoreFromCheckpoint):
+        * html/parser/HTMLTokenizer.h:
+        (HTMLTokenizer):
+        (Checkpoint):
+        (WebCore::HTMLTokenizer::Checkpoint::Checkpoint):
+        * xml/parser/MarkupTokenizerBase.h:
+        (WebCore::MarkupTokenizerBase::InputStreamPreprocessor::InputStreamPreprocessor):
+        (WebCore::MarkupTokenizerBase::InputStreamPreprocessor::skipNextNewLine):
+        (InputStreamPreprocessor):
+        (WebCore::MarkupTokenizerBase::InputStreamPreprocessor::reset):
+
 2013-01-11  Tony Chang  <t...@chromium.org>
 
         [chromium] Don't regenerate all bindings when any idl file changes

Modified: trunk/Source/WebCore/html/parser/HTMLTokenizer.cpp (139496 => 139497)


--- trunk/Source/WebCore/html/parser/HTMLTokenizer.cpp	2013-01-11 22:18:27 UTC (rev 139496)
+++ trunk/Source/WebCore/html/parser/HTMLTokenizer.cpp	2013-01-11 22:20:13 UTC (rev 139497)
@@ -136,6 +136,41 @@
     m_additionalAllowedCharacter = '\0';
 }
 
+#if ENABLE(THREADED_HTML_PARSER)
+
+bool HTMLTokenizer::canCreateCheckpoint() const
+{
+    if (!m_appropriateEndTagName.isEmpty())
+        return false;
+    if (!m_temporaryBuffer.isEmpty())
+        return false;
+    if (!m_bufferedEndTagName.isEmpty())
+        return false;
+    return true;
+}
+
+void HTMLTokenizer::createCheckpoint(Checkpoint& result) const
+{
+    ASSERT(canCreateCheckpoint());
+    result.options = m_options;
+    result.state = m_state;
+    result.additionalAllowedCharacter = m_additionalAllowedCharacter;
+    result.skipNextNewLine = m_inputStreamPreprocessor.skipNextNewLine();
+    result.shouldAllowCDATA = m_shouldAllowCDATA;
+}
+
+void HTMLTokenizer::restoreFromCheckpoint(const Checkpoint& checkpoint)
+{
+    m_token = 0;
+    m_options = checkpoint.options;
+    m_state = checkpoint.state;
+    m_additionalAllowedCharacter = checkpoint.additionalAllowedCharacter;
+    m_inputStreamPreprocessor.reset(checkpoint.skipNextNewLine);
+    m_shouldAllowCDATA = checkpoint.shouldAllowCDATA;
+}
+
+#endif
+
 inline bool HTMLTokenizer::processEntity(SegmentedString& source)
 {
     bool notEnoughCharacters = false;
@@ -161,6 +196,7 @@
         return true;
     m_token->beginEndTag(m_bufferedEndTagName);
     m_bufferedEndTagName.clear();
+    m_appropriateEndTagName.clear();
     m_temporaryBuffer.clear();
     return false;
 }
@@ -196,6 +232,7 @@
         // We started an end tag during our last iteration.
         m_token->beginEndTag(m_bufferedEndTagName);
         m_bufferedEndTagName.clear();
+        m_appropriateEndTagName.clear();
         m_temporaryBuffer.clear();
         if (m_state == HTMLTokenizerState::DataState) {
             // We're back in the data state, so we must be done with the tag.
@@ -317,9 +354,11 @@
     HTML_BEGIN_STATE(EndTagOpenState) {
         if (isASCIIUpper(cc)) {
             m_token->beginEndTag(static_cast<LChar>(toLowerCase(cc)));
+            m_appropriateEndTagName.clear();
             HTML_ADVANCE_TO(TagNameState);
         } else if (isASCIILower(cc)) {
             m_token->beginEndTag(static_cast<LChar>(cc));
+            m_appropriateEndTagName.clear();
             HTML_ADVANCE_TO(TagNameState);
         } else if (cc == '>') {
             parseError();

Modified: trunk/Source/WebCore/html/parser/HTMLTokenizer.h (139496 => 139497)


--- trunk/Source/WebCore/html/parser/HTMLTokenizer.h	2013-01-11 22:18:27 UTC (rev 139496)
+++ trunk/Source/WebCore/html/parser/HTMLTokenizer.h	2013-01-11 22:20:13 UTC (rev 139497)
@@ -124,6 +124,33 @@
 
     void reset();
 
+#if ENABLE(THREADED_HTML_PARSER)
+
+    struct Checkpoint {
+        HTMLParserOptions options;
+        HTMLTokenizerState::State state;
+        UChar additionalAllowedCharacter;
+        bool skipNextNewLine;
+        bool forceNullCharacterReplacement;
+        bool shouldAllowCDATA;
+
+        Checkpoint()
+            : options(0)
+            , state()
+            , additionalAllowedCharacter('\0')
+            , skipNextNewLine(false)
+            , forceNullCharacterReplacement(false)
+            , shouldAllowCDATA(false)
+        {
+        }
+    };
+
+    bool canCreateCheckpoint() const;
+    void createCheckpoint(Checkpoint&) const;
+    void restoreFromCheckpoint(const Checkpoint&);
+
+#endif
+
     // This function returns true if it emits a token. Otherwise, callers
     // must provide the same (in progress) token on the next call (unless
     // they call reset() first).

Modified: trunk/Source/WebCore/xml/parser/MarkupTokenizerBase.h (139496 => 139497)


--- trunk/Source/WebCore/xml/parser/MarkupTokenizerBase.h	2013-01-11 22:18:27 UTC (rev 139496)
+++ trunk/Source/WebCore/xml/parser/MarkupTokenizerBase.h	2013-01-11 22:20:13 UTC (rev 139497)
@@ -61,9 +61,8 @@
     public:
         InputStreamPreprocessor(MarkupTokenizerBase<Token, State>* tokenizer)
             : m_tokenizer(tokenizer)
-            , m_nextInputCharacter('\0')
-            , m_skipNextNewLine(false)
         {
+            reset();
         }
 
         ALWAYS_INLINE UChar nextInputCharacter() const { return m_nextInputCharacter; }
@@ -124,6 +123,14 @@
             return peek(source);
         }
 
+        bool skipNextNewLine() const { return m_skipNextNewLine; }
+
+        void reset(bool skipNextNewLine = false)
+        {
+            m_nextInputCharacter = '\0';
+            m_skipNextNewLine = skipNextNewLine;
+        }
+
         static const UChar endOfFileMarker = 0;
 
     private:
_______________________________________________
webkit-changes mailing list
webkit-changes@lists.webkit.org
http://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to