Changeset 151236 in webkit


Ignore:
Timestamp:
Jun 5, 2013 2:20:40 PM (11 years ago)
Author:
commit-queue@webkit.org
Message:

Avoid multiple copies of inline script & style strings
https://bugs.webkit.org/show_bug.cgi?id=117202

Patch by Arunprasad Rajkumar <arurajku@cisco.com> on 2013-06-05
Reviewed by Darin Adler.

Merge from https://chromiumcodereview.appspot.com/16005007.

No new tests needed.

The HTML parser breaks up large text nodes into small chunks to avoid some
O(n2) editing algorithms. This fix skips that workaround for <script> and
<style> elements, which aren't likely to need editing. As a result, <script>
ends up with a single text node, containing a contiguous String, which is the
source code of that inline script block.

Prior this fix, we could end up with two copies of large inline scripts: one
monolithic string retained by JSC and a number of shards retained by the DOM.
After this fix, both the DOM and JSC use the same monolithic string, removing a
copy.

  • dom/Text.cpp:

(WebCore::Text::createWithLengthLimit):

  • html/parser/HTMLConstructionSite.cpp:

(WebCore::shouldUseLengthLimit):
(WebCore::HTMLConstructionSite::insertTextNode):

Location:
trunk/Source/WebCore
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/WebCore/ChangeLog

    r151227 r151236  
     12013-06-05  Arunprasad Rajkumar  <arurajku@cisco.com>
     2
     3        Avoid multiple copies of inline script & style strings
     4        https://bugs.webkit.org/show_bug.cgi?id=117202
     5
     6        Reviewed by Darin Adler.
     7
     8        Merge from https://chromiumcodereview.appspot.com/16005007.
     9
     10        No new tests needed.
     11
     12        The HTML parser breaks up large text nodes into small chunks to avoid some
     13        O(n^2) editing algorithms. This fix skips that workaround for <script> and
     14        <style> elements, which aren't likely to need editing. As a result, <script>
     15        ends up with a single text node, containing a contiguous String, which is the
     16        source code of that inline script block.
     17
     18        Prior this fix, we could end up with two copies of large inline scripts: one
     19        monolithic string retained by JSC and a number of shards retained by the DOM.
     20        After this fix, both the DOM and JSC use the same monolithic string, removing a
     21        copy.
     22
     23        * dom/Text.cpp:
     24        (WebCore::Text::createWithLengthLimit):
     25        * html/parser/HTMLConstructionSite.cpp:
     26        (WebCore::shouldUseLengthLimit):
     27        (WebCore::HTMLConstructionSite::insertTextNode):
     28
    1292013-06-05  Kondapally Kalyan  <kalyan.kondapally@intel.com>
    230
  • trunk/Source/WebCore/dom/Text.cpp

    r151160 r151236  
    327327}
    328328
    329 PassRefPtr<Text> Text::createWithLengthLimit(Document* document, const String& data, unsigned start, unsigned maxChars)
     329PassRefPtr<Text> Text::createWithLengthLimit(Document* document, const String& data, unsigned start, unsigned lengthLimit)
    330330{
    331331    unsigned dataLength = data.length();
    332332
    333     if (!start && dataLength <= maxChars)
     333    if (!start && dataLength <= lengthLimit)
    334334        return create(document, data);
    335335
    336336    RefPtr<Text> result = Text::create(document, String());
    337     result->parserAppendData(data, start, maxChars);
     337    result->parserAppendData(data, start, lengthLimit);
    338338
    339339    return result;
  • trunk/Source/WebCore/html/parser/HTMLConstructionSite.cpp

    r149980 r151236  
    7474        || item->hasTagName(rpTag)
    7575        || item->hasTagName(rtTag);
     76}
     77
     78static bool shouldUseLengthLimit(const ContainerNode* node)
     79{
     80    return !node->hasTagName(scriptTag)
     81        && !node->hasTagName(styleTag)
     82        && !node->hasTagName(SVGNames::scriptTag);
    7683}
    7784
     
    491498
    492499    unsigned currentPosition = 0;
     500    unsigned lengthLimit = shouldUseLengthLimit(task.parent.get()) ? Text::defaultLengthLimit : std::numeric_limits<unsigned>::max();
    493501
    494502    // FIXME: Splitting text nodes into smaller chunks contradicts HTML5 spec, but is currently necessary
     
    500508        // was the last text node inserted by the parser.
    501509        CharacterData* textNode = static_cast<CharacterData*>(previousChild);
    502         currentPosition = textNode->parserAppendData(characters, 0, Text::defaultLengthLimit);
     510        currentPosition = textNode->parserAppendData(characters, 0, lengthLimit);
    503511    }
    504512
    505513    while (currentPosition < characters.length()) {
    506         RefPtr<Text> textNode = Text::createWithLengthLimit(task.parent->document(), shouldUseAtomicString ? AtomicString(characters).string() : characters, currentPosition);
     514        RefPtr<Text> textNode = Text::createWithLengthLimit(task.parent->document(), shouldUseAtomicString ? AtomicString(characters).string() : characters, currentPosition, lengthLimit);
    507515        // If we have a whole string of unbreakable characters the above could lead to an infinite loop. Exceeding the length limit is the lesser evil.
    508516        if (!textNode->length()) {
Note: See TracChangeset for help on using the changeset viewer.