Bug 1417976 - Part 2: Include DocShell IDs to marker payloads r?mstange draft
authorNazım Can Altınova <canaltinova@gmail.com>
Tue, 24 Jul 2018 14:44:21 +0200
changeset 825817 b6670234c07a8fa0e9c55171a3fd71510c9270b4
parent 825816 05bf20daf6dff853fc8e77e9d449849b5eff4c65
child 825818 7e16830c97bcbbb271aba5879aa48dd63e107421
push id118183
push userbmo:canaltinova@gmail.com
push dateThu, 02 Aug 2018 13:16:45 +0000
reviewersmstange
bugs1417976
milestone63.0a1
Bug 1417976 - Part 2: Include DocShell IDs to marker payloads r?mstange MozReview-Commit-ID: AML1ESUnFlu
dom/base/nsDOMNavigationTiming.cpp
dom/events/EventListenerManager.cpp
dom/performance/Performance.cpp
layout/base/AutoProfilerStyleMarker.h
layout/base/PresShell.cpp
layout/base/nsRefreshDriver.cpp
layout/generic/nsGfxScrollFrame.cpp
layout/painting/nsDisplayList.cpp
tools/profiler/core/platform.cpp
tools/profiler/public/GeckoProfiler.h
tools/profiler/public/ProfilerMarkerPayload.h
tools/profiler/tests/gtest/GeckoProfiler.cpp
--- a/dom/base/nsDOMNavigationTiming.cpp
+++ b/dom/base/nsDOMNavigationTiming.cpp
@@ -94,35 +94,38 @@ nsDOMNavigationTiming::NotifyUnloadAccep
   mUnloadStart = mBeforeUnloadStart;
   mUnloadedURI = aOldURI;
 }
 
 void
 nsDOMNavigationTiming::NotifyUnloadEventStart()
 {
   mUnloadStart = TimeStamp::Now();
-  PROFILER_TRACING("Navigation", "Unload", TRACING_INTERVAL_START);
+  PROFILER_TRACING("Navigation", "Unload", TRACING_INTERVAL_START,
+    mDocShell ? Some(mDocShell->HistoryID()) : Nothing());
 }
 
 void
 nsDOMNavigationTiming::NotifyUnloadEventEnd()
 {
   mUnloadEnd = TimeStamp::Now();
-  PROFILER_TRACING("Navigation", "Unload", TRACING_INTERVAL_END);
+  PROFILER_TRACING("Navigation", "Unload", TRACING_INTERVAL_END,
+    mDocShell ? Some(mDocShell->HistoryID()) : Nothing());
 }
 
 void
 nsDOMNavigationTiming::NotifyLoadEventStart()
 {
   if (!mLoadEventStart.IsNull()) {
     return;
   }
   mLoadEventStart = TimeStamp::Now();
 
-  PROFILER_TRACING("Navigation", "Load", TRACING_INTERVAL_START);
+  PROFILER_TRACING("Navigation", "Load", TRACING_INTERVAL_START,
+    mDocShell ? Some(mDocShell->HistoryID()) : Nothing());
 
   if (IsTopLevelContentDocumentInContentProcess()) {
     TimeStamp now = TimeStamp::Now();
 
     Telemetry::AccumulateTimeDelta(Telemetry::TIME_TO_LOAD_EVENT_START_MS,
                                    mNavigationStart,
                                    now);
 
@@ -143,17 +146,18 @@ nsDOMNavigationTiming::NotifyLoadEventSt
 void
 nsDOMNavigationTiming::NotifyLoadEventEnd()
 {
   if (!mLoadEventEnd.IsNull()) {
     return;
   }
   mLoadEventEnd = TimeStamp::Now();
 
-  PROFILER_TRACING("Navigation", "Load", TRACING_INTERVAL_END);
+  PROFILER_TRACING("Navigation", "Load", TRACING_INTERVAL_END,
+    mDocShell ? Some(mDocShell->HistoryID()) : Nothing());
 
   if (IsTopLevelContentDocumentInContentProcess()) {
     Telemetry::AccumulateTimeDelta(Telemetry::TIME_TO_LOAD_EVENT_END_MS,
                                    mNavigationStart);
   }
 }
 
 void
@@ -207,17 +211,18 @@ nsDOMNavigationTiming::NotifyDOMContentL
 {
   if (!mDOMContentLoadedEventStart.IsNull()) {
     return;
   }
 
   mLoadedURI = aURI;
   mDOMContentLoadedEventStart = TimeStamp::Now();
 
-  PROFILER_TRACING("Navigation", "DOMContentLoaded", TRACING_INTERVAL_START);
+  PROFILER_TRACING("Navigation", "DOMContentLoaded", TRACING_INTERVAL_START,
+    mDocShell ? Some(mDocShell->HistoryID()) : Nothing());
 
   if (IsTopLevelContentDocumentInContentProcess()) {
     TimeStamp now = TimeStamp::Now();
 
     Telemetry::AccumulateTimeDelta(Telemetry::TIME_TO_DOM_CONTENT_LOADED_START_MS,
                                    mNavigationStart,
                                    now);
 
@@ -240,17 +245,18 @@ nsDOMNavigationTiming::NotifyDOMContentL
 {
   if (!mDOMContentLoadedEventEnd.IsNull()) {
     return;
   }
 
   mLoadedURI = aURI;
   mDOMContentLoadedEventEnd = TimeStamp::Now();
 
-  PROFILER_TRACING("Navigation", "DOMContentLoaded", TRACING_INTERVAL_END);
+  PROFILER_TRACING("Navigation", "DOMContentLoaded", TRACING_INTERVAL_END,
+    mDocShell ? Some(mDocShell->HistoryID()) : Nothing());
 
   if (IsTopLevelContentDocumentInContentProcess()) {
     Telemetry::AccumulateTimeDelta(Telemetry::TIME_TO_DOM_CONTENT_LOADED_END_MS,
                                    mNavigationStart);
   }
 }
 
 void
--- a/dom/events/EventListenerManager.cpp
+++ b/dom/events/EventListenerManager.cpp
@@ -29,16 +29,17 @@
 #include "mozilla/TimeStamp.h"
 
 #include "EventListenerService.h"
 #include "GeckoProfiler.h"
 #include "nsCOMArray.h"
 #include "nsCOMPtr.h"
 #include "nsContentUtils.h"
 #include "nsDOMCID.h"
+#include "nsDocShell.h"
 #include "nsError.h"
 #include "nsGkAtoms.h"
 #include "nsIContent.h"
 #include "nsIContentSecurityPolicy.h"
 #include "nsIDocument.h"
 #include "nsIDOMEventListener.h"
 #include "nsIScriptGlobalObject.h"
 #include "nsISupports.h"
@@ -1307,27 +1308,33 @@ EventListenerManager::HandleEventInterna
                 "EventListenerManager::HandleEventInternal", OTHER, typeStr);
 
               uint16_t phase = (*aDOMEvent)->EventPhase();
               profiler_add_marker(
                 "DOMEvent",
                 MakeUnique<DOMEventMarkerPayload>(typeStr, phase,
                                                   aEvent->mTimeStamp,
                                                   "DOMEvent",
-                                                  TRACING_INTERVAL_START));
+                                                  TRACING_INTERVAL_START,
+                                                  docShell
+                                                    ? Some(docShell->HistoryID())
+                                                    : Nothing()));
 
               rv = HandleEventSubType(listener, *aDOMEvent, aCurrentTarget);
 
               phase = (*aDOMEvent)->EventPhase();
               profiler_add_marker(
                 "DOMEvent",
                 MakeUnique<DOMEventMarkerPayload>(typeStr, phase,
                                                   aEvent->mTimeStamp,
                                                   "DOMEvent",
-                                                  TRACING_INTERVAL_END));
+                                                  TRACING_INTERVAL_END,
+                                                  docShell
+                                                    ? Some(docShell->HistoryID())
+                                                    : Nothing()));
             } else
 #endif
             {
               rv = HandleEventSubType(listener, *aDOMEvent, aCurrentTarget);
             }
             if (innerWindow) {
               Unused << innerWindow->SetEvent(oldWindowEvent);
             }
