Bug 1071056 - preserve unpaired START markers until next pop. r=bgirard
☠☠ backed out by bc585ed304a4 ☠ ☠
authorTom Tromey <tom@tromey.com>
Mon, 13 Oct 2014 16:29:51 -0400
changeset 210229 f9b9ee8fb89e81f9521b6c06315a851df514c1cd
parent 210207 c782a908f89c5d5a8f6c120113ca2d08bdcd2a90
child 210230 bc585ed304a47ba9d2f5b3a31fca6bc224c5348c
push id1
push userroot
push dateMon, 20 Oct 2014 17:29:22 +0000
reviewersbgirard
bugs1071056
milestone35.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
@@ -954,21 +954,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();