Bug 1321617 - Tell the CrossProcessProfilerController whether a profile is a response to a GatherProfile request or whether it was sent because the process was exiting. r?mconley draft
authorMarkus Stange <mstange@themasta.com>
Sat, 08 Apr 2017 20:27:56 -0400
changeset 559162 1569eb0b6973fedef10d79bc3356d208306fc653
parent 558975 37d80135ecb58eef37aba5528f271925091b9f07
child 559163 fc23b15ea50cb435790be2e4f79ad78d02335776
push id53008
push userbmo:mstange@themasta.com
push dateSun, 09 Apr 2017 03:27:44 +0000
reviewersmconley
bugs1321617
milestone55.0a1
Bug 1321617 - Tell the CrossProcessProfilerController whether a profile is a response to a GatherProfile request or whether it was sent because the process was exiting. r?mconley MozReview-Commit-ID: BLkaeZqtRhv
dom/ipc/ContentChild.cpp
dom/ipc/ContentChild.h
dom/ipc/ContentParent.cpp
dom/ipc/ContentParent.h
dom/ipc/PContent.ipdl
dom/plugins/ipc/PPluginModule.ipdl
dom/plugins/ipc/PluginModuleChild.cpp
dom/plugins/ipc/PluginModuleParent.cpp
dom/plugins/ipc/PluginModuleParent.h
gfx/ipc/GPUChild.cpp
gfx/ipc/GPUChild.h
gfx/ipc/GPUParent.cpp
gfx/ipc/PGPU.ipdl
tools/profiler/gecko/CrossProcessProfilerController.cpp
tools/profiler/public/CrossProcessProfilerController.h
--- a/dom/ipc/ContentChild.cpp
+++ b/dom/ipc/ContentChild.cpp
@@ -2530,28 +2530,34 @@ ContentChild::RecvPauseProfiler(const bo
     profiler_pause();
   } else {
     profiler_resume();
   }
 
   return IPC_OK();
 }
 
-mozilla::ipc::IPCResult
-ContentChild::RecvGatherProfile()
+void
+ContentChild::GatherProfile(bool aIsExitProfile)
 {
   nsCString profileCString;
   UniquePtr<char[]> profile = profiler_get_profile();
   if (profile) {
     profileCString = nsCString(profile.get(), strlen(profile.get()));
   } else {
     profileCString = EmptyCString();
   }
 
-  Unused << SendProfile(profileCString);
+  Unused << SendProfile(profileCString, aIsExitProfile);
+}
+
+mozilla::ipc::IPCResult
+ContentChild::RecvGatherProfile()
+{
+  GatherProfile(false);
   return IPC_OK();
 }
 
 mozilla::ipc::IPCResult
 ContentChild::RecvLoadPluginResult(const uint32_t& aPluginId,
                                    const bool& aResult)
 {
   nsresult rv;
@@ -2715,17 +2721,17 @@ ContentChild::RecvShutdown()
 
   GetIPCChannel()->SetAbortOnError(false);
 
 #ifdef MOZ_GECKO_PROFILER
   if (profiler_is_active()) {
     // We're shutting down while we were profiling. Send the
     // profile up to the parent so that we don't lose this
     // information.
-    Unused << RecvGatherProfile();
+    GatherProfile(true);
   }
 #endif
 
   // Start a timer that will insure we quickly exit after a reasonable
   // period of time. Prevents shutdown hangs after our connection to the
   // parent closes.
   StartForceKillTimer();
 
--- a/dom/ipc/ContentChild.h
+++ b/dom/ipc/ContentChild.h
@@ -649,16 +649,18 @@ private:
 
   virtual void ActorDestroy(ActorDestroyReason why) override;
 
   virtual void ProcessingError(Result aCode, const char* aReason) override;
 
   virtual already_AddRefed<nsIEventTarget>
   GetConstructedEventTarget(const Message& aMsg) override;
 
+  void GatherProfile(bool aIsExitProfile);
+
   InfallibleTArray<nsAutoPtr<AlertObserver> > mAlertObservers;
   RefPtr<ConsoleListener> mConsoleListener;
 
   nsTHashtable<nsPtrHashKey<nsIObserver>> mIdleObservers;
 
   InfallibleTArray<nsString> mAvailableDictionaries;
 
   // Temporary storage for a list of available font families, passed from the
--- a/dom/ipc/ContentParent.cpp
+++ b/dom/ipc/ContentParent.cpp
@@ -4673,21 +4673,21 @@ ContentParent::RecvCreateWindowInDiffere
   if (NS_FAILED(rv)) {
     NS_WARNING("Call to CommonCreateWindow failed.");
   }
 
   return IPC_OK();
 }
 
 mozilla::ipc::IPCResult