--- a/dom/performance/Performance.cpp
+++ b/dom/performance/Performance.cpp
@@ -2,16 +2,17 @@
 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "Performance.h"
 
 #include "GeckoProfiler.h"
+#include "nsIDocShell.h"
 #include "nsRFPService.h"
 #include "PerformanceEntry.h"
 #include "PerformanceMainThread.h"
 #include "PerformanceMark.h"
 #include "PerformanceMeasure.h"
 #include "PerformanceObserver.h"
 #include "PerformanceResourceTiming.h"
 #include "PerformanceService.h"
@@ -241,19 +242,27 @@ Performance::Mark(const nsAString& aName
   }
 
   RefPtr<PerformanceMark> performanceMark =
     new PerformanceMark(GetParentObject(), aName, Now());
   InsertUserEntry(performanceMark);
 
 #ifdef MOZ_GECKO_PROFILER
   if (profiler_is_active()) {
+    Maybe<nsID> docshellId;
+    nsCOMPtr<EventTarget> et = do_QueryInterface(GetOwner());
+    nsCOMPtr<nsIDocShell> docshell = nsContentUtils::GetDocShellForEventTarget(et);
+    if (docshell) {
+      docshellId = Some(docshell->HistoryID());
+    } else {
+      docshellId = Nothing();
+    }
     profiler_add_marker(
       "UserTiming",
-      MakeUnique<UserTimingMarkerPayload>(aName, TimeStamp::Now()));
+      MakeUnique<UserTimingMarkerPayload>(aName, TimeStamp::Now(), docshellId));
   }
 #endif
 }
 
 void
 Performance::ClearMarks(const Optional<nsAString>& aName)
 {
   ClearUserEntries(aName, NS_LITERAL_STRING("mark"));
@@ -339,20 +348,28 @@ Performance::Measure(const nsAString& aN
     if (aStartMark.WasPassed()) {
       startMark.emplace(aStartMark.Value());
     }
     Maybe<nsString> endMark;
     if (aEndMark.WasPassed()) {
       endMark.emplace(aEndMark.Value());
     }
 
+    Maybe<nsID> docshellId;
+    nsCOMPtr<EventTarget> et = do_QueryInterface(GetOwner());
+    nsCOMPtr<nsIDocShell> docshell = nsContentUtils::GetDocShellForEventTarget(et);
+    if (docshell) {
+      docshellId = Some(docshell->HistoryID());
+    } else {
+      docshellId = Nothing();
+    }
     profiler_add_marker(
       "UserTiming",
       MakeUnique<UserTimingMarkerPayload>(aName, startMark, endMark,
-                                          startTimeStamp, endTimeStamp));
+                                          startTimeStamp, endTimeStamp, docshellId));
   }
 #endif
 }
 
 void
 Performance::ClearMeasures(const Optional<nsAString>& aName)
 {
   ClearUserEntries(aName, NS_LITERAL_STRING("measure"));
--- a/layout/base/AutoProfilerStyleMarker.h
+++ b/layout/base/AutoProfilerStyleMarker.h
@@ -13,20 +13,22 @@
 #include "GeckoProfiler.h"
 #include "ProfilerMarkerPayload.h"
 
 namespace mozilla {
 
 class MOZ_RAII AutoProfilerStyleMarker
 {
 public:
-  explicit AutoProfilerStyleMarker(UniqueProfilerBacktrace aCause)
+  explicit AutoProfilerStyleMarker(UniqueProfilerBacktrace aCause,
+                                   const Maybe<nsID>& aDocshellId)
     : mActive(profiler_is_active())
     , mStartTime(TimeStamp::Now())
     , mCause(std::move(aCause))
+    , mDocshellId(aDocshellId)
   {
     if (!mActive) {
       return;
     }
     MOZ_ASSERT(!ServoTraversalStatistics::sActive,
                "Nested AutoProfilerStyleMarker");
     ServoTraversalStatistics::sSingleton = ServoTraversalStatistics();
     ServoTraversalStatistics::sActive = true;
@@ -35,20 +37,21 @@ public:
   ~AutoProfilerStyleMarker()
   {
     if (!mActive) {
       return;
     }
     ServoTraversalStatistics::sActive = false;
     profiler_add_marker("Styles", MakeUnique<StyleMarkerPayload>(
       mStartTime, TimeStamp::Now(), std::move(mCause),
-      ServoTraversalStatistics::sSingleton));
+      ServoTraversalStatistics::sSingleton, mDocshellId));
   }
 
 private:
   bool mActive;
   TimeStamp mStartTime;
   UniqueProfilerBacktrace mCause;
+  Maybe<nsID> mDocshellId;
 };
 
 } // namespace mozilla
 
 #endif // mozilla_AutoProfilerStyleMarker_h
