Bug 1071056 - preserve unpaired START markers until next pop. r=bgirard
authorTom Tromey <tom@tromey.com>
Tue, 14 Oct 2014 13:06:19 +0200
changeset 210308 0a3982b6cf3a0d92e908f1bf6a8613e0a4c3606d
parent 210307 2be42fbc9d98c147bc4ebccd26dbd58f409b2919
child 210309 14cfea6cd6aee50aeb649e1ade94e61b6129eee6
push id1
push userroot
push dateMon, 20 Oct 2014 17:29:22 +0000
reviewersbgirard
bugs1071056
milestone36.0a1
Bug 1071056 - preserve unpaired START markers until next pop. r=bgirard
docshell/base/nsDocShell.cpp
docshell/base/nsDocShell.h
--- a/docshell/base/nsDocShell.cpp
+++ b/docshell/base/nsDocShell.cpp
@@ -2853,24 +2853,31 @@ nsDocShell::PopProfileTimelineMarkers(JS
   // {name,start,end} JS object.
   // Paint markers are different because paint is handled at root docShell level
   // in the information that a paint was done is then stored at each sub
   // docShell level but we can only be sure that a paint did happen in a
   // docShell if an Layer marker type was recorded too.
 
   nsTArray<mozilla::dom::ProfileTimelineMarker> profileTimelineMarkers;
 
+  // If we see an unpaired START, we keep it around for the next call
+  // to PopProfileTimelineMarkers.  We store the kept START objects in
+  // this array.
+  decltype(mProfileTimelineMarkers) keptMarkers;
+
   for (uint32_t i = 0; i < mProfileTimelineMarkers.Length(); ++i) {
     ProfilerMarkerTracing* startPayload = static_cast<ProfilerMarkerTracing*>(
       mProfileTimelineMarkers[i]->mPayload);
     const char* startMarkerName = mProfileTimelineMarkers[i]->mName;
 
     bool hasSeenPaintedLayer = false;
 
     if (startPayload->GetMetaData() == TRACING_INTERVAL_START) {
+      bool hasSeenEnd = false;
+
       // The assumption is that the devtools timeline flushes markers frequently
       // enough for the amount of markers to always be small enough that the
       // nested for loop isn't going to be a performance problem.
       for (uint32_t j = i + 1; j < mProfileTimelineMarkers.Length(); ++j) {
         ProfilerMarkerTracing* endPayload = static_cast<ProfilerMarkerTracing*>(
           mProfileTimelineMarkers[j]->mPayload);
         const char* endMarkerName = mProfileTimelineMarkers[j]->mName;
 
@@ -2888,25 +2895,36 @@ nsDocShell::PopProfileTimelineMarkers(JS
           if (!isPaint || (isPaint && hasSeenPaintedLayer)) {
             mozilla::dom::ProfileTimelineMarker marker;
             marker.mName = NS_ConvertUTF8toUTF16(startMarkerName);
             marker.mStart = mProfileTimelineMarkers[i]->mTime;
             marker.mEnd = mProfileTimelineMarkers[j]->mTime;
             profileTimelineMarkers.AppendElement(marker);
           }
 
+          // We want the start to be dropped either way.
+          hasSeenEnd = true;
+
           break;
         }
       }
+
+      // If we did not see the corresponding END, keep the START.
+      if (!hasSeenEnd) {
+        keptMarkers.AppendElement(mProfileTimelineMarkers[i]);
+        mProfileTimelineMarkers.RemoveElementAt(i);
+        --i;
+      }
     }
   }
 
   ToJSValue(aCx, profileTimelineMarkers, aProfileTimelineMarkers);
 
   ClearProfileTimelineMarkers();
+  mProfileTimelineMarkers.SwapElements(keptMarkers);
 
   return NS_OK;
 #else
   return NS_ERROR_FAILURE;
 #endif
 }
 
 float
@@ -2947,18 +2965,17 @@ nsDocShell::AddProfileTimelineMarker(con
 #endif
 }
 
 void
 nsDocShell::ClearProfileTimelineMarkers()
 {
 #ifdef MOZ_ENABLE_PROFILER_SPS
   for (uint32_t i = 0; i < mProfileTimelineMarkers.Length(); ++i) {
-    delete mProfileTimelineMarkers[i]->mPayload;
-    mProfileTimelineMarkers[i]->mPayload = nullptr;
+    delete mProfileTimelineMarkers[i];
   }
   mProfileTimelineMarkers.Clear();
 #endif
 }
 
 nsIDOMStorageManager*
 nsDocShell::TopSessionStorageManager()
 {
--- a/docshell/base/nsDocShell.h
+++ b/docshell/base/nsDocShell.h
@@ -16,16 +16,17 @@
 #include "nsIScrollable.h"
 #include "nsITextScroll.h"
 #include "nsIContentViewerContainer.h"
 #include "nsIDOMStorageManager.h"
 #include "nsDocLoader.h"
 #include "mozilla/WeakPtr.h"
 #include "mozilla/TimeStamp.h"
 #include "GeckoProfiler.h"
+#include "ProfilerMarkers.h"
 
 // Helper Classes
 #include "nsCOMPtr.h"
 #include "nsPoint.h" // mCurrent/mDefaultScrollbarPreferences
 #include "nsString.h"
 #include "nsAutoPtr.h"
 #include "nsThreadUtils.h"
 
@@ -954,21 +955,27 @@ private:
     {
       InternalProfileTimelineMarker(const char* aName,
                                     ProfilerMarkerTracing* aPayload,
                                     float aTime)
         : mName(aName)
         , mPayload(aPayload)
         , mTime(aTime)
       {}
+
+      ~InternalProfileTimelineMarker()
+      {
+        delete mPayload;
+      }
+
       const char* mName;
       ProfilerMarkerTracing* mPayload;
       float mTime;
     };
-    nsTArray<nsAutoPtr<InternalProfileTimelineMarker>> mProfileTimelineMarkers;
+    nsTArray<InternalProfileTimelineMarker*> mProfileTimelineMarkers;
 
     // Get the elapsed time (in millis) since the profile timeline recording
     // started
     float GetProfileTimelineDelta();
 
     // Get rid of all the timeline markers accumulated so far
     void ClearProfileTimelineMarkers();