Changeset 143960 in webkit


Ignore:
Timestamp:
Feb 25, 2013 12:58:27 PM (11 years ago)
Author:
abarth@webkit.org
Message:

6% regression in intl1 page cycler on chromium-mac
https://bugs.webkit.org/show_bug.cgi?id=110784

Reviewed by Eric Seidel.

This patch attempts to heal the regression by reverting all the changes
to the preload scanner up to (and including)
http://trac.webkit.org/changeset/143020/.

  • html/parser/BackgroundHTMLParser.cpp:

(WebCore::BackgroundHTMLParser::resumeFrom):
(WebCore::BackgroundHTMLParser::pumpTokenizer):
(WebCore::BackgroundHTMLParser::sendTokensToMainThread):

  • html/parser/CSSPreloadScanner.cpp:

(WebCore::CSSPreloadScanner::scan):
(WebCore::CSSPreloadScanner::emitRule):

  • html/parser/CSSPreloadScanner.h:

(CSSPreloadScanner):

  • html/parser/HTMLPreloadScanner.cpp:

(WebCore::isStartTag):
(WebCore):
(WebCore::isStartOrEndTag):
(WebCore::TokenPreloadScanner::identifierFor):
(WebCore::TokenPreloadScanner::inititatorFor):
(WebCore::TokenPreloadScanner::StartTagScanner::processAttributes):
(WebCore::TokenPreloadScanner::StartTagScanner::createPreloadRequest):
(WebCore::TokenPreloadScanner::processPossibleTemplateTag):
(WebCore::TokenPreloadScanner::processPossibleStyleTag):
(WebCore::TokenPreloadScanner::processPossibleBaseTag):
(WebCore::TokenPreloadScanner::scan):
(WebCore::HTMLPreloadScanner::scan):

  • html/parser/HTMLPreloadScanner.h:

(TokenPreloadScanner):