--- a/layout/base/PresShell.cpp
+++ b/layout/base/PresShell.cpp
@@ -3817,17 +3817,18 @@ PresShell::ScheduleViewManagerFlush(Pain
     presContext->RefreshDriver()->ScheduleViewManagerFlush();
   }
   SetNeedLayoutFlush();
 }
 
 void
 nsIPresShell::DispatchSynthMouseMove(WidgetGUIEvent* aEvent)
 {
-  AUTO_PROFILER_TRACING("Paint", "DispatchSynthMouseMove");
+  AUTO_PROFILER_TRACING_WITH_DOCSHELL("Paint", "DispatchSynthMouseMove",
+    mPresContext->GetDocShell()->HistoryID());
   nsEventStatus status = nsEventStatus_eIgnore;
   nsView* targetView = nsView::GetViewFor(aEvent->mWidget);
   if (!targetView)
     return;
   targetView->GetViewManager()->DispatchEvent(aEvent, targetView, &status);
 }
 
 void
@@ -4278,17 +4279,19 @@ PresShell::DoFlushPendingNotifications(m
       if (aFlush.mFlushAnimations && mPresContext->EffectCompositor()) {
         mPresContext->EffectCompositor()->PostRestyleForThrottledAnimations();
       }
 
       // The FlushResampleRequests() above flushed style changes.
       if (!mIsDestroying) {
         nsAutoScriptBlocker scriptBlocker;
 #ifdef MOZ_GECKO_PROFILER
-        AutoProfilerStyleMarker tracingStyleFlush(std::move(mStyleCause));
+        nsCOMPtr<nsIDocShell> docShell = mPresContext->GetDocShell();
+        AutoProfilerStyleMarker tracingStyleFlush(std::move(mStyleCause),
+          docShell ? Some(docShell->HistoryID()) : Nothing());
 #endif
 
         mPresContext->RestyleManager()->ProcessPendingRestyles();
       }
     }
 
     // Process whatever XBL constructors those restyles queued up.  This
     // ensures that onload doesn't fire too early and that we won't do extra
