Changeset 143051 in webkit
- Timestamp:
- Feb 15, 2013 2:14:31 PM (11 years ago)
- Location:
- trunk/Source/WebCore
- Files:
-
- 12 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/Source/WebCore/ChangeLog
r143048 r143051 1 2013-02-15 Adam Barth <abarth@webkit.org> 2 3 Enable the preload scanner on the background parser thread 4 https://bugs.webkit.org/show_bug.cgi?id=108027 5 6 Reviewed by Tony Gentilcore. 7 8 The patch causes us to pass all the fast/preloader tests with the 9 threaded parser enabled. 10 11 This patch wires up the BackgroundHTMLParser to the 12 TokenPreloadScanner. Currently, we bail out of preload scanning if we 13 encounter a document.write becaues we don't know how to rewind the 14 preload scanner, but that's something we can tune in the future. 15 16 The BackgroundHTMLParser delivers the preloads to the 17 HTMLDocumentParser together with the token stream. If the 18 HTMLDocumentParser isn't able to use the token stream immediately, it 19 kicks off the preloads. 20 21 * html/parser/BackgroundHTMLParser.cpp: 22 (WebCore::checkThatPreloadsAreSafeToSendToAnotherThread): 23 (WebCore::BackgroundHTMLParser::BackgroundHTMLParser): 24 (WebCore::BackgroundHTMLParser::resumeFrom): 25 (WebCore::BackgroundHTMLParser::pumpTokenizer): 26 (WebCore::BackgroundHTMLParser::sendTokensToMainThread): 27 * html/parser/BackgroundHTMLParser.h: 28 (Configuration): 29 - We need to add a struct for the create function because the 30 number of arguments exceeds the limits of Functional.h. 31 (BackgroundHTMLParser): 32 (WebCore::BackgroundHTMLParser::create): 33 * html/parser/CSSPreloadScanner.cpp: 34 (WebCore::CSSPreloadScanner::scanCommon): 35 (WebCore::CSSPreloadScanner::scan): 36 (WebCore::CSSPreloadScanner::emitRule): 37 - We need to use a new string here so that the string is safe to 38 send to another thread. 39 * html/parser/CSSPreloadScanner.h: 40 (CSSPreloadScanner): 41 * html/parser/HTMLDocumentParser.cpp: 42 (WebCore::HTMLDocumentParser::didReceiveParsedChunkFromBackgroundParser): 43 (WebCore::HTMLDocumentParser::startBackgroundParser): 44 - Following the example of the XSSAuditor, we create the 45 TokenPreloadScanner on the main thread and then send it to the 46 background thread for operation. 47 * html/parser/HTMLDocumentParser.h: 48 (WebCore): 49 (ParsedChunk): 50 * html/parser/HTMLParserOptions.h: 51 (HTMLParserOptions): 52 - We need to add a default constructor so that the 53 HTMLDocumentParser can create an empty 54 BackgroundHTMLParser::Configuration struct. 55 * html/parser/HTMLPreloadScanner.cpp: 56 (WebCore::TokenPreloadScanner::scan): 57 (WebCore::TokenPreloadScanner::scanCommon): 58 (WebCore::HTMLPreloadScanner::scan): 59 * html/parser/HTMLPreloadScanner.h: 60 (TokenPreloadScanner): 61 (WebCore::TokenPreloadScanner::isSafeToSendToAnotherThread): 62 * html/parser/HTMLResourcePreloader.cpp: 63 (WebCore::HTMLResourcePreloader::takeAndPreload): 64 (WebCore): 65 * html/parser/HTMLResourcePreloader.h: 66 (WebCore::PreloadRequest::PreloadRequest): 67 (WebCore): 68 (HTMLResourcePreloader): 69 1 70 2013-02-15 Ryosuke Niwa <rniwa@webkit.org> 2 71 -
trunk/Source/WebCore/html/parser/BackgroundHTMLParser.cpp
r142829 r143051 52 52 for (size_t i = 0; i < tokens->size(); ++i) 53 53 ASSERT(tokens->at(i).isSafeToSendToAnotherThread()); 54 } 55 56 static void checkThatPreloadsAreSafeToSendToAnotherThread(const PreloadRequestStream& preloads) 57 { 58 for (size_t i = 0; i < preloads.size(); ++i) 59 ASSERT(preloads[i]->isSafeToSendToAnotherThread()); 54 60 } 55 61 … … 107 113 } 108 114 109 // FIXME: Tune this constant based on a benchmark. The current value was cho osen arbitrarily.115 // FIXME: Tune this constant based on a benchmark. The current value was chosen arbitrarily. 110 116 static const size_t pendingTokenLimit = 4000; 111 117 112 BackgroundHTMLParser::BackgroundHTMLParser(PassRefPtr<WeakReference<BackgroundHTMLParser> > reference, const HTMLParserOptions& options, const WeakPtr<HTMLDocumentParser>& parser, PassOwnPtr<XSSAuditor> xssAuditor)118 BackgroundHTMLParser::BackgroundHTMLParser(PassRefPtr<WeakReference<BackgroundHTMLParser> > reference, PassOwnPtr<Configuration> config) 113 119 : m_weakFactory(reference, this) 114 120 , m_token(adoptPtr(new HTMLToken)) 115 , m_tokenizer(HTMLTokenizer::create( options))116 , m_options( options)117 , m_parser( parser)121 , m_tokenizer(HTMLTokenizer::create(config->options)) 122 , m_options(config->options) 123 , m_parser(config->parser) 118 124 , m_pendingTokens(adoptPtr(new CompactHTMLTokenStream)) 119 , m_xssAuditor(xssAuditor) 125 , m_xssAuditor(config->xssAuditor.release()) 126 , m_preloadScanner(config->preloadScanner.release()) 120 127 { 121 128 m_namespaceStack.append(HTML); … … 134 141 m_tokenizer = checkpoint->tokenizer.release(); 135 142 m_input.rewindTo(checkpoint->inputCheckpoint, checkpoint->unparsedInput); 143 m_preloadScanner.clear(); // FIXME: We should rewind the preload scanner rather than clearing it. 136 144 pumpTokenizer(); 137 145 } … … 224 232 OwnPtr<XSSInfo> xssInfo = m_xssAuditor->filterToken(FilterTokenRequest(*m_token, m_sourceTracker, m_tokenizer->shouldAllowCDATA())); 225 233 CompactHTMLToken token(m_token.get(), TextPosition(m_input.current().currentLine(), m_input.current().currentColumn())); 234 226 235 if (xssInfo) 227 236 token.setXSSInfo(xssInfo.release()); 237 238 if (m_preloadScanner) 239 m_preloadScanner->scan(token, m_pendingPreloads); 240 228 241 m_pendingTokens->append(token); 229 242 } … … 245 258 #ifndef NDEBUG 246 259 checkThatTokensAreSafeToSendToAnotherThread(m_pendingTokens.get()); 260 checkThatPreloadsAreSafeToSendToAnotherThread(m_pendingPreloads); 247 261 #endif 248 262 249 263 OwnPtr<HTMLDocumentParser::ParsedChunk> chunk = adoptPtr(new HTMLDocumentParser::ParsedChunk); 250 264 chunk->tokens = m_pendingTokens.release(); 265 chunk->preloads.swap(m_pendingPreloads); 251 266 chunk->checkpoint = m_input.createCheckpoint(); 252 267 callOnMainThread(bind(&HTMLDocumentParser::didReceiveParsedChunkFromBackgroundParser, m_parser, chunk.release())); -
trunk/Source/WebCore/html/parser/BackgroundHTMLParser.h
r142829 r143051 32 32 #include "CompactHTMLToken.h" 33 33 #include "HTMLParserOptions.h" 34 #include "HTMLPreloadScanner.h" 34 35 #include "HTMLSourceTracker.h" 35 36 #include "HTMLToken.h" … … 49 50 WTF_MAKE_FAST_ALLOCATED; 50 51 public: 51 static void create(PassRefPtr<WeakReference<BackgroundHTMLParser> > reference, const HTMLParserOptions& options, const WeakPtr<HTMLDocumentParser>& parser, PassOwnPtr<XSSAuditor> xssAuditor) 52 struct Configuration { 53 HTMLParserOptions options; 54 WeakPtr<HTMLDocumentParser> parser; 55 OwnPtr<XSSAuditor> xssAuditor; 56 OwnPtr<TokenPreloadScanner> preloadScanner; 57 }; 58 59 static void create(PassRefPtr<WeakReference<BackgroundHTMLParser> > reference, PassOwnPtr<Configuration> config) 52 60 { 53 new BackgroundHTMLParser(reference, options, parser, xssAuditor);61 new BackgroundHTMLParser(reference, config); 54 62 // Caller must free by calling stop(). 55 63 } … … 77 85 }; 78 86 79 BackgroundHTMLParser(PassRefPtr<WeakReference<BackgroundHTMLParser> >, const HTMLParserOptions&, const WeakPtr<HTMLDocumentParser>&, PassOwnPtr<XSSAuditor>);87 BackgroundHTMLParser(PassRefPtr<WeakReference<BackgroundHTMLParser> >, PassOwnPtr<Configuration>); 80 88 81 89 void markEndOfFile(); … … 94 102 HTMLParserOptions m_options; 95 103 WeakPtr<HTMLDocumentParser> m_parser; 104 96 105 OwnPtr<CompactHTMLTokenStream> m_pendingTokens; 106 PreloadRequestStream m_pendingPreloads; 107 97 108 OwnPtr<XSSAuditor> m_xssAuditor; 109 OwnPtr<TokenPreloadScanner> m_preloadScanner; 98 110 }; 99 111 -
trunk/Source/WebCore/html/parser/CSSPreloadScanner.cpp
r143020 r143051 52 52 53 53 template<typename Char> 54 void CSSPreloadScanner::scanCommon(const Char* begin, const Char* end, Vector<OwnPtr<PreloadRequest> >& requests)54 void CSSPreloadScanner::scanCommon(const Char* begin, const Char* end, PreloadRequestStream& requests) 55 55 { 56 56 m_requests = &requests; … … 60 60 } 61 61 62 void CSSPreloadScanner::scan(const HTMLToken::DataVector& data, Vector<OwnPtr<PreloadRequest> >& requests)62 void CSSPreloadScanner::scan(const HTMLToken::DataVector& data, PreloadRequestStream& requests) 63 63 { 64 64 scanCommon(data.data(), data.data() + data.size(), requests); 65 65 } 66 66 67 void CSSPreloadScanner::scan(const String& data, Vector<OwnPtr<PreloadRequest> >& requests)67 void CSSPreloadScanner::scan(const String& data, PreloadRequestStream& requests) 68 68 { 69 69 if (data.is8Bit()) { … … 214 214 if (!url.isEmpty()) { 215 215 KURL baseElementURL; // FIXME: This should be passed in from the HTMLPreloadScaner via scan()! 216 OwnPtr<PreloadRequest> request = PreloadRequest::create( 217 cachedResourceRequestInitiators().css, url, baseElementURL, CachedResource::CSSStyleSheet); 216 OwnPtr<PreloadRequest> request = PreloadRequest::create("css", url, baseElementURL, CachedResource::CSSStyleSheet); 218 217 // FIXME: Should this be including the charset in the preload request? 219 218 m_requests->append(request.release()); -
trunk/Source/WebCore/html/parser/CSSPreloadScanner.h
r143020 r143051 42 42 void reset(); 43 43 44 void scan(const HTMLToken::DataVector&, Vector<OwnPtr<PreloadRequest> >&);45 void scan(const String&, Vector<OwnPtr<PreloadRequest> >&);44 void scan(const HTMLToken::DataVector&, PreloadRequestStream&); 45 void scan(const String&, PreloadRequestStream&); 46 46 47 47 private: … … 60 60 61 61 template<typename Char> 62 void scanCommon(const Char* begin, const Char* end, Vector<OwnPtr<PreloadRequest> >&);62 void scanCommon(const Char* begin, const Char* end, PreloadRequestStream&); 63 63 64 64 inline void tokenize(UChar); … … 70 70 71 71 // Only non-zero during scan() 72 Vector<OwnPtr<PreloadRequest> >* m_requests;72 PreloadRequestStream* m_requests; 73 73 }; 74 74 -
trunk/Source/WebCore/html/parser/HTMLDocumentParser.cpp
r142673 r143051 287 287 { 288 288 if (isWaitingForScripts()) { 289 m_preloader->takeAndPreload(chunk->preloads); 289 290 m_speculations.append(chunk); 290 291 return; 291 292 } 292 293 ASSERT(m_speculations.isEmpty()); 294 chunk->preloads.clear(); // We don't need to preload because we're going to parse immediately. 293 295 processParsedChunkFromBackgroundParser(chunk); 294 296 } … … 556 558 m_backgroundParser = WeakPtr<BackgroundHTMLParser>(reference); 557 559 558 WeakPtr<HTMLDocumentParser> parser = m_weakFactory.createWeakPtr(); 559 OwnPtr<XSSAuditor> xssAuditor = adoptPtr(new XSSAuditor); 560 xssAuditor->init(document()); 561 ASSERT(xssAuditor->isSafeToSendToAnotherThread()); 562 HTMLParserThread::shared()->postTask(bind(&BackgroundHTMLParser::create, reference.release(), m_options, parser, xssAuditor.release())); 560 OwnPtr<BackgroundHTMLParser::Configuration> config = adoptPtr(new BackgroundHTMLParser::Configuration); 561 config->options = m_options; 562 config->parser = m_weakFactory.createWeakPtr(); 563 config->xssAuditor = adoptPtr(new XSSAuditor); 564 config->xssAuditor->init(document()); 565 config->preloadScanner = adoptPtr(new TokenPreloadScanner(document()->url().copy())); 566 567 ASSERT(config->xssAuditor->isSafeToSendToAnotherThread()); 568 ASSERT(config->preloadScanner->isSafeToSendToAnotherThread()); 569 HTMLParserThread::shared()->postTask(bind(&BackgroundHTMLParser::create, reference.release(), config.release())); 563 570 } 564 571 -
trunk/Source/WebCore/html/parser/HTMLDocumentParser.h
r142641 r143051 33 33 #include "HTMLInputStream.h" 34 34 #include "HTMLParserOptions.h" 35 #include "HTMLPreloadScanner.h" 35 36 #include "HTMLScriptRunnerHost.h" 36 37 #include "HTMLSourceTracker.h" … … 57 58 class HTMLScriptRunner; 58 59 class HTMLTreeBuilder; 59 class HTMLPreloadScanner;60 60 class HTMLResourcePreloader; 61 61 class ScriptController; … … 89 89 struct ParsedChunk { 90 90 OwnPtr<CompactHTMLTokenStream> tokens; 91 PreloadRequestStream preloads; 91 92 HTMLInputCheckpoint checkpoint; 92 93 }; -
trunk/Source/WebCore/html/parser/HTMLParserOptions.h
r139959 r143051 39 39 unsigned maximumDOMTreeDepth; 40 40 41 explicit HTMLParserOptions(Document* );41 explicit HTMLParserOptions(Document* = 0); 42 42 }; 43 43 -
trunk/Source/WebCore/html/parser/HTMLPreloadScanner.cpp
r143020 r143051 355 355 { 356 356 ASSERT(m_predictedBaseElementURL.isEmpty()); 357 m_predictedBaseElementURL = KURL(m_documentURL, stripLeadingAndTrailingHTMLSpaces(token.getAttributeItem(hrefAttr)->value())) ;357 m_predictedBaseElementURL = KURL(m_documentURL, stripLeadingAndTrailingHTMLSpaces(token.getAttributeItem(hrefAttr)->value())).copy(); 358 358 } 359 359 #endif … … 382 382 m_scanner.setPredictedBaseElementURL(startingBaseElementURL); 383 383 384 Vector<OwnPtr<PreloadRequest> > requests; 384 PreloadRequestStream requests; 385 385 386 while (m_tokenizer->nextToken(m_source, m_token)) { 386 387 if (m_token.type() == HTMLToken::StartTag) … … 389 390 m_token.clear(); 390 391 } 391 for (size_t i = 0; i < requests.size(); i++) 392 preloader->preload(requests[i].release());393 } 394 395 } 392 393 preloader->takeAndPreload(requests); 394 } 395 396 } -
trunk/Source/WebCore/html/parser/HTMLPreloadScanner.h
r143020 r143051 45 45 ~TokenPreloadScanner(); 46 46 47 void scan(const HTMLToken&, Vector<OwnPtr<PreloadRequest> >& requests);47 void scan(const HTMLToken&, PreloadRequestStream& requests); 48 48 #if ENABLE(THREADED_HTML_PARSER) 49 void scan(const CompactHTMLToken&, Vector<OwnPtr<PreloadRequest> >& requests);49 void scan(const CompactHTMLToken&, PreloadRequestStream& requests); 50 50 #endif 51 51 52 52 void setPredictedBaseElementURL(const KURL& url) { m_predictedBaseElementURL = url; } 53 54 bool isSafeToSendToAnotherThread() 55 { 56 return m_documentURL.isSafeToSendToAnotherThread() 57 && m_predictedBaseElementURL.isSafeToSendToAnotherThread(); 58 } 53 59 54 60 private: … … 70 76 71 77 template<typename Token> 72 inline void scanCommon(const Token&, Vector<OwnPtr<PreloadRequest> >& requests);78 inline void scanCommon(const Token&, PreloadRequestStream& requests); 73 79 74 80 static TagId tagIdFor(const HTMLToken::DataVector&); -
trunk/Source/WebCore/html/parser/HTMLResourcePreloader.cpp
r142796 r143051 57 57 } 58 58 59 void HTMLResourcePreloader::takeAndPreload(PreloadRequestStream& r) 60 { 61 PreloadRequestStream requests; 62 requests.swap(r); 63 64 for (PreloadRequestStream::iterator it = requests.begin(); it != requests.end(); ++it) 65 preload(it->release()); 66 } 67 59 68 void HTMLResourcePreloader::preload(PassOwnPtr<PreloadRequest> preload) 60 69 { -
trunk/Source/WebCore/html/parser/HTMLResourcePreloader.h
r142796 r143051 51 51 PreloadRequest(const String& initiator, const String& resourceURL, const KURL& baseURL, CachedResource::Type resourceType) 52 52 : m_initiator(initiator) 53 , m_resourceURL(resourceURL )54 , m_baseURL(baseURL )53 , m_resourceURL(resourceURL.isolatedCopy()) 54 , m_baseURL(baseURL.copy()) 55 55 , m_resourceType(resourceType) 56 56 , m_crossOriginModeAllowsCookies(false) … … 68 68 }; 69 69 70 typedef Vector<OwnPtr<PreloadRequest> > PreloadRequestStream; 71 70 72 class HTMLResourcePreloader { 71 73 WTF_MAKE_NONCOPYABLE(HTMLResourcePreloader); WTF_MAKE_FAST_ALLOCATED; … … 77 79 } 78 80 81 void takeAndPreload(PreloadRequestStream&); 79 82 void preload(PassOwnPtr<PreloadRequest>); 80 83
Note: See TracChangeset
for help on using the changeset viewer.