Changeset 130190 in webkit


Ignore:
Timestamp:
Oct 2, 2012, 11:41:05 AM (13 years ago)
Author:
msaboff@apple.com
Message:

HTMLConstructionSite::insertTextNode isn't optimized for 8 bit strings
https://bugs.webkit.org/show_bug.cgi?id=97740

Reviewed by Darin Adler.

Source/WebCore:

Changed parserAppendData to take a string instead of a UChar*. Also added an optional offset
argument to handle string+offset. The actual string append now uses the appropriate string
size.

  • dom/CharacterData.cpp:

(WebCore::CharacterData::parserAppendData):

  • dom/CharacterData.h:

(CharacterData):

  • dom/Text.cpp:

(WebCore::Text::createWithLengthLimit):

  • html/parser/HTMLConstructionSite.cpp:

(WebCore::HTMLConstructionSite::insertTextNode):

Source/WTF:

Added an append method that takes an LChar source. Made both the UChar and LChar versions optimally handle
the appendee and appendend string bitness.

  • wtf/text/WTFString.cpp:

(WTF::String::append):

  • wtf/text/WTFString.h:

(String):

Location:
trunk/Source
Files:
8 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/WTF/ChangeLog

    r130187 r130190  
     12012-10-02  Michael Saboff  <msaboff@apple.com>
     2
     3        HTMLConstructionSite::insertTextNode isn't optimized for 8 bit strings
     4        https://bugs.webkit.org/show_bug.cgi?id=97740
     5
     6        Reviewed by Darin Adler.
     7
     8        Added an append method that takes an LChar source.  Made both the UChar and LChar versions optimally handle
     9        the appendee and appendend string bitness.
     10
     11        * wtf/text/WTFString.cpp:
     12        (WTF::String::append):
     13        * wtf/text/WTFString.h:
     14        (String):
     15
    1162012-10-02  Ilya Tikhonovsky  <loislo@chromium.org>
    217
  • trunk/Source/WTF/wtf/text/WTFString.cpp

    r130187 r130190  
    168168}
    169169
    170 void String::append(const UChar* charactersToAppend, unsigned lengthToAppend)
     170void String::append(const LChar* charactersToAppend, unsigned lengthToAppend)
    171171{
    172172    if (!m_impl) {
     
    181181
    182182    ASSERT(charactersToAppend);
     183
     184    unsigned strLength = m_impl->length();
     185
     186    if (m_impl->is8Bit()) {
     187        if (lengthToAppend > numeric_limits<unsigned>::max() - strLength)
     188            CRASH();
     189        LChar* data;
     190        RefPtr<StringImpl> newImpl = StringImpl::createUninitialized(strLength + lengthToAppend, data);
     191        StringImpl::copyChars(data, m_impl->characters8(), strLength);
     192        StringImpl::copyChars(data + strLength, charactersToAppend, lengthToAppend);
     193        m_impl = newImpl.release();
     194        return;
     195    }
     196
     197    if (lengthToAppend > numeric_limits<unsigned>::max() - strLength)
     198        CRASH();
    183199    UChar* data;
    184     if (lengthToAppend > numeric_limits<unsigned>::max() - length())
     200    RefPtr<StringImpl> newImpl = StringImpl::createUninitialized(length() + lengthToAppend, data);
     201    StringImpl::copyChars(data, m_impl->characters16(), strLength);
     202    StringImpl::copyChars(data + strLength, charactersToAppend, lengthToAppend);
     203    m_impl = newImpl.release();
     204}
     205
     206void String::append(const UChar* charactersToAppend, unsigned lengthToAppend)
     207{
     208    if (!m_impl) {
     209        if (!charactersToAppend)
     210            return;
     211        m_impl = StringImpl::create(charactersToAppend, lengthToAppend);
     212        return;
     213    }
     214
     215    if (!lengthToAppend)
     216        return;
     217
     218    unsigned strLength = m_impl->length();
     219   
     220    ASSERT(charactersToAppend);
     221    if (lengthToAppend > numeric_limits<unsigned>::max() - strLength)
    185222        CRASH();
    186     RefPtr<StringImpl> newImpl = StringImpl::createUninitialized(length() + lengthToAppend, data);
    187     memcpy(data, characters(), length() * sizeof(UChar));
    188     memcpy(data + length(), charactersToAppend, lengthToAppend * sizeof(UChar));
     223    UChar* data;
     224    RefPtr<StringImpl> newImpl = StringImpl::createUninitialized(strLength + lengthToAppend, data);
     225    if (m_impl->is8Bit())
     226        StringImpl::copyChars(data, characters8(), strLength);
     227    else
     228        StringImpl::copyChars(data, characters16(), strLength);
     229    StringImpl::copyChars(data + strLength, charactersToAppend, lengthToAppend);
    189230    m_impl = newImpl.release();
    190231}
     232
    191233
    192234void String::insert(const UChar* charactersToInsert, unsigned lengthToInsert, unsigned position)
  • trunk/Source/WTF/wtf/text/WTFString.h

    r130144 r130190  
    303303    void append(char c) { append(static_cast<LChar>(c)); };
    304304    WTF_EXPORT_STRING_API void append(UChar);
     305    WTF_EXPORT_STRING_API void append(const LChar*, unsigned length);
    305306    WTF_EXPORT_STRING_API void append(const UChar*, unsigned length);
    306307    WTF_EXPORT_STRING_API void insert(const String&, unsigned pos);
  • trunk/Source/WebCore/ChangeLog

    r130189 r130190  
     12012-10-02  Michael Saboff  <msaboff@apple.com>
     2
     3        HTMLConstructionSite::insertTextNode isn't optimized for 8 bit strings
     4        https://bugs.webkit.org/show_bug.cgi?id=97740
     5
     6        Reviewed by Darin Adler.
     7
     8        Changed parserAppendData to take a string instead of a UChar*.  Also added an optional offset
     9        argument to handle string+offset.  The actual string append now uses the appropriate string
     10        size.
     11
     12        * dom/CharacterData.cpp:
     13        (WebCore::CharacterData::parserAppendData):
     14        * dom/CharacterData.h:
     15        (CharacterData):
     16        * dom/Text.cpp:
     17        (WebCore::Text::createWithLengthLimit):
     18        * html/parser/HTMLConstructionSite.cpp:
     19        (WebCore::HTMLConstructionSite::insertTextNode):
     20
    1212012-10-02  Ojan Vafai  <ojan@chromium.org>
    222
  • trunk/Source/WebCore/dom/CharacterData.cpp

    r130139 r130190  
    6464}
    6565
    66 unsigned CharacterData::parserAppendData(const UChar* data, unsigned dataLength, unsigned lengthLimit)
     66unsigned CharacterData::parserAppendData(const String& string, unsigned offset, unsigned lengthLimit)
    6767{
    6868    unsigned oldLength = m_data.length();
    6969
    70     unsigned end = min(dataLength, lengthLimit - oldLength);
     70    ASSERT(lengthLimit >= oldLength);
     71
     72    unsigned characterLength = string.length() - offset;
     73    unsigned characterLengthLimit = min(characterLength, lengthLimit - oldLength);
    7174
    7275    // Check that we are not on an unbreakable boundary.
    73     // Some text break iterator implementations work best if the passed buffer is as small as possible, 
    74     // see <https://bugs.webkit.org/show_bug.cgi?id=29092>. 
     76    // Some text break iterator implementations work best if the passed buffer is as small as possible,
     77    // see <https://bugs.webkit.org/show_bug.cgi?id=29092>.
    7578    // We need at least two characters look-ahead to account for UTF-16 surrogates.
    76     if (end < dataLength) {
    77         NonSharedCharacterBreakIterator it(data, (end + 2 > dataLength) ? dataLength : end + 2);
    78         if (!isTextBreak(it, end))
    79             end = textBreakPreceding(it, end);
    80     }
    81    
    82     if (!end)
     79    if (characterLengthLimit < characterLength) {
     80        NonSharedCharacterBreakIterator it(string.characters() + offset, (characterLengthLimit + 2 > characterLength) ? characterLength : characterLengthLimit + 2);
     81        if (!isTextBreak(it, characterLengthLimit))
     82            characterLengthLimit = textBreakPreceding(it, characterLengthLimit);
     83    }
     84
     85    if (!characterLengthLimit)
    8386        return 0;
    8487
    85     m_data.append(data, end);
     88    if (string.is8Bit())
     89        m_data.append(string.characters8() + offset, characterLengthLimit);
     90    else
     91        m_data.append(string.characters16() + offset, characterLengthLimit);
    8692
    8793    updateRenderer(oldLength, 0);
     
    9197    if (parentNode())
    9298        parentNode()->childrenChanged();
    93    
    94     return end;
     99
     100    return characterLengthLimit;
    95101}
    96102
  • trunk/Source/WebCore/dom/CharacterData.h

    r121530 r130190  
    4646    // Like appendData, but optimized for the parser (e.g., no mutation events).
    4747    // Returns how much could be added before length limit was met.
    48     unsigned parserAppendData(const UChar*, unsigned dataLength, unsigned lengthLimit);
     48    unsigned parserAppendData(const String& string, unsigned offset, unsigned lengthLimit);
    4949
    5050    virtual void reportMemoryUsage(MemoryObjectInfo*) const;
  • trunk/Source/WebCore/dom/Text.cpp

    r127706 r130190  
    289289
    290290    RefPtr<Text> result = Text::create(document, String());
    291     result->parserAppendData(data.characters() + start, dataLength - start, maxChars);
     291    result->parserAppendData(data, start, maxChars);
    292292
    293293    return result;
  • trunk/Source/WebCore/html/parser/HTMLConstructionSite.cpp

    r129164 r130190  
    369369        // was the last text node inserted by the parser.
    370370        CharacterData* textNode = static_cast<CharacterData*>(previousChild);
    371         currentPosition = textNode->parserAppendData(characters.characters(), characters.length(), Text::defaultLengthLimit);
     371        currentPosition = textNode->parserAppendData(characters, 0, Text::defaultLengthLimit);
    372372    }
    373373
Note: See TracChangeset for help on using the changeset viewer.