Bug 1322396 - part 1 - report external resources of documents when flushing use counters in tests; r=dholbert
☠☠ backed out by 289cc51feb50 ☠ ☠
authorNathan Froyd <froydnj@mozilla.com>
Mon, 09 Jan 2017 13:55:31 -0500
changeset 328542 aae1f858f6deca2d9c1cfb78229c24a886aefe45
parent 328541 c89eb360f419e9e688aa08604e7a2c088aae62b3
child 328543 211d8715c9659e67ecde84f112c35c122a0bbe55
push id85473
push usernfroyd@mozilla.com
push dateMon, 09 Jan 2017 18:55:41 +0000
treeherdermozilla-inbound@211d8715c965 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersdholbert
bugs1322396
milestone53.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1322396 - part 1 - report external resources of documents when flushing use counters in tests; r=dholbert Our use counter tests force reporting of use counters from documents to make the tests more deterministic: relying on the default report-at-document-destruction behavior would introduce any number of intermittents. However, documents may have any number of external resource documents, and we have no mechanism for forcing a deterministic reporting of the use counters from those documents. Relying on those external resources to have been destroyed (and thereby reported their use counters) when we examine the values of the use counters in question is a recipe for intermittent failures. Therefore, we introduce an optional report kind for use counter reporting: if a document is reporting its use counters for the purposes of a test, we will also report the use counters for the document's external resource documents. This change makes everything more deterministic.
dom/base/nsDOMWindowUtils.cpp
dom/base/nsDocument.cpp
dom/base/nsDocument.h
--- a/dom/base/nsDOMWindowUtils.cpp
+++ b/dom/base/nsDOMWindowUtils.cpp
@@ -4021,17 +4021,20 @@ NS_IMETHODIMP
 nsDOMWindowUtils::ForceUseCounterFlush(nsIDOMNode *aNode)
 {
   NS_ENSURE_ARG_POINTER(aNode);
 
   if (nsCOMPtr<nsIDocument> doc = do_QueryInterface(aNode)) {
     mozilla::css::ImageLoader* loader = doc->StyleImageLoader();
     loader->FlushUseCounters();
 
-    static_cast<nsDocument*>(doc.get())->ReportUseCounters();
+    // Flush the document and any external documents that it depends on.
+    const auto reportKind
+      = nsDocument::UseCounterReportKind::eIncludeExternalResources;
+    static_cast<nsDocument*>(doc.get())->ReportUseCounters(reportKind);
     return NS_OK;
   }
 
   if (nsCOMPtr<nsIContent> content = do_QueryInterface(aNode)) {
     if (HTMLImageElement* img = HTMLImageElement::FromContent(content)) {
       img->FlushUseCounters();
       return NS_OK;
     }
--- a/dom/base/nsDocument.cpp
+++ b/dom/base/nsDocument.cpp
@@ -12299,26 +12299,39 @@ MightBeAboutOrChromeScheme(nsIURI* aURI)
   MOZ_ASSERT(aURI);
   bool isAbout = true;
   bool isChrome = true;
   aURI->SchemeIs("about", &isAbout);
   aURI->SchemeIs("chrome", &isChrome);
   return isAbout || isChrome;
 }
 
-void
-nsDocument::ReportUseCounters()
+static bool
+ReportExternalResourceUseCounters(nsIDocument* aDocument, void* aData)
+{
+  const auto reportKind
+    = nsDocument::UseCounterReportKind::eIncludeExternalResources;
+  static_cast<nsDocument*>(aDocument)->ReportUseCounters(reportKind);
+  return true;
+}
+
+void
+nsDocument::ReportUseCounters(UseCounterReportKind aKind)
 {
   static const bool sDebugUseCounters = false;
   if (mReportedUseCounters) {
     return;
   }
 
   mReportedUseCounters = true;
 
+  if (aKind == UseCounterReportKind::eIncludeExternalResources) {
+    EnumerateExternalResources(ReportExternalResourceUseCounters, nullptr);
+  }
+
   if (Telemetry::HistogramUseCounterCount > 0 &&
       (IsContentDocument() || IsResourceDoc())) {
     nsCOMPtr<nsIURI> uri;
     NodePrincipal()->GetURI(getter_AddRefs(uri));
     if (!uri || MightBeAboutOrChromeScheme(uri)) {
       return;
     }
 
--- a/dom/base/nsDocument.h
+++ b/dom/base/nsDocument.h
@@ -769,17 +769,29 @@ public:
   virtual void SetValueMissingState(const nsAString& aName, bool aValue) override;
 
   // for radio group
   nsRadioGroupStruct* GetRadioGroup(const nsAString& aName) const;
   nsRadioGroupStruct* GetOrCreateRadioGroup(const nsAString& aName);
 
   virtual nsViewportInfo GetViewportInfo(const mozilla::ScreenIntSize& aDisplaySize) override;
 
-  void ReportUseCounters();
+  enum class UseCounterReportKind {
+    // Flush the document's use counters only; the use counters for any
+    // external resource documents will be flushed when the external
+    // resource documents themselves are destroyed.
+    eDefault,
+
+    // Flush use counters for the document and for its external resource
+    // documents. (Should only be necessary for tests, where we need
+    // flushing to happen synchronously and deterministically.)
+    eIncludeExternalResources,
+  };
+
+  void ReportUseCounters(UseCounterReportKind aKind = UseCounterReportKind::eDefault);
 
   virtual void AddIntersectionObserver(
     mozilla::dom::DOMIntersectionObserver* aObserver) override;
   virtual void RemoveIntersectionObserver(
     mozilla::dom::DOMIntersectionObserver* aObserver) override;
   virtual void UpdateIntersectionObservations() override;
   virtual void ScheduleIntersectionObserverNotification() override;
   virtual void NotifyIntersectionObservers() override;