Bug 1245743 - Don't push new timeline markers while popping markers. r=vporof, a=ritu
authorTom Tromey <tom@tromey.com>
Wed, 09 Mar 2016 19:19:47 -0500
changeset 323743 679f5793569e51e9fd54d68664bdd6e7a949f07b
parent 323742 3d3218e55f22306ba55bdd6aa7693a23369f5492
child 323744 dcb34dd977943c61c6dfe2d2754c93f8e9d0c2a9
push id5913
push userjlund@mozilla.com
push dateMon, 25 Apr 2016 16:57:49 +0000
treeherdermozilla-beta@dcaf0a6fa115 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersvporof, ritu
bugs1245743
milestone47.0a2
Bug 1245743 - Don't push new timeline markers while popping markers. r=vporof, a=ritu MozReview-Commit-ID: IllTB7DOdlZ
docshell/base/timeline/ObservedDocShell.cpp
docshell/base/timeline/ObservedDocShell.h
--- a/docshell/base/timeline/ObservedDocShell.cpp
+++ b/docshell/base/timeline/ObservedDocShell.cpp
@@ -5,34 +5,40 @@
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "ObservedDocShell.h"
 
 #include "AbstractTimelineMarker.h"
 #include "LayerTimelineMarker.h"
 #include "MainThreadUtils.h"
 #include "mozilla/Move.h"
+#include "mozilla/ScopeExit.h"
 
 namespace mozilla {
 
 ObservedDocShell::ObservedDocShell(nsIDocShell* aDocShell)
   : MarkersStorage("ObservedDocShellMutex")
   , mDocShell(aDocShell)
+  , mPopping(false)
 {
   MOZ_ASSERT(NS_IsMainThread());
 }
 
 void
 ObservedDocShell::AddMarker(UniquePtr<AbstractTimelineMarker>&& aMarker)
 {
   // Only allow main thread markers to go into this list. No need to lock
   // here since `mTimelineMarkers` will only be accessed or modified on the
   // main thread only.
   MOZ_ASSERT(NS_IsMainThread());
-  mTimelineMarkers.AppendElement(Move(aMarker));
+  // Don't accept any markers generated by the process of popping
+  // markers.
+  if (!mPopping) {
+    mTimelineMarkers.AppendElement(Move(aMarker));
+  }
 }
 
 void
 ObservedDocShell::AddOTMTMarker(UniquePtr<AbstractTimelineMarker>&& aMarker)
 {
   // Only allow off the main thread markers to go into this list. Since most
   // of our markers come from the main thread, be a little more efficient and
   // avoid dealing with multithreading scenarios until all the markers are
@@ -53,16 +59,20 @@ ObservedDocShell::ClearMarkers()
 
 void
 ObservedDocShell::PopMarkers(JSContext* aCx,
                              nsTArray<dom::ProfileTimelineMarker>& aStore)
 {
   MOZ_ASSERT(NS_IsMainThread());
   MutexAutoLock lock(GetLock()); // for `mOffTheMainThreadTimelineMarkers`.
 
+  MOZ_RELEASE_ASSERT(!mPopping);
+  mPopping = true;
+  auto resetPopping = MakeScopeExit([&] { mPopping = false; });
+
   // First, move all of our markers into a single array. We'll chose
   // the `mTimelineMarkers` store because that's where we expect most of
   // our markers to be.
   mTimelineMarkers.AppendElements(Move(mOffTheMainThreadTimelineMarkers));
 
   // If we see an unpaired START, we keep it around for the next call
   // to ObservedDocShell::PopMarkers. We store the kept START objects here.
   nsTArray<UniquePtr<AbstractTimelineMarker>> keptStartMarkers;
--- a/docshell/base/timeline/ObservedDocShell.h
+++ b/docshell/base/timeline/ObservedDocShell.h
@@ -27,16 +27,17 @@ struct ProfileTimelineMarker;
 // allowed to exist. See TimelineConsumers for register/unregister logic.
 class ObservedDocShell : public MarkersStorage
 {
 private:
   RefPtr<nsIDocShell> mDocShell;
 
   // Main thread only.
   nsTArray<UniquePtr<AbstractTimelineMarker>> mTimelineMarkers;
+  bool mPopping;
 
   // Off the main thread only.
   nsTArray<UniquePtr<AbstractTimelineMarker>> mOffTheMainThreadTimelineMarkers;
 
 public:
   explicit ObservedDocShell(nsIDocShell* aDocShell);
   nsIDocShell* operator*() const { return mDocShell.get(); }