Bug 1520238 - Record memory counters when requested (at startup or from the add-on) - r=mstange
authorGerald Squelart <gsquelart@mozilla.com>
Tue, 30 Apr 2019 01:42:05 +0000
changeset 530681 21dcb2db394431972b3af0d5ab02ad43f5c22edd
parent 530680 1a6729434b06259c87ab0d891875a6a45a92c43f
child 530682 83d4f96efbb57b55e2530cea3a9b2f662bcdc8f4
push id11265
push userffxbld-merge
push dateMon, 13 May 2019 10:53:39 +0000
treeherdermozilla-beta@77e0fe8dbdd3 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmstange
bugs1520238, 1521929
milestone68.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1520238 - Record memory counters when requested (at startup or from the add-on) - r=mstange Memory tracks are fed from a memory counter, which is unconditionally installed from profiler_start(). This means: - It is installed even if memory measurements are not requested. - Startup profiling doesn't use profiler_start() and therefore never starts recording memory. Because installing the memory counter may need to take the (non-recursive) profiler lock, it cannot simply be installed from the common `locked_profiler_start()` function. Instead, it will have to be installed after each `locked_profiler_start()` call. Also, it should only be installed if the "memory" feature is requested. That "memory" feature is now considered available only if Firefox was built with MOZ_REPLACE_MALLOC and MOZ_PROFILER_MEMORY. (This may effectively prevent the old RSS&USS memory reporting which doesn't depend on these #defines, but This Is Fine as it is not used anymore and slated for removal in bug 1521929.) Differential Revision: https://phabricator.services.mozilla.com/D25533
tools/profiler/core/platform.cpp
--- a/tools/profiler/core/platform.cpp
+++ b/tools/profiler/core/platform.cpp
@@ -212,16 +212,19 @@ static uint32_t AvailableFeatures() {
   ProfilerFeature::ClearJava(features);
 #endif
 #if !defined(HAVE_NATIVE_UNWIND)
   ProfilerFeature::ClearStackWalk(features);
 #endif
 #if !defined(MOZ_TASK_TRACER)
   ProfilerFeature::ClearTaskTracer(features);
 #endif
+#if !(defined(MOZ_REPLACE_MALLOC) && defined(MOZ_PROFILER_MEMORY))
+  ProfilerFeature::ClearMemory(features);
+#endif
   if (!JS::TraceLoggerSupported()) {
     ProfilerFeature::ClearJSTracer(features);
   }
 
   return features;
 }
 
 // Default features common to all contexts (even if not available).
@@ -2957,16 +2960,24 @@ void profiler_init(void* aStackTop) {
       filters = SplitAtCommas(startupFilters, filterStorage);
       LOG("- MOZ_PROFILER_STARTUP_FILTERS = %s", startupFilters);
     }
 
     locked_profiler_start(lock, capacity, interval, features, filters.begin(),
                           filters.length(), duration);
   }
 
+#if defined(MOZ_REPLACE_MALLOC) && defined(MOZ_PROFILER_MEMORY)
+  if (ProfilerFeature::HasMemory(features)) {
+    // start counting memory allocations (outside of lock because this may call
+    // profiler_add_sampled_counter which would attempt to take the lock.)
+    mozilla::profiler::install_memory_counter(true);
+  }
+#endif
+
   // We do this with gPSMutex unlocked. The comment in profiler_stop() explains
   // why.
   NotifyProfilerStarted(capacity, duration, interval, features, filters.begin(),
                         filters.length());
 }
 
 static void locked_profiler_save_profile_to_file(PSLockRef aLock,
                                                  const char* aFilename,
@@ -3386,18 +3397,21 @@ void profiler_start(uint32_t aCapacity, 
       samplerThread = locked_profiler_stop(lock);
     }
 
     locked_profiler_start(lock, aCapacity, aInterval, aFeatures, aFilters,
                           aFilterCount, aDuration);
   }
 
 #if defined(MOZ_REPLACE_MALLOC) && defined(MOZ_PROFILER_MEMORY)
-  // start counting memory allocations (outside of lock)
-  mozilla::profiler::install_memory_counter(true);
+  if (ProfilerFeature::HasMemory(aFeatures)) {
+    // start counting memory allocations (outside of lock because this may call
+    // profiler_add_sampled_counter which would attempt to take the lock.)
+    mozilla::profiler::install_memory_counter(true);
+  }
 #endif
 
   // We do these operations with gPSMutex unlocked. The comments in
   // profiler_stop() explain why.
   if (samplerThread) {
     ProfilerParent::ProfilerStopped();
     NotifyObservers("profiler-stopped");
     delete samplerThread;
@@ -3423,35 +3437,51 @@ void profiler_ensure_started(uint32_t aC
     }
 
     if (ActivePS::Exists(lock)) {
       // The profiler is active.
       if (!ActivePS::Equals(lock, aCapacity, aDuration, aInterval, aFeatures,
                             aFilters, aFilterCount)) {
         // Stop and restart with different settings.
         samplerThread = locked_profiler_stop(lock);
+#if defined(MOZ_REPLACE_MALLOC) && defined(MOZ_PROFILER_MEMORY)
+        if (!ProfilerFeature::HasMemory(aFeatures)) {
+          // Ensure we don't record memory measurements anymore (if we were).
+          mozilla::profiler::install_memory_counter(false);
+        }
+#endif
         locked_profiler_start(lock, aCapacity, aInterval, aFeatures, aFilters,
                               aFilterCount, aDuration);
         startedProfiler = true;
       }
     } else {
       // The profiler is stopped.
       locked_profiler_start(lock, aCapacity, aInterval, aFeatures, aFilters,
                             aFilterCount, aDuration);
       startedProfiler = true;
     }
   }
 
+#if defined(MOZ_REPLACE_MALLOC) && defined(MOZ_PROFILER_MEMORY)
+  if (startedProfiler && ProfilerFeature::HasMemory(aFeatures)) {
+    // start counting memory allocations (outside of lock because this may
+    // call profiler_add_sampled_counter which would attempt to take the
+    // lock.)
+    mozilla::profiler::install_memory_counter(true);
+  }
+#endif
+
   // We do these operations with gPSMutex unlocked. The comments in
   // profiler_stop() explain why.
   if (samplerThread) {
     ProfilerParent::ProfilerStopped();
     NotifyObservers("profiler-stopped");
     delete samplerThread;
   }
+
   if (startedProfiler) {
     NotifyProfilerStarted(aCapacity, aDuration, aInterval, aFeatures, aFilters,
                           aFilterCount);
   }
 }
 
 static MOZ_MUST_USE SamplerThread* locked_profiler_stop(PSLockRef aLock) {
   LOG("locked_profiler_stop");