mirror of
https://github.com/mozilla/gecko-dev.git
synced 2025-03-04 07:40:42 +00:00
Bug 1287392 - Part 4: Expose a file writer API for GeckoProfiler. r=mstange
This commit is contained in:
parent
b8f15cf0fc
commit
6a49d378ba
@ -444,6 +444,15 @@ void GeckoSampler::ToJSObjectAsync(double aSinceTime,
|
||||
mGatherer->Start(aSinceTime, aPromise);
|
||||
}
|
||||
|
||||
void GeckoSampler::ToFileAsync(const nsACString& aFileName, double aSinceTime)
|
||||
{
|
||||
if (NS_WARN_IF(!mGatherer)) {
|
||||
return;
|
||||
}
|
||||
|
||||
mGatherer->Start(aSinceTime, aFileName);
|
||||
}
|
||||
|
||||
struct SubprocessClosure {
|
||||
explicit SubprocessClosure(SpliceableJSONWriter* aWriter)
|
||||
: mWriter(aWriter)
|
||||
|
@ -112,6 +112,7 @@ class GeckoSampler: public Sampler {
|
||||
#endif
|
||||
mozilla::UniquePtr<char[]> ToJSON(double aSinceTime = 0);
|
||||
virtual void ToJSObjectAsync(double aSinceTime = 0, mozilla::dom::Promise* aPromise = 0);
|
||||
void ToFileAsync(const nsACString& aFileName, double aSinceTime = 0);
|
||||
void StreamMetaJSCustomObject(SpliceableJSONWriter& aWriter);
|
||||
void StreamTaskTracer(SpliceableJSONWriter& aWriter);
|
||||
void FlushOnJSShutdown(JSContext* aContext);
|
||||
|
@ -624,6 +624,20 @@ void mozilla_sampler_get_profile_data_async(double aSinceTime,
|
||||
t->ToJSObjectAsync(aSinceTime, aPromise);
|
||||
}
|
||||
|
||||
void mozilla_sampler_save_profile_to_file_async(double aSinceTime,
|
||||
const char* aFileName)
|
||||
{
|
||||
nsCString filename(aFileName);
|
||||
NS_DispatchToMainThread(NS_NewRunnableFunction([=] () {
|
||||
GeckoSampler *t = tlsTicker.get();
|
||||
if (NS_WARN_IF(!t)) {
|
||||
return;
|
||||
}
|
||||
|
||||
t->ToFileAsync(filename, aSinceTime);
|
||||
}));
|
||||
}
|
||||
|
||||
void mozilla_sampler_get_profiler_start_params(int* aEntrySize,
|
||||
double* aInterval,
|
||||
mozilla::Vector<const char*>* aFilters,
|
||||
|
@ -1,11 +1,15 @@
|
||||
/* 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 "mozilla/ProfileGatherer.h"
|
||||
#include "mozilla/Services.h"
|
||||
#include "nsIObserverService.h"
|
||||
#include "nsIProfileSaveEvent.h"
|
||||
#include "GeckoSampler.h"
|
||||
#include "nsLocalFile.h"
|
||||
#include "nsIFileStreams.h"
|
||||
|
||||
using mozilla::dom::AutoJSAPI;
|
||||
using mozilla::dom::Promise;
|
||||
@ -42,7 +46,7 @@ ProfileGatherer::GatheredOOPProfile()
|
||||
return;
|
||||
}
|
||||
|
||||
if (NS_WARN_IF(!mPromise)) {
|
||||
if (NS_WARN_IF(!mPromise && !mFile)) {
|
||||
// If we're not holding on to a Promise, then someone is
|
||||
// calling us erroneously.
|
||||
return;
|
||||
@ -96,6 +100,46 @@ ProfileGatherer::Start(double aSinceTime,
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
ProfileGatherer::Start(double aSinceTime,
|
||||
nsIFile* aFile)
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
if (mGathering) {
|
||||
return;
|
||||
}
|
||||
|
||||
mSinceTime = aSinceTime;
|
||||
mFile = aFile;
|
||||
mGathering = true;
|
||||
mPendingProfiles = 0;
|
||||
|
||||
nsCOMPtr<nsIObserverService> os = mozilla::services::GetObserverService();
|
||||
if (os) {
|
||||
DebugOnly<nsresult> rv =
|
||||
os->AddObserver(this, "profiler-subprocess", false);
|
||||
NS_WARNING_ASSERTION(NS_SUCCEEDED(rv), "AddObserver failed");
|
||||
rv = os->NotifyObservers(this, "profiler-subprocess-gather", nullptr);
|
||||
NS_WARNING_ASSERTION(NS_SUCCEEDED(rv), "NotifyObservers failed");
|
||||
}
|
||||
|
||||
if (!mPendingProfiles) {
|
||||
Finish();
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
ProfileGatherer::Start(double aSinceTime,
|
||||
const nsACString& aFileName)
|
||||
{
|
||||
nsCOMPtr<nsIFile> file = do_CreateInstance(NS_LOCAL_FILE_CONTRACTID);
|
||||
nsresult rv = file->InitWithNativePath(aFileName);
|
||||
if (NS_FAILED(rv)) {
|
||||
MOZ_CRASH();
|
||||
}
|
||||
Start(aSinceTime, file);
|
||||
}
|
||||
|
||||
void
|
||||
ProfileGatherer::Finish()
|
||||
{
|
||||
@ -109,6 +153,17 @@ ProfileGatherer::Finish()
|
||||
|
||||
UniquePtr<char[]> buf = mTicker->ToJSON(mSinceTime);
|
||||
|
||||
if (mFile) {
|
||||
nsCOMPtr<nsIFileOutputStream> of =
|
||||
do_CreateInstance("@mozilla.org/network/file-output-stream;1");
|
||||
of->Init(mFile, -1, -1, 0);
|
||||
uint32_t sz;
|
||||
of->Write(buf.get(), strlen(buf.get()), &sz);
|
||||
of->Close();
|
||||
Reset();
|
||||
return;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIObserverService> os = mozilla::services::GetObserverService();
|
||||
if (os) {
|
||||
DebugOnly<nsresult> rv = os->RemoveObserver(this, "profiler-subprocess");
|
||||
@ -153,6 +208,7 @@ ProfileGatherer::Reset()
|
||||
{
|
||||
mSinceTime = 0;
|
||||
mPromise = nullptr;
|
||||
mFile = nullptr;
|
||||
mPendingProfiles = 0;
|
||||
mGathering = false;
|
||||
}
|
||||
@ -165,6 +221,8 @@ ProfileGatherer::Cancel()
|
||||
if (mPromise) {
|
||||
mPromise->MaybeReject(NS_ERROR_DOM_ABORT_ERR);
|
||||
}
|
||||
mPromise = nullptr;
|
||||
mFile = nullptr;
|
||||
|
||||
// Clear out the GeckoSampler reference, since it's being destroyed.
|
||||
mTicker = nullptr;
|
||||
|
@ -39,11 +39,18 @@ if CONFIG['MOZ_ENABLE_PROFILER_SPS']:
|
||||
'gecko/nsProfiler.cpp',
|
||||
'gecko/nsProfilerFactory.cpp',
|
||||
'gecko/nsProfilerStartParams.cpp',
|
||||
'gecko/ProfileGatherer.cpp',
|
||||
'gecko/ProfilerIOInterposeObserver.cpp',
|
||||
'gecko/SaveProfileTask.cpp',
|
||||
'gecko/ThreadResponsiveness.cpp',
|
||||
]
|
||||
if CONFIG['OS_TARGET'] == 'Darwin':
|
||||
SOURCES += [
|
||||
'gecko/ProfileGatherer.cpp',
|
||||
]
|
||||
else:
|
||||
UNIFIED_SOURCES += [
|
||||
'gecko/ProfileGatherer.cpp',
|
||||
]
|
||||
|
||||
if CONFIG['OS_TARGET'] in ('Android', 'Linux'):
|
||||
UNIFIED_SOURCES += [
|
||||
|
@ -71,6 +71,9 @@ mozilla::UniquePtr<char[]> mozilla_sampler_get_profile(double aSinceTime);
|
||||
JSObject *mozilla_sampler_get_profile_data(JSContext* aCx, double aSinceTime);
|
||||
void mozilla_sampler_get_profile_data_async(double aSinceTime,
|
||||
mozilla::dom::Promise* aPromise);
|
||||
MOZ_EXPORT
|
||||
void mozilla_sampler_save_profile_to_file_async(double aSinceTime,
|
||||
const char* aFileName);
|
||||
void mozilla_sampler_get_profiler_start_params(int* aEntrySize,
|
||||
double* aInterval,
|
||||
mozilla::Vector<const char*>* aFilters,
|
||||
|
@ -6,6 +6,7 @@
|
||||
#define MOZ_PROFILE_GATHERER_H
|
||||
|
||||
#include "mozilla/dom/Promise.h"
|
||||
#include "nsIFile.h"
|
||||
|
||||
class GeckoSampler;
|
||||
|
||||
@ -21,6 +22,8 @@ public:
|
||||
void WillGatherOOPProfile();
|
||||
void GatheredOOPProfile();
|
||||
void Start(double aSinceTime, mozilla::dom::Promise* aPromise);
|
||||
void Start(double aSinceTime, nsIFile* aFile);
|
||||
void Start(double aSinceTime, const nsACString& aFileName);
|
||||
void Cancel();
|
||||
void OOPExitProfile(const nsCString& aProfile);
|
||||
|
||||
@ -31,6 +34,7 @@ private:
|
||||
|
||||
nsTArray<nsCString> mExitProfiles;
|
||||
RefPtr<mozilla::dom::Promise> mPromise;
|
||||
nsCOMPtr<nsIFile> mFile;
|
||||
GeckoSampler* mTicker;
|
||||
double mSinceTime;
|
||||
uint32_t mPendingProfiles;
|
||||
|
Loading…
x
Reference in New Issue
Block a user