Unreviewed, rolling out r123679.
authorcommit-queue@webkit.org <commit-queue@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Sat, 28 Jul 2012 01:02:33 +0000 (01:02 +0000)
committercommit-queue@webkit.org <commit-queue@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Sat, 28 Jul 2012 01:02:33 +0000 (01:02 +0000)
http://trac.webkit.org/changeset/123679
https://bugs.webkit.org/show_bug.cgi?id=92565

Slowed down HTML parsing by 3.6% (Requested by abarth on
#webkit).

Patch by Sheriff Bot <webkit.review.bot@gmail.com> on 2012-07-27

Source/WebCore:

* html/FTPDirectoryDocument.cpp:
(WebCore::FTPDirectoryDocumentParser::append):
* html/parser/HTMLEntityParser.cpp:
(WebCore::HTMLEntityParser::consumeNamedEntity):
* html/parser/HTMLParserIdioms.cpp:
(WebCore::stripLeadingAndTrailingHTMLSpaces):
* html/parser/HTMLSourceTracker.cpp:
(WebCore::HTMLSourceTracker::sourceForToken):
* loader/cache/CachedScript.cpp:
(WebCore::CachedScript::script):
* platform/text/SegmentedString.cpp:
(WebCore::SegmentedString::SegmentedString):
(WebCore::SegmentedString::operator=):
(WebCore::SegmentedString::clear):
(WebCore::SegmentedString::append):
(WebCore::SegmentedString::prepend):
(WebCore::SegmentedString::advanceSubstring):
(WebCore::SegmentedString::advance):
(WebCore::SegmentedString::advanceSlowCase):
(WebCore::SegmentedString::advanceAndUpdateLineNumberSlowCase):
* platform/text/SegmentedString.h:
(WebCore::SegmentedSubstring::SegmentedSubstring):
(WebCore::SegmentedSubstring::clear):
(WebCore::SegmentedSubstring::appendTo):
(SegmentedSubstring):
(WebCore::SegmentedString::SegmentedString):
(WebCore::SegmentedString::push):
(WebCore::SegmentedString::isEmpty):
(WebCore::SegmentedString::lookAhead):
(WebCore::SegmentedString::lookAheadIgnoringCase):
(WebCore::SegmentedString::advance):
(WebCore::SegmentedString::advanceAndASSERT):
(WebCore::SegmentedString::advanceAndASSERTIgnoringCase):
(WebCore::SegmentedString::advancePastNewlineAndUpdateLineNumber):
(SegmentedString):
(WebCore::SegmentedString::advancePastNonNewline):
(WebCore::SegmentedString::advanceAndUpdateLineNumber):
(WebCore::SegmentedString::operator*):
(WebCore::SegmentedString::operator->):
(WebCore::SegmentedString::current):
(WebCore::SegmentedString::equalsLiterally):
(WebCore::SegmentedString::equalsIgnoringCase):
(WebCore::SegmentedString::lookAheadInline):
(WebCore::SegmentedString::lookAheadSlowCase):
* xml/parser/CharacterReferenceParserInlineMethods.h:
(WebCore::consumeCharacterReference):
* xml/parser/MarkupTokenizerBase.h:
(WebCore::MarkupTokenizerBase::InputStreamPreprocessor::nextInputCharacter):
(WebCore::MarkupTokenizerBase::InputStreamPreprocessor::peek):
(WebCore::MarkupTokenizerBase::InputStreamPreprocessor::advance):

Source/WTF:

* wtf/text/WTFString.h:

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@123943 268f45cc-cd09-0410-ab3c-d52691b4dbfc

12 files changed:
Source/WTF/ChangeLog
Source/WTF/wtf/text/WTFString.h
Source/WebCore/ChangeLog
Source/WebCore/html/FTPDirectoryDocument.cpp
Source/WebCore/html/parser/HTMLEntityParser.cpp
Source/WebCore/html/parser/HTMLParserIdioms.cpp
Source/WebCore/html/parser/HTMLSourceTracker.cpp
Source/WebCore/loader/cache/CachedScript.cpp
Source/WebCore/platform/text/SegmentedString.cpp
Source/WebCore/platform/text/SegmentedString.h
Source/WebCore/xml/parser/CharacterReferenceParserInlineMethods.h
Source/WebCore/xml/parser/MarkupTokenizerBase.h

index ccd1325..e798712 100644 (file)
@@ -1,3 +1,14 @@
+2012-07-27  Sheriff Bot  <webkit.review.bot@gmail.com>
+
+        Unreviewed, rolling out r123679.
+        http://trac.webkit.org/changeset/123679
+        https://bugs.webkit.org/show_bug.cgi?id=92565
+
+        Slowed down HTML parsing by 3.6% (Requested by abarth on
+        #webkit).
+
+        * wtf/text/WTFString.h:
+
 2012-07-27  Arnaud Renevier  <a.renevier@sisa.samsung.com>
 
         use createUninitialized when creating TypedArray from another array
index 35144fa..9f492a7 100644 (file)
@@ -190,13 +190,6 @@ public:
 
     bool is8Bit() const { return m_impl->is8Bit(); }
 
-    unsigned sizeInBytes() const
-    {
-        if (!m_impl)
-            return 0;
-        return m_impl->length() * (is8Bit() ? sizeof(LChar) : sizeof(UChar));
-    }
-
     WTF_EXPORT_PRIVATE CString ascii() const;
     WTF_EXPORT_PRIVATE CString latin1() const;
     WTF_EXPORT_PRIVATE CString utf8(bool strict = false) const;
index 993952f..fe6a418 100644 (file)
@@ -1,3 +1,63 @@
+2012-07-27  Sheriff Bot  <webkit.review.bot@gmail.com>
+
+        Unreviewed, rolling out r123679.
+        http://trac.webkit.org/changeset/123679
+        https://bugs.webkit.org/show_bug.cgi?id=92565
+
+        Slowed down HTML parsing by 3.6% (Requested by abarth on
+        #webkit).
+
+        * html/FTPDirectoryDocument.cpp:
+        (WebCore::FTPDirectoryDocumentParser::append):
+        * html/parser/HTMLEntityParser.cpp:
+        (WebCore::HTMLEntityParser::consumeNamedEntity):
+        * html/parser/HTMLParserIdioms.cpp:
+        (WebCore::stripLeadingAndTrailingHTMLSpaces):
+        * html/parser/HTMLSourceTracker.cpp:
+        (WebCore::HTMLSourceTracker::sourceForToken):
+        * loader/cache/CachedScript.cpp:
+        (WebCore::CachedScript::script):
+        * platform/text/SegmentedString.cpp:
+        (WebCore::SegmentedString::SegmentedString):
+        (WebCore::SegmentedString::operator=):
+        (WebCore::SegmentedString::clear):
+        (WebCore::SegmentedString::append):
+        (WebCore::SegmentedString::prepend):
+        (WebCore::SegmentedString::advanceSubstring):
+        (WebCore::SegmentedString::advance):
+        (WebCore::SegmentedString::advanceSlowCase):
+        (WebCore::SegmentedString::advanceAndUpdateLineNumberSlowCase):
+        * platform/text/SegmentedString.h:
+        (WebCore::SegmentedSubstring::SegmentedSubstring):
+        (WebCore::SegmentedSubstring::clear):
+        (WebCore::SegmentedSubstring::appendTo):
+        (SegmentedSubstring):
+        (WebCore::SegmentedString::SegmentedString):
+        (WebCore::SegmentedString::push):
+        (WebCore::SegmentedString::isEmpty):
+        (WebCore::SegmentedString::lookAhead):
+        (WebCore::SegmentedString::lookAheadIgnoringCase):
+        (WebCore::SegmentedString::advance):
+        (WebCore::SegmentedString::advanceAndASSERT):
+        (WebCore::SegmentedString::advanceAndASSERTIgnoringCase):
+        (WebCore::SegmentedString::advancePastNewlineAndUpdateLineNumber):
+        (SegmentedString):
+        (WebCore::SegmentedString::advancePastNonNewline):
+        (WebCore::SegmentedString::advanceAndUpdateLineNumber):
+        (WebCore::SegmentedString::operator*):
+        (WebCore::SegmentedString::operator->):
+        (WebCore::SegmentedString::current):
+        (WebCore::SegmentedString::equalsLiterally):
+        (WebCore::SegmentedString::equalsIgnoringCase):
+        (WebCore::SegmentedString::lookAheadInline):
+        (WebCore::SegmentedString::lookAheadSlowCase):
+        * xml/parser/CharacterReferenceParserInlineMethods.h:
+        (WebCore::consumeCharacterReference):
+        * xml/parser/MarkupTokenizerBase.h:
+        (WebCore::MarkupTokenizerBase::InputStreamPreprocessor::nextInputCharacter):
+        (WebCore::MarkupTokenizerBase::InputStreamPreprocessor::peek):
+        (WebCore::MarkupTokenizerBase::InputStreamPreprocessor::advance):
+
 2012-07-27  Jer Noble  <jer.noble@apple.com>
 
         Reset the set of "seen" plugins when the main frame load is committed.
index 319b8d2..18689c9 100644 (file)
@@ -368,7 +368,7 @@ void FTPDirectoryDocumentParser::append(const SegmentedString& source)
     m_dest = m_buffer;
     SegmentedString str = source;
     while (!str.isEmpty()) {
-        UChar c = str.currentChar();
+        UChar c = *str;
 
         if (c == '\r') {
             *m_dest++ = '\n';
index 1871805..442cedb 100644 (file)
@@ -87,7 +87,7 @@ public:
         StringBuilder consumedCharacters;
         HTMLEntitySearch entitySearch;
         while (!source.isEmpty()) {
-            cc = source.currentChar();
+            cc = *source;
             entitySearch.advance(cc);
             if (!entitySearch.isEntityPrefix())
                 break;
@@ -114,13 +114,13 @@ public:
             const int length = entitySearch.mostRecentMatch()->length;
             const UChar* reference = entitySearch.mostRecentMatch()->entity;
             for (int i = 0; i < length; ++i) {
-                cc = source.currentChar();
+                cc = *source;
                 ASSERT_UNUSED(reference, cc == *reference++);
                 consumedCharacters.append(cc);
                 source.advanceAndASSERT(cc);
                 ASSERT(!source.isEmpty());
             }
-            cc = source.currentChar();
+            cc = *source;
         }
         if (entitySearch.mostRecentMatch()->lastCharacter() == ';'
             || !additionalAllowedCharacter
index 8f057b1..c3becc3 100644 (file)
 
 namespace WebCore {
 
-template <typename CharType>
-static String stripLeadingAndTrailingHTMLSpaces(String string, CharType characters, unsigned length)
+String stripLeadingAndTrailingHTMLSpaces(const String& string)
 {
-    unsigned numLeadingSpaces = 0;
-    unsigned numTrailingSpaces = 0;
+    const UChar* characters = string.characters();
+    unsigned length = string.length();
 
-    for (; numLeadingSpaces < length; ++numLeadingSpaces) {
+    unsigned numLeadingSpaces;
+    for (numLeadingSpaces = 0; numLeadingSpaces < length; ++numLeadingSpaces) {
         if (isNotHTMLSpace(characters[numLeadingSpaces]))
             break;
     }
@@ -48,32 +48,17 @@ static String stripLeadingAndTrailingHTMLSpaces(String string, CharType characte
     if (numLeadingSpaces == length)
         return string.isNull() ? string : emptyAtom.string();
 
-    for (; numTrailingSpaces < length; ++numTrailingSpaces) {
+    unsigned numTrailingSpaces;
+    for (numTrailingSpaces = 0; numTrailingSpaces < length; ++numTrailingSpaces) {
         if (isNotHTMLSpace(characters[length - numTrailingSpaces - 1]))
             break;
     }
 
     ASSERT(numLeadingSpaces + numTrailingSpaces < length);
 
-    if (!(numLeadingSpaces | numTrailingSpaces))
-        return string;
-
     return string.substring(numLeadingSpaces, length - (numLeadingSpaces + numTrailingSpaces));
 }
 
-String stripLeadingAndTrailingHTMLSpaces(const String& string)
-{
-    unsigned length = string.length();
-
-    if (!length)
-        return string.isNull() ? string : emptyAtom.string();
-
-    if (string.is8Bit())
-        return stripLeadingAndTrailingHTMLSpaces(string, string.characters8(), length);
-
-    return stripLeadingAndTrailingHTMLSpaces(string, string.characters(), length);
-}
-
 String serializeForNumberType(const Decimal& number)
 {
     if (number.isZero()) {
index b042dd6..e7c6876 100644 (file)
@@ -71,12 +71,12 @@ String HTMLSourceTracker::sourceForToken(const HTMLToken& token)
 
     size_t i = 0;
     for ( ; i < length && !m_previousSource.isEmpty(); ++i) {
-        source.append(m_previousSource.currentChar());
+        source.append(*m_previousSource);
         m_previousSource.advance();
     }
     for ( ; i < length; ++i) {
         ASSERT(!m_currentSource.isEmpty());
-        source.append(m_currentSource.currentChar());
+        source.append(*m_currentSource);
         m_currentSource.advance();
     }
 
index 086fa1b..a2da744 100644 (file)
@@ -71,7 +71,7 @@ const String& CachedScript::script()
     if (!m_script && m_data) {
         m_script = m_decoder->decode(m_data->data(), encodedSize());
         m_script += m_decoder->flush();
-        setDecodedSize(m_script.sizeInBytes());
+        setDecodedSize(m_script.length() * sizeof(UChar));
     }
     m_decodedDataDeletionTimer.startOneShot(0);
     
index 3d8b779..63373ba 100644 (file)
@@ -28,16 +28,13 @@ SegmentedString::SegmentedString(const SegmentedString& other)
     , m_currentString(other.m_currentString)
     , m_substrings(other.m_substrings)
     , m_closed(other.m_closed)
-    , m_empty(other.m_empty)
-    , m_advanceFunc(other.m_advanceFunc)
-    , m_advanceAndUpdateLineNumberFunc(other.m_advanceAndUpdateLineNumberFunc)
 {
-    if (m_pushedChar2)
-        m_currentChar = m_pushedChar2;
-    else if (m_pushedChar1)
-        m_currentChar = m_pushedChar1;
+    if (other.m_currentChar == &other.m_pushedChar1)
+        m_currentChar = &m_pushedChar1;
+    else if (other.m_currentChar == &other.m_pushedChar2)
+        m_currentChar = &m_pushedChar2;
     else
-        m_currentChar = m_currentString.m_length ? m_currentString.getCurrentChar() : 0;
+        m_currentChar = other.m_currentChar;
 }
 
 const SegmentedString& SegmentedString::operator=(const SegmentedString& other)
@@ -46,22 +43,17 @@ const SegmentedString& SegmentedString::operator=(const SegmentedString& other)
     m_pushedChar2 = other.m_pushedChar2;
     m_currentString = other.m_currentString;
     m_substrings = other.m_substrings;
-    if (m_pushedChar2)
-        m_currentChar = m_pushedChar2;
-    else if (m_pushedChar1)
-        m_currentChar = m_pushedChar1;
+    if (other.m_currentChar == &other.m_pushedChar1)
+        m_currentChar = &m_pushedChar1;
+    else if (other.m_currentChar == &other.m_pushedChar2)
+        m_currentChar = &m_pushedChar2;
     else
-        m_currentChar = m_currentString.m_length ? m_currentString.getCurrentChar() : 0;
-
+        m_currentChar = other.m_currentChar;
     m_closed = other.m_closed;
-    m_empty = other.m_empty;
     m_numberOfCharactersConsumedPriorToCurrentString = other.m_numberOfCharactersConsumedPriorToCurrentString;
     m_numberOfCharactersConsumedPriorToCurrentLine = other.m_numberOfCharactersConsumedPriorToCurrentLine;
     m_currentLine = other.m_currentLine;
 
-    m_advanceFunc = other.m_advanceFunc;
-    m_advanceAndUpdateLineNumberFunc = other.m_advanceAndUpdateLineNumberFunc;
-
     return *this;
 }
 
@@ -104,9 +96,6 @@ void SegmentedString::clear()
     m_currentLine = 0;
     m_substrings.clear();
     m_closed = false;
-    m_empty = true;
-    m_advanceFunc = &SegmentedString::advanceEmpty;
-    m_advanceAndUpdateLineNumberFunc = &SegmentedString::advanceEmpty;
 }
 
 void SegmentedString::append(const SegmentedSubstring& s)
@@ -118,10 +107,8 @@ void SegmentedString::append(const SegmentedSubstring& s)
     if (!m_currentString.m_length) {
         m_numberOfCharactersConsumedPriorToCurrentString += m_currentString.numberOfCharactersConsumed();
         m_currentString = s;
-        updateAdvanceFunctionPointers();
     } else
         m_substrings.append(s);
-    m_empty = false;
 }
 
 void SegmentedString::prepend(const SegmentedSubstring& s)
@@ -138,16 +125,13 @@ void SegmentedString::prepend(const SegmentedSubstring& s)
     //        cases in the future.
     m_numberOfCharactersConsumedPriorToCurrentString += m_currentString.numberOfCharactersConsumed();
     m_numberOfCharactersConsumedPriorToCurrentString -= s.m_length;
-    if (!m_currentString.m_length) {
+    if (!m_currentString.m_length)
         m_currentString = s;
-        updateAdvanceFunctionPointers();
-    } else {
+    else {
         // Shift our m_currentString into our list.
         m_substrings.prepend(m_currentString);
         m_currentString = s;
-        updateAdvanceFunctionPointers();
     }
-    m_empty = false;
 }
 
 void SegmentedString::close()
@@ -168,7 +152,7 @@ void SegmentedString::append(const SegmentedString& s)
         for (; it != e; ++it)
             append(*it);
     }
-    m_currentChar = m_pushedChar1 ? m_pushedChar1 : (m_currentString.m_length ? m_currentString.getCurrentChar() : 0);
+    m_currentChar = m_pushedChar1 ? &m_pushedChar1 : m_currentString.m_current;
 }
 
 void SegmentedString::prepend(const SegmentedString& s)
@@ -182,7 +166,7 @@ void SegmentedString::prepend(const SegmentedString& s)
             prepend(*it);
     }
     prepend(s.m_currentString);
-    m_currentChar = m_pushedChar1 ? m_pushedChar1 : (m_currentString.m_length ? m_currentString.getCurrentChar() : 0);
+    m_currentChar = m_pushedChar1 ? &m_pushedChar1 : m_currentString.m_current;
 }
 
 void SegmentedString::advanceSubstring()
@@ -194,13 +178,8 @@ void SegmentedString::advanceSubstring()
         // string, we now account for those characters as part of the current
         // string, not as part of "prior to current string."
         m_numberOfCharactersConsumedPriorToCurrentString -= m_currentString.numberOfCharactersConsumed();
-        updateAdvanceFunctionPointers();
-    } else {
+    } else
         m_currentString.clear();
-        m_empty = true;
-        m_advanceFunc = &SegmentedString::advanceEmpty;
-        m_advanceAndUpdateLineNumberFunc = &SegmentedString::advanceEmpty;
-    }
 }
 
 String SegmentedString::toString() const
@@ -225,71 +204,22 @@ void SegmentedString::advance(unsigned count, UChar* consumedCharacters)
 {
     ASSERT(count <= length());
     for (unsigned i = 0; i < count; ++i) {
-        consumedCharacters[i] = currentChar();
+        consumedCharacters[i] = *current();
         advance();
     }
 }
 
-void SegmentedString::advance8()
-{
-    ASSERT(!m_pushedChar1);
-    decrementAndCheckLength();
-    m_currentChar = m_currentString.incrementAndGetCurrentChar8();
-}
-
-void SegmentedString::advance16()
-{
-    ASSERT(!m_pushedChar1);
-    decrementAndCheckLength();
-    m_currentChar = m_currentString.incrementAndGetCurrentChar16();
-}
-
-void SegmentedString::advanceAndUpdateLineNumber8()
-{
-    ASSERT(!m_pushedChar1);
-    ASSERT(m_currentString.getCurrentChar() == m_currentChar);
-    if (m_currentChar == '\n') {
-        ++m_currentLine;
-        m_numberOfCharactersConsumedPriorToCurrentLine = numberOfCharactersConsumed() + 1;
-    }
-    decrementAndCheckLength();
-    m_currentChar = m_currentString.incrementAndGetCurrentChar8();
-}
-
-void SegmentedString::advanceAndUpdateLineNumber16()
-{
-    ASSERT(!m_pushedChar1);
-    ASSERT(m_currentString.getCurrentChar() == m_currentChar);
-    if (m_currentChar == '\n') {
-        ++m_currentLine;
-        m_numberOfCharactersConsumedPriorToCurrentLine = numberOfCharactersConsumed() + 1;
-    }
-    decrementAndCheckLength();
-    m_currentChar = m_currentString.incrementAndGetCurrentChar16();
-}
-
 void SegmentedString::advanceSlowCase()
 {
     if (m_pushedChar1) {
         m_pushedChar1 = m_pushedChar2;
         m_pushedChar2 = 0;
-
-        if (m_pushedChar1) {
-            m_currentChar = m_pushedChar1;
-            return;
-        }
-
-        updateAdvanceFunctionPointers();
-    } else if (m_currentString.m_length) {
+    } else if (m_currentString.m_current) {
+        ++m_currentString.m_current;
         if (--m_currentString.m_length == 0)
             advanceSubstring();
-    } else if (!isComposite()) {
-        m_currentString.clear();
-        m_empty = true;
-        m_advanceFunc = &SegmentedString::advanceEmpty;
-        m_advanceAndUpdateLineNumberFunc = &SegmentedString::advanceEmpty;
     }
-    m_currentChar = m_currentString.m_length ? m_currentString.getCurrentChar() : 0;
+    m_currentChar = m_pushedChar1 ? &m_pushedChar1 : m_currentString.m_current;
 }
 
 void SegmentedString::advanceAndUpdateLineNumberSlowCase()
@@ -297,37 +227,16 @@ void SegmentedString::advanceAndUpdateLineNumberSlowCase()
     if (m_pushedChar1) {
         m_pushedChar1 = m_pushedChar2;
         m_pushedChar2 = 0;
-
-        if (m_pushedChar1) {
-            m_currentChar = m_pushedChar1;
-            return;
-        }
-
-        updateAdvanceFunctionPointers();
-    } else if (m_currentString.m_length) {
-        if (m_currentString.getCurrentChar() == '\n' && m_currentString.doNotExcludeLineNumbers()) {
+    } else if (m_currentString.m_current) {
+        if (*m_currentString.m_current++ == '\n' && m_currentString.doNotExcludeLineNumbers()) {
             ++m_currentLine;
             // Plus 1 because numberOfCharactersConsumed value hasn't incremented yet; it does with m_length decrement below.
             m_numberOfCharactersConsumedPriorToCurrentLine = numberOfCharactersConsumed() + 1;
         }
         if (--m_currentString.m_length == 0)
             advanceSubstring();
-        else
-            m_currentString.incrementAndGetCurrentChar(); // Only need the ++
-    } else if (!isComposite()) {
-        m_currentString.clear();
-        m_empty = true;
-        m_advanceFunc = &SegmentedString::advanceEmpty;
-        m_advanceAndUpdateLineNumberFunc = &SegmentedString::advanceEmpty;
     }
-
-    m_currentChar = m_currentString.m_length ? m_currentString.getCurrentChar() : 0;
-}
-
-void SegmentedString::advanceEmpty()
-{
-    ASSERT(!m_currentString.m_length && !isComposite());
-    m_currentChar = 0;
+    m_currentChar = m_pushedChar1 ? &m_pushedChar1 : m_currentString.m_current;
 }
 
 OrdinalNumber SegmentedString::currentLine() const
index 340250b..777a65e 100644 (file)
@@ -33,32 +33,20 @@ class SegmentedSubstring {
 public:
     SegmentedSubstring()
         : m_length(0)
+        , m_current(0)
         , m_doNotExcludeLineNumbers(true)
-        , m_is8Bit(false)
     {
-        m_data.string16Ptr = 0;
     }
 
     SegmentedSubstring(const String& str)
         : m_length(str.length())
-        , m_doNotExcludeLineNumbers(true)
+        , m_current(str.isEmpty() ? 0 : str.characters())
         , m_string(str)
+        , m_doNotExcludeLineNumbers(true)
     {
-        if (m_length) {
-            if (m_string.is8Bit()) {
-                m_is8Bit = true;
-                m_data.string8Ptr = m_string.characters8();
-            } else {
-                m_is8Bit = false;
-                m_data.string16Ptr = m_string.characters16();
-            }
-        } else
-            m_is8Bit = false;
     }
 
-    void clear() { m_length = 0; m_data.string16Ptr = 0; m_is8Bit = false;}
-    
-    bool is8Bit() { return m_is8Bit; }
+    void clear() { m_length = 0; m_current = 0; }
     
     bool excludeLineNumbers() const { return !m_doNotExcludeLineNumbers; }
     bool doNotExcludeLineNumbers() const { return m_doNotExcludeLineNumbers; }
@@ -69,70 +57,19 @@ public:
 
     void appendTo(StringBuilder& builder) const
     {
-        int offset = m_string.length() - m_length;
-
-        if (!offset) {
-            if (m_length)
-                builder.append(m_string);
-        } else
-            builder.append(m_string.substring(offset, m_length));
-    }
-
-    UChar getCurrentChar8()
-    {
-        return *m_data.string8Ptr;
-    }
-
-    UChar getCurrentChar16()
-    {
-        return m_data.string16Ptr ? *m_data.string16Ptr : 0;
-    }
-
-    UChar incrementAndGetCurrentChar8()
-    {
-        ASSERT(m_data.string8Ptr);
-        return *++m_data.string8Ptr;
-    }
-
-    UChar incrementAndGetCurrentChar16()
-    {
-        ASSERT(m_data.string16Ptr);
-        return *++m_data.string16Ptr;
-    }
-
-    String currentSubString(unsigned length)
-    {
-        int offset = m_string.length() - m_length;
-        return m_string.substring(offset, length);
-    }
-
-    ALWAYS_INLINE UChar getCurrentChar()
-    {
-        ASSERT(m_length);
-        if (is8Bit())
-            return getCurrentChar8();
-        return getCurrentChar16();
-    }
-    
-    ALWAYS_INLINE UChar incrementAndGetCurrentChar()
-    {
-        ASSERT(m_length);
-        if (is8Bit())
-            return incrementAndGetCurrentChar8();
-        return incrementAndGetCurrentChar16();
+        if (m_string.characters() == m_current)
+            builder.append(m_string);
+        else
+            builder.append(String(m_current, m_length));
     }
 
 public:
-    union {
-        const LChar* string8Ptr;
-        const UChar* string16Ptr;
-    } m_data;
     int m_length;
+    const UChar* m_current;
 
 private:
-    bool m_doNotExcludeLineNumbers;
-    bool m_is8Bit;
     String m_string;
+    bool m_doNotExcludeLineNumbers;
 };
 
 class SegmentedString {
@@ -145,9 +82,6 @@ public:
         , m_numberOfCharactersConsumedPriorToCurrentLine(0)
         , m_currentLine(0)
         , m_closed(false)
-        , m_empty(true)
-        , m_advanceFunc(&SegmentedString::advanceEmpty)
-        , m_advanceAndUpdateLineNumberFunc(&SegmentedString::advanceEmpty)
     {
     }
 
@@ -155,16 +89,12 @@ public:
         : m_pushedChar1(0)
         , m_pushedChar2(0)
         , m_currentString(str)
-        , m_currentChar(0)
+        , m_currentChar(m_currentString.m_current)
         , m_numberOfCharactersConsumedPriorToCurrentString(0)
         , m_numberOfCharactersConsumedPriorToCurrentLine(0)
         , m_currentLine(0)
         , m_closed(false)
-        , m_empty(!str.length())
     {
-        if (m_currentString.m_length)
-            m_currentChar = m_currentString.getCurrentChar();
-        updateAdvanceFunctionPointers();
     }
 
     SegmentedString(const SegmentedString&);
@@ -184,15 +114,14 @@ public:
     {
         if (!m_pushedChar1) {
             m_pushedChar1 = c;
-            m_currentChar = m_pushedChar1 ? m_pushedChar1 : m_currentString.getCurrentChar();
-            updateSlowCaseFunctionPointers();
+            m_currentChar = m_pushedChar1 ? &m_pushedChar1 : m_currentString.m_current;
         } else {
             ASSERT(!m_pushedChar2);
             m_pushedChar2 = c;
         }
     }
 
-    bool isEmpty() const { return m_empty; }
+    bool isEmpty() const { return !current(); }
     unsigned length() const;
 
     bool isClosed() const { return m_closed; }
@@ -203,47 +132,66 @@ public:
         NotEnoughCharacters,
     };
 
-    LookAheadResult lookAhead(const String& string) { return lookAheadInline(string, true); }
-    LookAheadResult lookAheadIgnoringCase(const String& string) { return lookAheadInline(string, false); }
-
-    inline void advance()
-    {
-        (this->*m_advanceFunc)();
-    }
+    LookAheadResult lookAhead(const String& string) { return lookAheadInline<SegmentedString::equalsLiterally>(string); }
+    LookAheadResult lookAheadIgnoringCase(const String& string) { return lookAheadInline<SegmentedString::equalsIgnoringCase>(string); }
 
-    inline void advanceAndUpdateLineNumber()
+    void advance()
     {
-        (this->*m_advanceAndUpdateLineNumberFunc)();
+        if (!m_pushedChar1 && m_currentString.m_length > 1) {
+            --m_currentString.m_length;
+            m_currentChar = ++m_currentString.m_current;
+            return;
+        }
+        advanceSlowCase();
     }
 
     void advanceAndASSERT(UChar expectedCharacter)
     {
-        ASSERT_UNUSED(expectedCharacter, currentChar() == expectedCharacter);
+        ASSERT_UNUSED(expectedCharacter, *current() == expectedCharacter);
         advance();
     }
 
     void advanceAndASSERTIgnoringCase(UChar expectedCharacter)
     {
-        ASSERT_UNUSED(expectedCharacter, WTF::Unicode::foldCase(currentChar()) == WTF::Unicode::foldCase(expectedCharacter));
+        ASSERT_UNUSED(expectedCharacter, WTF::Unicode::foldCase(*current()) == WTF::Unicode::foldCase(expectedCharacter));
         advance();
     }
 
+    void advancePastNewlineAndUpdateLineNumber()
+    {
+        ASSERT(*current() == '\n');
+        if (!m_pushedChar1 && m_currentString.m_length > 1) {
+            int newLineFlag = m_currentString.doNotExcludeLineNumbers();
+            m_currentLine += newLineFlag;
+            if (newLineFlag)
+                m_numberOfCharactersConsumedPriorToCurrentLine = numberOfCharactersConsumed() + 1;
+            --m_currentString.m_length;
+            m_currentChar = ++m_currentString.m_current;
+            return;
+        }
+        advanceAndUpdateLineNumberSlowCase();
+    }
+    
     void advancePastNonNewline()
     {
-        ASSERT(currentChar() != '\n');
-        advance();
+        ASSERT(*current() != '\n');
+        if (!m_pushedChar1 && m_currentString.m_length > 1) {
+            --m_currentString.m_length;
+            m_currentChar = ++m_currentString.m_current;
+            return;
+        }
+        advanceSlowCase();
     }
-
-    void advancePastNewlineAndUpdateLineNumber()
+    
+    void advanceAndUpdateLineNumber()
     {
-        ASSERT(currentChar() == '\n');
         if (!m_pushedChar1 && m_currentString.m_length > 1) {
-            int newLineFlag = m_currentString.doNotExcludeLineNumbers();
+            int newLineFlag = (*m_currentString.m_current == '\n') & m_currentString.doNotExcludeLineNumbers();
             m_currentLine += newLineFlag;
             if (newLineFlag)
                 m_numberOfCharactersConsumedPriorToCurrentLine = numberOfCharactersConsumed() + 1;
-            decrementAndCheckLength();
-            m_currentChar = m_currentString.incrementAndGetCurrentChar();
+            --m_currentString.m_length;
+            m_currentChar = ++m_currentString.m_current;
             return;
         }
         advanceAndUpdateLineNumberSlowCase();
@@ -268,7 +216,9 @@ public:
 
     String toString() const;
 
-    UChar currentChar() const { return m_currentChar; }    
+    const UChar& operator*() const { return *current(); }
+    const UChar* operator->() const { return current(); }
+    
 
     // The method is moderately slow, comparing to currentLine method.
     OrdinalNumber currentColumn() const;
@@ -281,68 +231,27 @@ private:
     void append(const SegmentedSubstring&);
     void prepend(const SegmentedSubstring&);
 
-    void advance8();
-    void advance16();
-    void advanceAndUpdateLineNumber8();
-    void advanceAndUpdateLineNumber16();
     void advanceSlowCase();
     void advanceAndUpdateLineNumberSlowCase();
-    void advanceEmpty();
     void advanceSubstring();
-    
-    void updateSlowCaseFunctionPointers()
-    {
-        m_advanceFunc = &SegmentedString::advanceSlowCase;
-        m_advanceAndUpdateLineNumberFunc = &SegmentedString::advanceAndUpdateLineNumberSlowCase;
-    }
+    const UChar* current() const { return m_currentChar; }
 
-    void decrementAndCheckLength()
-    {
-        ASSERT(m_currentString.m_length > 1);
-        if (--m_currentString.m_length == 1)
-            updateSlowCaseFunctionPointers();
-    }
+    static bool equalsLiterally(const UChar* str1, const UChar* str2, size_t count) { return !memcmp(str1, str2, count * sizeof(UChar)); }
+    static bool equalsIgnoringCase(const UChar* str1, const UChar* str2, size_t count) { return !WTF::Unicode::umemcasecmp(str1, str2, count); }
 
-    void updateAdvanceFunctionPointers()
-    {
-        if ((m_currentString.m_length > 1) && !m_pushedChar1) {
-            if (m_currentString.is8Bit()) {
-                m_advanceFunc = &SegmentedString::advance8;
-                if (m_currentString.doNotExcludeLineNumbers())
-                    m_advanceAndUpdateLineNumberFunc = &SegmentedString::advanceAndUpdateLineNumber8;
-                else
-                    m_advanceAndUpdateLineNumberFunc = &SegmentedString::advance8;
-                return;
-            }
-
-            m_advanceFunc = &SegmentedString::advance16;
-            if (m_currentString.doNotExcludeLineNumbers())
-                m_advanceAndUpdateLineNumberFunc = &SegmentedString::advanceAndUpdateLineNumber16;
-            else
-                m_advanceAndUpdateLineNumberFunc = &SegmentedString::advance16;
-            return;
-        }
-
-        if (!m_currentString.m_length && !isComposite()) {
-            m_advanceFunc = &SegmentedString::advanceEmpty;
-            m_advanceAndUpdateLineNumberFunc = &SegmentedString::advanceEmpty;
-        }
-
-        updateSlowCaseFunctionPointers();
-    }
-
-    inline LookAheadResult lookAheadInline(const String& string, bool caseSensitive)
+    template<bool equals(const UChar* str1, const UChar* str2, size_t count)>
+    inline LookAheadResult lookAheadInline(const String& string)
     {
         if (!m_pushedChar1 && string.length() <= static_cast<unsigned>(m_currentString.m_length)) {
-            String currentSubstring = m_currentString.currentSubString(string.length());
-            if (currentSubstring.startsWith(string, caseSensitive))
+            if (equals(string.characters(), m_currentString.m_current, string.length()))
                 return DidMatch;
             return DidNotMatch;
         }
-        return lookAheadSlowCase(string, caseSensitive);
+        return lookAheadSlowCase<equals>(string);
     }
-    
-    LookAheadResult lookAheadSlowCase(const String& string, bool caseSensitive)
+
+    template<bool equals(const UChar* str1, const UChar* str2, size_t count)>
+    LookAheadResult lookAheadSlowCase(const String& string)
     {
         unsigned count = string.length();
         if (count > length())
@@ -351,7 +260,7 @@ private:
         String consumedString = String::createUninitialized(count, consumedCharacters);
         advance(count, consumedCharacters);
         LookAheadResult result = DidNotMatch;
-        if (consumedString.startsWith(string, caseSensitive))
+        if (equals(string.characters(), consumedCharacters, count))
             result = DidMatch;
         prepend(SegmentedString(consumedString));
         return result;
@@ -362,15 +271,12 @@ private:
     UChar m_pushedChar1;
     UChar m_pushedChar2;
     SegmentedSubstring m_currentString;
-    UChar m_currentChar;
+    const UChar* m_currentChar;
     int m_numberOfCharactersConsumedPriorToCurrentString;
     int m_numberOfCharactersConsumedPriorToCurrentLine;
     int m_currentLine;
     Deque<SegmentedSubstring> m_substrings;
     bool m_closed;
-    bool m_empty;
-    void (SegmentedString::*m_advanceFunc)();
-    void (SegmentedString::*m_advanceAndUpdateLineNumberFunc)();
 };
 
 }
index 92df636..d83cecb 100644 (file)
@@ -68,7 +68,7 @@ bool consumeCharacterReference(SegmentedString& source, StringBuilder& decodedCh
     StringBuilder consumedCharacters;
     
     while (!source.isEmpty()) {
-        UChar cc = source.currentChar();
+        UChar cc = *source;
         switch (entityState) {
         case Initial: {
             if (cc == '\x09' || cc == '\x0A' || cc == '\x0C' || cc == ' ' || cc == '<' || cc == '&')
index 93a0ed5..0a3cada 100644 (file)
@@ -66,7 +66,7 @@ protected:
         {
         }
 
-        ALWAYS_INLINE UChar nextInputCharacter() const { return m_nextInputCharacter; }
+        UChar nextInputCharacter() const { return m_nextInputCharacter; }
 
         // Returns whether we succeeded in peeking at the next character.
         // The only way we can fail to peek is if there are no more
@@ -74,7 +74,7 @@ protected:
         ALWAYS_INLINE bool peek(SegmentedString& source)
         {
         PeekAgain:
-            m_nextInputCharacter = source.currentChar();
+            m_nextInputCharacter = *source;
 
             // Every branch in this function is expensive, so we have a
             // fast-reject branch for characters that don't require special
@@ -91,7 +91,7 @@ protected:
                 source.advancePastNewlineAndUpdateLineNumber();
                 if (source.isEmpty())
                     return false;
-                m_nextInputCharacter = source.currentChar();
+                m_nextInputCharacter = *source;
             }
             if (m_nextInputCharacter == '\r') {
                 m_nextInputCharacter = '\n';
@@ -116,7 +116,7 @@ protected:
         }
 
         // Returns whether there are more characters in |source| after advancing.
-        ALWAYS_INLINE bool advance(SegmentedString& source)
+        bool advance(SegmentedString& source)
         {
             source.advanceAndUpdateLineNumber();
             if (source.isEmpty())