-ContentParent::RecvProfile(const nsCString& aProfile)
+ContentParent::RecvProfile(const nsCString& aProfile, const bool& aIsExitProfile)
 {
 #ifdef MOZ_GECKO_PROFILER
   if (mProfilerController) {
-    mProfilerController->RecvProfile(aProfile);
+    mProfilerController->RecvProfile(aProfile, aIsExitProfile);
   }
 #endif
   return IPC_OK();
 }
 
 mozilla::ipc::IPCResult
 ContentParent::RecvGetGraphicsDeviceInitData(ContentDeviceData* aOut)
 {
--- a/dom/ipc/ContentParent.h
+++ b/dom/ipc/ContentParent.h
@@ -1095,17 +1095,18 @@ private:
 
   virtual PWebrtcGlobalParent* AllocPWebrtcGlobalParent() override;
   virtual bool DeallocPWebrtcGlobalParent(PWebrtcGlobalParent *aActor) override;
 
 
   virtual mozilla::ipc::IPCResult RecvUpdateDropEffect(const uint32_t& aDragAction,
                                                        const uint32_t& aDropEffect) override;
 
-  virtual mozilla::ipc::IPCResult RecvProfile(const nsCString& aProfile) override;
+  virtual mozilla::ipc::IPCResult RecvProfile(const nsCString& aProfile,
+                                              const bool& aIsExitProfile) override;
 
   virtual mozilla::ipc::IPCResult RecvGetGraphicsDeviceInitData(ContentDeviceData* aOut) override;
 
   virtual mozilla::ipc::IPCResult RecvGetAndroidSystemInfo(AndroidSystemInfo* aInfo) override;
 
   virtual mozilla::ipc::IPCResult RecvNotifyBenchmarkResult(const nsString& aCodecName,
                                                             const uint32_t& aDecodeFPS) override;
 
--- a/dom/ipc/PContent.ipdl
+++ b/dom/ipc/PContent.ipdl
@@ -967,17 +967,17 @@ parent:
      *
      * NOTE: The principal is untrusted in the parent process. Only
      *       principals that can live in the content process should
      *       provided.
      */
     async PContentPermissionRequest(PermissionRequest[] aRequests, Principal aPrincipal,
                                     TabId tabId);
 
-    async Profile(nsCString aProfile);
+    async Profile(nsCString aProfile, bool aIsExitProfile);
 
     /**
      * Request graphics initialization information from the parent.
      */
     sync GetGraphicsDeviceInitData()
         returns (ContentDeviceData aData);
 
     sync CreateWindow(nullable PBrowser aThisTab,
--- a/dom/plugins/ipc/PPluginModule.ipdl
+++ b/dom/plugins/ipc/PPluginModule.ipdl
@@ -148,17 +148,17 @@ parent:
 
   async NPN_ReloadPlugins(bool aReloadPages);
 
   // Notifies the chrome process that a PluginModuleChild linked to a content
   // process was destroyed. The chrome process may choose to asynchronously shut
   // down the plugin process in response.
   async NotifyContentModuleDestroyed();
 
-  async Profile(nsCString aProfile);
+  async Profile(nsCString aProfile, bool aIsExitProfile);
 
   // Answers to request about site data
   async ReturnClearSiteData(NPError aRv, uint64_t aCallbackId);
 
   async ReturnSitesWithData(nsCString[] aSites, uint64_t aCallbackId);
 
   intr GetKeyState(int32_t aVirtKey)
     returns (int16_t aState);
--- a/dom/plugins/ipc/PluginModuleChild.cpp
+++ b/dom/plugins/ipc/PluginModuleChild.cpp
@@ -2740,17 +2740,17 @@ PluginModuleChild::RecvGatherProfile()
     nsCString profileCString;
     UniquePtr<char[]> profile = profiler_get_profile();
     if (profile != nullptr) {
         profileCString = nsCString(profile.get(), strlen(profile.get()));
     } else {
         profileCString = nsCString("", 0);
     }
 
-    Unused << SendProfile(profileCString);
+    Unused << SendProfile(profileCString, false);
     return IPC_OK();
 }
 
 NPError
 PluginModuleChild::PluginRequiresAudioDeviceChanges(
                           PluginInstanceChild* aInstance,
                           NPBool aShouldRegister)
 {
--- a/dom/plugins/ipc/PluginModuleParent.cpp
+++ b/dom/plugins/ipc/PluginModuleParent.cpp
@@ -3256,21 +3256,22 @@ PluginModuleChromeParent::OnCrash(DWORD 
             NS_ERROR("Failed to open child process when attempting kill.");
         }
     }
 }
 
 #endif // MOZ_CRASHREPORTER_INJECTOR
 
 mozilla::ipc::IPCResult
