Bug 1505948: Add cache info to network profiler markers r=mstange,nwgh
☠☠ backed out by 53001d176b97 ☠ ☠
authorRandell Jesup <rjesup@jesup.org>
Wed, 14 Nov 2018 15:54:22 -0500
changeset 502925 e157b95e9b5e1872ddc30d5d0351ae6828e05bc0
parent 502924 91659baa6ddbb00282b9a3f9b9748cb25597c13e
child 502926 7a7f203680a817e22224c11a9df9a431accdae0c
push id10290
push userffxbld-merge
push dateMon, 03 Dec 2018 16:23:23 +0000
treeherdermozilla-beta@700bed2445e6 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmstange, nwgh
bugs1505948
milestone65.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 1505948: Add cache info to network profiler markers r=mstange,nwgh
netwerk/protocol/http/HttpBaseChannel.h
netwerk/protocol/http/HttpChannelChild.cpp
netwerk/protocol/http/nsHttpChannel.cpp
netwerk/protocol/http/nsHttpChannel.h
tools/profiler/core/ProfilerMarkerPayload.cpp
tools/profiler/core/platform.cpp
tools/profiler/moz.build
tools/profiler/public/GeckoProfiler.h
tools/profiler/public/ProfilerMarkerPayload.h
--- a/netwerk/protocol/http/HttpBaseChannel.h
+++ b/netwerk/protocol/http/HttpBaseChannel.h
@@ -69,16 +69,25 @@ class PerformanceStorage;
 
 class LogCollector;
 
 namespace net {
 extern mozilla::LazyLogModule gHttpLog;
 
 typedef nsTArray<Tuple<nsCString, nsCString>> ArrayOfStringPairs;
 
+enum CacheDisposition : uint8_t {
+  kCacheUnresolved = 0,
+  kCacheHit = 1,
+  kCacheHitViaReval = 2,
+  kCacheMissedViaReval = 3,
+  kCacheMissed = 4,
+  kCacheUnknown = 5
+};
+
 /*
  * This class is a partial implementation of nsIHttpChannel.  It contains code
  * shared by nsHttpChannel and HttpChannelChild.
  * - Note that this class has nothing to do with nsBaseChannel, which is an
  *   earlier effort at a base class for channels that somehow never made it all
  *   the way to the HTTP channel.
  */
 class HttpBaseChannel : public nsHashPropertyBag
--- a/netwerk/protocol/http/HttpChannelChild.cpp
+++ b/netwerk/protocol/http/HttpChannelChild.cpp
@@ -1226,16 +1226,17 @@ HttpChannelChild::OnStopRequest(const ns
 
 #ifdef MOZ_GECKO_PROFILER
   if (profiler_is_active()) {
     int32_t priority = PRIORITY_NORMAL;
     GetPriority(&priority);
     profiler_add_network_marker(mURI, priority, mChannelId, NetworkLoadType::LOAD_STOP,
                                 mLastStatusReported, TimeStamp::Now(),
                                 mTransferSize,
+                                kCacheUnknown,
                                 &mTransactionTimings);
   }
 #endif
 
   mResponseTrailers = new nsHttpHeaderArray(aResponseTrailers);
 
   DoPreOnStopRequest(channelStatus);
 
@@ -1876,17 +1877,17 @@ HttpChannelChild::Redirect1Begin(const u
   LOG(("HttpChannelChild::Redirect1Begin [this=%p]\n", this));
 
   ipc::MergeParentLoadInfoForwarder(loadInfoForwarder, mLoadInfo);
 
   nsCOMPtr<nsIURI> uri = DeserializeURI(newOriginalURI);
 
   PROFILER_ADD_NETWORK_MARKER(mURI, mPriority, channelId, NetworkLoadType::LOAD_REDIRECT,
                               mLastStatusReported, TimeStamp::Now(),
-                              0,
+                              0, kCacheUnknown,
                               &mTransactionTimings,
                               uri);
 
   if (!securityInfoSerialization.IsEmpty()) {
     NS_DeserializeObject(securityInfoSerialization,
                          getter_AddRefs(mSecurityInfo));
   }
 
@@ -2671,17 +2672,17 @@ HttpChannelChild::AsyncOpen(nsIStreamLis
   // process so that devtools can capture a stack trace at the
   // appropriate spot.  See bug 806753 for some information about why
   // other http-* notifications are disabled in child processes.
   gHttpHandler->OnOpeningRequest(this);
 
   mLastStatusReported = TimeStamp::Now();
   PROFILER_ADD_NETWORK_MARKER(mURI, mPriority, mChannelId, NetworkLoadType::LOAD_START,
                               mChannelCreationTimestamp, mLastStatusReported,
-                              0, nullptr, nullptr);
+                              0, kCacheUnknown, nullptr, nullptr);
 
   mIsPending = true;
   mWasOpened = true;
   mListener = listener;
   mListenerContext = aContext;
 
   // add ourselves to the load group.
   if (mLoadGroup)
--- a/netwerk/protocol/http/nsHttpChannel.cpp
+++ b/netwerk/protocol/http/nsHttpChannel.cpp
@@ -157,23 +157,16 @@ static uint32_t sRCWNMaxWaitMs = 500;
 
 #define WRONG_RACING_RESPONSE_SOURCE(req)                                                  \
     (mRaceCacheWithNetwork &&                                                                 \
         (((mFirstResponseSource == RESPONSE_FROM_CACHE) && (req != mCachePump)) ||         \
          ((mFirstResponseSource == RESPONSE_FROM_NETWORK) && (req != mTransactionPump))))
 
 static NS_DEFINE_CID(kStreamListenerTeeCID, NS_STREAMLISTENERTEE_CID);
 
-enum CacheDisposition {
-    kCacheHit = 1,
-    kCacheHitViaReval = 2,
-    kCacheMissedViaReval = 3,
-    kCacheMissed = 4
-};
-
 using mozilla::Telemetry::LABELS_DOCUMENT_ANALYTICS_TRACKER_FASTBLOCKED;
 
 static const struct {
   LABELS_DOCUMENT_ANALYTICS_TRACKER_FASTBLOCKED mTelemetryLabel;
   const char* mHostName;
 } gFastBlockAnalyticsProviders[] = {
   // clang-format off
   { LABELS_DOCUMENT_ANALYTICS_TRACKER_FASTBLOCKED::googleanalytics, "google-analytics.com" },
@@ -326,16 +319,17 @@ AutoRedirectVetoNotifier::ReportRedirect
 }
 
 //-----------------------------------------------------------------------------
 // nsHttpChannel <public>
 //-----------------------------------------------------------------------------
 
 nsHttpChannel::nsHttpChannel()
     : HttpAsyncAborter<nsHttpChannel>(this)
+    , mCacheDisposition(kCacheUnresolved)
     , mLogicalOffset(0)
     , mPostID(0)
     , mRequestTime(0)
     , mOfflineCacheLastModifiedTime(0)
     , mSuspendTotalTime(0)
     , mRedirectType(0)
     , mCacheOpenWithPriority(false)
     , mCacheQueueSizeWhenOpen(0)
@@ -937,16 +931,17 @@ nsHttpChannel::ContinueConnect()
                 }
             }
             rv = ReadFromCache(true);
             if (NS_FAILED(rv) && event) {
                 event->Revoke();
             }
 
             AccumulateCacheHitTelemetry(kCacheHit);
+            mCacheDisposition = kCacheHit;
 
             return rv;
         }
         if (mLoadFlags & LOAD_ONLY_FROM_CACHE) {
             // the cache contains the requested resource, but it must be
             // validated before we can reuse it.  since we are not allowed
             // to hit the net, there's nothing more to do.  the document
             // is effectively not in the cache.
@@ -2744,16 +2739,17 @@ nsHttpChannel::ContinueProcessResponse2(
         if (!mDidReval) {
             cacheDisposition = kCacheMissed;
         } else if (successfulReval) {
             cacheDisposition = kCacheHitViaReval;
         } else {
             cacheDisposition = kCacheMissedViaReval;
         }
         AccumulateCacheHitTelemetry(cacheDisposition);
+        mCacheDisposition = cacheDisposition;
 
         Telemetry::Accumulate(Telemetry::HTTP_RESPONSE_VERSION,
                               static_cast<uint32_t>(mResponseHead->Version()));
 
         if (mResponseHead->Version() == HttpVersion::v0_9) {
             // DefaultPortTopLevel = 0, DefaultPortSubResource = 1,
             // NonDefaultPortTopLevel = 2, NonDefaultPortSubResource = 3
             uint32_t v09Info = 0;
@@ -5888,17 +5884,17 @@ nsHttpChannel::ContinueProcessRedirectio
     }
 
 #ifdef MOZ_GECKO_PROFILER
     if (profiler_is_active()) {
         int32_t priority = PRIORITY_NORMAL;
         GetPriority(&priority);
         profiler_add_network_marker(mURI, priority, mChannelId, NetworkLoadType::LOAD_REDIRECT,
                                     mLastStatusReported, TimeStamp::Now(),
-                                    mLogicalOffset, nullptr,
+                                    mLogicalOffset, mCacheDisposition, nullptr,
                                     mRedirectURI);
     }
 #endif
 
     nsCOMPtr<nsIIOService> ioService;
     rv = gHttpHandler->GetIOService(getter_AddRefs(ioService));
     if (NS_FAILED(rv)) return rv;
 
@@ -6343,17 +6339,17 @@ nsHttpChannel::AsyncOpen(nsIStreamListen
     }
 #endif
 
 #ifdef MOZ_GECKO_PROFILER
     mLastStatusReported = TimeStamp::Now(); // in case we enable the profiler after AsyncOpen()
     if (profiler_is_active()) {
         profiler_add_network_marker(mURI, mPriority, mChannelId, NetworkLoadType::LOAD_START,
                                     mChannelCreationTimestamp, mLastStatusReported,
-                                    0);
+                                    0, mCacheDisposition);
     }
 #endif
 
     NS_CompareLoadInfoAndLoadContext(this);
 
 #ifdef DEBUG
     AssertPrivateBrowsingId();
 #endif
@@ -7733,17 +7729,17 @@ nsHttpChannel::OnStopRequest(nsIRequest 
             // These do allocations/frees/etc; avoid if not active
             nsCOMPtr<nsIURI> uri;
             GetURI(getter_AddRefs(uri));
             int32_t priority = PRIORITY_NORMAL;
             GetPriority(&priority);
             profiler_add_network_marker(uri, priority, mChannelId, NetworkLoadType::LOAD_STOP,
                                         mLastStatusReported, TimeStamp::Now(),
                                         mLogicalOffset,
-                                        &mTransactionTimings);
+                                        mCacheDisposition, &mTransactionTimings, nullptr);
         }
 #endif
 
         // handle auth retry...
         if (authRetry) {
             mAuthRetryPending = false;
             status = DoAuthRetry(conn);
             if (NS_SUCCEEDED(status))
--- a/netwerk/protocol/http/nsHttpChannel.h
+++ b/netwerk/protocol/http/nsHttpChannel.h
@@ -281,16 +281,18 @@ public:
     void SetConnectionInfo(nsHttpConnectionInfo *); // clones the argument
     void SetTransactionObserver(TransactionObserver *arg) { mTransactionObserver = arg; }
     TransactionObserver *GetTransactionObserver() { return mTransactionObserver; }
 
     typedef MozPromise<nsCOMPtr<nsITabParent>, nsresult, false> TabPromise;
     already_AddRefed<TabPromise> TakeRedirectTabPromise() { return mRedirectTabPromise.forget(); }
     uint64_t CrossProcessRedirectIdentifier() { return mCrossProcessRedirectIdentifier; }
 
+    CacheDisposition mCacheDisposition;
+
 protected:
     virtual ~nsHttpChannel();
 
 private:
     typedef nsresult (nsHttpChannel::*nsContinueRedirectionFunc)(nsresult result);
 
     bool     RequestIsConditional();
     void HandleContinueCancelledByTrackingProtection();
--- a/tools/profiler/core/ProfilerMarkerPayload.cpp
+++ b/tools/profiler/core/ProfilerMarkerPayload.cpp
@@ -7,16 +7,17 @@
 
 #include "GeckoProfiler.h"
 #include "ProfilerBacktrace.h"
 #include "ProfilerMarkerPayload.h"
 #include "gfxASurface.h"
 #include "Layers.h"
 #include "mozilla/Sprintf.h"
 #include "mozilla/Maybe.h"
+#include "mozilla/net/HttpBaseChannel.h"
 
 using namespace mozilla;
 
 static void MOZ_ALWAYS_INLINE
 WriteTime(SpliceableJSONWriter& aWriter,
           const TimeStamp& aProcessStartTime,
           const TimeStamp& aTime, const char *aName)
 {
@@ -151,27 +152,50 @@ static const char *GetNetworkState(Netwo
     case NetworkLoadType::LOAD_STOP:
       return "STATUS_STOP";
     case NetworkLoadType::LOAD_REDIRECT:
       return "STATUS_REDIRECT";
   }
   return "";
 }
 
+static const char *GetCacheState(mozilla::net::CacheDisposition aCacheDisposition)
+{
+  switch (aCacheDisposition) {
+    case mozilla::net::kCacheUnresolved:
+      return "Unresolved";
+    case mozilla::net::kCacheHit:
+      return "Hit";
+    case mozilla::net::kCacheHitViaReval:
+      return "HitViaReval";
+    case mozilla::net::kCacheMissedViaReval:
+      return "MissedViaReval";
+    case mozilla::net::kCacheMissed:
+      return "Missed";
+    case mozilla::net::kCacheUnknown:
+    default:
+      return nullptr;
+  }
+  return nullptr;
+}
 
 void
 NetworkMarkerPayload::StreamPayload(SpliceableJSONWriter& aWriter,
                                     const TimeStamp& aProcessStartTime,
                                     UniqueStacks& aUniqueStacks)
 {
   StreamCommonProps("Network", aWriter, aProcessStartTime, aUniqueStacks);
   aWriter.IntProperty("id", mID);
   const char *typeString = GetNetworkState(mType);
+  const char *cacheString = GetCacheState(mCacheDisposition);
   // want to use aUniqueStacks.mUniqueStrings->WriteElement(aWriter, typeString);
   aWriter.StringProperty("status", typeString);
+  if (cacheString) {
+    aWriter.StringProperty("cache", cacheString);
+  }
   aWriter.IntProperty("pri", mPri);
   if (mCount > 0) {
     aWriter.IntProperty("count", mCount);
   }
   if (mURI) {
     aWriter.StringProperty("URI", mURI.get());
   }
   if (mRedirectURI) {
--- a/tools/profiler/core/platform.cpp
+++ b/tools/profiler/core/platform.cpp
@@ -3760,16 +3760,17 @@ profiler_add_marker(const char* aMarkerN
 void
 profiler_add_network_marker(nsIURI* aURI,
                             int32_t aPriority,
                             uint64_t aChannelId,
                             NetworkLoadType aType,
                             mozilla::TimeStamp aStart,
                             mozilla::TimeStamp aEnd,
                             int64_t aCount,
+                            mozilla::net::CacheDisposition aCacheDisposition,
                             const mozilla::net::TimingStruct* aTimings,
                             nsIURI* aRedirectURI)
 {
   if (!profiler_is_active()) {
     return;
   }
   // These do allocations/frees/etc; avoid if not active
   nsAutoCString spec;
@@ -3787,16 +3788,17 @@ profiler_add_network_marker(nsIURI* aURI
   profiler_add_marker(name,
                       MakeUnique<NetworkMarkerPayload>(static_cast<int64_t>(aChannelId),
                                                        PromiseFlatCString(spec).get(),
                                                        aType,
                                                        aStart,
                                                        aEnd,
                                                        aPriority,
                                                        aCount,
+                                                       aCacheDisposition,
                                                        aTimings,
                                                        PromiseFlatCString(redirect_spec).get()));
 }
 
 // This logic needs to add a marker for a different thread, so we actually need
 // to lock here.
 void
 profiler_add_marker_for_thread(int aThreadId,
--- a/tools/profiler/moz.build
+++ b/tools/profiler/moz.build
@@ -90,16 +90,18 @@ if CONFIG['MOZ_GECKO_PROFILER']:
             'core/shared-libraries-win32.cc',
         ]
 
     LOCAL_INCLUDES += [
         '/caps',
         '/docshell/base',
         '/ipc/chromium/src',
         '/mozglue/linker',
+        '/netwerk/base',
+        '/netwerk/protocol/http',
         '/toolkit/crashreporter/google-breakpad/src',
         '/tools/profiler/core/',
         '/tools/profiler/gecko/',
         '/xpcom/base',
     ]
 
     if CONFIG['OS_TARGET'] == 'Android':
         DEFINES['ANDROID_NDK_MAJOR_VERSION'] = CONFIG['ANDROID_NDK_MAJOR_VERSION']
--- a/tools/profiler/public/GeckoProfiler.h
+++ b/tools/profiler/public/GeckoProfiler.h
@@ -88,16 +88,17 @@
 #endif
 
 class ProfilerBacktrace;
 class ProfilerMarkerPayload;
 class SpliceableJSONWriter;
 namespace mozilla {
 namespace net {
 struct TimingStruct;
+enum CacheDisposition : uint8_t;
 }
 }
 class nsIURI;
 
 namespace mozilla {
 class MallocAllocPolicy;
 template <class T, size_t MinInlineCapacity, class AllocPolicy> class Vector;
 class TimeStamp;
@@ -602,26 +603,27 @@ void profiler_add_marker_for_thread(int 
                                     mozilla::UniquePtr<ProfilerMarkerPayload> aPayload);
 
 enum class NetworkLoadType {
   LOAD_START,
   LOAD_STOP,
   LOAD_REDIRECT
 };
 
-#define PROFILER_ADD_NETWORK_MARKER(uri, pri, channel, type, start, end, count, timings, redirect) \
-  profiler_add_network_marker(uri, pri, channel, type, start, end, count, timings, redirect)
+#define PROFILER_ADD_NETWORK_MARKER(uri, pri, channel, type, start, end, count, cache, timings, redirect) \
+  profiler_add_network_marker(uri, pri, channel, type, start, end, count, cache, timings, redirect)
 
 void profiler_add_network_marker(nsIURI* aURI,
                                  int32_t aPriority,
                                  uint64_t aChannelId,
                                  NetworkLoadType aType,
                                  mozilla::TimeStamp aStart,
                                  mozilla::TimeStamp aEnd,
                                  int64_t aCount,
+                                 mozilla::net::CacheDisposition aCacheDisposition,
                                  const mozilla::net::TimingStruct* aTimings = nullptr,
                                  nsIURI* aRedirectURI = nullptr);
 
 
 enum TracingKind {
   TRACING_EVENT,
   TRACING_INTERVAL_START,
   TRACING_INTERVAL_END,
--- a/tools/profiler/public/ProfilerMarkerPayload.h
+++ b/tools/profiler/public/ProfilerMarkerPayload.h
@@ -257,43 +257,46 @@ class NetworkMarkerPayload : public Prof
 public:
   NetworkMarkerPayload(int64_t aID,
                        const char* aURI,
                        NetworkLoadType aType,
                        const mozilla::TimeStamp& aStartTime,
                        const mozilla::TimeStamp& aEndTime,
                        int32_t aPri,
                        int64_t aCount,
+                       mozilla::net::CacheDisposition aCacheDisposition,
                        const mozilla::net::TimingStruct* aTimings = nullptr,
                        const char* aRedirectURI = nullptr)
     : ProfilerMarkerPayload(aStartTime, aEndTime, mozilla::Nothing())
     , mID(aID)
     , mURI(aURI ? strdup(aURI) : nullptr)
     , mRedirectURI(aRedirectURI && (strlen(aRedirectURI) > 0)
                      ? strdup(aRedirectURI)
                      : nullptr)
     , mType(aType)
     , mPri(aPri)
     , mCount(aCount)
+    , mCacheDisposition(aCacheDisposition)
   {
     if (aTimings) {
       mTimings = *aTimings;
     }
   }
 
   DECL_STREAM_PAYLOAD
 
 private:
   int64_t mID;
   mozilla::UniqueFreePtr<char> mURI;
   mozilla::UniqueFreePtr<char> mRedirectURI;
   NetworkLoadType mType;
   int32_t mPri;
   int64_t mCount;
   mozilla::net::TimingStruct mTimings;
+  mozilla::net::CacheDisposition mCacheDisposition;
 };
 
 class ScreenshotPayload : public ProfilerMarkerPayload
 {
 public:
   explicit ScreenshotPayload(mozilla::TimeStamp aTimeStamp,
                              nsCString&& aScreenshotDataURL,
                              const mozilla::gfx::IntSize& aWindowSize,