diff --git a/dom/ipc/ContentParent.cpp b/dom/ipc/ContentParent.cpp index af715e802844..d623b72a0e20 100755 --- a/dom/ipc/ContentParent.cpp +++ b/dom/ipc/ContentParent.cpp @@ -1569,6 +1569,11 @@ ContentParent::Init() rv = profiler->GetStartParams(getter_AddRefs(currentProfilerParams)); MOZ_ASSERT(NS_SUCCEEDED(rv)); + nsCOMPtr gatherer; + rv = profiler->GetProfileGatherer(getter_AddRefs(gatherer)); + MOZ_ASSERT(NS_SUCCEEDED(rv)); + mGatherer = static_cast(gatherer.get()); + StartProfiler(currentProfilerParams); } #endif @@ -3293,6 +3298,7 @@ ContentParent::Observe(nsISupports* aSubject, StartProfiler(params); } else if (!strcmp(aTopic, "profiler-stopped")) { + mGatherer = nullptr; Unused << SendStopProfiler(); } else if (!strcmp(aTopic, "profiler-paused")) { @@ -3302,9 +3308,10 @@ ContentParent::Observe(nsISupports* aSubject, Unused << SendPauseProfiler(false); } else if (!strcmp(aTopic, "profiler-subprocess-gather")) { - mGatherer = static_cast(aSubject); - mGatherer->WillGatherOOPProfile(); - Unused << SendGatherProfile(); + if (mGatherer) { + mGatherer->WillGatherOOPProfile(); + Unused << SendGatherProfile(); + } } else if (!strcmp(aTopic, "profiler-subprocess")) { nsCOMPtr pse = do_QueryInterface(aSubject); @@ -5656,7 +5663,6 @@ ContentParent::RecvProfile(const nsCString& aProfile) } mProfile = aProfile; mGatherer->GatheredOOPProfile(); - mGatherer = nullptr; #endif return true; } @@ -5747,6 +5753,14 @@ ContentParent::StartProfiler(nsIProfilerStartParams* aParams) ipcParams.threadFilters() = aParams->GetThreadFilterNames(); Unused << SendStartProfiler(ipcParams); + + nsCOMPtr profiler(do_GetService("@mozilla.org/tools/profiler;1")); + if (NS_WARN_IF(!profiler)) { + return; + } + nsCOMPtr gatherer; + profiler->GetProfileGatherer(getter_AddRefs(gatherer)); + mGatherer = static_cast(gatherer.get()); #endif } diff --git a/dom/plugins/ipc/PluginModuleParent.cpp b/dom/plugins/ipc/PluginModuleParent.cpp index c4374febbb67..813f2522a9aa 100755 --- a/dom/plugins/ipc/PluginModuleParent.cpp +++ b/dom/plugins/ipc/PluginModuleParent.cpp @@ -627,6 +627,25 @@ PluginModuleChromeParent::OnProcessLaunched(const bool aSucceeded) } #endif } + +#ifdef MOZ_ENABLE_PROFILER_SPS + nsCOMPtr profiler(do_GetService("@mozilla.org/tools/profiler;1")); + bool profilerActive = false; + DebugOnly rv = profiler->IsActive(&profilerActive); + MOZ_ASSERT(NS_SUCCEEDED(rv)); + if (profilerActive) { + nsCOMPtr currentProfilerParams; + rv = profiler->GetStartParams(getter_AddRefs(currentProfilerParams)); + MOZ_ASSERT(NS_SUCCEEDED(rv)); + + nsCOMPtr gatherer; + rv = profiler->GetProfileGatherer(getter_AddRefs(gatherer)); + MOZ_ASSERT(NS_SUCCEEDED(rv)); + mGatherer = static_cast(gatherer.get()); + + StartProfiler(currentProfilerParams); + } +#endif } bool @@ -3162,23 +3181,9 @@ PluginProfilerObserver::Observe(nsISupports *aSubject, { if (!strcmp(aTopic, "profiler-started")) { nsCOMPtr params(do_QueryInterface(aSubject)); - uint32_t entries; - double interval; - params->GetEntries(&entries); - params->GetInterval(&interval); - const nsTArray& features = params->GetFeatures(); - const nsTArray& threadFilterNames = params->GetThreadFilterNames(); - - ProfilerInitParams ipcParams; - ipcParams.enabled() = true; - ipcParams.entries() = entries; - ipcParams.interval() = interval; - ipcParams.features() = features; - ipcParams.threadFilters() = threadFilterNames; - - Unused << mPmp->SendStartProfiler(ipcParams); + mPmp->StartProfiler(params); } else if (!strcmp(aTopic, "profiler-stopped")) { - Unused << mPmp->SendStopProfiler(); + mPmp->StopProfiler(); } else if (!strcmp(aTopic, "profiler-subprocess-gather")) { RefPtr gatherer = static_cast(aSubject); mPmp->GatherAsyncProfile(gatherer); @@ -3215,9 +3220,44 @@ PluginModuleChromeParent::ShutdownPluginProfiling() } void -PluginModuleChromeParent::GatherAsyncProfile(ProfileGatherer* aGatherer) +PluginModuleChromeParent::StartProfiler(nsIProfilerStartParams* aParams) { - mGatherer = aGatherer; + if (NS_WARN_IF(!aParams)) { + return; + } + + ProfilerInitParams ipcParams; + + ipcParams.enabled() = true; + aParams->GetEntries(&ipcParams.entries()); + aParams->GetInterval(&ipcParams.interval()); + ipcParams.features() = aParams->GetFeatures(); + ipcParams.threadFilters() = aParams->GetThreadFilterNames(); + + Unused << SendStartProfiler(ipcParams); + + nsCOMPtr profiler(do_GetService("@mozilla.org/tools/profiler;1")); + if (NS_WARN_IF(!profiler)) { + return; + } + nsCOMPtr gatherer; + profiler->GetProfileGatherer(getter_AddRefs(gatherer)); + mGatherer = static_cast(gatherer.get()); +} + +void +PluginModuleChromeParent::StopProfiler() +{ + mGatherer = nullptr; + Unused << SendStopProfiler(); +} + +void +PluginModuleChromeParent::GatherAsyncProfile() +{ + if (NS_WARN_IF(!mGatherer)) { + return; + } mGatherer->WillGatherOOPProfile(); Unused << SendGatherProfile(); } @@ -3242,7 +3282,6 @@ PluginModuleChromeParent::RecvProfile(const nsCString& aProfile) mProfile = aProfile; mGatherer->GatheredOOPProfile(); - mGatherer = nullptr; #endif return true; } diff --git a/dom/plugins/ipc/PluginModuleParent.h b/dom/plugins/ipc/PluginModuleParent.h index c3c0f9ed057f..74c3a0bc491c 100644 --- a/dom/plugins/ipc/PluginModuleParent.h +++ b/dom/plugins/ipc/PluginModuleParent.h @@ -456,8 +456,10 @@ class PluginModuleChromeParent void OnExitedSyncSend() override; #ifdef MOZ_ENABLE_PROFILER_SPS - void GatherAsyncProfile(mozilla::ProfileGatherer* aGatherer); + void GatherAsyncProfile(); void GatheredAsyncProfile(nsIProfileSaveEvent* aSaveEvent); + void StartProfiler(nsIProfilerStartParams* aParams); + void StopProfiler(); #endif virtual bool diff --git a/tools/profiler/core/GeckoSampler.cpp b/tools/profiler/core/GeckoSampler.cpp index 119154c5a9e3..82e8ed9036b3 100644 --- a/tools/profiler/core/GeckoSampler.cpp +++ b/tools/profiler/core/GeckoSampler.cpp @@ -410,6 +410,14 @@ JSObject* GeckoSampler::ToJSObject(JSContext *aCx, double aSinceTime) } return &val.toObject(); } + +void GeckoSampler::GetGatherer(nsISupports** aRetVal) +{ + if (!aRetVal || NS_WARN_IF(!mGatherer)) { + return; + } + NS_ADDREF(*aRetVal = mGatherer); +} #endif UniquePtr GeckoSampler::ToJSON(double aSinceTime) diff --git a/tools/profiler/core/GeckoSampler.h b/tools/profiler/core/GeckoSampler.h index a5bc73a6b4fe..aaba3961c06f 100644 --- a/tools/profiler/core/GeckoSampler.h +++ b/tools/profiler/core/GeckoSampler.h @@ -104,6 +104,7 @@ class GeckoSampler: public Sampler { void ToStreamAsJSON(std::ostream& stream, double aSinceTime = 0); #ifndef SPS_STANDALONE virtual JSObject *ToJSObject(JSContext *aCx, double aSinceTime = 0); + void GetGatherer(nsISupports** aRetVal); #endif mozilla::UniquePtr ToJSON(double aSinceTime = 0); virtual void ToJSObjectAsync(double aSinceTime = 0, mozilla::dom::Promise* aPromise = 0); diff --git a/tools/profiler/core/platform.cpp b/tools/profiler/core/platform.cpp index aa8b65e9d366..af915a171172 100644 --- a/tools/profiler/core/platform.cpp +++ b/tools/profiler/core/platform.cpp @@ -642,6 +642,26 @@ void mozilla_sampler_get_profiler_start_params(int* aEntrySize, } } +void mozilla_sampler_get_gatherer(nsISupports** aRetVal) +{ + if (!aRetVal) { + return; + } + + if (NS_WARN_IF(!profiler_is_active())) { + *aRetVal = nullptr; + return; + } + + GeckoSampler *t = tlsTicker.get(); + if (NS_WARN_IF(!t)) { + *aRetVal = nullptr; + return; + } + + t->GetGatherer(aRetVal); +} + #endif void mozilla_sampler_save_profile_to_file(const char* aFilename) diff --git a/tools/profiler/gecko/nsIProfiler.idl b/tools/profiler/gecko/nsIProfiler.idl index 5a628de4b005..98260a1e6f77 100644 --- a/tools/profiler/gecko/nsIProfiler.idl +++ b/tools/profiler/gecko/nsIProfiler.idl @@ -27,7 +27,7 @@ interface nsIProfilerStartParams : nsISupports [noscript, notxpcom, nostdcall] StringArrayRef getThreadFilterNames(); }; -[scriptable, uuid(b373b360-c997-448a-b60d-4985b70dc810)] +[scriptable, uuid(ead3f75c-0e0e-4fbb-901c-1e5392ef5b2a)] interface nsIProfiler : nsISupports { boolean CanProfile(); @@ -66,6 +66,12 @@ interface nsIProfiler : nsISupports */ readonly attribute nsIProfilerStartParams startParams; + /** + * The profileGatherer will be null if the profiler is not currently + * active. + */ + readonly attribute nsISupports profileGatherer; + void GetBufferInfo(out uint32_t aCurrentPosition, out uint32_t aTotalSize, out uint32_t aGeneration); diff --git a/tools/profiler/gecko/nsProfiler.cpp b/tools/profiler/gecko/nsProfiler.cpp index b4b0068f01ee..c38447381bc7 100644 --- a/tools/profiler/gecko/nsProfiler.cpp +++ b/tools/profiler/gecko/nsProfiler.cpp @@ -288,3 +288,21 @@ nsProfiler::GetBufferInfo(uint32_t *aCurrentPosition, uint32_t *aTotalSize, uint profiler_get_buffer_info(aCurrentPosition, aTotalSize, aGeneration); return NS_OK; } + +NS_IMETHODIMP +nsProfiler::GetProfileGatherer(nsISupports** aRetVal) +{ + if (!aRetVal) { + return NS_ERROR_INVALID_POINTER; + } + + // If we're not profiling, there will be no gatherer. + if (!profiler_is_active()) { + *aRetVal = nullptr; + } else { + nsCOMPtr gatherer; + profiler_get_gatherer(getter_AddRefs(gatherer)); + gatherer.forget(aRetVal); + } + return NS_OK; +} \ No newline at end of file diff --git a/tools/profiler/public/GeckoProfilerFunc.h b/tools/profiler/public/GeckoProfilerFunc.h index 9ee14f3c34f9..bc9562a36512 100644 --- a/tools/profiler/public/GeckoProfilerFunc.h +++ b/tools/profiler/public/GeckoProfilerFunc.h @@ -14,6 +14,8 @@ #include "mozilla/Vector.h" #include +class nsISupports; + namespace mozilla { class TimeStamp; @@ -73,6 +75,7 @@ void mozilla_sampler_get_profiler_start_params(int* aEntrySize, double* aInterval, mozilla::Vector* aFilters, mozilla::Vector* aFeatures); +void mozilla_sampler_get_gatherer(nsISupports** aRetVal); #endif // Make this function easily callable from a debugger in a build without diff --git a/tools/profiler/public/GeckoProfilerImpl.h b/tools/profiler/public/GeckoProfilerImpl.h index 943752fde269..3792bb17fcc3 100644 --- a/tools/profiler/public/GeckoProfilerImpl.h +++ b/tools/profiler/public/GeckoProfilerImpl.h @@ -179,6 +179,13 @@ void profiler_get_start_params(int* aEntrySize, { mozilla_sampler_get_profiler_start_params(aEntrySize, aInterval, aFilters, aFeatures); } + +static inline +void profiler_get_gatherer(nsISupports** aRetVal) +{ + mozilla_sampler_get_gatherer(aRetVal); +} + #endif static inline