Changeset 144010 in webkit
- Timestamp:
- Feb 25, 2013 11:21:52 PM (11 years ago)
- Location:
- trunk/Source/WebCore
- Files:
-
- 9 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/Source/WebCore/ChangeLog
r144007 r144010 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 Unreviewed. 7 8 This patch restores the code that I rolled out in 9 http://trac.webkit.org/changeset/143960 and 10 http://trac.webkit.org/changeset/143983. Rolling out those patches did 11 not heal the bot. 12 13 * dom/Element.cpp: 14 (WebCore::Element::addAttributeInternal): 15 (WebCore::ShareableElementData::ShareableElementData): 16 (WebCore::UniqueElementData::makeShareableCopy): 17 (WebCore::UniqueElementData::addAttribute): 18 (WebCore::UniqueElementData::removeAttribute): 19 (WebCore::ElementData::reportMemoryUsage): 20 (WebCore::UniqueElementData::getAttributeItem): 21 (WebCore): 22 (WebCore::UniqueElementData::attributeItem): 23 * dom/Element.h: 24 (ElementData): 25 (UniqueElementData): 26 (WebCore::isShadowHost): 27 (WebCore::ElementData::length): 28 (WebCore::ElementData::attributeItem): 29 * html/parser/BackgroundHTMLParser.cpp: 30 (WebCore::BackgroundHTMLParser::resumeFrom): 31 (WebCore::BackgroundHTMLParser::pumpTokenizer): 32 (WebCore::BackgroundHTMLParser::sendTokensToMainThread): 33 * html/parser/CSSPreloadScanner.cpp: 34 (WebCore): 35 (WebCore::CSSPreloadScanner::scanCommon): 36 (WebCore::CSSPreloadScanner::scan): 37 (WebCore::CSSPreloadScanner::emitRule): 38 * html/parser/CSSPreloadScanner.h: 39 (CSSPreloadScanner): 40 * html/parser/HTMLDocumentParser.cpp: 41 (WebCore::HTMLDocumentParser::startBackgroundParser): 42 * html/parser/HTMLPreloadScanner.cpp: 43 (WebCore::TokenPreloadScanner::tagIdFor): 44 (WebCore): 45 (WebCore::TokenPreloadScanner::initiatorFor): 46 (WebCore::TokenPreloadScanner::StartTagScanner::processAttributes): 47 (TokenPreloadScanner::StartTagScanner): 48 (WebCore::TokenPreloadScanner::StartTagScanner::createPreloadRequest): 49 (WebCore::TokenPreloadScanner::createCheckpoint): 50 (WebCore::TokenPreloadScanner::rewindTo): 51 (WebCore::TokenPreloadScanner::scan): 52 (WebCore::TokenPreloadScanner::scanCommon): 53 (WebCore::TokenPreloadScanner::updatePredictedBaseURL): 54 (WebCore::HTMLPreloadScanner::scan): 55 * html/parser/HTMLPreloadScanner.h: 56 (TokenPreloadScanner): 57 (WebCore::TokenPreloadScanner::isSafeToSendToAnotherThread): 58 (WebCore::TokenPreloadScanner::Checkpoint::Checkpoint): 59 (Checkpoint): 60 1 61 2013-02-25 Chris Rogers <crogers@google.com> 2 62 -
trunk/Source/WebCore/dom/Element.cpp
r143983 r144010 1821 1821 if (!inSynchronizationOfLazyAttribute) 1822 1822 willModifyAttribute(name, nullAtom, value); 1823 ensureUniqueElementData()->addAttribute( Attribute(name, value));1823 ensureUniqueElementData()->addAttribute(name, value); 1824 1824 if (!inSynchronizationOfLazyAttribute) 1825 1825 didAddAttribute(name, value); … … 2970 2970 2971 2971 for (unsigned i = 0; i < m_arraySize; ++i) 2972 new (& reinterpret_cast<Attribute*>(&m_attributeArray)[i]) Attribute(*other.attributeItem(i));2972 new (&m_attributeArray[i]) Attribute(other.m_attributeVector.at(i)); 2973 2973 } 2974 2974 … … 3020 3020 PassRefPtr<ShareableElementData> UniqueElementData::makeShareableCopy() const 3021 3021 { 3022 void* slot = WTF::fastMalloc(sizeForShareableElementDataWithAttributeCount(m utableAttributeVector().size()));3022 void* slot = WTF::fastMalloc(sizeForShareableElementDataWithAttributeCount(m_attributeVector.size())); 3023 3023 return adoptRef(new (slot) ShareableElementData(*this)); 3024 3024 } 3025 3025 3026 void ElementData::addAttribute(const Attribute& attribute) 3027 { 3028 ASSERT(isUnique()); 3029 mutableAttributeVector().append(attribute); 3030 } 3031 3032 void ElementData::removeAttribute(size_t index) 3033 { 3034 ASSERT(isUnique()); 3026 void UniqueElementData::addAttribute(const QualifiedName& attributeName, const AtomicString& value) 3027 { 3028 m_attributeVector.append(Attribute(attributeName, value)); 3029 } 3030 3031 void UniqueElementData::removeAttribute(size_t index) 3032 { 3035 3033 ASSERT_WITH_SECURITY_IMPLICATION(index < length()); 3036 m utableAttributeVector().remove(index);3034 m_attributeVector.remove(index); 3037 3035 } 3038 3036 … … 3064 3062 info.addMember(m_idForStyleResolution, "idForStyleResolution"); 3065 3063 if (m_isUnique) { 3066 info.addMember(presentationAttributeStyle(), "presentationAttributeStyle()"); 3067 info.addMember(mutableAttributeVector(), "mutableAttributeVector"); 3064 const UniqueElementData* uniqueThis = static_cast<const UniqueElementData*>(this); 3065 info.addMember(uniqueThis->m_presentationAttributeStyle, "presentationAttributeStyle"); 3066 info.addMember(uniqueThis->m_attributeVector, "attributeVector"); 3068 3067 } 3069 3068 for (unsigned i = 0, len = length(); i < len; i++) … … 3090 3089 } 3091 3090 3091 Attribute* UniqueElementData::getAttributeItem(const QualifiedName& name) 3092 { 3093 for (unsigned i = 0; i < length(); ++i) { 3094 if (m_attributeVector.at(i).name().matches(name)) 3095 return &m_attributeVector.at(i); 3096 } 3097 return 0; 3098 } 3099 3100 Attribute* UniqueElementData::attributeItem(unsigned index) 3101 { 3102 ASSERT_WITH_SECURITY_IMPLICATION(index < length()); 3103 return &m_attributeVector.at(index); 3104 } 3105 3092 3106 } // namespace WebCore -
trunk/Source/WebCore/dom/Element.h
r143983 r144010 76 76 const Attribute* attributeItem(unsigned index) const; 77 77 const Attribute* getAttributeItem(const QualifiedName&) const; 78 Attribute* attributeItem(unsigned index);79 Attribute* getAttributeItem(const QualifiedName&);80 78 size_t getAttributeItemIndex(const QualifiedName&) const; 81 79 size_t getAttributeItemIndex(const AtomicString& name, bool shouldIgnoreAttributeCase) const; 82 80 83 // These functions do no error checking.84 void addAttribute(const Attribute&);85 void removeAttribute(size_t index);86 87 81 bool hasID() const { return !m_idForStyleResolution.isNull(); } 88 82 bool hasClass() const { return !m_classNames.isNull(); } … … 93 87 94 88 bool isUnique() const { return m_isUnique; } 95 const Attribute* immutableAttributeArray() const;96 89 97 90 protected: … … 121 114 #endif 122 115 123 Attribute* getAttributeItem(const AtomicString& name, bool shouldIgnoreAttributeCase);124 116 const Attribute* getAttributeItem(const AtomicString& name, bool shouldIgnoreAttributeCase) const; 125 117 size_t getAttributeItemIndexSlowCase(const AtomicString& name, bool shouldIgnoreAttributeCase) const; 126 118 127 119 PassRefPtr<UniqueElementData> makeUniqueCopy() const; 128 129 Vector<Attribute, 4>& mutableAttributeVector();130 const Vector<Attribute, 4>& mutableAttributeVector() const;131 120 }; 132 121 … … 155 144 static PassRefPtr<UniqueElementData> create(); 156 145 PassRefPtr<ShareableElementData> makeShareableCopy() const; 146 147 // These functions do no error/duplicate checking. 148 void addAttribute(const QualifiedName&, const AtomicString&); 149 void removeAttribute(size_t index); 150 151 Attribute* attributeItem(unsigned index); 152 Attribute* getAttributeItem(const QualifiedName&); 157 153 158 154 UniqueElementData(); … … 903 899 return node && node->isElementNode() && toElement(node)->shadow(); 904 900 } 905 inline Vector<Attribute, 4>& ElementData::mutableAttributeVector()906 {907 ASSERT(m_isUnique);908 return static_cast<UniqueElementData*>(this)->m_attributeVector;909 }910 911 inline const Vector<Attribute, 4>& ElementData::mutableAttributeVector() const912 {913 ASSERT(m_isUnique);914 return static_cast<const UniqueElementData*>(this)->m_attributeVector;915 }916 917 inline const Attribute* ElementData::immutableAttributeArray() const918 {919 ASSERT(!m_isUnique);920 return reinterpret_cast<const Attribute*>(&static_cast<const ShareableElementData*>(this)->m_attributeArray);921 }922 901 923 902 inline size_t ElementData::length() const 924 903 { 925 904 if (isUnique()) 926 return mutableAttributeVector().size();905 return static_cast<const UniqueElementData*>(this)->m_attributeVector.size(); 927 906 return m_arraySize; 928 907 } … … 933 912 return 0; 934 913 return static_cast<const UniqueElementData*>(this)->m_presentationAttributeStyle.get(); 935 }936 937 inline Attribute* ElementData::getAttributeItem(const AtomicString& name, bool shouldIgnoreAttributeCase)938 {939 size_t index = getAttributeItemIndex(name, shouldIgnoreAttributeCase);940 if (index != notFound)941 return attributeItem(index);942 return 0;943 914 } 944 915 … … 991 962 } 992 963 993 inline Attribute* ElementData::getAttributeItem(const QualifiedName& name)994 {995 for (unsigned i = 0; i < length(); ++i) {996 if (attributeItem(i)->name().matches(name))997 return attributeItem(i);998 }999 return 0;1000 }1001 1002 964 inline const Attribute* ElementData::attributeItem(unsigned index) const 1003 965 { 1004 966 ASSERT_WITH_SECURITY_IMPLICATION(index < length()); 1005 967 if (m_isUnique) 1006 return &mutableAttributeVector().at(index); 1007 return &immutableAttributeArray()[index]; 1008 } 1009 1010 inline Attribute* ElementData::attributeItem(unsigned index) 1011 { 1012 ASSERT_WITH_SECURITY_IMPLICATION(index < length()); 1013 return &mutableAttributeVector().at(index); 968 return &static_cast<const UniqueElementData*>(this)->m_attributeVector.at(index); 969 return &static_cast<const ShareableElementData*>(this)->m_attributeArray[index]; 1014 970 } 1015 971 -
trunk/Source/WebCore/html/parser/BackgroundHTMLParser.cpp
r143960 r144010 157 157 m_tokenizer = checkpoint->tokenizer.release(); 158 158 m_input.rewindTo(checkpoint->inputCheckpoint, checkpoint->unparsedInput); 159 m_preloadScanner->rewindTo(checkpoint->preloadScannerCheckpoint); 159 160 pumpTokenizer(); 160 161 } … … 252 253 token.setXSSInfo(xssInfo.release()); 253 254 255 m_preloadScanner->scan(token, m_pendingPreloads); 256 254 257 m_pendingTokens->append(token); 255 258 } … … 278 281 chunk->preloads.swap(m_pendingPreloads); 279 282 chunk->inputCheckpoint = m_input.createCheckpoint(); 283 chunk->preloadScannerCheckpoint = m_preloadScanner->createCheckpoint(); 280 284 callOnMainThread(bind(&HTMLDocumentParser::didReceiveParsedChunkFromBackgroundParser, m_parser, chunk.release())); 281 285 -
trunk/Source/WebCore/html/parser/CSSPreloadScanner.cpp
r143960 r144010 51 51 } 52 52 53 void CSSPreloadScanner::scan(const UChar* begin, const UChar* end, Vector<OwnPtr<PreloadRequest> >& requests) 53 template<typename Char> 54 void CSSPreloadScanner::scanCommon(const Char* begin, const Char* end, PreloadRequestStream& requests) 54 55 { 55 56 m_requests = &requests; 56 for (const UChar* it = begin; it != end && m_state != DoneParsingImportRules; ++it)57 for (const Char* it = begin; it != end && m_state != DoneParsingImportRules; ++it) 57 58 tokenize(*it); 58 59 m_requests = 0; 59 60 } 60 61 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; 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); 67 76 } 68 77 … … 205 214 if (!url.isEmpty()) { 206 215 KURL baseElementURL; // FIXME: This should be passed in from the HTMLPreloadScaner via scan()! 207 OwnPtr<PreloadRequest> request = PreloadRequest::create( 208 cachedResourceRequestInitiators().css, url, baseElementURL, CachedResource::CSSStyleSheet); 216 OwnPtr<PreloadRequest> request = PreloadRequest::create("css", url, baseElementURL, CachedResource::CSSStyleSheet); 209 217 // FIXME: Should this be including the charset in the preload request? 210 218 m_requests->append(request.release()); -
trunk/Source/WebCore/html/parser/CSSPreloadScanner.h
r143960 r144010 29 29 30 30 #include "HTMLResourcePreloader.h" 31 #include "HTMLToken.h" 31 32 #include <wtf/text/StringBuilder.h> 32 33 … … 41 42 void reset(); 42 43 43 void scan(const UChar* begin, const UChar* end, Vector<OwnPtr<PreloadRequest> >&);44 void scan(const LChar* begin, const LChar* end, Vector<OwnPtr<PreloadRequest> >&);44 void scan(const HTMLToken::DataVector&, PreloadRequestStream&); 45 void scan(const String&, PreloadRequestStream&); 45 46 46 47 private: … … 58 59 }; 59 60 61 template<typename Char> 62 void scanCommon(const Char* begin, const Char* end, PreloadRequestStream&); 63 60 64 inline void tokenize(UChar); 61 65 void emitRule(); … … 66 70 67 71 // Only non-zero during scan() 68 Vector<OwnPtr<PreloadRequest> >* m_requests;72 PreloadRequestStream* m_requests; 69 73 }; 70 74 -
trunk/Source/WebCore/html/parser/HTMLDocumentParser.cpp
r144000 r144010 625 625 626 626 ASSERT(config->xssAuditor->isSafeToSendToAnotherThread()); 627 ASSERT(config->preloadScanner->isSafeToSendToAnotherThread()); 627 628 HTMLParserThread::shared()->postTask(bind(&BackgroundHTMLParser::create, reference.release(), config.release())); 628 629 } -
trunk/Source/WebCore/html/parser/HTMLPreloadScanner.cpp
r143960 r144010 44 44 using namespace HTMLNames; 45 45 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 { 46 TokenPreloadScanner::TagId TokenPreloadScanner::tagIdFor(const HTMLToken::DataVector& data) 47 { 48 AtomicString tagName(data); 58 49 if (tagName == imgTag) 59 50 return ImgTagId; … … 73 64 } 74 65 75 String TokenPreloadScanner::inititatorFor(TagId tagId) 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) 76 86 { 77 87 switch (tagId) { … … 108 118 { 109 119 ASSERT(isMainThread()); 110 111 120 if (m_tagId >= UnknownTagId) 112 121 return; 113 114 122 for (HTMLToken::AttributeList::const_iterator iter = attributes.begin(); iter != attributes.end(); ++iter) { 115 123 AtomicString attributeName(iter->name); … … 119 127 } 120 128 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 121 139 PassOwnPtr<PreloadRequest> createPreloadRequest(const KURL& predictedBaseURL) 122 140 { … … 124 142 return nullptr; 125 143 126 OwnPtr<PreloadRequest> request = PreloadRequest::create(initi tatorFor(m_tagId), m_urlToLoad, predictedBaseURL, resourceType());144 OwnPtr<PreloadRequest> request = PreloadRequest::create(initiatorFor(m_tagId), m_urlToLoad, predictedBaseURL, resourceType()); 127 145 request->setCrossOriginModeAllowsCookies(crossOriginModeAllowsCookies()); 128 146 request->setCharset(charset()); … … 245 263 } 246 264 247 #if ENABLE(TEMPLATE_ELEMENT) 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 } 260 #endif 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; 265 TokenPreloadScannerCheckpoint TokenPreloadScanner::createCheckpoint() 266 { 267 TokenPreloadScannerCheckpoint checkpoint = m_checkpoints.size(); 268 m_checkpoints.append(Checkpoint(m_predictedBaseElementURL, m_inStyle 269 #if ENABLE(TEMPLATE_ELEMENT) 270 , m_templateCount 271 #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; 282 #if ENABLE(TEMPLATE_ELEMENT) 283 m_templateCount = checkpoint.templateCount; 284 #endif 285 m_cssScanner.reset(); 286 m_checkpoints.clear(); 295 287 } 296 288 297 289 void TokenPreloadScanner::scan(const HTMLToken& token, Vector<OwnPtr<PreloadRequest> >& requests) 298 290 { 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())) 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); 308 309 return; 309 310 AtomicString tagName(token.name()); 311 TagId tagId = identifierFor(tagName); 312 313 #if ENABLE(TEMPLATE_ELEMENT) 314 if (processPossibleTemplateTag(tagId, token.type())) 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 } 315 325 return; 316 #endif 317 if (processPossibleStyleTag(tagId, token.type())) 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()); 318 356 return; 319 if (!isStartTag(token.type())) 357 } 358 default: { 320 359 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()); 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(); 329 370 } 330 371 … … 352 393 m_scanner.setPredictedBaseElementURL(startingBaseElementURL); 353 394 354 Vector<OwnPtr<PreloadRequest> > requests; 395 PreloadRequestStream requests; 396 355 397 while (m_tokenizer->nextToken(m_source, m_token)) { 356 if ( isStartTag(m_token.type()))398 if (m_token.type() == HTMLToken::StartTag) 357 399 m_tokenizer->updateStateFor(AtomicString(m_token.name())); 358 400 m_scanner.scan(m_token, requests); 359 401 m_token.clear(); 360 402 } 361 for (size_t i = 0; i < requests.size(); i++) 362 preloader->preload(requests[i].release());363 } 364 365 } 403 404 preloader->takeAndPreload(requests); 405 } 406 407 } -
trunk/Source/WebCore/html/parser/HTMLPreloadScanner.h
r143960 r144010 29 29 30 30 #include "CSSPreloadScanner.h" 31 #include "CompactHTMLToken.h" 31 32 #include "HTMLToken.h" 32 33 #include "SegmentedString.h" 34 #include <wtf/Vector.h> 33 35 34 36 namespace WebCore { … … 46 48 ~TokenPreloadScanner(); 47 49 48 void scan(const HTMLToken&, Vector<OwnPtr<PreloadRequest> >& requests); 50 void scan(const HTMLToken&, PreloadRequestStream& requests); 51 #if ENABLE(THREADED_HTML_PARSER) 52 void scan(const CompactHTMLToken&, PreloadRequestStream& requests); 53 #endif 49 54 50 55 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 } 51 67 52 68 private: … … 67 83 class StartTagScanner; 68 84 69 static TagId identifierFor(const AtomicString& tagName);70 static String inititatorFor(TagId);85 template<typename Token> 86 inline void scanCommon(const Token&, PreloadRequestStream& requests); 71 87 88 static TagId tagIdFor(const HTMLToken::DataVector&); 89 static TagId tagIdFor(const String&); 90 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 72 98 #if ENABLE(TEMPLATE_ELEMENT) 73 bool processPossibleTemplateTag(TagId, HTMLToken::Type);99 , size_t templateCount 74 100 #endif 101 ) 102 : predictedBaseElementURL(predictedBaseElementURL) 103 , inStyle(inStyle) 104 #if ENABLE(TEMPLATE_ELEMENT) 105 , templateCount(templateCount) 106 #endif 107 { 108 } 75 109 76 bool processPossibleStyleTag(TagId, HTMLToken::Type); 77 bool processPossibleBaseTag(TagId, const HTMLToken&); 110 KURL predictedBaseElementURL; 111 bool inStyle; 112 #if ENABLE(TEMPLATE_ELEMENT) 113 size_t templateCount; 114 #endif 115 }; 78 116 79 117 CSSPreloadScanner m_cssScanner; 80 KURL m_documentURL;118 const KURL m_documentURL; 81 119 KURL m_predictedBaseElementURL; 82 120 bool m_inStyle; … … 85 123 size_t m_templateCount; 86 124 #endif 125 126 Vector<Checkpoint> m_checkpoints; 87 127 }; 88 128
Note: See TracChangeset
for help on using the changeset viewer.