OLD | NEW |
1 /* | 1 /* |
2 * Copyright (C) 2012 Google, Inc. All rights reserved. | 2 * Copyright (C) 2012 Google, Inc. All rights reserved. |
3 * | 3 * |
4 * Redistribution and use in source and binary forms, with or without | 4 * Redistribution and use in source and binary forms, with or without |
5 * modification, are permitted provided that the following conditions | 5 * modification, are permitted provided that the following conditions |
6 * are met: | 6 * are met: |
7 * 1. Redistributions of source code must retain the above copyright | 7 * 1. Redistributions of source code must retain the above copyright |
8 * notice, this list of conditions and the following disclaimer. | 8 * notice, this list of conditions and the following disclaimer. |
9 * 2. Redistributions in binary form must reproduce the above copyright | 9 * 2. Redistributions in binary form must reproduce the above copyright |
10 * notice, this list of conditions and the following disclaimer in the | 10 * notice, this list of conditions and the following disclaimer in the |
(...skipping 20 matching lines...) Expand all Loading... |
31 #include "core/dom/ExecutionContext.h" | 31 #include "core/dom/ExecutionContext.h" |
32 #include "core/frame/Deprecation.h" | 32 #include "core/frame/Deprecation.h" |
33 #include "core/frame/FrameConsole.h" | 33 #include "core/frame/FrameConsole.h" |
34 #include "core/frame/FrameHost.h" | 34 #include "core/frame/FrameHost.h" |
35 #include "core/frame/LocalFrame.h" | 35 #include "core/frame/LocalFrame.h" |
36 #include "core/inspector/ConsoleMessage.h" | 36 #include "core/inspector/ConsoleMessage.h" |
37 #include "core/workers/WorkerGlobalScope.h" | 37 #include "core/workers/WorkerGlobalScope.h" |
38 #include "platform/Histogram.h" | 38 #include "platform/Histogram.h" |
39 #include "platform/TraceEvent.h" | 39 #include "platform/TraceEvent.h" |
40 | 40 |
| 41 namespace { |
| 42 |
| 43 int totalPagesMeasuredCSSSampleId() { return 1; } |
| 44 |
| 45 // Make sure update_use_counter_css.py was run which updates histograms.xml. |
| 46 int maximumCSSSampleId() { return 539; } |
| 47 |
| 48 blink::EnumerationHistogram& useCounterHistogram() |
| 49 { |
| 50 DEFINE_STATIC_LOCAL(blink::EnumerationHistogram, histogram, ("WebCore.UseCou
nter_TEST.Features", blink::UseCounter::NumberOfFeatures)); |
| 51 return histogram; |
| 52 } |
| 53 |
| 54 blink::EnumerationHistogram& CSSUseCounterHistogram() |
| 55 { |
| 56 DEFINE_STATIC_LOCAL(blink::EnumerationHistogram, histogram, ("WebCore.UseCou
nter_TEST.CSSProperties", maximumCSSSampleId())); |
| 57 return histogram; |
| 58 } |
| 59 |
| 60 } // namespace |
| 61 |
41 namespace blink { | 62 namespace blink { |
42 | 63 |
43 static int totalPagesMeasuredCSSSampleId() { return 1; } | |
44 | |
45 int UseCounter::mapCSSPropertyIdToCSSSampleIdForHistogram(CSSPropertyID cssPrope
rtyID) | 64 int UseCounter::mapCSSPropertyIdToCSSSampleIdForHistogram(CSSPropertyID cssPrope
rtyID) |
46 { | 65 { |
47 switch (cssPropertyID) { | 66 switch (cssPropertyID) { |
48 // Begin at 2, because 1 is reserved for totalPagesMeasuredCSSSampleId. | 67 // Begin at 2, because 1 is reserved for totalPagesMeasuredCSSSampleId. |
49 case CSSPropertyColor: return 2; | 68 case CSSPropertyColor: return 2; |
50 case CSSPropertyDirection: return 3; | 69 case CSSPropertyDirection: return 3; |
51 case CSSPropertyDisplay: return 4; | 70 case CSSPropertyDisplay: return 4; |
52 case CSSPropertyFont: return 5; | 71 case CSSPropertyFont: return 5; |
53 case CSSPropertyFontFamily: return 6; | 72 case CSSPropertyFontFamily: return 6; |
54 case CSSPropertyFontSize: return 7; | 73 case CSSPropertyFontSize: return 7; |
(...skipping 517 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
572 | 591 |
573 case CSSPropertyInvalid: | 592 case CSSPropertyInvalid: |
574 ASSERT_NOT_REACHED(); | 593 ASSERT_NOT_REACHED(); |
575 return 0; | 594 return 0; |
576 } | 595 } |
577 | 596 |
578 ASSERT_NOT_REACHED(); | 597 ASSERT_NOT_REACHED(); |
579 return 0; | 598 return 0; |
580 } | 599 } |
581 | 600 |
582 // Make sure update_use_counter_css.py was run which updates histograms.xml. | 601 UseCounter::UseCounter() |
583 static int maximumCSSSampleId() { return 539; } | 602 : m_muteCount(0) |
584 | 603 , m_featuresRecorded(NumberOfFeatures) |
585 static EnumerationHistogram& featureObserverHistogram() | 604 , m_CSSRecorded(lastUnresolvedCSSProperty + 1) |
586 { | 605 { |
587 DEFINE_STATIC_LOCAL(EnumerationHistogram, histogram, ("WebCore.FeatureObserv
er", UseCounter::NumberOfFeatures)); | |
588 return histogram; | |
589 } | 606 } |
590 | 607 |
591 void UseCounter::muteForInspector() | 608 void UseCounter::muteForInspector() |
592 { | 609 { |
593 m_muteCount++; | 610 m_muteCount++; |
594 } | 611 } |
595 | 612 |
596 void UseCounter::unmuteForInspector() | 613 void UseCounter::unmuteForInspector() |
597 { | 614 { |
598 m_muteCount--; | 615 m_muteCount--; |
599 } | 616 } |
600 | 617 |
601 void UseCounter::recordMeasurement(Feature feature) | 618 void UseCounter::recordMeasurement(Feature feature) |
602 { | 619 { |
603 if (m_muteCount) | 620 if (m_muteCount) |
604 return; | 621 return; |
605 | 622 |
606 DCHECK(feature != PageDestruction); // PageDestruction is reserved as a scal
ing factor. | 623 DCHECK(feature != OBSOLETE_PageDestruction && feature != PageVisits); // Pag
eDestruction is reserved as a scaling factor. |
607 DCHECK(feature < NumberOfFeatures); | 624 DCHECK(feature < NumberOfFeatures); |
608 | 625 |
609 if (!m_featureBits.quickGet(feature)) { | 626 if (!m_featuresRecorded.quickGet(feature)) { |
| 627 // Note that HTTPArchive tooling looks specifically for this event - see
https://github.com/HTTPArchive/httparchive/issues/59 |
610 TRACE_EVENT1(TRACE_DISABLED_BY_DEFAULT("blink.feature_usage"), "FeatureF
irstUsed", "feature", feature); | 628 TRACE_EVENT1(TRACE_DISABLED_BY_DEFAULT("blink.feature_usage"), "FeatureF
irstUsed", "feature", feature); |
611 m_featureBits.quickSet(feature); | 629 useCounterHistogram().count(feature); |
| 630 m_featuresRecorded.quickSet(feature); |
612 } | 631 } |
| 632 m_legacyCounter.countFeature(feature); |
613 } | 633 } |
614 | 634 |
615 bool UseCounter::hasRecordedMeasurement(Feature feature) const | 635 bool UseCounter::hasRecordedMeasurement(Feature feature) const |
616 { | 636 { |
617 if (m_muteCount) | 637 if (m_muteCount) |
618 return false; | 638 return false; |
619 | 639 |
620 DCHECK(feature != PageDestruction); // PageDestruction is reserved as a scal
ing factor. | 640 DCHECK(feature != OBSOLETE_PageDestruction && feature != PageVisits); // Pag
eDestruction is reserved as a scaling factor. |
621 DCHECK(feature < NumberOfFeatures); | 641 DCHECK(feature < NumberOfFeatures); |
622 | 642 |
623 return m_featureBits.quickGet(feature); | 643 return m_featuresRecorded.quickGet(feature); |
624 } | |
625 | |
626 UseCounter::UseCounter() | |
627 : m_muteCount(0) | |
628 , m_featureBits(NumberOfFeatures) | |
629 , m_CSSFeatureBits(lastUnresolvedCSSProperty + 1) | |
630 { | |
631 } | |
632 | |
633 UseCounter::~UseCounter() | |
634 { | |
635 // We always log PageDestruction so that we have a scale for the rest of the
features. | |
636 // TODO(rbyers): This is flawed due to renderer fast shutdown - crbug.com/59
7963 | |
637 featureObserverHistogram().count(PageDestruction); | |
638 | |
639 updateMeasurements(); | |
640 } | |
641 | |
642 void UseCounter::updateMeasurements() | |
643 { | |
644 EnumerationHistogram& featureHistogram = featureObserverHistogram(); | |
645 featureHistogram.count(PageVisits); | |
646 for (size_t i = 0; i < NumberOfFeatures; ++i) { | |
647 if (m_featureBits.quickGet(i)) | |
648 featureHistogram.count(i); | |
649 } | |
650 // Clearing count bits is timing sensitive. | |
651 m_featureBits.clearAll(); | |
652 | |
653 // FIXME: Sometimes this function is called more than once per page. The fol
lowing | |
654 // bool guards against incrementing the page count when there are no
CSS | |
655 // bits set. https://crbug.com/236262. | |
656 DEFINE_STATIC_LOCAL(EnumerationHistogram, cssPropertiesHistogram, ("WebCore.
FeatureObserver.CSSProperties", maximumCSSSampleId())); | |
657 bool needsPagesMeasuredUpdate = false; | |
658 for (size_t i = firstCSSProperty; i <= lastUnresolvedCSSProperty; ++i) { | |
659 if (m_CSSFeatureBits.quickGet(i)) { | |
660 int cssSampleId = mapCSSPropertyIdToCSSSampleIdForHistogram(static_c
ast<CSSPropertyID>(i)); | |
661 cssPropertiesHistogram.count(cssSampleId); | |
662 needsPagesMeasuredUpdate = true; | |
663 } | |
664 } | |
665 | |
666 if (needsPagesMeasuredUpdate) | |
667 cssPropertiesHistogram.count(totalPagesMeasuredCSSSampleId()); | |
668 | |
669 m_CSSFeatureBits.clearAll(); | |
670 } | 644 } |
671 | 645 |
672 void UseCounter::didCommitLoad() | 646 void UseCounter::didCommitLoad() |
673 { | 647 { |
674 // TODO(rbyers): This gets invoked more than expected. crbug.com/236262 | 648 // TODO(rbyers): This gets invoked more than expected. crbug.com/236262 |
675 // Eg. every SVGImage has it's own Page instance, they should probably all b
e delegating | 649 // Eg. every SVGImage has it's own Page instance, they should probably all b
e delegating |
676 // their UseCounter to the containing Page. | 650 // their UseCounter to the containing Page. |
677 updateMeasurements(); | 651 m_legacyCounter.updateMeasurements(); |
| 652 |
| 653 // TODO: Is didCommitLoad really the right time to do this? crbug.com/60804
0 |
| 654 m_featuresRecorded.clearAll(); |
| 655 useCounterHistogram().count(PageVisits); |
| 656 m_CSSRecorded.clearAll(); |
| 657 CSSUseCounterHistogram().count(totalPagesMeasuredCSSSampleId()); |
678 } | 658 } |
679 | 659 |
680 void UseCounter::count(const Frame* frame, Feature feature) | 660 void UseCounter::count(const Frame* frame, Feature feature) |
681 { | 661 { |
682 if (!frame) | 662 if (!frame) |
683 return; | 663 return; |
684 FrameHost* host = frame->host(); | 664 FrameHost* host = frame->host(); |
685 if (!host) | 665 if (!host) |
686 return; | 666 return; |
687 | 667 |
(...skipping 11 matching lines...) Expand all Loading... |
699 if (!frame) | 679 if (!frame) |
700 return false; | 680 return false; |
701 FrameHost* host = frame->host(); | 681 FrameHost* host = frame->host(); |
702 if (!host) | 682 if (!host) |
703 return false; | 683 return false; |
704 return host->useCounter().hasRecordedMeasurement(feature); | 684 return host->useCounter().hasRecordedMeasurement(feature); |
705 } | 685 } |
706 | 686 |
707 bool UseCounter::isCounted(CSSPropertyID unresolvedProperty) | 687 bool UseCounter::isCounted(CSSPropertyID unresolvedProperty) |
708 { | 688 { |
709 return m_CSSFeatureBits.quickGet(unresolvedProperty); | 689 return m_CSSRecorded.quickGet(unresolvedProperty); |
710 } | 690 } |
711 | 691 |
712 bool UseCounter::isCounted(Document& document, const String& string) | 692 bool UseCounter::isCounted(Document& document, const String& string) |
713 { | 693 { |
714 Frame* frame = document.frame(); | 694 Frame* frame = document.frame(); |
715 if (!frame) | 695 if (!frame) |
716 return false; | 696 return false; |
717 FrameHost* host = frame->host(); | 697 FrameHost* host = frame->host(); |
718 if (!host) | 698 if (!host) |
719 return false; | 699 return false; |
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
757 UseCounter::count(context, feature); | 737 UseCounter::count(context, feature); |
758 } | 738 } |
759 | 739 |
760 void UseCounter::countCrossOriginIframe(const Document& document, Feature featur
e) | 740 void UseCounter::countCrossOriginIframe(const Document& document, Feature featur
e) |
761 { | 741 { |
762 LocalFrame* frame = document.frame(); | 742 LocalFrame* frame = document.frame(); |
763 if (frame && frame->isCrossOriginSubframe()) | 743 if (frame && frame->isCrossOriginSubframe()) |
764 count(frame, feature); | 744 count(frame, feature); |
765 } | 745 } |
766 | 746 |
767 void UseCounter::count(CSSParserMode cssParserMode, CSSPropertyID feature) | 747 void UseCounter::count(CSSParserMode cssParserMode, CSSPropertyID property) |
768 { | 748 { |
769 DCHECK(feature >= firstCSSProperty); | 749 DCHECK(property >= firstCSSProperty); |
770 DCHECK(feature <= lastUnresolvedCSSProperty); | 750 DCHECK(property <= lastUnresolvedCSSProperty); |
771 | 751 |
772 if (!isUseCounterEnabledForMode(cssParserMode) || m_muteCount) | 752 if (!isUseCounterEnabledForMode(cssParserMode) || m_muteCount) |
773 return; | 753 return; |
774 | 754 |
775 if (!m_CSSFeatureBits.quickGet(feature)) { | 755 if (!m_CSSRecorded.quickGet(property)) { |
776 TRACE_EVENT1(TRACE_DISABLED_BY_DEFAULT("blink.feature_usage"), "CSSFeatu
reFirstUsed", "feature", feature); | 756 // Note that HTTPArchive tooling looks specifically for this event - see
https://github.com/HTTPArchive/httparchive/issues/59 |
777 m_CSSFeatureBits.quickSet(feature); | 757 TRACE_EVENT1(TRACE_DISABLED_BY_DEFAULT("blink.feature_usage"), "CSSFeatu
reFirstUsed", "feature", property); |
| 758 CSSUseCounterHistogram().count(mapCSSPropertyIdToCSSSampleIdForHistogram
(property)); |
| 759 m_CSSRecorded.quickSet(property); |
778 } | 760 } |
| 761 m_legacyCounter.countCSS(property); |
779 } | 762 } |
780 | 763 |
781 void UseCounter::count(Feature feature) | 764 void UseCounter::count(Feature feature) |
782 { | 765 { |
783 DCHECK(Deprecation::deprecationMessage(feature).isEmpty()); | 766 DCHECK(Deprecation::deprecationMessage(feature).isEmpty()); |
784 recordMeasurement(feature); | 767 recordMeasurement(feature); |
785 } | 768 } |
786 | 769 |
787 UseCounter* UseCounter::getFrom(const Document* document) | 770 UseCounter* UseCounter::getFrom(const Document* document) |
788 { | 771 { |
(...skipping 11 matching lines...) Expand all Loading... |
800 | 783 |
801 UseCounter* UseCounter::getFrom(const StyleSheetContents* sheetContents) | 784 UseCounter* UseCounter::getFrom(const StyleSheetContents* sheetContents) |
802 { | 785 { |
803 // FIXME: We may want to handle stylesheets that have multiple owners | 786 // FIXME: We may want to handle stylesheets that have multiple owners |
804 // https://crbug.com/242125 | 787 // https://crbug.com/242125 |
805 if (sheetContents && sheetContents->hasSingleOwnerNode()) | 788 if (sheetContents && sheetContents->hasSingleOwnerNode()) |
806 return getFrom(sheetContents->singleOwnerDocument()); | 789 return getFrom(sheetContents->singleOwnerDocument()); |
807 return 0; | 790 return 0; |
808 } | 791 } |
809 | 792 |
| 793 /* |
| 794 * |
| 795 * LEGACY metrics support - WebCore.FeatureObserver is to be superceded by WebCo
re.UseCounter |
| 796 * |
| 797 */ |
| 798 |
| 799 static EnumerationHistogram& featureObserverHistogram() |
| 800 { |
| 801 DEFINE_STATIC_LOCAL(EnumerationHistogram, histogram, ("WebCore.FeatureObserv
er", UseCounter::NumberOfFeatures)); |
| 802 return histogram; |
| 803 } |
| 804 |
| 805 UseCounter::LegacyCounter::LegacyCounter() |
| 806 : m_featureBits(NumberOfFeatures) |
| 807 , m_CSSBits(lastUnresolvedCSSProperty + 1) |
| 808 { |
| 809 } |
| 810 |
| 811 UseCounter::LegacyCounter::~LegacyCounter() |
| 812 { |
| 813 // PageDestruction was intended to be used as a scale, but it's broken (due
to fast shutdown). |
| 814 // See https://crbug.com/597963. |
| 815 featureObserverHistogram().count(OBSOLETE_PageDestruction); |
| 816 updateMeasurements(); |
| 817 } |
| 818 |
| 819 void UseCounter::LegacyCounter::countFeature(Feature feature) |
| 820 { |
| 821 m_featureBits.quickSet(feature); |
| 822 } |
| 823 |
| 824 void UseCounter::LegacyCounter::countCSS(CSSPropertyID property) |
| 825 { |
| 826 m_CSSBits.quickSet(property); |
| 827 } |
| 828 |
| 829 void UseCounter::LegacyCounter::updateMeasurements() |
| 830 { |
| 831 EnumerationHistogram& featureHistogram = featureObserverHistogram(); |
| 832 featureHistogram.count(PageVisits); |
| 833 for (size_t i = 0; i < NumberOfFeatures; ++i) { |
| 834 if (m_featureBits.quickGet(i)) |
| 835 featureHistogram.count(i); |
| 836 } |
| 837 // Clearing count bits is timing sensitive. |
| 838 m_featureBits.clearAll(); |
| 839 |
| 840 // FIXME: Sometimes this function is called more than once per page. The fol
lowing |
| 841 // bool guards against incrementing the page count when there are no
CSS |
| 842 // bits set. https://crbug.com/236262. |
| 843 DEFINE_STATIC_LOCAL(EnumerationHistogram, cssPropertiesHistogram, ("WebCore.
FeatureObserver.CSSProperties", maximumCSSSampleId())); |
| 844 bool needsPagesMeasuredUpdate = false; |
| 845 for (size_t i = firstCSSProperty; i <= lastUnresolvedCSSProperty; ++i) { |
| 846 if (m_CSSBits.quickGet(i)) { |
| 847 int cssSampleId = mapCSSPropertyIdToCSSSampleIdForHistogram(static_c
ast<CSSPropertyID>(i)); |
| 848 cssPropertiesHistogram.count(cssSampleId); |
| 849 needsPagesMeasuredUpdate = true; |
| 850 } |
| 851 } |
| 852 |
| 853 if (needsPagesMeasuredUpdate) |
| 854 cssPropertiesHistogram.count(totalPagesMeasuredCSSSampleId()); |
| 855 |
| 856 m_CSSBits.clearAll(); |
| 857 } |
| 858 |
810 } // namespace blink | 859 } // namespace blink |
OLD | NEW |