Bug 1321617 - Move parts of StreamJSON out into the callers and rename it to locked_profiler_stream_json_for_this_process. r?njn draft
authorMarkus Stange <mstange@themasta.com>
Sat, 08 Apr 2017 21:07:52 -0400
changeset 559164 a579a9e7e6a76ecf0a6e948f45a974fed5ed4dd5
parent 559163 fc23b15ea50cb435790be2e4f79ad78d02335776
child 559165 6860c3092eaefbcbf96dd5b2e80991c3087249a6
push id53008
push userbmo:mstange@themasta.com
push dateSun, 09 Apr 2017 03:27:44 +0000
reviewersnjn
bugs1321617
milestone55.0a1
Bug 1321617 - Move parts of StreamJSON out into the callers and rename it to locked_profiler_stream_json_for_this_process. r?njn MozReview-Commit-ID: 239BJOa2bix
tools/profiler/core/platform.cpp
--- a/tools/profiler/core/platform.cpp
+++ b/tools/profiler/core/platform.cpp
@@ -1348,104 +1348,81 @@ BuildJavaThreadJSObject(SpliceableJSONWr
       }
     }
   }
   aWriter.EndArray();
 }
 #endif
 
 static void
-StreamJSON(PS::LockRef aLock, SpliceableJSONWriter& aWriter, double aSinceTime)
+locked_profiler_stream_json_for_this_process(PS::LockRef aLock, SpliceableJSONWriter& aWriter, double aSinceTime)
 {
-  LOG("StreamJSON");
+  LOG("locked_profiler_stream_json_for_this_process");
 
   MOZ_RELEASE_ASSERT(NS_IsMainThread());
   MOZ_RELEASE_ASSERT(gPS && gPS->IsActive(aLock));
 
-  aWriter.Start(SpliceableJSONWriter::SingleLineStyle);
+  // Put shared library info
+  aWriter.StartArrayProperty("libs");
+  AppendSharedLibraries(aWriter);
+  aWriter.EndArray();
+
+  // Put meta data
+  aWriter.StartObjectProperty("meta");
   {
-    // Put shared library info
-    aWriter.StartArrayProperty("libs");
-    AppendSharedLibraries(aWriter);
-    aWriter.EndArray();
-
-    // Put meta data
-    aWriter.StartObjectProperty("meta");
+    StreamMetaJSCustomObject(aLock, aWriter);
+  }
+  aWriter.EndObject();
+
+  // Data of TaskTracer doesn't belong in the circular buffer.
+  if (gPS->FeatureTaskTracer(aLock)) {
+    aWriter.StartObjectProperty("tasktracer");
+    StreamTaskTracer(aLock, aWriter);
+    aWriter.EndObject();
+  }
+
+  // Lists the samples for each thread profile
+  aWriter.StartArrayProperty("threads");
+  {
+    gPS->SetIsPaused(aLock, true);
+
     {
-      StreamMetaJSCustomObject(aLock, aWriter);
-    }
-    aWriter.EndObject();
-
-    // Data of TaskTracer doesn't belong in the circular buffer.
-    if (gPS->FeatureTaskTracer(aLock)) {
-      aWriter.StartObjectProperty("tasktracer");
-      StreamTaskTracer(aLock, aWriter);
-      aWriter.EndObject();
+      const PS::ThreadVector& threads = gPS->Threads(aLock);
+      for (size_t i = 0; i < threads.size(); i++) {
+        // Thread not being profiled, skip it
+        ThreadInfo* info = threads.at(i);
+        if (!info->HasProfile()) {
+          continue;
+        }
+
+        // Note that we intentionally include thread profiles which
+        // have been marked for pending delete.
+
+        info->StreamJSON(gPS->Buffer(aLock), aWriter, gPS->StartTime(aLock),
+                          aSinceTime);
+      }
     }
 
-    // Lists the samples for each thread profile
-    aWriter.StartArrayProperty("threads");
-    {
-      gPS->SetIsPaused(aLock, true);
-
-      {
-        const PS::ThreadVector& threads = gPS->Threads(aLock);
-        for (size_t i = 0; i < threads.size(); i++) {
-          // Thread not being profiled, skip it
-          ThreadInfo* info = threads.at(i);
-          if (!info->HasProfile()) {
-            continue;
-          }
-
-          // Note that we intentionally include thread profiles which
-          // have been marked for pending delete.
-
-          info->StreamJSON(gPS->Buffer(aLock), aWriter, gPS->StartTime(aLock),
-                           aSinceTime);
-        }
-      }
-
 #if defined(PROFILE_JAVA)
-      if (gPS->FeatureJava(aLock)) {
-        java::GeckoJavaSampler::Pause();
-
-        aWriter.Start();
-        {
-          BuildJavaThreadJSObject(aWriter);
-        }
-        aWriter.End();
-
-        java::GeckoJavaSampler::Unpause();
+    if (gPS->FeatureJava(aLock)) {
+      java::GeckoJavaSampler::Pause();
+
+      aWriter.Start();
+      {
+        BuildJavaThreadJSObject(aWriter);
       }
-#endif
-
-      gPS->SetIsPaused(aLock, false);
+      aWriter.End();
+
+      java::GeckoJavaSampler::Unpause();
     }
-    aWriter.EndArray();
-
-    aWriter.StartArrayProperty("processes");
-    // When notifying observers in other places in this file we are careful
-    // to do it when gPSMutex is unlocked, to avoid deadlocks. But that's not
-    // necessary here, because "profiler-subprocess" observers just call back
-    // into SubprocessCallback, which is simple and doesn't lock gPSMutex.
-    if (CanNotifyObservers()) {
-      // Send a event asking any subprocesses (plugins) to
-      // give us their information
-      SubprocessClosure closure(&aWriter);
-      nsCOMPtr<nsIObserverService> os =
-        mozilla::services::GetObserverService();
-      if (os) {
-        RefPtr<ProfileSaveEvent> pse =
-          new ProfileSaveEvent(SubProcessCallback, &closure);
-        os->NotifyObservers(pse, "profiler-subprocess", nullptr);
-      }
-    }
-    aWriter.EndArray();
+#endif
+
+    gPS->SetIsPaused(aLock, false);
   }
-  aWriter.End();
+  aWriter.EndArray();
 }
 
 // END saving/streaming code
 ////////////////////////////////////////////////////////////////////////
 
 ProfilerMarker::ProfilerMarker(const char* aMarkerName,
                                ProfilerMarkerPayload* aPayload,
                                double aTime)
@@ -2123,17 +2100,41 @@ profiler_get_profile(double aSinceTime)
 
   PS::AutoLock lock(gPSMutex);
 
   if (!gPS->IsActive(lock)) {
     return nullptr;
   }
 
   SpliceableChunkedJSONWriter b;
-  StreamJSON(lock, b, aSinceTime);
+  b.Start(SpliceableJSONWriter::SingleLineStyle);
+  {
+    locked_profiler_stream_json_for_this_process(lock, b, aSinceTime);
+
+    b.StartArrayProperty("processes");
+    // When notifying observers in other places in this file we are careful
+    // to do it when gPSMutex is unlocked, to avoid deadlocks. But that's not
+    // necessary here, because "profiler-subprocess" observers just call back
+    // into SubprocessCallback, which is simple and doesn't lock gPSMutex.
+    if (CanNotifyObservers()) {
+      // Send a event asking any subprocesses (plugins) to
+      // give us their information
+      SubprocessClosure closure(&b);
+      nsCOMPtr<nsIObserverService> os =
+        mozilla::services::GetObserverService();
+      if (os) {
+        RefPtr<ProfileSaveEvent> pse =
+          new ProfileSaveEvent(SubProcessCallback, &closure);
+        os->NotifyObservers(pse, "profiler-subprocess", nullptr);
+      }
+    }
+    b.EndArray();
+  }
+  b.End();
+
   return b.WriteFunc()->CopyData();
 }
 
 void
 profiler_get_start_params(int* aEntries, double* aInterval,
                           mozilla::Vector<const char*>* aFeatures,
                           mozilla::Vector<const char*>* aFilters)
 {
@@ -2170,17 +2171,27 @@ locked_profiler_save_profile_to_file(PS:
 
   MOZ_RELEASE_ASSERT(NS_IsMainThread());
   MOZ_RELEASE_ASSERT(gPS && gPS->IsActive(aLock));
 
   std::ofstream stream;
   stream.open(aFilename);
   if (stream.is_open()) {
     SpliceableJSONWriter w(mozilla::MakeUnique<OStreamJSONWriteFunc>(stream));
-    StreamJSON(aLock, w, /* sinceTime */ 0);
+    w.Start(SpliceableJSONWriter::SingleLineStyle);
+    {
+      locked_profiler_stream_json_for_this_process(aLock, w, /* sinceTime */ 0);
+
+      // Don't include profiles from other processes because this is a
+      // synchronous function.
+      w.StartArrayProperty("processes");
+      w.EndArray();
+    }
+    w.End();
+
     stream.close();
   }
 }
 
 void
 profiler_save_profile_to_file(const char* aFilename)
 {
   LOG("profiler_save_profile_to_file(%s)", aFilename);