Bug 1359833 - Part 10. Add telemetry to track how often imgRequestProxy needs to dispatch. r=tnikkel data-r=bsmedberg
authorAndrew Osmond <aosmond@mozilla.com>
Wed, 19 Jul 2017 14:15:12 -0400
changeset 418443 09deb3ef1f63354a1d4716826c4ccbec1d730db4
parent 418442 b44a7fd7a4175d0e705245ec74267e2d16d8cc6f
child 418444 5eeb5b9f118b819bebb8ef8cc2c06cdb6b412761
push id7566
push usermtabara@mozilla.com
push dateWed, 02 Aug 2017 08:25:16 +0000
treeherdermozilla-beta@86913f512c3c [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerstnikkel
bugs1359833
milestone56.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 1359833 - Part 10. Add telemetry to track how often imgRequestProxy needs to dispatch. r=tnikkel data-r=bsmedberg
image/imgRequestProxy.cpp
image/imgRequestProxy.h
toolkit/components/telemetry/Histograms.json
--- a/image/imgRequestProxy.cpp
+++ b/image/imgRequestProxy.cpp
@@ -10,16 +10,17 @@
 #include "imgLoader.h"
 #include "Image.h"
 #include "ImageOps.h"
 #include "nsError.h"
 #include "nsCRTGlue.h"
 #include "imgINotificationObserver.h"
 #include "mozilla/dom/TabGroup.h"       // for TabGroup
 #include "mozilla/dom/DocGroup.h"       // for DocGroup
+#include "mozilla/Telemetry.h"          // for Telemetry
 
 using namespace mozilla::image;
 
 // The split of imgRequestProxy and imgRequestProxyStatic means that
 // certain overridden functions need to be usable in the destructor.
 // Since virtual functions can't be used in that way, this class
 // provides a behavioural trait for each class to use instead.
 class ProxyBehaviour
@@ -111,28 +112,45 @@ imgRequestProxy::imgRequestProxy() :
   mListener(nullptr),
   mLoadFlags(nsIRequest::LOAD_NORMAL),
   mLockCount(0),
   mAnimationConsumers(0),
   mCanceled(false),
   mIsInLoadGroup(false),
   mListenerIsStrongRef(false),
   mDecodeRequested(false),
-  mDeferNotifications(false)
+  mDeferNotifications(false),
+  mHadListener(false),
+  mHadDispatch(false)
 {
   /* member initializers and constructor code */
 
 }
 
 imgRequestProxy::~imgRequestProxy()
 {
   /* destructor code */
   NS_PRECONDITION(!mListener,
                   "Someone forgot to properly cancel this request!");
 
+  // If we had a listener, that means we would have issued notifications. With
+  // bug 1359833, we added support for main thread scheduler groups. Each
+  // imgRequestProxy may have its own associated listener, document and/or
+  // scheduler group. Typically most imgRequestProxy belong to the same
+  // document, or have no listener, which means we will want to execute all main
+  // thread code in that shared scheduler group. Less frequently, there may be
+  // multiple imgRequests and they have separate documents, which means that
+  // when we issue state notifications, some or all need to be dispatched to the
+  // appropriate scheduler group for each request. This should be rare, so we
+  // want to monitor the frequency of dispatching in the wild.
+  if (mHadListener) {
+    mozilla::Telemetry::Accumulate(mozilla::Telemetry::IMAGE_REQUEST_DISPATCHED,
+                                   mHadDispatch);
+  }
+
   // Unlock the image the proper number of times if we're holding locks on
   // it. Note that UnlockImage() decrements mLockCount each time it's called.
   while (mLockCount) {
     UnlockImage();
   }
 
   ClearAnimationConsumers();
 
@@ -169,16 +187,17 @@ imgRequestProxy::Init(imgRequest* aOwner
   MOZ_ASSERT(mAnimationConsumers == 0, "Cannot have animation before Init");
 
   mBehaviour->SetOwner(aOwner);
   mListener = aObserver;
   // Make sure to addref mListener before the AddToOwner call below, since
   // that call might well want to release it if the imgRequest has
   // already seen OnStopRequest.
   if (mListener) {
+    mHadListener = true;
     mListenerIsStrongRef = true;
     NS_ADDREF(mListener);
   }
   mLoadGroup = aLoadGroup;
   mURI = aURI;
 
   // Note: AddToOwner won't send all the On* notifications immediately
   AddToOwner(aLoadingDocument);
@@ -269,16 +288,17 @@ imgRequestProxy::GetEventTarget() const
 void
 imgRequestProxy::Dispatch(already_AddRefed<nsIRunnable> aEvent)
 {
   LOG_FUNC(gImgLog, "imgRequestProxy::Dispatch");
 
   MOZ_ASSERT(mListener);
   MOZ_ASSERT(mEventTarget);
 
+  mHadDispatch = true;
   mEventTarget->Dispatch(Move(aEvent), NS_DISPATCH_NORMAL);
 }
 
 void
 imgRequestProxy::AddToOwner(nsIDocument* aLoadingDocument)
 {
   // An imgRequestProxy can be initialized with neither a listener nor a
   // document. The caller could follow up later by cloning the canonical
--- a/image/imgRequestProxy.h
+++ b/image/imgRequestProxy.h
@@ -228,24 +228,26 @@ private:
 
   nsCOMPtr<nsILoadGroup> mLoadGroup;
   RefPtr<mozilla::dom::TabGroup> mTabGroup;
   nsCOMPtr<nsIEventTarget> mEventTarget;
 
   nsLoadFlags mLoadFlags;
   uint32_t    mLockCount;
   uint32_t    mAnimationConsumers;
-  bool mCanceled;
-  bool mIsInLoadGroup;
-  bool mListenerIsStrongRef;
-  bool mDecodeRequested;
+  bool mCanceled : 1;
+  bool mIsInLoadGroup : 1;
+  bool mListenerIsStrongRef : 1;
+  bool mDecodeRequested : 1;
 
   // Whether we want to defer our notifications by the non-virtual Observer
   // interfaces as image loads proceed.
-  bool mDeferNotifications;
+  bool mDeferNotifications : 1;
+  bool mHadListener : 1;
+  bool mHadDispatch : 1;
 };
 
 // Used for static image proxies for which no requests are available, so
 // certain behaviours must be overridden to compensate.
 class imgRequestProxyStatic : public imgRequestProxy
 {
 
 public:
--- a/toolkit/components/telemetry/Histograms.json
+++ b/toolkit/components/telemetry/Histograms.json
@@ -1785,16 +1785,24 @@
     "alert_emails": ["gfx-telemetry-alerts@mozilla.com"],
     "expires_in_version": "never",
     "kind": "exponential",
     "low": 500,
     "high": 50000000,
     "n_buckets": 50,
     "description": "PNG image decode speed (Kbytes/sec)"
   },
+  "IMAGE_REQUEST_DISPATCHED": {
+    "record_in_processes": ["main", "content"],
+    "alert_emails": ["gfx-telemetry-alerts@mozilla.com","aosmond@mozilla.com"],
+    "expires_in_version": "62",
+    "kind": "boolean",
+    "description": "Track how many image requests required event dispatching because we were unable to predict the correct scheduler group: true if the request required dispatching. See image/imgRequestProxy.cpp for details.",
+    "bug_numbers": [1359833]
+  },
   "CANVAS_2D_USED": {
     "record_in_processes": ["main", "content"],
     "expires_in_version": "never",
     "kind": "boolean",
     "description": "2D canvas used"
   },
   "CANVAS_WEBGL_ACCL_FAILURE_ID": {
     "record_in_processes": ["main", "content", "gpu"],