-PluginModuleChromeParent::RecvProfile(const nsCString& aProfile)
+PluginModuleChromeParent::RecvProfile(const nsCString& aProfile,
+                                      const bool&  aIsExitProfile)
 {
 #ifdef MOZ_GECKO_PROFILER
     if (mProfilerController) {
-        mProfilerController->RecvProfile(aProfile);
+        mProfilerController->RecvProfile(aProfile, aIsExitProfile);
     }
 #endif
     return IPC_OK();
 }
 
 mozilla::ipc::IPCResult
 PluginModuleParent::AnswerGetKeyState(const int32_t& aVirtKey, int16_t* aRet)
 {
--- a/dom/plugins/ipc/PluginModuleParent.h
+++ b/dom/plugins/ipc/PluginModuleParent.h
@@ -228,17 +228,17 @@ protected:
 protected:
     void SetChildTimeout(const int32_t aChildTimeout);
     static void TimeoutChanged(const char* aPref, void* aModule);
 
     virtual void UpdatePluginTimeout() {}
 
     virtual mozilla::ipc::IPCResult RecvNotifyContentModuleDestroyed() override { return IPC_OK(); }
 
-    virtual mozilla::ipc::IPCResult RecvProfile(const nsCString& aProfile) override { return IPC_OK(); }
+    virtual mozilla::ipc::IPCResult RecvProfile(const nsCString& aProfile, const bool& aIsExitProfile) override { return IPC_OK(); }
 
     virtual mozilla::ipc::IPCResult AnswerGetKeyState(const int32_t& aVirtKey, int16_t* aRet) override;
 
     virtual mozilla::ipc::IPCResult RecvReturnClearSiteData(const NPError& aRv,
                                                             const uint64_t& aCallbackId) override;
 
     virtual mozilla::ipc::IPCResult RecvReturnSitesWithData(nsTArray<nsCString>&& aSites,
                                                             const uint64_t& aCallbackId) override;
@@ -522,17 +522,17 @@ class PluginModuleChromeParent
     SetContentParent(dom::ContentParent* aContentParent);
 
     bool
     SendAssociatePluginId();
 
     void CachedSettingChanged();
 
     virtual mozilla::ipc::IPCResult
-    RecvProfile(const nsCString& aProfile) override;
+    RecvProfile(const nsCString& aProfile, const bool& aIsExitProfile) override;
 
     virtual mozilla::ipc::IPCResult
     AnswerGetKeyState(const int32_t& aVirtKey, int16_t* aRet) override;
 
     // Proxy GetOpenFileName/GetSaveFileName on Windows.
     virtual mozilla::ipc::IPCResult
     AnswerGetFileName(const GetFileNameFunc& aFunc,
                       const OpenFileNameIPC& aOfnIn,
--- a/gfx/ipc/GPUChild.cpp
+++ b/gfx/ipc/GPUChild.cpp
@@ -200,21 +200,21 @@ GPUChild::RecvRecordChildEvents(nsTArray
 mozilla::ipc::IPCResult
 GPUChild::RecvNotifyDeviceReset()
 {
   mHost->mListener->OnProcessDeviceReset(mHost);
   return IPC_OK();
 }
 
 mozilla::ipc::IPCResult
-GPUChild::RecvProfile(const nsCString& aProfile)
+GPUChild::RecvProfile(const nsCString& aProfile, const bool& aIsExitProfile)
 {
 #ifdef MOZ_GECKO_PROFILER
   if (mProfilerController) {
-    mProfilerController->RecvProfile(aProfile);
+    mProfilerController->RecvProfile(aProfile, aIsExitProfile);
   }
 #endif
   return IPC_OK();
 }
 
 bool
 GPUChild::SendRequestMemoryReport(const uint32_t& aGeneration,
                                   const bool& aAnonymize,
--- a/gfx/ipc/GPUChild.h
+++ b/gfx/ipc/GPUChild.h
@@ -56,17 +56,17 @@ public:
   mozilla::ipc::IPCResult RecvUpdateChildScalars(InfallibleTArray<ScalarAction>&& aScalarActions) override;
   mozilla::ipc::IPCResult RecvUpdateChildKeyedScalars(InfallibleTArray<KeyedScalarAction>&& aScalarActions) override;
   mozilla::ipc::IPCResult RecvRecordChildEvents(nsTArray<ChildEventData>&& events) override;
 
   void ActorDestroy(ActorDestroyReason aWhy) override;
   mozilla::ipc::IPCResult RecvGraphicsError(const nsCString& aError) override;
   mozilla::ipc::IPCResult RecvNotifyUiObservers(const nsCString& aTopic) override;
   mozilla::ipc::IPCResult RecvNotifyDeviceReset() override;
-  mozilla::ipc::IPCResult RecvProfile(const nsCString& aProfile) override;
+  mozilla::ipc::IPCResult RecvProfile(const nsCString& aProfile, const bool& aIsExitProfile) override;
   mozilla::ipc::IPCResult RecvAddMemoryReport(const MemoryReport& aReport) override;
   mozilla::ipc::IPCResult RecvFinishMemoryReport(const uint32_t& aGeneration) override;
 
   void SendStartProfiler(const ProfilerInitParams& aParams) override;
   void SendStopProfiler() override;
   void SendPauseProfiler(const bool& aPause) override;
   void SendGatherProfile() override;
 
--- a/gfx/ipc/GPUParent.cpp
+++ b/gfx/ipc/GPUParent.cpp
@@ -423,17 +423,17 @@ mozilla::ipc::IPCResult
 GPUParent::RecvGatherProfile()
 {
   nsCString profileCString;
   UniquePtr<char[]> profile = profiler_get_profile();
   if (profile) {
     profileCString = nsDependentCString(profile.get());
   }
 
-  Unused << SendProfile(profileCString);
+  Unused << SendProfile(profileCString, false);
   return IPC_OK();
 }
 
 mozilla::ipc::IPCResult
 GPUParent::RecvRequestMemoryReport(const uint32_t& aGeneration,
                                    const bool& aAnonymize,
                                    const bool& aMinimizeMemoryUsage,
                                    const MaybeFileDesc& aDMDFile)
--- a/gfx/ipc/PGPU.ipdl
+++ b/gfx/ipc/PGPU.ipdl
@@ -123,15 +123,15 @@ child:
   async AccumulateChildKeyedHistograms(KeyedAccumulation[] accumulations);
   async UpdateChildScalars(ScalarAction[] actions);
   async UpdateChildKeyedScalars(KeyedScalarAction[] actions);
   async RecordChildEvents(ChildEventData[] events);
 
   async NotifyDeviceReset();
 
   // Called in response to GatherProfile.
-  async Profile(nsCString aProfile);
+  async Profile(nsCString aProfile, bool aIsExitProfile);
   async AddMemoryReport(MemoryReport aReport);
   async FinishMemoryReport(uint32_t aGeneration);
 };
 
 } // namespace gfx
 } // namespace mozilla
--- a/tools/profiler/gecko/CrossProcessProfilerController.cpp
+++ b/tools/profiler/gecko/CrossProcessProfilerController.cpp
@@ -157,17 +157,18 @@ CrossProcessProfilerController::Observe(
   else if (!strcmp(aTopic, "profiler-resumed")) {
     mProcess->SendPauseProfiler(false);
   }
 }
 
 // This is called in response to a SendGatherProfile request, or when the
 // other process exits while the profiler is running.
 void
-CrossProcessProfilerController::RecvProfile(const nsCString& aProfile)
+CrossProcessProfilerController::RecvProfile(const nsCString& aProfile,
+                                            bool aIsExitProfile)
 {
   // Store the profile on this object.
   mProfile = aProfile;
   // Tell the gatherer that we've received the profile from this process, but
   // don't actually give it the profile. It will request the profile once all
   // processes have replied, through the "profiler-subprocess" observer
   // notification.
   nsProfiler::GetOrCreate()->GatheredOOPProfile();
--- a/tools/profiler/public/CrossProcessProfilerController.h
+++ b/tools/profiler/public/CrossProcessProfilerController.h
@@ -20,17 +20,17 @@ class ProfilerControllingProcess;
 // RecvProfile needs to be called when the other process replies with its
 // profile.
 class CrossProcessProfilerController final
 {
 public:
   // aProcess is expected to outlast this CrossProcessProfilerController object.
   explicit CrossProcessProfilerController(ProfilerControllingProcess* aProcess);
   ~CrossProcessProfilerController();
-  void RecvProfile(const nsCString& aProfile);
+  void RecvProfile(const nsCString& aProfile, bool aIsExitProfile);
 
 private:
   void StartProfiler(nsIProfilerStartParams* aParams);
   void Observe(nsISupports* aSubject, const char* aTopic);
 
   friend class ProfilerObserver;
 
   ProfilerControllingProcess* mProcess;