Changeset 143960 in webkit
- Timestamp:
- Feb 25, 2013 12:58:27 PM (11 years ago)
- Location:
- trunk/Source/WebCore
- Files:
-
- 6 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/Source/WebCore/ChangeLog
r143954 r143960 1 2013-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 1 37 2013-02-25 Mark Lam <mark.lam@apple.com> 2 38 -
trunk/Source/WebCore/html/parser/BackgroundHTMLParser.cpp
r143830 r143960 157 157 m_tokenizer = checkpoint->tokenizer.release(); 158 158 m_input.rewindTo(checkpoint->inputCheckpoint, checkpoint->unparsedInput); 159 m_preloadScanner->rewindTo(checkpoint->preloadScannerCheckpoint);160 159 pumpTokenizer(); 161 160 } … … 253 252 token.setXSSInfo(xssInfo.release()); 254 253 255 m_preloadScanner->scan(token, m_pendingPreloads);256 257 254 m_pendingTokens->append(token); 258 255 } … … 281 278 chunk->preloads.swap(m_pendingPreloads); 282 279 chunk->inputCheckpoint = m_input.createCheckpoint(); 283 chunk->preloadScannerCheckpoint = m_preloadScanner->createCheckpoint();284 280 callOnMainThread(bind(&HTMLDocumentParser::didReceiveParsedChunkFromBackgroundParser, m_parser, chunk.release())); 285 281 -
trunk/Source/WebCore/html/parser/CSSPreloadScanner.cpp
r143051 r143960 51 51 } 52 52 53 template<typename Char> 54 void CSSPreloadScanner::scanCommon(const Char* begin, const Char* end, PreloadRequestStream& requests) 53 void CSSPreloadScanner::scan(const UChar* begin, const UChar* end, Vector<OwnPtr<PreloadRequest> >& requests) 55 54 { 56 55 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) 58 57 tokenize(*it); 59 58 m_requests = 0; 60 59 } 61 60 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); 61 void 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; 76 67 } 77 68 … … 214 205 if (!url.isEmpty()) { 215 206 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); 217 209 // FIXME: Should this be including the charset in the preload request? 218 210 m_requests->append(request.release()); -
trunk/Source/WebCore/html/parser/CSSPreloadScanner.h
r143051 r143960 29 29 30 30 #include "HTMLResourcePreloader.h" 31 #include "HTMLToken.h"32 31 #include <wtf/text/StringBuilder.h> 33 32 … … 42 41 void reset(); 43 42 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> >&); 46 45 47 46 private: … … 59 58 }; 60 59 61 template<typename Char>62 void scanCommon(const Char* begin, const Char* end, PreloadRequestStream&);63 64 60 inline void tokenize(UChar); 65 61 void emitRule(); … … 70 66 71 67 // Only non-zero during scan() 72 PreloadRequestStream* m_requests;68 Vector<OwnPtr<PreloadRequest> >* m_requests; 73 69 }; 74 70 -
trunk/Source/WebCore/html/parser/HTMLPreloadScanner.cpp
r143685 r143960 44 44 using namespace HTMLNames; 45 45 46 TokenPreloadScanner::TagId TokenPreloadScanner::tagIdFor(const HTMLToken::DataVector& data) 47 { 48 AtomicString tagName(data); 46 static bool isStartTag(HTMLToken::Type type) 47 { 48 return type == HTMLToken::StartTag; 49 } 50 51 static bool isStartOrEndTag(HTMLToken::Type type) 52 { 53 return type == HTMLToken::EndTag || isStartTag(type); 54 } 55 56 TokenPreloadScanner::TagId TokenPreloadScanner::identifierFor(const AtomicString& tagName) 57 { 49 58 if (tagName == imgTag) 50 59 return ImgTagId; … … 64 73 } 65 74 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) 75 String TokenPreloadScanner::inititatorFor(TagId tagId) 86 76 { 87 77 switch (tagId) { … … 118 108 { 119 109 ASSERT(isMainThread()); 110 120 111 if (m_tagId >= UnknownTagId) 121 112 return; 113 122 114 for (HTMLToken::AttributeList::const_iterator iter = attributes.begin(); iter != attributes.end(); ++iter) { 123 115 AtomicString attributeName(iter->name); … … 127 119 } 128 120 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 #endif138 139 121 PassOwnPtr<PreloadRequest> createPreloadRequest(const KURL& predictedBaseURL) 140 122 { … … 142 124 return nullptr; 143 125 144 OwnPtr<PreloadRequest> request = PreloadRequest::create(initi atorFor(m_tagId), m_urlToLoad, predictedBaseURL, resourceType());126 OwnPtr<PreloadRequest> request = PreloadRequest::create(inititatorFor(m_tagId), m_urlToLoad, predictedBaseURL, resourceType()); 145 127 request->setCrossOriginModeAllowsCookies(crossOriginModeAllowsCookies()); 146 128 request->setCharset(charset()); … … 263 245 } 264 246 265 TokenPreloadScannerCheckpoint TokenPreloadScanner::createCheckpoint()266 {267 TokenPreloadScannerCheckpoint checkpoint = m_checkpoints.size();268 m_checkpoints.append(Checkpoint(m_predictedBaseElementURL, m_inStyle269 247 #if ENABLE(TEMPLATE_ELEMENT) 270 , m_templateCount 248 bool 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 } 271 260 #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 262 bool 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 276 bool 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 297 void 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 282 313 #if ENABLE(TEMPLATE_ELEMENT) 283 m_templateCount = checkpoint.templateCount; 314 if (processPossibleTemplateTag(tagId, token.type())) 315 return; 284 316 #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()); 370 329 } 371 330 … … 393 352 m_scanner.setPredictedBaseElementURL(startingBaseElementURL); 394 353 395 PreloadRequestStream requests; 396 354 Vector<OwnPtr<PreloadRequest> > requests; 397 355 while (m_tokenizer->nextToken(m_source, m_token)) { 398 if ( m_token.type() == HTMLToken::StartTag)356 if (isStartTag(m_token.type())) 399 357 m_tokenizer->updateStateFor(AtomicString(m_token.name())); 400 358 m_scanner.scan(m_token, requests); 401 359 m_token.clear(); 402 360 } 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 29 29 30 30 #include "CSSPreloadScanner.h" 31 #include "CompactHTMLToken.h"32 31 #include "HTMLToken.h" 33 32 #include "SegmentedString.h" 34 #include <wtf/Vector.h>35 33 36 34 namespace WebCore { … … 48 46 ~TokenPreloadScanner(); 49 47 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); 54 49 55 50 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 }67 51 68 52 private: … … 83 67 class StartTagScanner; 84 68 85 template<typename Token>86 inline void scanCommon(const Token&, PreloadRequestStream& requests);69 static TagId identifierFor(const AtomicString& tagName); 70 static String inititatorFor(TagId); 87 71 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 90 75 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&); 116 78 117 79 CSSPreloadScanner m_cssScanner; 118 constKURL m_documentURL;80 KURL m_documentURL; 119 81 KURL m_predictedBaseElementURL; 120 82 bool m_inStyle; … … 123 85 size_t m_templateCount; 124 86 #endif 125 126 Vector<Checkpoint> m_checkpoints;127 87 }; 128 88
Note: See TracChangeset
for help on using the changeset viewer.