| 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 |