mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 1008435 - Let the Gecko Profiler work with child processes. r=BenWa,smaug.
We now allow profiling the content process for e10s, and plugin processes. --HG-- extra : rebase_source : 1f2e35d4d55b33b56160132893dbf7d4787925fa extra : amend_source : d03465d4318f8e50c7624ad0eeb681b30c068b11
This commit is contained in:
parent
cae77eaed3
commit
df420b6488
@ -16,6 +16,7 @@
|
||||
|
||||
#include "BlobChild.h"
|
||||
#include "CrashReporterChild.h"
|
||||
#include "GeckoProfiler.h"
|
||||
#include "TabChild.h"
|
||||
|
||||
#include "mozilla/Attributes.h"
|
||||
@ -2385,6 +2386,48 @@ ContentChild::RecvOnAppThemeChanged()
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
ContentChild::RecvStartProfiler(const uint32_t& aEntries,
|
||||
const double& aInterval,
|
||||
const nsTArray<nsCString>& aFeatures,
|
||||
const nsTArray<nsCString>& aThreadNameFilters)
|
||||
{
|
||||
nsTArray<const char*> featureArray;
|
||||
for (size_t i = 0; i < aFeatures.Length(); ++i) {
|
||||
featureArray.AppendElement(aFeatures[i].get());
|
||||
}
|
||||
|
||||
nsTArray<const char*> threadNameFilterArray;
|
||||
for (size_t i = 0; i < aThreadNameFilters.Length(); ++i) {
|
||||
threadNameFilterArray.AppendElement(aThreadNameFilters[i].get());
|
||||
}
|
||||
|
||||
profiler_start(aEntries, aInterval, featureArray.Elements(), featureArray.Length(),
|
||||
threadNameFilterArray.Elements(), threadNameFilterArray.Length());
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
ContentChild::RecvStopProfiler()
|
||||
{
|
||||
profiler_stop();
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
ContentChild::AnswerGetProfile(nsCString* aProfile)
|
||||
{
|
||||
char* profile = profiler_get_profile();
|
||||
if (profile) {
|
||||
*aProfile = nsCString(profile, strlen(profile));
|
||||
free(profile);
|
||||
} else {
|
||||
*aProfile = EmptyCString();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
PBrowserOrId
|
||||
ContentChild::GetBrowserOrId(TabChild* aTabChild)
|
||||
{
|
||||
|
@ -358,6 +358,13 @@ public:
|
||||
|
||||
virtual bool RecvOnAppThemeChanged() MOZ_OVERRIDE;
|
||||
|
||||
virtual bool RecvStartProfiler(const uint32_t& aEntries,
|
||||
const double& aInterval,
|
||||
const nsTArray<nsCString>& aFeatures,
|
||||
const nsTArray<nsCString>& aThreadNameFilters) MOZ_OVERRIDE;
|
||||
virtual bool RecvStopProfiler() MOZ_OVERRIDE;
|
||||
virtual bool AnswerGetProfile(nsCString* aProfile) MOZ_OVERRIDE;
|
||||
|
||||
#ifdef ANDROID
|
||||
gfxIntSize GetScreenSize() { return mScreenSize; }
|
||||
#endif
|
||||
|
@ -201,6 +201,11 @@ using namespace mozilla::system;
|
||||
#include "nsIBrowserSearchService.h"
|
||||
#endif
|
||||
|
||||
#ifdef MOZ_ENABLE_PROFILER_SPS
|
||||
#include "nsIProfiler.h"
|
||||
#include "nsIProfileSaveEvent.h"
|
||||
#endif
|
||||
|
||||
static NS_DEFINE_CID(kCClipboardCID, NS_CLIPBOARD_CID);
|
||||
static const char* sClipboardTextFlavors[] = { kUnicodeMime };
|
||||
|
||||
@ -590,6 +595,11 @@ static const char* sObserverTopics[] = {
|
||||
"a11y-init-or-shutdown",
|
||||
#endif
|
||||
"app-theme-changed",
|
||||
#ifdef MOZ_ENABLE_PROFILER_SPS
|
||||
"profiler-started",
|
||||
"profiler-stopped",
|
||||
"profiler-subprocess",
|
||||
#endif
|
||||
};
|
||||
|
||||
/* static */ already_AddRefed<ContentParent>
|
||||
@ -2795,6 +2805,31 @@ ContentParent::Observe(nsISupports* aSubject,
|
||||
else if (!strcmp(aTopic, "app-theme-changed")) {
|
||||
unused << SendOnAppThemeChanged();
|
||||
}
|
||||
#ifdef MOZ_ENABLE_PROFILER_SPS
|
||||
else if (!strcmp(aTopic, "profiler-started")) {
|
||||
nsCOMPtr<nsIProfilerStartParams> params(do_QueryInterface(aSubject));
|
||||
uint32_t entries;
|
||||
double interval;
|
||||
params->GetEntries(&entries);
|
||||
params->GetInterval(&interval);
|
||||
const nsTArray<nsCString>& features = params->GetFeatures();
|
||||
const nsTArray<nsCString>& threadFilterNames = params->GetThreadFilterNames();
|
||||
unused << SendStartProfiler(entries, interval, features, threadFilterNames);
|
||||
}
|
||||
else if (!strcmp(aTopic, "profiler-stopped")) {
|
||||
unused << SendStopProfiler();
|
||||
}
|
||||
else if (!strcmp(aTopic, "profiler-subprocess")) {
|
||||
nsCOMPtr<nsIProfileSaveEvent> pse = do_QueryInterface(aSubject);
|
||||
if (pse) {
|
||||
nsCString result;
|
||||
unused << CallGetProfile(&result);
|
||||
if (!result.IsEmpty()) {
|
||||
pse->AddSubProfile(result.get());
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
@ -509,6 +509,15 @@ child:
|
||||
*/
|
||||
OnAppThemeChanged();
|
||||
|
||||
/**
|
||||
* Control the Gecko Profiler in the child process.
|
||||
*/
|
||||
async StartProfiler(uint32_t aEntries, double aInterval, nsCString[] aFeatures,
|
||||
nsCString[] aThreadNameFilters);
|
||||
async StopProfiler();
|
||||
intr GetProfile()
|
||||
returns (nsCString aProfile);
|
||||
|
||||
parent:
|
||||
/**
|
||||
* Tell the parent process a new accessible document has been created.
|
||||
|
@ -81,7 +81,13 @@ child:
|
||||
intr PCrashReporter()
|
||||
returns (NativeThreadId tid, uint32_t processType);
|
||||
|
||||
intr GeckoGetProfile()
|
||||
/**
|
||||
* Control the Gecko Profiler in the plugin process.
|
||||
*/
|
||||
async StartProfiler(uint32_t aEntries, double aInterval, nsCString[] aFeatures,
|
||||
nsCString[] aThreadNameFilters);
|
||||
async StopProfiler();
|
||||
intr GetProfile()
|
||||
returns (nsCString aProfile);
|
||||
|
||||
async SettingChanged(PluginSettings settings);
|
||||
|
@ -2370,7 +2370,37 @@ PluginModuleChild::ProcessNativeEvents() {
|
||||
#endif
|
||||
|
||||
bool
|
||||
PluginModuleChild::AnswerGeckoGetProfile(nsCString* aProfile) {
|
||||
PluginModuleChild::RecvStartProfiler(const uint32_t& aEntries,
|
||||
const double& aInterval,
|
||||
const nsTArray<nsCString>& aFeatures,
|
||||
const nsTArray<nsCString>& aThreadNameFilters)
|
||||
{
|
||||
nsTArray<const char*> featureArray;
|
||||
for (size_t i = 0; i < aFeatures.Length(); ++i) {
|
||||
featureArray.AppendElement(aFeatures[i].get());
|
||||
}
|
||||
|
||||
nsTArray<const char*> threadNameFilterArray;
|
||||
for (size_t i = 0; i < aThreadNameFilters.Length(); ++i) {
|
||||
threadNameFilterArray.AppendElement(aThreadNameFilters[i].get());
|
||||
}
|
||||
|
||||
profiler_start(aEntries, aInterval, featureArray.Elements(), featureArray.Length(),
|
||||
threadNameFilterArray.Elements(), threadNameFilterArray.Length());
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
PluginModuleChild::RecvStopProfiler()
|
||||
{
|
||||
profiler_stop();
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
PluginModuleChild::AnswerGetProfile(nsCString* aProfile)
|
||||
{
|
||||
char* profile = profiler_get_profile();
|
||||
if (profile != nullptr) {
|
||||
*aProfile = nsCString(profile, strlen(profile));
|
||||
@ -2380,4 +2410,3 @@ PluginModuleChild::AnswerGeckoGetProfile(nsCString* aProfile) {
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -142,8 +142,12 @@ protected:
|
||||
virtual bool
|
||||
RecvProcessNativeEventsInInterruptCall() MOZ_OVERRIDE;
|
||||
|
||||
virtual bool
|
||||
AnswerGeckoGetProfile(nsCString* aProfile) MOZ_OVERRIDE;
|
||||
virtual bool RecvStartProfiler(const uint32_t& aEntries,
|
||||
const double& aInterval,
|
||||
const nsTArray<nsCString>& aFeatures,
|
||||
const nsTArray<nsCString>& aThreadNameFilters) MOZ_OVERRIDE;
|
||||
virtual bool RecvStopProfiler() MOZ_OVERRIDE;
|
||||
virtual bool AnswerGetProfile(nsCString* aProfile) MOZ_OVERRIDE;
|
||||
|
||||
public:
|
||||
PluginModuleChild(bool aIsChrome);
|
||||
|
@ -40,6 +40,7 @@
|
||||
#endif
|
||||
|
||||
#ifdef MOZ_ENABLE_PROFILER_SPS
|
||||
#include "nsIProfiler.h"
|
||||
#include "nsIProfileSaveEvent.h"
|
||||
#endif
|
||||
|
||||
@ -1968,13 +1969,26 @@ PluginProfilerObserver::Observe(nsISupports *aSubject,
|
||||
const char *aTopic,
|
||||
const char16_t *aData)
|
||||
{
|
||||
nsCOMPtr<nsIProfileSaveEvent> pse = do_QueryInterface(aSubject);
|
||||
if (pse) {
|
||||
nsCString result;
|
||||
bool success = mPmp->CallGeckoGetProfile(&result);
|
||||
if (success && !result.IsEmpty()) {
|
||||
pse->AddSubProfile(result.get());
|
||||
}
|
||||
if (!strcmp(aTopic, "profiler-started")) {
|
||||
nsCOMPtr<nsIProfilerStartParams> params(do_QueryInterface(aSubject));
|
||||
uint32_t entries;
|
||||
double interval;
|
||||
params->GetEntries(&entries);
|
||||
params->GetInterval(&interval);
|
||||
const nsTArray<nsCString>& features = params->GetFeatures();
|
||||
const nsTArray<nsCString>& threadFilterNames = params->GetThreadFilterNames();
|
||||
unused << mPmp->SendStartProfiler(entries, interval, features, threadFilterNames);
|
||||
} else if (!strcmp(aTopic, "profiler-stopped")) {
|
||||
unused << mPmp->SendStopProfiler();
|
||||
} else if (!strcmp(aTopic, "profiler-subprocess")) {
|
||||
nsCOMPtr<nsIProfileSaveEvent> pse = do_QueryInterface(aSubject);
|
||||
if (pse) {
|
||||
nsCString result;
|
||||
bool success = mPmp->CallGetProfile(&result);
|
||||
if (success && !result.IsEmpty()) {
|
||||
pse->AddSubProfile(result.get());
|
||||
}
|
||||
}
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
@ -1985,6 +1999,8 @@ PluginModuleChromeParent::InitPluginProfiling()
|
||||
nsCOMPtr<nsIObserverService> observerService = mozilla::services::GetObserverService();
|
||||
if (observerService) {
|
||||
mProfilerObserver = new PluginProfilerObserver(this);
|
||||
observerService->AddObserver(mProfilerObserver, "profiler-started", false);
|
||||
observerService->AddObserver(mProfilerObserver, "profiler-stopped", false);
|
||||
observerService->AddObserver(mProfilerObserver, "profiler-subprocess", false);
|
||||
}
|
||||
}
|
||||
@ -1994,6 +2010,8 @@ PluginModuleChromeParent::ShutdownPluginProfiling()
|
||||
{
|
||||
nsCOMPtr<nsIObserverService> observerService = mozilla::services::GetObserverService();
|
||||
if (observerService) {
|
||||
observerService->RemoveObserver(mProfilerObserver, "profiler-started");
|
||||
observerService->RemoveObserver(mProfilerObserver, "profiler-stopped");
|
||||
observerService->RemoveObserver(mProfilerObserver, "profiler-subprocess");
|
||||
}
|
||||
}
|
||||
|
@ -323,6 +323,10 @@ void ThreadProfile::StreamJSObject(JSStreamWriter& b)
|
||||
if (XRE_GetProcessType() == GeckoProcessType_Plugin) {
|
||||
// TODO Add the proper plugin name
|
||||
b.NameValue("name", "Plugin");
|
||||
} else if (XRE_GetProcessType() == GeckoProcessType_Content) {
|
||||
// This isn't going to really help once we have multiple content
|
||||
// processes, but it'll do for now.
|
||||
b.NameValue("name", "Content");
|
||||
} else {
|
||||
b.NameValue("name", Name());
|
||||
}
|
||||
|
@ -28,6 +28,7 @@ if CONFIG['MOZ_ENABLE_PROFILER_SPS']:
|
||||
'JSStreamWriter.cpp',
|
||||
'nsProfiler.cpp',
|
||||
'nsProfilerFactory.cpp',
|
||||
'nsProfilerStartParams.cpp',
|
||||
'platform.cpp',
|
||||
'ProfileEntry.cpp',
|
||||
'ProfilerBacktrace.cpp',
|
||||
|
@ -5,6 +5,13 @@
|
||||
|
||||
#include "nsISupports.idl"
|
||||
|
||||
%{C++
|
||||
template<class T> class nsTArray;
|
||||
class nsCString;
|
||||
%}
|
||||
|
||||
[ref] native StringArrayRef(const nsTArray<nsCString>);
|
||||
|
||||
[scriptable, uuid(f7f3709c-04a9-45c6-8e34-40f762654a78)]
|
||||
interface nsIProfiler : nsISupports
|
||||
{
|
||||
@ -37,3 +44,17 @@ interface nsIProfiler : nsISupports
|
||||
AString getSharedLibraryInformation();
|
||||
};
|
||||
|
||||
/**
|
||||
* Start-up parameters for subprocesses are passed through nsIObserverService,
|
||||
* which, unfortunately, means we need to implement nsISupports in order to
|
||||
* go through it.
|
||||
*/
|
||||
[uuid(0a175ba7-8fcf-4ce9-9c4b-ccc6272f4425)]
|
||||
interface nsIProfilerStartParams : nsISupports
|
||||
{
|
||||
attribute uint32_t entries;
|
||||
attribute double interval;
|
||||
|
||||
[noscript, notxpcom, nostdcall] StringArrayRef getFeatures();
|
||||
[noscript, notxpcom, nostdcall] StringArrayRef getThreadFilterNames();
|
||||
};
|
||||
|
67
tools/profiler/nsProfilerStartParams.cpp
Normal file
67
tools/profiler/nsProfilerStartParams.cpp
Normal file
@ -0,0 +1,67 @@
|
||||
/* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#include "nsProfilerStartParams.h"
|
||||
|
||||
NS_IMPL_ISUPPORTS(nsProfilerStartParams, nsIProfilerStartParams)
|
||||
|
||||
nsProfilerStartParams::nsProfilerStartParams(uint32_t aEntries,
|
||||
double aInterval,
|
||||
const nsTArray<nsCString>& aFeatures,
|
||||
const nsTArray<nsCString>& aThreadFilterNames) :
|
||||
mEntries(aEntries),
|
||||
mInterval(aInterval),
|
||||
mFeatures(aFeatures),
|
||||
mThreadFilterNames(aThreadFilterNames)
|
||||
{
|
||||
}
|
||||
|
||||
nsProfilerStartParams::~nsProfilerStartParams()
|
||||
{
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsProfilerStartParams::GetEntries(uint32_t* aEntries)
|
||||
{
|
||||
NS_ENSURE_ARG_POINTER(aEntries);
|
||||
*aEntries = mEntries;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsProfilerStartParams::SetEntries(uint32_t aEntries)
|
||||
{
|
||||
NS_ENSURE_ARG(aEntries);
|
||||
mEntries = aEntries;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsProfilerStartParams::GetInterval(double* aInterval)
|
||||
{
|
||||
NS_ENSURE_ARG_POINTER(aInterval);
|
||||
*aInterval = mInterval;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsProfilerStartParams::SetInterval(double aInterval)
|
||||
{
|
||||
NS_ENSURE_ARG(aInterval);
|
||||
mInterval = aInterval;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
const nsTArray<nsCString>&
|
||||
nsProfilerStartParams::GetFeatures()
|
||||
{
|
||||
return mFeatures;
|
||||
}
|
||||
|
||||
const nsTArray<nsCString>&
|
||||
nsProfilerStartParams::GetThreadFilterNames()
|
||||
{
|
||||
return mThreadFilterNames;
|
||||
}
|
32
tools/profiler/nsProfilerStartParams.h
Normal file
32
tools/profiler/nsProfilerStartParams.h
Normal file
@ -0,0 +1,32 @@
|
||||
/* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#ifndef _NSPROFILERSTARTPARAMS_H_
|
||||
#define _NSPROFILERSTARTPARAMS_H_
|
||||
|
||||
#include "nsIProfiler.h"
|
||||
#include "nsString.h"
|
||||
#include "nsTArray.h"
|
||||
|
||||
class nsProfilerStartParams : public nsIProfilerStartParams
|
||||
{
|
||||
public:
|
||||
NS_DECL_ISUPPORTS
|
||||
NS_DECL_NSIPROFILERSTARTPARAMS
|
||||
|
||||
nsProfilerStartParams(uint32_t aEntries,
|
||||
double aInterval,
|
||||
const nsTArray<nsCString>& aFeatures,
|
||||
const nsTArray<nsCString>& aThreadFilterNames);
|
||||
|
||||
private:
|
||||
virtual ~nsProfilerStartParams();
|
||||
uint32_t mEntries;
|
||||
double mInterval;
|
||||
nsTArray<nsCString> mFeatures;
|
||||
nsTArray<nsCString> mThreadFilterNames;
|
||||
};
|
||||
|
||||
#endif
|
@ -19,6 +19,7 @@
|
||||
#include "nsIObserverService.h"
|
||||
#include "nsDirectoryServiceUtils.h"
|
||||
#include "nsDirectoryServiceDefs.h"
|
||||
#include "nsProfilerStartParams.h"
|
||||
#include "mozilla/Services.h"
|
||||
#include "nsThreadUtils.h"
|
||||
#include "ProfilerMarkers.h"
|
||||
@ -780,8 +781,24 @@ void mozilla_sampler_start(int aProfileEntries, double aInterval,
|
||||
|
||||
if (Sampler::CanNotifyObservers()) {
|
||||
nsCOMPtr<nsIObserverService> os = mozilla::services::GetObserverService();
|
||||
if (os)
|
||||
os->NotifyObservers(nullptr, "profiler-started", nullptr);
|
||||
if (os) {
|
||||
nsTArray<nsCString> featuresArray;
|
||||
nsTArray<nsCString> threadNameFiltersArray;
|
||||
|
||||
for (size_t i = 0; i < aFeatureCount; ++i) {
|
||||
featuresArray.AppendElement(aFeatures[i]);
|
||||
}
|
||||
|
||||
for (size_t i = 0; i < aFilterCount; ++i) {
|
||||
threadNameFiltersArray.AppendElement(aThreadNameFilters[i]);
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIProfilerStartParams> params =
|
||||
new nsProfilerStartParams(aProfileEntries, aInterval, featuresArray,
|
||||
threadNameFiltersArray);
|
||||
|
||||
os->NotifyObservers(params, "profiler-started", nullptr);
|
||||
}
|
||||
}
|
||||
|
||||
LOG("END mozilla_sampler_start");
|
||||
|
Loading…
Reference in New Issue
Block a user