Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(416)

Side by Side Diff: Source/core/css/StyleSheetContents.cpp

Issue 196653006: Optimize StyleSheetContents::checkLoaded by keeping track of completed (Closed) Base URL: svn://svn.chromium.org/blink/trunk
Patch Set: Address comments. Created 6 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « Source/core/css/StyleSheetContents.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 /* 1 /*
2 * (C) 1999-2003 Lars Knoll (knoll@kde.org) 2 * (C) 1999-2003 Lars Knoll (knoll@kde.org)
3 * Copyright (C) 2004, 2006, 2007, 2012 Apple Inc. All rights reserved. 3 * Copyright (C) 2004, 2006, 2007, 2012 Apple Inc. All rights reserved.
4 * 4 *
5 * This library is free software; you can redistribute it and/or 5 * This library is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU Library General Public 6 * modify it under the terms of the GNU Library General Public
7 * License as published by the Free Software Foundation; either 7 * License as published by the Free Software Foundation; either
8 * version 2 of the License, or (at your option) any later version. 8 * version 2 of the License, or (at your option) any later version.
9 * 9 *
10 * This library is distributed in the hope that it will be useful, 10 * This library is distributed in the hope that it will be useful,
(...skipping 356 matching lines...) Expand 10 before | Expand all | Expand 10 after
367 return false; 367 return false;
368 } 368 }
369 369
370 bool StyleSheetContents::loadCompleted() const 370 bool StyleSheetContents::loadCompleted() const
371 { 371 {
372 StyleSheetContents* parentSheet = parentStyleSheet(); 372 StyleSheetContents* parentSheet = parentStyleSheet();
373 if (parentSheet) 373 if (parentSheet)
374 return parentSheet->loadCompleted(); 374 return parentSheet->loadCompleted();
375 375
376 StyleSheetContents* root = rootStyleSheet(); 376 StyleSheetContents* root = rootStyleSheet();
377 for (ClientsIterator it = root->m_clients.begin(); it != root->m_clients.end (); ++it) { 377 return root->m_loadingClients.isEmpty();
378 if (!(*it)->loadCompleted())
379 return false;
380 }
381 return true;
382 } 378 }
383 379
384 void StyleSheetContents::checkLoaded() 380 void StyleSheetContents::checkLoaded()
385 { 381 {
386 if (isLoading()) 382 if (isLoading())
387 return; 383 return;
388 384
389 // Avoid |this| being deleted by scripts that run via 385 // Avoid |this| being deleted by scripts that run via
390 // ScriptableDocumentParser::executeScriptsWaitingForResources(). 386 // ScriptableDocumentParser::executeScriptsWaitingForResources().
391 // See https://bugs.webkit.org/show_bug.cgi?id=95106 387 // See https://bugs.webkit.org/show_bug.cgi?id=95106
392 RefPtrWillBeRawPtr<StyleSheetContents> protect(this); 388 RefPtrWillBeRawPtr<StyleSheetContents> protect(this);
393 389
394 StyleSheetContents* parentSheet = parentStyleSheet(); 390 StyleSheetContents* parentSheet = parentStyleSheet();
395 if (parentSheet) { 391 if (parentSheet) {
396 parentSheet->checkLoaded(); 392 parentSheet->checkLoaded();
397 return; 393 return;
398 } 394 }
399 395
400 StyleSheetContents* root = rootStyleSheet(); 396 StyleSheetContents* root = rootStyleSheet();
401 if (root->m_clients.isEmpty()) 397 if (root->m_loadingClients.isEmpty())
402 return; 398 return;
403 399
404 // Avoid |CSSSStyleSheet| and |ownerNode| being deleted by scripts that run via 400 // Avoid |CSSSStyleSheet| and |ownerNode| being deleted by scripts that run via
405 // ScriptableDocumentParser::executeScriptsWaitingForResources(). Also prote ct 401 // ScriptableDocumentParser::executeScriptsWaitingForResources(). Also prote ct
406 // the |CSSStyleSheet| from being deleted during iteration via the |sheetLoa ded| 402 // the |CSSStyleSheet| from being deleted during iteration via the |sheetLoa ded|
407 // method. 403 // method.
408 // 404 //
409 // FIXME: oilpan: with oilpan we do not need to protect the CSSStyleSheets 405 // FIXME: oilpan: with oilpan we do not need to protect the CSSStyleSheets
410 // explicitly during the iteration. The iterator will make the pointers 406 // explicitly during the iteration. The iterator will make the pointers
411 // strong during iteration so we can just directly iterate root->m_clients. 407 // strong during iteration so we can just directly iterate root->m_clients.
412 WillBeHeapVector<RefPtrWillBeMember<CSSStyleSheet>, 5> protectedClients; 408 WillBeHeapVector<RefPtrWillBeMember<CSSStyleSheet> > protectedClients;
413 for (ClientsIterator it = root->m_clients.begin(); it != root->m_clients.end (); ++it) 409 copyToVector(m_loadingClients, protectedClients);
414 protectedClients.append(*it);
415 410
416 for (unsigned i = 0; i < protectedClients.size(); ++i) { 411 for (unsigned i = 0; i < protectedClients.size(); ++i) {
417 if (protectedClients[i]->loadCompleted()) 412 if (protectedClients[i]->loadCompleted())
418 continue; 413 continue;
419 414
420 // sheetLoaded might be invoked after its owner node is removed from doc ument. 415 // sheetLoaded might be invoked after its owner node is removed from doc ument.
421 if (RefPtr<Node> ownerNode = protectedClients[i]->ownerNode()) { 416 if (RefPtr<Node> ownerNode = protectedClients[i]->ownerNode()) {
422 if (protectedClients[i]->sheetLoaded()) 417 if (protectedClients[i]->sheetLoaded())
423 ownerNode->notifyLoadedSheetAndAllCriticalSubresources(m_didLoad ErrorOccur); 418 ownerNode->notifyLoadedSheetAndAllCriticalSubresources(m_didLoad ErrorOccur);
424 } 419 }
425 } 420 }
426 } 421 }
427 422
428 void StyleSheetContents::notifyLoadedSheet(const CSSStyleSheetResource* sheet) 423 void StyleSheetContents::notifyLoadedSheet(const CSSStyleSheetResource* sheet)
429 { 424 {
430 ASSERT(sheet); 425 ASSERT(sheet);
431 m_didLoadErrorOccur |= sheet->errorOccurred(); 426 m_didLoadErrorOccur |= sheet->errorOccurred();
432 // updateLayoutIgnorePendingStyleSheets can cause us to create the RuleSet o n this 427 // updateLayoutIgnorePendingStyleSheets can cause us to create the RuleSet o n this
433 // sheet before its imports have loaded. So clear the RuleSet when the impor ts 428 // sheet before its imports have loaded. So clear the RuleSet when the impor ts
434 // load since the import's subrules are flattened into its parent sheet's Ru leSet. 429 // load since the import's subrules are flattened into its parent sheet's Ru leSet.
435 clearRuleSet(); 430 clearRuleSet();
436 } 431 }
437 432
438 void StyleSheetContents::startLoadingDynamicSheet() 433 void StyleSheetContents::startLoadingDynamicSheet()
439 { 434 {
440 StyleSheetContents* root = rootStyleSheet(); 435 StyleSheetContents* root = rootStyleSheet();
441 for (ClientsIterator it = root->m_clients.begin(); it != root->m_clients.end (); ++it) 436 for (ClientsIterator it = root->m_loadingClients.begin(); it != root->m_load ingClients.end(); ++it)
437 (*it)->startLoadingDynamicSheet();
438 for (ClientsIterator it = root->m_completedClients.begin(); it != root->m_co mpletedClients.end(); ++it)
442 (*it)->startLoadingDynamicSheet(); 439 (*it)->startLoadingDynamicSheet();
443 } 440 }
444 441
445 StyleSheetContents* StyleSheetContents::rootStyleSheet() const 442 StyleSheetContents* StyleSheetContents::rootStyleSheet() const
446 { 443 {
447 const StyleSheetContents* root = this; 444 const StyleSheetContents* root = this;
448 while (root->parentStyleSheet()) 445 while (root->parentStyleSheet())
449 root = root->parentStyleSheet(); 446 root = root->parentStyleSheet();
450 return const_cast<StyleSheetContents*>(root); 447 return const_cast<StyleSheetContents*>(root);
451 } 448 }
452 449
453 bool StyleSheetContents::hasSingleOwnerNode() const 450 bool StyleSheetContents::hasSingleOwnerNode() const
454 { 451 {
455 StyleSheetContents* root = rootStyleSheet(); 452 return rootStyleSheet()->hasOneClient();
456 if (root->m_clients.isEmpty())
457 return false;
458 return root->m_clients.size() == 1;
459 } 453 }
460 454
461 Node* StyleSheetContents::singleOwnerNode() const 455 Node* StyleSheetContents::singleOwnerNode() const
462 { 456 {
463 StyleSheetContents* root = rootStyleSheet(); 457 StyleSheetContents* root = rootStyleSheet();
464 if (root->m_clients.isEmpty()) 458 if (!root->hasOneClient())
465 return 0; 459 return 0;
466 ASSERT(root->m_clients.size() == 1); 460 if (root->m_loadingClients.size())
467 return (*root->m_clients.begin())->ownerNode(); 461 return (*root->m_loadingClients.begin())->ownerNode();
462 return (*root->m_completedClients.begin())->ownerNode();
468 } 463 }
469 464
470 Document* StyleSheetContents::singleOwnerDocument() const 465 Document* StyleSheetContents::singleOwnerDocument() const
471 { 466 {
472 Node* ownerNode = singleOwnerNode(); 467 Node* ownerNode = singleOwnerNode();
473 return ownerNode ? &ownerNode->document() : 0; 468 return ownerNode ? &ownerNode->document() : 0;
474 } 469 }
475 470
476 KURL StyleSheetContents::completeURL(const String& url) const 471 KURL StyleSheetContents::completeURL(const String& url) const
477 { 472 {
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
518 return childRulesHaveFailedOrCanceledSubresources(m_childRules); 513 return childRulesHaveFailedOrCanceledSubresources(m_childRules);
519 } 514 }
520 515
521 StyleSheetContents* StyleSheetContents::parentStyleSheet() const 516 StyleSheetContents* StyleSheetContents::parentStyleSheet() const
522 { 517 {
523 return m_ownerRule ? m_ownerRule->parentStyleSheet() : 0; 518 return m_ownerRule ? m_ownerRule->parentStyleSheet() : 0;
524 } 519 }
525 520
526 void StyleSheetContents::registerClient(CSSStyleSheet* sheet) 521 void StyleSheetContents::registerClient(CSSStyleSheet* sheet)
527 { 522 {
528 ASSERT(!m_clients.contains(sheet)); 523 ASSERT(!m_loadingClients.contains(sheet) && !m_completedClients.contains(she et));
529 m_clients.add(sheet); 524 m_loadingClients.add(sheet);
530 } 525 }
531 526
532 void StyleSheetContents::unregisterClient(CSSStyleSheet* sheet) 527 void StyleSheetContents::unregisterClient(CSSStyleSheet* sheet)
533 { 528 {
534 ASSERT(m_clients.contains(sheet)); 529 ASSERT(m_loadingClients.contains(sheet) || m_completedClients.contains(sheet ));
535 m_clients.remove(sheet); 530 m_loadingClients.remove(sheet);
531 m_completedClients.remove(sheet);
532 }
533
534 void StyleSheetContents::clientLoadCompleted(CSSStyleSheet* sheet)
535 {
536 ASSERT(m_loadingClients.contains(sheet));
537 m_loadingClients.remove(sheet);
538 m_completedClients.add(sheet);
539 }
540
541 void StyleSheetContents::clientLoadStarted(CSSStyleSheet* sheet)
542 {
543 ASSERT(m_completedClients.contains(sheet));
544 m_completedClients.remove(sheet);
545 m_loadingClients.add(sheet);
536 } 546 }
537 547
538 void StyleSheetContents::addedToMemoryCache() 548 void StyleSheetContents::addedToMemoryCache()
539 { 549 {
540 ASSERT(!m_isInMemoryCache); 550 ASSERT(!m_isInMemoryCache);
541 ASSERT(isCacheable()); 551 ASSERT(isCacheable());
542 m_isInMemoryCache = true; 552 m_isInMemoryCache = true;
543 } 553 }
544 554
545 void StyleSheetContents::removedFromMemoryCache() 555 void StyleSheetContents::removedFromMemoryCache()
(...skipping 11 matching lines...) Expand all
557 567
558 RuleSet& StyleSheetContents::ensureRuleSet(const MediaQueryEvaluator& medium, Ad dRuleFlags addRuleFlags) 568 RuleSet& StyleSheetContents::ensureRuleSet(const MediaQueryEvaluator& medium, Ad dRuleFlags addRuleFlags)
559 { 569 {
560 if (!m_ruleSet) { 570 if (!m_ruleSet) {
561 m_ruleSet = RuleSet::create(); 571 m_ruleSet = RuleSet::create();
562 m_ruleSet->addRulesFromSheet(this, medium, addRuleFlags); 572 m_ruleSet->addRulesFromSheet(this, medium, addRuleFlags);
563 } 573 }
564 return *m_ruleSet.get(); 574 return *m_ruleSet.get();
565 } 575 }
566 576
577 static void clearResolvers(WillBeHeapHashSet<RawPtrWillBeWeakMember<CSSStyleShee t> >& clients)
578 {
579 for (WillBeHeapHashSet<RawPtrWillBeWeakMember<CSSStyleSheet> >::iterator it = clients.begin(); it != clients.end(); ++it) {
580 if (Document* document = (*it)->ownerDocument())
581 document->styleEngine()->clearResolver();
582 }
583 }
584
567 void StyleSheetContents::clearRuleSet() 585 void StyleSheetContents::clearRuleSet()
568 { 586 {
569 if (StyleSheetContents* parentSheet = parentStyleSheet()) 587 if (StyleSheetContents* parentSheet = parentStyleSheet())
570 parentSheet->clearRuleSet(); 588 parentSheet->clearRuleSet();
571 589
572 // Don't want to clear the StyleResolver if the RuleSet hasn't been created 590 // Don't want to clear the StyleResolver if the RuleSet hasn't been created
573 // since we only clear the StyleResolver so that it's members are properly 591 // since we only clear the StyleResolver so that it's members are properly
574 // updated in ScopedStyleResolver::addRulesFromSheet. 592 // updated in ScopedStyleResolver::addRulesFromSheet.
575 if (!m_ruleSet) 593 if (!m_ruleSet)
576 return; 594 return;
577 595
578 // Clearing the ruleSet means we need to recreate the styleResolver data str uctures. 596 // Clearing the ruleSet means we need to recreate the styleResolver data str uctures.
579 // See the StyleResolver calls in ScopedStyleResolver::addRulesFromSheet. 597 // See the StyleResolver calls in ScopedStyleResolver::addRulesFromSheet.
580 for (ClientsIterator it = m_clients.begin(); it != m_clients.end(); ++it) { 598 clearResolvers(m_loadingClients);
581 if (Document* document = (*it)->ownerDocument()) 599 clearResolvers(m_completedClients);
582 document->styleEngine()->clearResolver(); 600 m_ruleSet.clear();
601 }
602
603 static void removeFontFaceRules(WillBeHeapHashSet<RawPtrWillBeWeakMember<CSSStyl eSheet> >& clients, const StyleRuleFontFace* fontFaceRule)
604 {
605 for (WillBeHeapHashSet<RawPtrWillBeWeakMember<CSSStyleSheet> >::iterator it = clients.begin(); it != clients.end(); ++it) {
606 if (Node* ownerNode = (*it)->ownerNode())
607 ownerNode->document().styleEngine()->removeFontFaceRules(WillBeHeapV ector<RawPtrWillBeMember<const StyleRuleFontFace> >(1, fontFaceRule));
583 } 608 }
584 m_ruleSet.clear();
585 } 609 }
586 610
587 void StyleSheetContents::notifyRemoveFontFaceRule(const StyleRuleFontFace* fontF aceRule) 611 void StyleSheetContents::notifyRemoveFontFaceRule(const StyleRuleFontFace* fontF aceRule)
588 { 612 {
589 StyleSheetContents* root = rootStyleSheet(); 613 StyleSheetContents* root = rootStyleSheet();
590 614 removeFontFaceRules(root->m_loadingClients, fontFaceRule);
591 for (ClientsIterator it = root->m_clients.begin(); it != root->m_clients.end (); ++it) { 615 removeFontFaceRules(root->m_completedClients, fontFaceRule);
592 if (Node* ownerNode = (*it)->ownerNode())
593 ownerNode->document().styleEngine()->removeFontFaceRules(WillBeHeapV ector<RawPtrWillBeMember<const StyleRuleFontFace> >(1, fontFaceRule));
594 }
595 } 616 }
596 617
597 static void findFontFaceRulesFromRules(const WillBeHeapVector<RefPtrWillBeMember <StyleRuleBase> >& rules, WillBeHeapVector<RawPtrWillBeMember<const StyleRuleFon tFace> >& fontFaceRules) 618 static void findFontFaceRulesFromRules(const WillBeHeapVector<RefPtrWillBeMember <StyleRuleBase> >& rules, WillBeHeapVector<RawPtrWillBeMember<const StyleRuleFon tFace> >& fontFaceRules)
598 { 619 {
599 for (unsigned i = 0; i < rules.size(); ++i) { 620 for (unsigned i = 0; i < rules.size(); ++i) {
600 StyleRuleBase* rule = rules[i].get(); 621 StyleRuleBase* rule = rules[i].get();
601 622
602 if (rule->isFontFaceRule()) { 623 if (rule->isFontFaceRule()) {
603 fontFaceRules.append(toStyleRuleFontFace(rule)); 624 fontFaceRules.append(toStyleRuleFontFace(rule));
604 } else if (rule->isMediaRule()) { 625 } else if (rule->isMediaRule()) {
(...skipping 14 matching lines...) Expand all
619 } 640 }
620 641
621 findFontFaceRulesFromRules(childRules(), fontFaceRules); 642 findFontFaceRulesFromRules(childRules(), fontFaceRules);
622 } 643 }
623 644
624 void StyleSheetContents::trace(Visitor* visitor) 645 void StyleSheetContents::trace(Visitor* visitor)
625 { 646 {
626 visitor->trace(m_ownerRule); 647 visitor->trace(m_ownerRule);
627 visitor->trace(m_importRules); 648 visitor->trace(m_importRules);
628 visitor->trace(m_childRules); 649 visitor->trace(m_childRules);
629 visitor->trace(m_clients); 650 visitor->trace(m_loadingClients);
651 visitor->trace(m_completedClients);
630 visitor->trace(m_ruleSet); 652 visitor->trace(m_ruleSet);
631 } 653 }
632 654
633 } 655 }
OLDNEW
« no previous file with comments | « Source/core/css/StyleSheetContents.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698