@@ -4302,17 +4305,19 @@ PresShell::DoFlushPendingNotifications(m
     // In particular, reflow depends on style being completely up to
     // date.  If it's not, then style reparenting, which can
     // happen during reflow, might suddenly pick up the new rules and
     // we'll end up with frames whose style doesn't match the frame
     // type.
     if (!mIsDestroying) {
       nsAutoScriptBlocker scriptBlocker;
 #ifdef MOZ_GECKO_PROFILER
-      AutoProfilerStyleMarker tracingStyleFlush(std::move(mStyleCause));
+      nsCOMPtr<nsIDocShell> docShell = mPresContext->GetDocShell();
+      AutoProfilerStyleMarker tracingStyleFlush(std::move(mStyleCause),
+        docShell ? Some(docShell->HistoryID()) : Nothing());
 #endif
 
       mPresContext->RestyleManager()->ProcessPendingRestyles();
       // Clear mNeedStyleFlush here agagin to make this flag work properly for
       // optimization since the flag might have set in ProcessPendingRestyles().
       mNeedStyleFlush = false;
     }
 
@@ -4324,18 +4329,20 @@ PresShell::DoFlushPendingNotifications(m
     // worry about them.  They can't be triggered during reflow, so we should
     // be good.
 
     if (flushType >= (SuppressInterruptibleReflows()
                         ? FlushType::Layout
                         : FlushType::InterruptibleLayout) &&
         !mIsDestroying) {
 #ifdef MOZ_GECKO_PROFILER
+      nsCOMPtr<nsIDocShell> docShell = mPresContext->GetDocShell();
       AutoProfilerTracing tracingLayoutFlush("Paint", "Reflow",
-                                              std::move(mReflowCause));
+                                             std::move(mReflowCause),
+                                             docShell ? Some(docShell->HistoryID()) : Nothing());
       mReflowCause = nullptr;
 #endif
       didLayoutFlush = true;
       mFrameConstructor->RecalcQuotesAndCounters();
       viewManager->FlushDelayedResize(true);
       if (ProcessReflowCommands(flushType < FlushType::Layout) &&
           mContentToScrollTo) {
         // We didn't get interrupted.  Go ahead and scroll to our content
--- a/layout/base/nsRefreshDriver.cpp
+++ b/layout/base/nsRefreshDriver.cpp
@@ -1722,17 +1722,17 @@ nsRefreshDriver::RunFrameRequestCallback
   for (nsIDocument* doc : mFrameRequestCallbackDocs) {
     TakeFrameRequestCallbacksFrom(doc, frameRequestCallbacks);
   }
 
   // Reset mFrameRequestCallbackDocs so they can be readded as needed.
   mFrameRequestCallbackDocs.Clear();
 
   if (!frameRequestCallbacks.IsEmpty()) {
-    AUTO_PROFILER_TRACING("Paint", "Scripts");
+    AUTO_PROFILER_TRACING_WITH_DOCSHELL("Paint", "Scripts", GetDocShell(mPresContext)->HistoryID());
     for (const DocumentFrameCallbacks& docCallbacks : frameRequestCallbacks) {
       // XXXbz Bug 863140: GetInnerWindow can return the outer
       // window in some cases.
       nsPIDOMWindowInner* innerWindow =
         docCallbacks.mDocument->GetInnerWindow();
       DOMHighResTimeStamp timeStamp = 0;
       if (innerWindow) {
         mozilla::dom::Performance* perf = innerWindow->GetPerformance();
--- a/layout/generic/nsGfxScrollFrame.cpp
+++ b/layout/generic/nsGfxScrollFrame.cpp
@@ -4967,26 +4967,34 @@ ScrollFrameHelper::ScrollEndEvent::Run()
     mHelper->FireScrollEndEvent();
   }
   return NS_OK;
 }
 
 void
 ScrollFrameHelper::FireScrollEvent()
 {
-  AUTO_PROFILER_TRACING("Paint", "FireScrollEvent");
+  nsIContent* content = mOuter->GetContent();
+  nsPresContext* prescontext = mOuter->PresContext();
+#ifdef MOZ_GECKO_PROFILER
+  nsCOMPtr<nsIDocShell> docShell = prescontext->GetDocShell();
+  if (docShell) {
+    AUTO_PROFILER_TRACING_WITH_DOCSHELL("Paint", "FireScrollEvent", docShell->HistoryID());
+  } else {
+    AUTO_PROFILER_TRACING("Paint", "FireScrollEvent");
+  }
+#endif
+
   MOZ_ASSERT(mScrollEvent);
   mScrollEvent->Revoke();
   mScrollEvent = nullptr;
 
   ActiveLayerTracker::SetCurrentScrollHandlerFrame(mOuter);
   WidgetGUIEvent event(true, eScroll, nullptr);
   nsEventStatus status = nsEventStatus_eIgnore;
-  nsIContent* content = mOuter->GetContent();
-  nsPresContext* prescontext = mOuter->PresContext();
   // Fire viewport scroll events at the document (where they
   // will bubble to the window)
   mozilla::layers::ScrollLinkedEffectDetector detector(content->GetComposedDoc());
   if (mIsRoot) {
     nsIDocument* doc = content->GetUncomposedDoc();
     if (doc) {
       EventDispatcher::Dispatch(doc, prescontext, &event, nullptr,  &status);
     }
--- a/layout/painting/nsDisplayList.cpp
+++ b/layout/painting/nsDisplayList.cpp
@@ -2493,17 +2493,24 @@ nsDisplayList::BuildLayers(nsDisplayList
   layerBuilder->Init(aBuilder, aLayerManager);
 
   if (aFlags & PAINT_COMPRESSED) {
     layerBuilder->SetLayerTreeCompressionMode();
   }
 
   RefPtr<ContainerLayer> root;
   {
-    AUTO_PROFILER_TRACING("Paint", "LayerBuilding");
+#ifdef MOZ_GECKO_PROFILER
+    nsCOMPtr<nsIDocShell> docShell = presContext->GetDocShell();
+    if (docShell) {
+      AUTO_PROFILER_TRACING_WITH_DOCSHELL("Paint", "LayerBuilding", docShell->HistoryID());
+    } else {
+      AUTO_PROFILER_TRACING("Paint", "LayerBuilding");
+    }
+#endif
 
     if (XRE_IsContentProcess() && gfxPrefs::AlwaysPaint()) {
       FrameLayerBuilder::InvalidateAllLayers(aLayerManager);
     }
 
     if (aIsWidgetTransaction) {
       layerBuilder->DidBeginRetainedLayerTransaction(aLayerManager);
     }
--- a/tools/profiler/core/platform.cpp
+++ b/tools/profiler/core/platform.cpp
@@ -3654,46 +3654,47 @@ profiler_add_marker_for_thread(int aThre
   // Insert the marker into the buffer
   ProfileBuffer& buffer = ActivePS::Buffer(lock);
   buffer.AddStoredMarker(marker);
   buffer.AddEntry(ProfileBufferEntry::Marker(marker));
 }
 
 void
 profiler_tracing(const char* aCategory, const char* aMarkerName,
-                 TracingKind aKind)
+                 TracingKind aKind, const Maybe<nsID>& aDocshellId)
 {
   MOZ_RELEASE_ASSERT(CorePS::Exists());
 
   VTUNE_TRACING(aMarkerName, aKind);
 
   // This function is hot enough that we use RacyFeatures, notActivePS.
   if (!RacyFeatures::IsActiveWithoutPrivacy()) {
     return;
   }
 
-  auto payload = MakeUnique<TracingMarkerPayload>(aCategory, aKind);
+  auto payload = MakeUnique<TracingMarkerPayload>(aCategory, aKind, aDocshellId);
   racy_profiler_add_marker(aMarkerName, std::move(payload));
 }
 
 void
 profiler_tracing(const char* aCategory, const char* aMarkerName,
-                 TracingKind aKind, UniqueProfilerBacktrace aCause)
+                 TracingKind aKind, UniqueProfilerBacktrace aCause,
+                 const Maybe<nsID>& aDocshellId)
 {
   MOZ_RELEASE_ASSERT(CorePS::Exists());
 
   VTUNE_TRACING(aMarkerName, aKind);
 
   // This function is hot enough that we use RacyFeatures, notActivePS.
   if (!RacyFeatures::IsActiveWithoutPrivacy()) {
     return;
   }
 
   auto payload =
-    MakeUnique<TracingMarkerPayload>(aCategory, aKind, std::move(aCause));
+    MakeUnique<TracingMarkerPayload>(aCategory, aKind, aDocshellId, std::move(aCause));
   racy_profiler_add_marker(aMarkerName, std::move(payload));
 }
 
 void
 profiler_set_js_context(JSContext* aCx)
 {
   MOZ_ASSERT(aCx);
 
--- a/tools/profiler/public/GeckoProfiler.h
+++ b/tools/profiler/public/GeckoProfiler.h
@@ -41,18 +41,18 @@
 #define AUTO_PROFILER_LABEL_DYNAMIC_CSTR(label, category, cStr)
 #define AUTO_PROFILER_LABEL_DYNAMIC_NSCSTRING(label, category, nsCStr)
 #define AUTO_PROFILER_LABEL_DYNAMIC_LOSSY_NSSTRING(label, category, nsStr)
 #define AUTO_PROFILER_LABEL_FAST(label, category, ctx)
 
 #define PROFILER_ADD_MARKER(markerName)
 #define PROFILER_ADD_NETWORK_MARKER(uri, pri, channel, type, start, end, count, timings, redirect)
 
-#define PROFILER_TRACING(category, markerName, kind)
-#define AUTO_PROFILER_TRACING(category, markerName)
+#define PROFILER_TRACING(category, markerName, kind, docshellId)
+#define AUTO_PROFILER_TRACING(category, markerName, docshellId)
 
 #else // !MOZ_GECKO_PROFILER
 
 #include <functional>
 #include <signal.h>
 #include <stdarg.h>
 #include <stdint.h>
 #include <stdlib.h>
@@ -572,26 +572,30 @@ void profiler_add_network_marker(nsIURI*
 enum TracingKind {
   TRACING_EVENT,
   TRACING_INTERVAL_START,
   TRACING_INTERVAL_END,
 };
 
 // Adds a tracing marker to the profile. A no-op if the profiler is inactive or
 // in privacy mode.
-#define PROFILER_TRACING(category, markerName, kind) \
-  profiler_tracing(category, markerName, kind)
+#define PROFILER_TRACING(category, markerName, kind, docshellId) \
+  profiler_tracing(category, markerName, kind, docshellId)
 void profiler_tracing(const char* aCategory, const char* aMarkerName,
-                      TracingKind aKind);
+                      TracingKind aKind,
+                      const mozilla::Maybe<nsID>& aDocshellId = mozilla::Nothing());
 void profiler_tracing(const char* aCategory, const char* aMarkerName,
-                      TracingKind aKind, UniqueProfilerBacktrace aCause);
+                      TracingKind aKind, UniqueProfilerBacktrace aCause,
+                      const mozilla::Maybe<nsID>& aDocshellId = mozilla::Nothing());
 
 // Adds a START/END pair of tracing markers.
 #define AUTO_PROFILER_TRACING(category, markerName) \
-  mozilla::AutoProfilerTracing PROFILER_RAII(category, markerName)
+  mozilla::AutoProfilerTracing PROFILER_RAII(category, markerName, mozilla::Nothing())
+#define AUTO_PROFILER_TRACING_WITH_DOCSHELL(category, markerName, docshellId) \
+  mozilla::AutoProfilerTracing PROFILER_RAII(category, markerName, mozilla::Some(docshellId))
 
 //---------------------------------------------------------------------------
 // Output profiles
 //---------------------------------------------------------------------------
 
 // Get the profile encoded as a JSON string. A no-op (returning nullptr) if the
 // profiler is inactive.
 // If aIsShuttingDown is true, the current time is included as the process
@@ -765,45 +769,49 @@ private:
 public:
   // See the comment on the definition in platform.cpp for details about this.
   static MOZ_THREAD_LOCAL(ProfilingStack*) sProfilingStack;
 };
 
 class MOZ_RAII AutoProfilerTracing
 {
 public:
-  AutoProfilerTracing(const char* aCategory, const char* aMarkerName
+  AutoProfilerTracing(const char* aCategory, const char* aMarkerName,
+                      const mozilla::Maybe<nsID>& aDocshellId
                       MOZ_GUARD_OBJECT_NOTIFIER_PARAM)
     : mCategory(aCategory)
     , mMarkerName(aMarkerName)
+    , mDocshellId(aDocshellId)
   {
     MOZ_GUARD_OBJECT_NOTIFIER_INIT;
-    profiler_tracing(mCategory, mMarkerName, TRACING_INTERVAL_START);
+    profiler_tracing(mCategory, mMarkerName, TRACING_INTERVAL_START, mDocshellId);
   }
 
   AutoProfilerTracing(const char* aCategory, const char* aMarkerName,
-                      UniqueProfilerBacktrace aBacktrace
+                      UniqueProfilerBacktrace aBacktrace,
+                      const mozilla::Maybe<nsID>& aDocshellId
                       MOZ_GUARD_OBJECT_NOTIFIER_PARAM)
     : mCategory(aCategory)
     , mMarkerName(aMarkerName)
   {
     MOZ_GUARD_OBJECT_NOTIFIER_INIT;
     profiler_tracing(mCategory, mMarkerName, TRACING_INTERVAL_START,
-                     std::move(aBacktrace));
+                     std::move(aBacktrace), mDocshellId);
   }
 
   ~AutoProfilerTracing()
   {
-    profiler_tracing(mCategory, mMarkerName, TRACING_INTERVAL_END);
+    profiler_tracing(mCategory, mMarkerName, TRACING_INTERVAL_END, mDocshellId);
   }
 
 protected:
   MOZ_DECL_USE_GUARD_OBJECT_NOTIFIER
   const char* mCategory;
   const char* mMarkerName;
+  const mozilla::Maybe<nsID> mDocshellId;
 };
 
 // Set MOZ_PROFILER_STARTUP* environment variables that will be inherited into
 // a child process that is about to be launched, in order to make that child
 // process start with the same profiler settings as in the current process.
 class MOZ_RAII AutoSetProfilerEnvVarsForChildProcess
 {
 public:
--- a/tools/profiler/public/ProfilerMarkerPayload.h
+++ b/tools/profiler/public/ProfilerMarkerPayload.h
@@ -33,26 +33,30 @@ class UniqueStacks;
 // This is an abstract class that can be implemented to supply data to be
 // attached with a profiler marker.
 //
 // When subclassing this, note that the destructor can be called on any thread,
 // i.e. not necessarily on the thread that created the object.
 class ProfilerMarkerPayload
 {
 public:
-  explicit ProfilerMarkerPayload(UniqueProfilerBacktrace aStack = nullptr)
+  explicit ProfilerMarkerPayload(const mozilla::Maybe<nsID>& aDocShellId = mozilla::Nothing(),
+                                 UniqueProfilerBacktrace aStack = nullptr)
     : mStack(std::move(aStack))
+    , mDocShellId(aDocShellId)
   {}
 
   ProfilerMarkerPayload(const mozilla::TimeStamp& aStartTime,
                         const mozilla::TimeStamp& aEndTime,
+                        const mozilla::Maybe<nsID>& aDocShellId,
                         UniqueProfilerBacktrace aStack = nullptr)
     : mStartTime(aStartTime)
     , mEndTime(aEndTime)
     , mStack(std::move(aStack))
+    , mDocShellId(aDocShellId)
   {}
 
   virtual ~ProfilerMarkerPayload() {}
 
   virtual void StreamPayload(SpliceableJSONWriter& aWriter,
                              const mozilla::TimeStamp& aProcessStartTime,
                              UniqueStacks& aUniqueStacks) = 0;
 
@@ -64,55 +68,64 @@ protected:
                          const mozilla::TimeStamp& aProcessStartTime,
                          UniqueStacks& aUniqueStacks);
 
   void SetStack(UniqueProfilerBacktrace aStack)
   {
     mStack = std::move(aStack);
   }
 
+  void SetDocShellId(const mozilla::Maybe<nsID>& aDocShellId)
+  {
+    mDocShellId = aDocShellId;
+  }
+
 private:
   mozilla::TimeStamp mStartTime;
   mozilla::TimeStamp mEndTime;
   UniqueProfilerBacktrace mStack;
+  mozilla::Maybe<nsID> mDocShellId;
 };
 
 #define DECL_STREAM_PAYLOAD \
   virtual void StreamPayload(SpliceableJSONWriter& aWriter, \
                              const mozilla::TimeStamp& aProcessStartTime, \
                              UniqueStacks& aUniqueStacks) override;
 
+// TODO: complete tracing markers
 class TracingMarkerPayload : public ProfilerMarkerPayload
 {
 public:
   TracingMarkerPayload(const char* aCategory, TracingKind aKind,
+                       const mozilla::Maybe<nsID>& aDocShellId = mozilla::Nothing(),
                        UniqueProfilerBacktrace aCause = nullptr)
     : mCategory(aCategory)
     , mKind(aKind)
   {
     if (aCause) {
       SetStack(std::move(aCause));
     }
+    SetDocShellId(aDocShellId);
   }
 
   DECL_STREAM_PAYLOAD
 
 private:
   const char *mCategory;
   TracingKind mKind;
 };
 
 class IOMarkerPayload : public ProfilerMarkerPayload
 {
 public:
   IOMarkerPayload(const char* aSource, const char* aFilename,
                   const mozilla::TimeStamp& aStartTime,
                   const mozilla::TimeStamp& aEndTime,
                   UniqueProfilerBacktrace aStack)
-    : ProfilerMarkerPayload(aStartTime, aEndTime, std::move(aStack))
+    : ProfilerMarkerPayload(aStartTime, aEndTime, mozilla::Nothing(), std::move(aStack))
     , mSource(aSource)
     , mFilename(aFilename ? strdup(aFilename) : nullptr)
   {
     MOZ_ASSERT(aSource);
   }
 
   DECL_STREAM_PAYLOAD
 
@@ -121,18 +134,19 @@ private:
   mozilla::UniqueFreePtr<char> mFilename;
 };
 
 class DOMEventMarkerPayload : public TracingMarkerPayload
 {
 public:
   DOMEventMarkerPayload(const nsAString& aEventType, uint16_t aPhase,
                         const mozilla::TimeStamp& aTimeStamp,
-                        const char* aCategory, TracingKind aKind)
-    : TracingMarkerPayload(aCategory, aKind)
+                        const char* aCategory, TracingKind aKind,
+                        const mozilla::Maybe<nsID>& aDocShellId)
+    : TracingMarkerPayload(aCategory, aKind, aDocShellId)
     , mTimeStamp(aTimeStamp)
     , mEventType(aEventType)
     , mPhase(aPhase)
   {}
 
   DECL_STREAM_PAYLOAD
 
 private:
@@ -140,28 +154,30 @@ private:
   nsString mEventType;
   uint16_t mPhase;
 };
 
 class UserTimingMarkerPayload : public ProfilerMarkerPayload
 {
 public:
   UserTimingMarkerPayload(const nsAString& aName,
-                          const mozilla::TimeStamp& aStartTime)
-    : ProfilerMarkerPayload(aStartTime, aStartTime)
+                          const mozilla::TimeStamp& aStartTime,
+                          const mozilla::Maybe<nsID>& aDocShellId)
+    : ProfilerMarkerPayload(aStartTime, aStartTime, aDocShellId)
     , mEntryType("mark")
     , mName(aName)
   {}
 
   UserTimingMarkerPayload(const nsAString& aName,
                           const mozilla::Maybe<nsString>& aStartMark,
                           const mozilla::Maybe<nsString>& aEndMark,
                           const mozilla::TimeStamp& aStartTime,
-                          const mozilla::TimeStamp& aEndTime)
-    : ProfilerMarkerPayload(aStartTime, aEndTime)
+                          const mozilla::TimeStamp& aEndTime,
+                          const mozilla::Maybe<nsID>& aDocShellId)
+    : ProfilerMarkerPayload(aStartTime, aEndTime, aDocShellId)
     , mEntryType("measure")
     , mName(aName)
     , mStartMark(aStartMark)
     , mEndMark(aEndMark)
   {}
 
   DECL_STREAM_PAYLOAD
 
@@ -176,17 +192,17 @@ private:
 // Contains the translation applied to a 2d layer so we can track the layer
 // position at each frame.
 class LayerTranslationMarkerPayload : public ProfilerMarkerPayload
 {
 public:
   LayerTranslationMarkerPayload(mozilla::layers::Layer* aLayer,
                                 mozilla::gfx::Point aPoint,
                                 mozilla::TimeStamp aStartTime)
-    : ProfilerMarkerPayload(aStartTime, aStartTime)
+    : ProfilerMarkerPayload(aStartTime, aStartTime, mozilla::Nothing())
     , mLayer(aLayer)
     , mPoint(aPoint)
   {}
 
   DECL_STREAM_PAYLOAD
 
 private:
   mozilla::layers::Layer* mLayer;
@@ -195,17 +211,17 @@ private:
 
 #include "Units.h"    // For ScreenIntPoint
 
 // Tracks when a vsync occurs according to the HardwareComposer.
 class VsyncMarkerPayload : public ProfilerMarkerPayload
 {
 public:
   explicit VsyncMarkerPayload(mozilla::TimeStamp aVsyncTimestamp)
-    : ProfilerMarkerPayload(aVsyncTimestamp, aVsyncTimestamp)
+    : ProfilerMarkerPayload(aVsyncTimestamp, aVsyncTimestamp, mozilla::Nothing())
     , mVsyncTimestamp(aVsyncTimestamp)
   {}
 
   DECL_STREAM_PAYLOAD
 
 private:
   mozilla::TimeStamp mVsyncTimestamp;
 };
@@ -215,18 +231,19 @@ 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,
                        const mozilla::net::TimingStruct* aTimings = nullptr,
-                       const char* aRedirectURI = nullptr)
-    : ProfilerMarkerPayload(aStartTime, aEndTime)
+                       const char* aRedirectURI = nullptr/*,
+                       const mozilla::Maybe<nsID>& aDocShellId*/)
+    : 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)
   {
     if (aTimings) {
@@ -248,98 +265,100 @@ private:
 
 class ScreenshotPayload : public ProfilerMarkerPayload
 {
 public:
   explicit ScreenshotPayload(mozilla::TimeStamp aTimeStamp,
                              nsCString&& aScreenshotDataURL,
                              const mozilla::gfx::IntSize& aWindowSize,
                              uintptr_t aWindowIdentifier)
-    : ProfilerMarkerPayload(aTimeStamp, mozilla::TimeStamp())
+    : ProfilerMarkerPayload(aTimeStamp, mozilla::TimeStamp(), mozilla::Nothing())
     , mScreenshotDataURL(std::move(aScreenshotDataURL))
     , mWindowSize(aWindowSize)
     , mWindowIdentifier(aWindowIdentifier)
   {}
 
   DECL_STREAM_PAYLOAD
 
 private:
   nsCString mScreenshotDataURL;
   mozilla::gfx::IntSize mWindowSize;
   uintptr_t mWindowIdentifier;
 };
 
+
 class GCSliceMarkerPayload : public ProfilerMarkerPayload
 {
 public:
   GCSliceMarkerPayload(const mozilla::TimeStamp& aStartTime,
                        const mozilla::TimeStamp& aEndTime,
                        JS::UniqueChars&& aTimingJSON)
-   : ProfilerMarkerPayload(aStartTime, aEndTime),
+   : ProfilerMarkerPayload(aStartTime, aEndTime, mozilla::Nothing()),
      mTimingJSON(std::move(aTimingJSON))
   {}
 
   DECL_STREAM_PAYLOAD
 
 private:
   JS::UniqueChars mTimingJSON;
 };
 
 class GCMajorMarkerPayload : public ProfilerMarkerPayload
 {
 public:
   GCMajorMarkerPayload(const mozilla::TimeStamp& aStartTime,
                        const mozilla::TimeStamp& aEndTime,
                        JS::UniqueChars&& aTimingJSON)
-   : ProfilerMarkerPayload(aStartTime, aEndTime),
+   : ProfilerMarkerPayload(aStartTime, aEndTime, mozilla::Nothing()),
      mTimingJSON(std::move(aTimingJSON))
   {}
 
   DECL_STREAM_PAYLOAD
 
 private:
   JS::UniqueChars mTimingJSON;
 };
 
 class GCMinorMarkerPayload : public ProfilerMarkerPayload
 {
 public:
   GCMinorMarkerPayload(const mozilla::TimeStamp& aStartTime,
                        const mozilla::TimeStamp& aEndTime,
                        JS::UniqueChars&& aTimingData)
-   : ProfilerMarkerPayload(aStartTime, aEndTime),
+   : ProfilerMarkerPayload(aStartTime, aEndTime, mozilla::Nothing()),
      mTimingData(std::move(aTimingData))
   {}
 
   DECL_STREAM_PAYLOAD
 
 private:
   JS::UniqueChars mTimingData;
 };
 
 class HangMarkerPayload : public ProfilerMarkerPayload
 {
 public:
   HangMarkerPayload(const mozilla::TimeStamp& aStartTime,
                     const mozilla::TimeStamp& aEndTime)
-   : ProfilerMarkerPayload(aStartTime, aEndTime)
+   : ProfilerMarkerPayload(aStartTime, aEndTime, mozilla::Nothing())
   {}
 
   DECL_STREAM_PAYLOAD
 private:
 };
 
 class StyleMarkerPayload : public ProfilerMarkerPayload
 {
 public:
   StyleMarkerPayload(const mozilla::TimeStamp& aStartTime,
                      const mozilla::TimeStamp& aEndTime,
                      UniqueProfilerBacktrace aCause,
-                     const mozilla::ServoTraversalStatistics& aStats)
-    : ProfilerMarkerPayload(aStartTime, aEndTime)
+                     const mozilla::ServoTraversalStatistics& aStats,
+                     const mozilla::Maybe<nsID>& aDocShellId)
+    : ProfilerMarkerPayload(aStartTime, aEndTime, aDocShellId)
     , mStats(aStats)
   {
     if (aCause) {
       SetStack(std::move(aCause));
     }
   }
 
   DECL_STREAM_PAYLOAD
--- a/tools/profiler/tests/gtest/GeckoProfiler.cpp
+++ b/tools/profiler/tests/gtest/GeckoProfiler.cpp
@@ -437,34 +437,34 @@ TEST(GeckoProfiler, Markers)
 {
   uint32_t features = ProfilerFeature::StackWalk;
   const char* filters[] = { "GeckoMain" };
 
   profiler_start(PROFILER_DEFAULT_ENTRIES, PROFILER_DEFAULT_INTERVAL,
                  features, filters, MOZ_ARRAY_LENGTH(filters));
 
   profiler_tracing("A", "B", TRACING_EVENT);
-  PROFILER_TRACING("A", "C", TRACING_INTERVAL_START);
-  PROFILER_TRACING("A", "C", TRACING_INTERVAL_END);
+  PROFILER_TRACING("A", "C", TRACING_INTERVAL_START, mozilla::Nothing());
+  PROFILER_TRACING("A", "C", TRACING_INTERVAL_END, mozilla::Nothing());
 
   UniqueProfilerBacktrace bt = profiler_get_backtrace();
   profiler_tracing("B", "A", TRACING_EVENT, std::move(bt));
 
   {
     AUTO_PROFILER_TRACING("C", "A");
   }
 
   profiler_add_marker("M1");
   profiler_add_marker(
     "M2", MakeUnique<TracingMarkerPayload>("C", TRACING_EVENT));
   PROFILER_ADD_MARKER("M3");
   profiler_add_marker(
     "M4",
     MakeUnique<TracingMarkerPayload>("C", TRACING_EVENT,
-                                     profiler_get_backtrace()));
+                                     mozilla::Nothing(), profiler_get_backtrace()));
 
   for (int i = 0; i < 10; i++) {
     profiler_add_marker("M5", MakeUnique<GTestMarkerPayload>(i));
   }
 
   // Create two strings: one that is the maximum allowed length, and one that
   // is one char longer.
   static const size_t kMax = ProfileBuffer::kMaxFrameKeyLength;