Location:
trunk/Source/WebCore
Files:
6 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/WebCore/ChangeLog

    r143954 r143960  
     12013-02-25  Adam Barth  <abarth@webkit.org>
     2
     3        6% regression in intl1 page cycler on chromium-mac
     4        https://bugs.webkit.org/show_bug.cgi?id=110784
     5
     6        Reviewed by Eric Seidel.
     7
     8        This patch attempts to heal the regression by reverting all the changes
     9        to the preload scanner up to (and including)
     10        http://trac.webkit.org/changeset/143020/.
     11
     12        * html/parser/BackgroundHTMLParser.cpp:
     13        (WebCore::BackgroundHTMLParser::resumeFrom):
     14        (WebCore::BackgroundHTMLParser::pumpTokenizer):
     15        (WebCore::BackgroundHTMLParser::sendTokensToMainThread):
     16        * html/parser/CSSPreloadScanner.cpp:
     17        (WebCore::CSSPreloadScanner::scan):
     18        (WebCore::CSSPreloadScanner::emitRule):
     19        * html/parser/CSSPreloadScanner.h:
     20        (CSSPreloadScanner):
     21        * html/parser/HTMLPreloadScanner.cpp:
     22        (WebCore::isStartTag):
     23        (WebCore):
     24        (WebCore::isStartOrEndTag):
     25        (WebCore::TokenPreloadScanner::identifierFor):
     26        (WebCore::TokenPreloadScanner::inititatorFor):
     27        (WebCore::TokenPreloadScanner::StartTagScanner::processAttributes):
     28        (WebCore::TokenPreloadScanner::StartTagScanner::createPreloadRequest):
     29        (WebCore::TokenPreloadScanner::processPossibleTemplateTag):
     30        (WebCore::TokenPreloadScanner::processPossibleStyleTag):
     31        (WebCore::TokenPreloadScanner::processPossibleBaseTag):
     32        (WebCore::TokenPreloadScanner::scan):
     33        (WebCore::HTMLPreloadScanner::scan):
     34        * html/parser/HTMLPreloadScanner.h:
     35        (TokenPreloadScanner):
     36
    1372013-02-25  Mark Lam  <mark.lam@apple.com>
    238
  • trunk/Source/WebCore/html/parser/BackgroundHTMLParser.cpp

    r143830 r143960  
    157157    m_tokenizer = checkpoint->tokenizer.release();
    158158    m_input.rewindTo(checkpoint->inputCheckpoint, checkpoint->unparsedInput);
    159     m_preloadScanner->rewindTo(checkpoint->preloadScannerCheckpoint);
    160159    pumpTokenizer();
    161160}
     
    253252                token.setXSSInfo(xssInfo.release());
    254253
    255             m_preloadScanner->scan(token, m_pendingPreloads);
    256 
    257254            m_pendingTokens->append(token);
    258255        }
     
    281278    chunk->preloads.swap(m_pendingPreloads);
    282279    chunk->inputCheckpoint = m_input.createCheckpoint();
    283     chunk->preloadScannerCheckpoint = m_preloadScanner->createCheckpoint();
    284280    callOnMainThread(bind(&HTMLDocumentParser::didReceiveParsedChunkFromBackgroundParser, m_parser, chunk.release()));
    285281
  • trunk/Source/WebCore/html/parser/CSSPreloadScanner.cpp

    r143051 r143960  
    5151}
    5252
    53 template<typename Char>
    54 void CSSPreloadScanner::scanCommon(const Char* begin, const Char* end, PreloadRequestStream& requests)
     53void CSSPreloadScanner::scan(const UChar* begin, const UChar* end, Vector<OwnPtr<PreloadRequest> >& requests)
    5554{
    5655    m_requests = &requests;
    57     for (const Char* it = begin; it != end && m_state != DoneParsingImportRules; ++it)
     56    for (const UChar* it = begin; it != end && m_state != DoneParsingImportRules; ++it)
    5857        tokenize(*it);
    5958    m_requests = 0;
    6059}
    6160
    62 void CSSPreloadScanner::scan(const HTMLToken::DataVector& data, PreloadRequestStream& requests)
    63 {
    64     scanCommon(data.data(), data.data() + data.size(), requests);
    65 }
    66 
    67 void CSSPreloadScanner::scan(const String& data, PreloadRequestStream& requests)
    68 {
    69     if (data.is8Bit()) {
    70         const LChar* begin = data.characters8();
    71         scanCommon(begin, begin + data.length(), requests);
    72         return;
    73     }
    74     const UChar* begin = data.characters16();
    75     scanCommon(begin, begin + data.length(), requests);
     61void CSSPreloadScanner::scan(const LChar* begin, const LChar* end, Vector<OwnPtr<PreloadRequest> >& requests)
     62{
     63    m_requests = &requests;
     64    for (const LChar* it = begin; it != end && m_state != DoneParsingImportRules; ++it)
     65        tokenize(*it);
     66    m_requests = 0;
    7667}
    7768
     
    214205        if (!url.isEmpty()) {
    215206            KURL baseElementURL; // FIXME: This should be passed in from the HTMLPreloadScaner via scan()!
    216             OwnPtr<PreloadRequest> request = PreloadRequest::create("css", url, baseElementURL, CachedResource::CSSStyleSheet);
     207            OwnPtr<PreloadRequest> request = PreloadRequest::create(
     208                cachedResourceRequestInitiators().css, url, baseElementURL, CachedResource::CSSStyleSheet);
    217209            // FIXME: Should this be including the charset in the preload request?
    218210            m_requests->append(request.release());
  • trunk/Source/WebCore/html/parser/CSSPreloadScanner.h

    r143051 r143960  
    2929
    3030#include "HTMLResourcePreloader.h"
    31 #include "HTMLToken.h"
    3231#include <wtf/text/StringBuilder.h>
    3332
     
    4241    void reset();
    4342
    44     void scan(const HTMLToken::DataVector&, PreloadRequestStream&);
    45     void scan(const String&, PreloadRequestStream&);
     43    void scan(const UChar* begin, const UChar* end, Vector<OwnPtr<PreloadRequest> >&);
     44    void scan(const LChar* begin, const LChar* end, Vector<OwnPtr<PreloadRequest> >&);
    4645
    4746private:
     
    5958    };
    6059
    61     template<typename Char>
    62     void scanCommon(const Char* begin, const Char* end, PreloadRequestStream&);
    63 
    6460    inline void tokenize(UChar);
    6561    void emitRule();
     
    7066
    7167    // Only non-zero during scan()
    72     PreloadRequestStream* m_requests;
     68    Vector<OwnPtr<PreloadRequest> >* m_requests;
    7369};
    7470
  • trunk/Source/WebCore/html/parser/HTMLPreloadScanner.cpp

    r143685 r143960  
    4444using namespace HTMLNames;
    4545
    46 TokenPreloadScanner::TagId TokenPreloadScanner::tagIdFor(const HTMLToken::DataVector& data)
    47 {
    48     AtomicString tagName(data);
     46static bool isStartTag(HTMLToken::Type type)
     47{
     48    return type == HTMLToken::StartTag;
     49}
     50
     51static bool isStartOrEndTag(HTMLToken::Type type)
     52{
     53    return type == HTMLToken::EndTag || isStartTag(type);
     54}
     55
     56TokenPreloadScanner::TagId TokenPreloadScanner::identifierFor(const AtomicString& tagName)
     57{
    4958    if (tagName == imgTag)
    5059        return ImgTagId;
     
    6473}
    6574
    66 TokenPreloadScanner::TagId TokenPreloadScanner::tagIdFor(const String& tagName)
    67 {
    68     if (threadSafeMatch(tagName, imgTag))
    69         return ImgTagId;
    70     if (threadSafeMatch(tagName, inputTag))
    71         return InputTagId;
    72     if (threadSafeMatch(tagName, linkTag))
    73         return LinkTagId;
    74     if (threadSafeMatch(tagName, scriptTag))
    75         return ScriptTagId;
    76     if (threadSafeMatch(tagName, styleTag))
    77         return StyleTagId;
    78     if (threadSafeMatch(tagName, baseTag))
    79         return BaseTagId;
    80     if (threadSafeMatch(tagName, templateTag))
    81         return TemplateTagId;
    82     return UnknownTagId;
    83 }
    84 
    85 String TokenPreloadScanner::initiatorFor(TagId tagId)
     75String TokenPreloadScanner::inititatorFor(TagId tagId)
    8676{
    8777    switch (tagId) {
     
    118108    {
    119109        ASSERT(isMainThread());
     110
    120111        if (m_tagId >= UnknownTagId)
    121112            return;
     113
    122114        for (HTMLToken::AttributeList::const_iterator iter = attributes.begin(); iter != attributes.end(); ++iter) {
    123115            AtomicString attributeName(iter->name);
     
    127119    }
    128120
    129 #if ENABLE(THREADED_HTML_PARSER)
    130     void processAttributes(const Vector<CompactHTMLToken::Attribute>& attributes)
    131     {
    132         if (m_tagId >= UnknownTagId)
    133             return;
    134         for (Vector<CompactHTMLToken::Attribute>::const_iterator iter = attributes.begin(); iter != attributes.end(); ++iter)
    135             processAttribute(iter->name, iter->value);
    136     }
    137 #endif
    138 
    139121    PassOwnPtr<PreloadRequest> createPreloadRequest(const KURL& predictedBaseURL)
    140122    {
     
    142124            return nullptr;
    143125
    144         OwnPtr<PreloadRequest> request = PreloadRequest::create(initiatorFor(m_tagId), m_urlToLoad, predictedBaseURL, resourceType());
     126        OwnPtr<PreloadRequest> request = PreloadRequest::create(inititatorFor(m_tagId), m_urlToLoad, predictedBaseURL, resourceType());
    145127        request->setCrossOriginModeAllowsCookies(crossOriginModeAllowsCookies());
    146128        request->setCharset(charset());
     
    263245}
    264246
    265 TokenPreloadScannerCheckpoint TokenPreloadScanner::createCheckpoint()
    266 {
    267     TokenPreloadScannerCheckpoint checkpoint = m_checkpoints.size();
    268     m_checkpoints.append(Checkpoint(m_predictedBaseElementURL, m_inStyle
    269247#if ENABLE(TEMPLATE_ELEMENT)
    270                                     , m_templateCount
     248bool TokenPreloadScanner::processPossibleTemplateTag(TagId tagId, HTMLToken::Type type)
     249{
     250    if (isStartOrEndTag(type) && tagId == TemplateTagId) {
     251        if (isStartTag(type))
     252            m_templateCount++;
     253        else
     254            m_templateCount--;
     255        return true; // Twas our token.
     256    }
     257    // If we're in a template we "consume" all tokens.
     258    return m_templateCount > 0;
     259}
    271260#endif
    272                                     ));
    273     return checkpoint;
    274 }
    275 
    276 void TokenPreloadScanner::rewindTo(TokenPreloadScannerCheckpoint checkpointIndex)
    277 {
    278     ASSERT(checkpointIndex < m_checkpoints.size()); // If this ASSERT fires, checkpointIndex is invalid.
    279     const Checkpoint& checkpoint = m_checkpoints[checkpointIndex];
    280     m_predictedBaseElementURL = checkpoint.predictedBaseElementURL;
    281     m_inStyle = checkpoint.inStyle;
     261
     262bool TokenPreloadScanner::processPossibleStyleTag(TagId tagId, HTMLToken::Type type)
     263{
     264    ASSERT(isStartOrEndTag(type));
     265    if (tagId != StyleTagId)
     266        return false;
     267
     268    m_inStyle = isStartTag(type);
     269
     270    if (!m_inStyle)
     271        m_cssScanner.reset();
     272
     273    return true;
     274}
     275
     276bool TokenPreloadScanner::processPossibleBaseTag(TagId tagId, const HTMLToken& token)
     277{
     278    ASSERT(isStartTag(token.type()));
     279    if (tagId != BaseTagId)
     280        return false;
     281
     282    // The first <base> element is the one that wins.
     283    if (!m_predictedBaseElementURL.isEmpty())
     284        return true;
     285
     286    for (HTMLToken::AttributeList::const_iterator iter = token.attributes().begin(); iter != token.attributes().end(); ++iter) {
     287        AtomicString attributeName(iter->name);
     288        if (attributeName == hrefAttr) {
     289            String hrefValue = StringImpl::create8BitIfPossible(iter->value);
     290            m_predictedBaseElementURL = KURL(m_documentURL, stripLeadingAndTrailingHTMLSpaces(hrefValue));
     291            break;
     292        }
     293    }
     294    return true;
     295}
     296
     297void TokenPreloadScanner::scan(const HTMLToken& token, Vector<OwnPtr<PreloadRequest> >& requests)
     298{
     299    // <style> is the only place we search for urls in non-start/end-tag tokens.
     300    if (m_inStyle) {
     301        if (token.type() != HTMLToken::Character)
     302            return;
     303        const HTMLToken::DataVector& characters = token.characters();
     304        return m_cssScanner.scan(characters.begin(), characters.end(), requests);
     305    }
     306
     307    if (!isStartOrEndTag(token.type()))
     308        return;
     309
     310    AtomicString tagName(token.name());
     311    TagId tagId = identifierFor(tagName);
     312
    282313#if ENABLE(TEMPLATE_ELEMENT)
    283     m_templateCount = checkpoint.templateCount;
     314    if (processPossibleTemplateTag(tagId, token.type()))
     315        return;
    284316#endif
    285     m_cssScanner.reset();
    286     m_checkpoints.clear();
    287 }
    288 
    289 void TokenPreloadScanner::scan(const HTMLToken& token, Vector<OwnPtr<PreloadRequest> >& requests)
    290 {
    291     scanCommon(token, requests);
    292 }
    293 
    294 #if ENABLE(THREADED_HTML_PARSER)
    295 void TokenPreloadScanner::scan(const CompactHTMLToken& token, Vector<OwnPtr<PreloadRequest> >& requests)
    296 {
    297     scanCommon(token, requests);
    298 }
    299 #endif
    300 
    301 template<typename Token>
    302 void TokenPreloadScanner::scanCommon(const Token& token, Vector<OwnPtr<PreloadRequest> >& requests)
    303 {
    304     switch (token.type()) {
    305     case HTMLToken::Character: {
    306         if (!m_inStyle)
    307             return;
    308         m_cssScanner.scan(token.data(), requests);
    309         return;
    310     }
    311     case HTMLToken::EndTag: {
    312         TagId tagId = tagIdFor(token.data());
    313 #if ENABLE(TEMPLATE_ELEMENT)
    314         if (tagId == TemplateTagId) {
    315             if (m_templateCount)
    316                 --m_templateCount;
    317             return;
    318         }
    319 #endif
    320         if (tagId == StyleTagId) {
    321             if (m_inStyle)
    322                 m_cssScanner.reset();
    323             m_inStyle = false;
    324         }
    325         return;
    326     }
    327     case HTMLToken::StartTag: {
    328 #if ENABLE(TEMPLATE_ELEMENT)
    329         if (m_templateCount)
    330             return;
    331 #endif
    332         TagId tagId = tagIdFor(token.data());
    333 #if ENABLE(TEMPLATE_ELEMENT)
    334         if (tagId == TemplateTagId) {
    335             ++m_templateCount;
    336             return;
    337         }
    338 #endif
    339         if (tagId == StyleTagId) {
    340             m_inStyle = true;
    341             return;
    342         }
    343         if (tagId == BaseTagId) {
    344             // The first <base> element is the one that wins.
    345             if (!m_predictedBaseElementURL.isEmpty())
    346                 return;
    347             updatePredictedBaseURL(token);
    348             return;
    349         }
    350 
    351         StartTagScanner scanner(tagId);
    352         scanner.processAttributes(token.attributes());
    353         OwnPtr<PreloadRequest> request = scanner.createPreloadRequest(m_predictedBaseElementURL);
    354         if (request)
    355             requests.append(request.release());
    356         return;
    357     }
    358     default: {
    359         return;
    360     }
    361     }
    362 }
    363 
    364 template<typename Token>
    365 void TokenPreloadScanner::updatePredictedBaseURL(const Token& token)
    366 {
    367     ASSERT(m_predictedBaseElementURL.isEmpty());
    368     if (const typename Token::Attribute* hrefAttribute = token.getAttributeItem(hrefAttr))
    369         m_predictedBaseElementURL = KURL(m_documentURL, stripLeadingAndTrailingHTMLSpaces(hrefAttribute->value)).copy();
     317    if (processPossibleStyleTag(tagId, token.type()))
     318        return;
     319    if (!isStartTag(token.type()))
     320        return;
     321    if (processPossibleBaseTag(tagId, token))
     322        return;
     323
     324    StartTagScanner scanner(tagId);
     325    scanner.processAttributes(token.attributes());
     326    OwnPtr<PreloadRequest> request =  scanner.createPreloadRequest(m_predictedBaseElementURL);
     327    if (request)
     328        requests.append(request.release());
    370329}
    371330
     
    393352        m_scanner.setPredictedBaseElementURL(startingBaseElementURL);
    394353
    395     PreloadRequestStream requests;
    396 
     354    Vector<OwnPtr<PreloadRequest> > requests;
    397355    while (m_tokenizer->nextToken(m_source, m_token)) {
    398         if (m_token.type() == HTMLToken::StartTag)
     356        if (isStartTag(m_token.type()))
    399357            m_tokenizer->updateStateFor(AtomicString(m_token.name()));
    400358        m_scanner.scan(m_token, requests);
    401359        m_token.clear();
    402360    }
    403 
    404     preloader->takeAndPreload(requests);
    405 }
    406 
    407 }
     361    for (size_t i = 0; i < requests.size(); i++)
     362        preloader->preload(requests[i].release());
     363}
     364
     365}
  • trunk/Source/WebCore/html/parser/HTMLPreloadScanner.h

    r143661 r143960  
    2929
    3030#include "CSSPreloadScanner.h"
    31 #include "CompactHTMLToken.h"
    3231#include "HTMLToken.h"
    3332#include "SegmentedString.h"
    34 #include <wtf/Vector.h>
    3533
    3634namespace WebCore {
     
    4846    ~TokenPreloadScanner();
    4947
    50     void scan(const HTMLToken&, PreloadRequestStream& requests);
    51 #if ENABLE(THREADED_HTML_PARSER)
    52     void scan(const CompactHTMLToken&, PreloadRequestStream& requests);
    53 #endif
     48    void scan(const HTMLToken&, Vector<OwnPtr<PreloadRequest> >& requests);
    5449
    5550    void setPredictedBaseElementURL(const KURL& url) { m_predictedBaseElementURL = url; }
    56 
    57     // A TokenPreloadScannerCheckpoint is valid until the next call to rewindTo,
    58     // at which point all outstanding checkpoints are invalidated.
    59     TokenPreloadScannerCheckpoint createCheckpoint();
    60     void rewindTo(TokenPreloadScannerCheckpoint);
    61 
    62     bool isSafeToSendToAnotherThread()
    63     {
    64         return m_documentURL.isSafeToSendToAnotherThread()
    65             && m_predictedBaseElementURL.isSafeToSendToAnotherThread();
    66     }
    6751
    6852private:
     
    8367    class StartTagScanner;
    8468
    85     template<typename Token>
    86     inline void scanCommon(const Token&, PreloadRequestStream& requests);
     69    static TagId identifierFor(const AtomicString& tagName);
     70    static String inititatorFor(TagId);
    8771
    88     static TagId tagIdFor(const HTMLToken::DataVector&);
    89     static TagId tagIdFor(const String&);
     72#if ENABLE(TEMPLATE_ELEMENT)
     73    bool processPossibleTemplateTag(TagId, HTMLToken::Type);
     74#endif
    9075
    91     static String initiatorFor(TagId);
    92 
    93     template<typename Token>
    94     void updatePredictedBaseURL(const Token&);
    95 
    96     struct Checkpoint {
    97         Checkpoint(const KURL& predictedBaseElementURL, bool inStyle
    98 #if ENABLE(TEMPLATE_ELEMENT)
    99             , size_t templateCount
    100 #endif
    101             )
    102             : predictedBaseElementURL(predictedBaseElementURL)
    103             , inStyle(inStyle)
    104 #if ENABLE(TEMPLATE_ELEMENT)
    105             , templateCount(templateCount)
    106 #endif
    107         {
    108         }
    109 
    110         KURL predictedBaseElementURL;
    111         bool inStyle;
    112 #if ENABLE(TEMPLATE_ELEMENT)
    113         size_t templateCount;
    114 #endif
    115     };
     76    bool processPossibleStyleTag(TagId, HTMLToken::Type);
     77    bool processPossibleBaseTag(TagId, const HTMLToken&);
    11678
    11779    CSSPreloadScanner m_cssScanner;
    118     const KURL m_documentURL;
     80    KURL m_documentURL;
    11981    KURL m_predictedBaseElementURL;
    12082    bool m_inStyle;
     
    12385    size_t m_templateCount;
    12486#endif
    125 
    126     Vector<Checkpoint> m_checkpoints;
    12787};
    12888
Note: See TracChangeset for help on using the changeset viewer.