Changeset 63372 in webkit


Ignore:
Timestamp:
Jul 14, 2010 4:44:03 PM (14 years ago)
Author:
abarth@webkit.org
Message:

2010-07-14 Adam Barth <abarth@webkit.org>

Reviewed by Eric Seidel.

Avoid extra memcpy of character tokens
https://bugs.webkit.org/show_bug.cgi?id=42002

This patch is just some cleanup to make fixing this bug easier.

  • html/HTMLTreeBuilder.cpp: (WebCore::HTMLTreeBuilder::ExternalCharacterTokenBuffer::ExternalCharacterTokenBuffer): (WebCore::HTMLTreeBuilder::ExternalCharacterTokenBuffer::~ExternalCharacterTokenBuffer): (WebCore::HTMLTreeBuilder::ExternalCharacterTokenBuffer::isEmpty): (WebCore::HTMLTreeBuilder::ExternalCharacterTokenBuffer::skipLeadingWhitespace): (WebCore::HTMLTreeBuilder::ExternalCharacterTokenBuffer::takeLeadingWhitespace): (WebCore::HTMLTreeBuilder::ExternalCharacterTokenBuffer::takeRemaining): (WebCore::HTMLTreeBuilder::ExternalCharacterTokenBuffer::giveRemainingTo): (WebCore::HTMLTreeBuilder::ExternalCharacterTokenBuffer::takeRemainingWhitespace): (WebCore::HTMLTreeBuilder::processDoctypeToken): (WebCore::HTMLTreeBuilder::processStartTag): (WebCore::HTMLTreeBuilder::processEndTag): (WebCore::HTMLTreeBuilder::processComment): (WebCore::HTMLTreeBuilder::processCharacter): (WebCore::HTMLTreeBuilder::processCharacterBuffer): (WebCore::HTMLTreeBuilder::processEndOfFile): (WebCore::HTMLTreeBuilder::defaultForInitial): (WebCore::HTMLTreeBuilder::defaultForBeforeHTML): (WebCore::HTMLTreeBuilder::defaultForBeforeHead): (WebCore::HTMLTreeBuilder::defaultForInHead): (WebCore::HTMLTreeBuilder::defaultForInHeadNoscript): (WebCore::HTMLTreeBuilder::defaultForAfterHead): (WebCore::HTMLTreeBuilder::defaultForInTableText):
  • html/HTMLTreeBuilder.h:
Location:
trunk/WebCore
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • trunk/WebCore/ChangeLog

    r63370 r63372  
     12010-07-14  Adam Barth  <abarth@webkit.org>
     2
     3        Reviewed by Eric Seidel.
     4
     5        Avoid extra memcpy of character tokens
     6        https://bugs.webkit.org/show_bug.cgi?id=42002
     7
     8        This patch is just some cleanup to make fixing this bug easier.
     9
     10        * html/HTMLTreeBuilder.cpp:
     11        (WebCore::HTMLTreeBuilder::ExternalCharacterTokenBuffer::ExternalCharacterTokenBuffer):
     12        (WebCore::HTMLTreeBuilder::ExternalCharacterTokenBuffer::~ExternalCharacterTokenBuffer):
     13        (WebCore::HTMLTreeBuilder::ExternalCharacterTokenBuffer::isEmpty):
     14        (WebCore::HTMLTreeBuilder::ExternalCharacterTokenBuffer::skipLeadingWhitespace):
     15        (WebCore::HTMLTreeBuilder::ExternalCharacterTokenBuffer::takeLeadingWhitespace):
     16        (WebCore::HTMLTreeBuilder::ExternalCharacterTokenBuffer::takeRemaining):
     17        (WebCore::HTMLTreeBuilder::ExternalCharacterTokenBuffer::giveRemainingTo):
     18        (WebCore::HTMLTreeBuilder::ExternalCharacterTokenBuffer::takeRemainingWhitespace):
     19        (WebCore::HTMLTreeBuilder::processDoctypeToken):
     20        (WebCore::HTMLTreeBuilder::processStartTag):
     21        (WebCore::HTMLTreeBuilder::processEndTag):
     22        (WebCore::HTMLTreeBuilder::processComment):
     23        (WebCore::HTMLTreeBuilder::processCharacter):
     24        (WebCore::HTMLTreeBuilder::processCharacterBuffer):
     25        (WebCore::HTMLTreeBuilder::processEndOfFile):
     26        (WebCore::HTMLTreeBuilder::defaultForInitial):
     27        (WebCore::HTMLTreeBuilder::defaultForBeforeHTML):
     28        (WebCore::HTMLTreeBuilder::defaultForBeforeHead):
     29        (WebCore::HTMLTreeBuilder::defaultForInHead):
     30        (WebCore::HTMLTreeBuilder::defaultForInHeadNoscript):
     31        (WebCore::HTMLTreeBuilder::defaultForAfterHead):
     32        (WebCore::HTMLTreeBuilder::defaultForInTableText):
     33        * html/HTMLTreeBuilder.h:
     34
    1352010-07-14  Andreas Kling  <andreas.kling@nokia.com>
    236
  • trunk/WebCore/html/HTMLTreeBuilder.cpp

    r63338 r63372  
    6565    return cc == '\t' || cc == '\x0A' || cc == '\x0C' || cc == '\x0D' || cc == ' ';
    6666}
    67 
    68 class ExternalCharacterTokenBuffer : public Noncopyable {
    69 public:
    70     explicit ExternalCharacterTokenBuffer(AtomicHTMLToken& token)
    71         : m_current(token.characters().characters())
    72         , m_end(m_current + token.characters().length())
    73     {
    74         ASSERT(!isEmpty());
    75     }
    76 
    77     ~ExternalCharacterTokenBuffer()
    78     {
    79         ASSERT(isEmpty());
    80     }
    81 
    82     bool isEmpty() const { return m_current == m_end; }
    83 
    84     void skipLeadingWhitespace()
    85     {
    86         ASSERT(!isEmpty());
    87         while (isTreeBuilderWhitepace(*m_current)) {
    88             if (++m_current == m_end)
    89                 return;
    90         }
    91     }
    92 
    93     String takeLeadingWhitespace()
    94     {
    95         ASSERT(!isEmpty());
    96         const UChar* start = m_current;
    97         skipLeadingWhitespace();
    98         if (start == m_current)
    99             return String();
    100         return String(start, m_current - start);
    101     }
    102 
    103     String takeRemaining()
    104     {
    105         ASSERT(!isEmpty());
    106         const UChar* start = m_current;
    107         m_current = m_end;
    108         return String(start, m_current - start);
    109     }
    110 
    111     void giveRemainingTo(Vector<UChar>& recipient)
    112     {
    113         recipient.append(m_current, m_end - m_current);
    114         m_current = m_end;
    115     }
    116 
    117     String takeRemainingWhitespace()
    118     {
    119         ASSERT(!isEmpty());
    120         Vector<UChar> whitespace;
    121         do {
    122             UChar cc = *m_current++;
    123             if (isTreeBuilderWhitepace(cc))
    124                 whitespace.append(cc);
    125         } while (m_current < m_end);
    126         // Returning the null string when there aren't any whitespace
    127         // characters is slightly cleaner semantically because we don't want
    128         // to insert a text node (as opposed to inserting an empty text node).
    129         if (whitespace.isEmpty())
    130             return String();
    131         return String::adopt(whitespace);
    132     }
    133 
    134 private:
    135     const UChar* m_current;
    136     const UChar* m_end;
    137 };
    13867
    13968inline bool hasNonWhitespace(const String& string)
     
    317246} // namespace
    318247
     248class HTMLTreeBuilder::ExternalCharacterTokenBuffer : public Noncopyable {
     249public:
     250    explicit ExternalCharacterTokenBuffer(AtomicHTMLToken& token)
     251        : m_current(token.characters().characters())
     252        , m_end(m_current + token.characters().length())
     253    {
     254        ASSERT(!isEmpty());
     255    }
     256
     257    ~ExternalCharacterTokenBuffer()
     258    {
     259        ASSERT(isEmpty());
     260    }
     261
     262    bool isEmpty() const { return m_current == m_end; }
     263
     264    void skipLeadingWhitespace()
     265    {
     266        ASSERT(!isEmpty());
     267        while (isTreeBuilderWhitepace(*m_current)) {
     268            if (++m_current == m_end)
     269                return;
     270        }
     271    }
     272
     273    String takeLeadingWhitespace()
     274    {
     275        ASSERT(!isEmpty());
     276        const UChar* start = m_current;
     277        skipLeadingWhitespace();
     278        if (start == m_current)
     279            return String();
     280        return String(start, m_current - start);
     281    }
     282
     283    String takeRemaining()
     284    {
     285        ASSERT(!isEmpty());
     286        const UChar* start = m_current;
     287        m_current = m_end;
     288        return String(start, m_current - start);
     289    }
     290
     291    void giveRemainingTo(Vector<UChar>& recipient)
     292    {
     293        recipient.append(m_current, m_end - m_current);
     294        m_current = m_end;
     295    }
     296
     297    String takeRemainingWhitespace()
     298    {
     299        ASSERT(!isEmpty());
     300        Vector<UChar> whitespace;
     301        do {
     302            UChar cc = *m_current++;
     303            if (isTreeBuilderWhitepace(cc))
     304                whitespace.append(cc);
     305        } while (m_current < m_end);
     306        // Returning the null string when there aren't any whitespace
     307        // characters is slightly cleaner semantically because we don't want
     308        // to insert a text node (as opposed to inserting an empty text node).
     309        if (whitespace.isEmpty())
     310            return String();
     311        return String::adopt(whitespace);
     312    }
     313
     314private:
     315    const UChar* m_current;
     316    const UChar* m_end;
     317};
     318
     319
    319320HTMLTreeBuilder::HTMLTreeBuilder(HTMLTokenizer* tokenizer, HTMLDocument* document, bool reportErrors)
    320321    : m_framesetOk(true)
     
    543544    }
    544545    if (m_insertionMode == InTableTextMode) {
    545         processDefaultForInTableTextMode(token);
     546        defaultForInTableText();
    546547        processDoctypeToken(token);
    547548        return;
     
    11791180    case InitialMode:
    11801181        ASSERT(insertionMode() == InitialMode);
    1181         processDefaultForInitialMode(token);
     1182        defaultForInitial();
    11821183        // Fall through.
    11831184    case BeforeHTMLMode:
     
    11881189            return;
    11891190        }
    1190         processDefaultForBeforeHTMLMode(token);
     1191        defaultForBeforeHTML();
    11911192        // Fall through.
    11921193    case BeforeHeadMode:
     
    12011202            return;
    12021203        }
    1203         processDefaultForBeforeHeadMode(token);
     1204        defaultForBeforeHead();
    12041205        // Fall through.
    12051206    case InHeadMode:
     
    12071208        if (processStartTagForInHead(token))
    12081209            return;
    1209         processDefaultForInHeadMode(token);
     1210        defaultForInHead();
    12101211        // Fall through.
    12111212    case AfterHeadMode:
     
    12441245            return;
    12451246        }
    1246         processDefaultForAfterHeadMode(token);
     1247        defaultForAfterHead();
    12471248        // Fall through
    12481249    case InBodyMode:
     
    13841385            return;
    13851386        }
    1386         processDefaultForInHeadNoscriptMode(token);
     1387        defaultForInHeadNoscript();
    13871388        processToken(token);
    13881389        break;
     
    14831484        break;
    14841485    case InTableTextMode:
    1485         processDefaultForInTableTextMode(token);
     1486        defaultForInTableText();
    14861487        processStartTag(token);
    14871488        break;
     
    21052106    case InitialMode:
    21062107        ASSERT(insertionMode() == InitialMode);
    2107         processDefaultForInitialMode(token);
     2108        defaultForInitial();
    21082109        // Fall through.
    21092110    case BeforeHTMLMode:
     
    21132114            return;
    21142115        }
    2115         processDefaultForBeforeHTMLMode(token);
     2116        defaultForBeforeHTML();
    21162117        // Fall through.
    21172118    case BeforeHeadMode:
     
    21212122            return;
    21222123        }
    2123         processDefaultForBeforeHeadMode(token);
     2124        defaultForBeforeHead();
    21242125        // Fall through.
    21252126    case InHeadMode:
     
    21342135            return;
    21352136        }
    2136         processDefaultForInHeadMode(token);
     2137        defaultForInHead();
    21372138        // Fall through.
    21382139    case AfterHeadMode:
     
    21422143            return;
    21432144        }
    2144         processDefaultForAfterHeadMode(token);
     2145        defaultForAfterHead();
    21452146        // Fall through
    21462147    case InBodyMode:
     
    22372238            return;
    22382239        }
    2239         processDefaultForInHeadNoscriptMode(token);
     2240        defaultForInHeadNoscript();
    22402241        processToken(token);
    22412242        break;
     
    23222323        break;
    23232324    case InTableTextMode:
    2324         processDefaultForInTableTextMode(token);
     2325        defaultForInTableText();
    23252326        processEndTag(token);
    23262327        break;
     
    24112412    }
    24122413    if (m_insertionMode == InTableTextMode) {
    2413         processDefaultForInTableTextMode(token);
     2414        defaultForInTableText();
    24142415        processComment(token);
    24152416        return;
     
    24212422{
    24222423    ASSERT(token.type() == HTMLToken::Character);
    2423 
    24242424    // FIXME: Currently this design has an extra memcpy because we copy the
    24252425    // characters out of the HTMLTokenizer's buffer into the AtomicHTMLToken
     
    24272427    // from the HTMLTokenizer's buffer into the text node.
    24282428    ExternalCharacterTokenBuffer buffer(token);
    2429 
     2429    processCharacterBuffer(buffer);
     2430}
     2431
     2432void HTMLTreeBuilder::processCharacterBuffer(ExternalCharacterTokenBuffer& buffer)
     2433{
    24302434ReprocessBuffer:
    24312435    switch (insertionMode()) {
     
    24352439        if (buffer.isEmpty())
    24362440            return;
    2437         processDefaultForInitialMode(token);
     2441        defaultForInitial();
    24382442        // Fall through.
    24392443    }
     
    24432447        if (buffer.isEmpty())
    24442448            return;
    2445         processDefaultForBeforeHTMLMode(token);
     2449        defaultForBeforeHTML();
    24462450        // Fall through.
    24472451    }
     
    24512455        if (buffer.isEmpty())
    24522456            return;
    2453         processDefaultForBeforeHeadMode(token);
     2457        defaultForBeforeHead();
    24542458        // Fall through.
    24552459    }
     
    24612465        if (buffer.isEmpty())
    24622466            return;
    2463         processDefaultForInHeadMode(token);
     2467        defaultForInHead();
    24642468        // Fall through.
    24652469    }
     
    24712475        if (buffer.isEmpty())
    24722476            return;
    2473         processDefaultForAfterHeadMode(token);
     2477        defaultForAfterHead();
    24742478        // Fall through.
    24752479    }
     
    25142518    case AfterAfterBodyMode: {
    25152519        ASSERT(insertionMode() == AfterBodyMode || insertionMode() == AfterAfterBodyMode);
    2516         parseError(token);
     2520        // FIXME: parse error
    25172521        setInsertionMode(InBodyMode);
    25182522        goto ReprocessBuffer;
     
    25312535        if (buffer.isEmpty())
    25322536            return;
    2533         processDefaultForInHeadNoscriptMode(token);
     2537        defaultForInHeadNoscript();
    25342538        goto ReprocessBuffer;
    25352539        break;
     
    25782582    case InitialMode:
    25792583        ASSERT(insertionMode() == InitialMode);
    2580         processDefaultForInitialMode(token);
     2584        defaultForInitial();
    25812585        // Fall through.
    25822586    case BeforeHTMLMode:
    25832587        ASSERT(insertionMode() == BeforeHTMLMode);
    2584         processDefaultForBeforeHTMLMode(token);
     2588        defaultForBeforeHTML();
    25852589        // Fall through.
    25862590    case BeforeHeadMode:
    25872591        ASSERT(insertionMode() == BeforeHeadMode);
    2588         processDefaultForBeforeHeadMode(token);
     2592        defaultForBeforeHead();
    25892593        // Fall through.
    25902594    case InHeadMode:
    25912595        ASSERT(insertionMode() == InHeadMode);
    2592         processDefaultForInHeadMode(token);
     2596        defaultForInHead();
    25932597        // Fall through.
    25942598    case AfterHeadMode:
    25952599        ASSERT(insertionMode() == AfterHeadMode);
    2596         processDefaultForAfterHeadMode(token);
     2600        defaultForAfterHead();
    25972601        // Fall through
    25982602    case InBodyMode:
     
    26082612    case InHeadNoscriptMode:
    26092613        ASSERT(insertionMode() == InHeadNoscriptMode);
    2610         processDefaultForInHeadNoscriptMode(token);
     2614        defaultForInHeadNoscript();
    26112615        processToken(token);
    26122616        break;
     
    26442648        break;
    26452649    case InTableTextMode:
    2646         processDefaultForInTableTextMode(token);
     2650        defaultForInTableText();
    26472651        processEndOfFile(token);
    26482652        break;
     
    26552659}
    26562660
    2657 void HTMLTreeBuilder::processDefaultForInitialMode(AtomicHTMLToken& token)
     2661void HTMLTreeBuilder::defaultForInitial()
    26582662{
    26592663    notImplemented();
    2660     parseError(token);
     2664    // FIXME: parse error
    26612665    setInsertionMode(BeforeHTMLMode);
    26622666}
    26632667
    2664 void HTMLTreeBuilder::processDefaultForBeforeHTMLMode(AtomicHTMLToken&)
     2668void HTMLTreeBuilder::defaultForBeforeHTML()
    26652669{
    26662670    AtomicHTMLToken startHTML(HTMLToken::StartTag, htmlTag.localName());
     
    26692673}
    26702674
    2671 void HTMLTreeBuilder::processDefaultForBeforeHeadMode(AtomicHTMLToken&)
     2675void HTMLTreeBuilder::defaultForBeforeHead()
    26722676{
    26732677    AtomicHTMLToken startHead(HTMLToken::StartTag, headTag.localName());
     
    26752679}
    26762680
    2677 void HTMLTreeBuilder::processDefaultForInHeadMode(AtomicHTMLToken&)
     2681void HTMLTreeBuilder::defaultForInHead()
    26782682{
    26792683    AtomicHTMLToken endHead(HTMLToken::EndTag, headTag.localName());
     
    26812685}
    26822686
    2683 void HTMLTreeBuilder::processDefaultForInHeadNoscriptMode(AtomicHTMLToken&)
     2687void HTMLTreeBuilder::defaultForInHeadNoscript()
    26842688{
    26852689    AtomicHTMLToken endNoscript(HTMLToken::EndTag, noscriptTag.localName());
     
    26872691}
    26882692
    2689 void HTMLTreeBuilder::processDefaultForAfterHeadMode(AtomicHTMLToken&)
     2693void HTMLTreeBuilder::defaultForAfterHead()
    26902694{
    26912695    AtomicHTMLToken startBody(HTMLToken::StartTag, bodyTag.localName());
     
    26942698}
    26952699
    2696 void HTMLTreeBuilder::processDefaultForInTableTextMode(AtomicHTMLToken& token)
     2700void HTMLTreeBuilder::defaultForInTableText()
    26972701{
    26982702    String characters = String::adopt(m_pendingTableCharacters);
    26992703    if (hasNonWhitespace(characters)) {
    2700         parseError(token);
     2704        // FIXME: parse error
    27012705        HTMLConstructionSite::RedirectToFosterParentGuard redirecter(m_tree, requiresRedirectToFosterParent(m_tree.currentElement()));
    27022706        m_tree.reconstructTheActiveFormattingElements();
  • trunk/WebCore/html/HTMLTreeBuilder.h

    r63116 r63372  
    7777private:
    7878    class FakeInsertionMode;
     79    class ExternalCharacterTokenBuffer;
    7980    // Represents HTML5 "insertion mode"
    8081    // http://www.whatwg.org/specs/web-apps/current-work/multipage/parsing.html#insertion-mode
     
    135136    void processAnyOtherEndTagForInBody(AtomicHTMLToken&);
    136137
     138    void processCharacterBuffer(ExternalCharacterTokenBuffer&);
     139
    137140    void processFakeStartTag(const QualifiedName&, PassRefPtr<NamedNodeMap> attributes = 0);
    138141    void processFakeEndTag(const QualifiedName&);
     
    145148
    146149    // Default processing for the different insertion modes.
    147     // FIXME: These functions need to be renamed to remove "process" from their names.
    148     void processDefaultForInitialMode(AtomicHTMLToken&);
    149     void processDefaultForBeforeHTMLMode(AtomicHTMLToken&);
    150     void processDefaultForBeforeHeadMode(AtomicHTMLToken&);
    151     void processDefaultForInHeadMode(AtomicHTMLToken&);
    152     void processDefaultForInHeadNoscriptMode(AtomicHTMLToken&);
    153     void processDefaultForAfterHeadMode(AtomicHTMLToken&);
    154     void processDefaultForInTableTextMode(AtomicHTMLToken&);
     150    void defaultForInitial();
     151    void defaultForBeforeHTML();
     152    void defaultForBeforeHead();
     153    void defaultForInHead();
     154    void defaultForInHeadNoscript();
     155    void defaultForAfterHead();
     156    void defaultForInTableText();
    155157
    156158    void processUsingSecondaryInsertionModeAndAdjustInsertionMode(AtomicHTMLToken&);
Note: See TracChangeset for help on using the changeset viewer.