Bug 1861467 - [wpt-sync] Update web-platform-tests to eedf737ce39c512d0ca3471f988972e...
[gecko.git] / dom / ipc / MemoryReportRequest.cpp
blob794351461da5abc3b42ef9d9213c099a4dc840b0
1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
3 /* This Source Code Form is subject to the terms of the Mozilla Public
4 * License, v. 2.0. If a copy of the MPL was not distributed with this
5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
7 #include "nsMemoryReporterManager.h"
8 #include "MemoryReportRequest.h"
9 #include "mozilla/ipc/FileDescriptor.h"
10 #include "mozilla/ipc/FileDescriptorUtils.h"
12 using namespace mozilla::ipc;
14 namespace mozilla::dom {
16 MemoryReportRequestHost::MemoryReportRequestHost(uint32_t aGeneration)
17 : mGeneration(aGeneration), mSuccess(false) {
18 MOZ_COUNT_CTOR(MemoryReportRequestHost);
19 mReporterManager = nsMemoryReporterManager::GetOrCreate();
20 NS_WARNING_ASSERTION(mReporterManager, "GetOrCreate failed");
23 void MemoryReportRequestHost::RecvReport(const MemoryReport& aReport) {
24 // Skip reports from older generations. We need to do this here since we
25 // could receive older reports from a subprocesses before it acknowledges
26 // a new request, and we only track one active request per process.
27 if (aReport.generation() != mGeneration) {
28 return;
31 if (mReporterManager) {
32 mReporterManager->HandleChildReport(mGeneration, aReport);
36 void MemoryReportRequestHost::Finish(uint32_t aGeneration) {
37 // Skip reports from older generations. See the comment in RecvReport.
38 if (mGeneration != aGeneration) {
39 return;
41 mSuccess = true;
44 MemoryReportRequestHost::~MemoryReportRequestHost() {
45 MOZ_COUNT_DTOR(MemoryReportRequestHost);
47 if (mReporterManager) {
48 mReporterManager->EndProcessReport(mGeneration, mSuccess);
49 mReporterManager = nullptr;
53 NS_IMPL_ISUPPORTS(MemoryReportRequestClient, nsIRunnable)
55 /* static */ void MemoryReportRequestClient::Start(
56 uint32_t aGeneration, bool aAnonymize, bool aMinimizeMemoryUsage,
57 const Maybe<FileDescriptor>& aDMDFile, const nsACString& aProcessString,
58 const ReportCallback& aReportCallback,
59 const FinishCallback& aFinishCallback) {
60 RefPtr<MemoryReportRequestClient> request = new MemoryReportRequestClient(
61 aGeneration, aAnonymize, aDMDFile, aProcessString, aReportCallback,
62 aFinishCallback);
64 DebugOnly<nsresult> rv;
65 if (aMinimizeMemoryUsage) {
66 nsCOMPtr<nsIMemoryReporterManager> mgr =
67 do_GetService("@mozilla.org/memory-reporter-manager;1");
68 rv = mgr->MinimizeMemoryUsage(request);
69 // mgr will eventually call actor->Run()
70 } else {
71 rv = request->Run();
74 NS_WARNING_ASSERTION(NS_SUCCEEDED(rv), "actor operation failed");
77 MemoryReportRequestClient::MemoryReportRequestClient(
78 uint32_t aGeneration, bool aAnonymize,
79 const Maybe<FileDescriptor>& aDMDFile, const nsACString& aProcessString,
80 const ReportCallback& aReportCallback,
81 const FinishCallback& aFinishCallback)
82 : mGeneration(aGeneration),
83 mAnonymize(aAnonymize),
84 mProcessString(aProcessString),
85 mReportCallback(aReportCallback),
86 mFinishCallback(aFinishCallback) {
87 if (aDMDFile.isSome()) {
88 mDMDFile = aDMDFile.value();
92 MemoryReportRequestClient::~MemoryReportRequestClient() = default;
94 class HandleReportCallback final : public nsIHandleReportCallback {
95 public:
96 using ReportCallback = typename MemoryReportRequestClient::ReportCallback;
98 NS_DECL_ISUPPORTS
100 explicit HandleReportCallback(uint32_t aGeneration,
101 const nsACString& aProcess,
102 const ReportCallback& aReportCallback)
103 : mGeneration(aGeneration),
104 mProcess(aProcess),
105 mReportCallback(aReportCallback) {}
107 NS_IMETHOD Callback(const nsACString& aProcess, const nsACString& aPath,
108 int32_t aKind, int32_t aUnits, int64_t aAmount,
109 const nsACString& aDescription,
110 nsISupports* aUnused) override {
111 MemoryReport memreport(mProcess, nsCString(aPath), aKind, aUnits, aAmount,
112 mGeneration, nsCString(aDescription));
113 mReportCallback(memreport);
114 return NS_OK;
117 private:
118 ~HandleReportCallback() = default;
120 uint32_t mGeneration;
121 const nsCString mProcess;
122 ReportCallback mReportCallback;
125 NS_IMPL_ISUPPORTS(HandleReportCallback, nsIHandleReportCallback)
127 class FinishReportingCallback final : public nsIFinishReportingCallback {
128 public:
129 using FinishCallback = typename MemoryReportRequestClient::FinishCallback;
131 NS_DECL_ISUPPORTS
133 explicit FinishReportingCallback(uint32_t aGeneration,
134 const FinishCallback& aFinishCallback)
135 : mGeneration(aGeneration), mFinishCallback(aFinishCallback) {}
137 NS_IMETHOD Callback(nsISupports* aUnused) override {
138 mFinishCallback(mGeneration);
139 return NS_OK;
142 private:
143 ~FinishReportingCallback() = default;
145 uint32_t mGeneration;
146 FinishCallback mFinishCallback;
149 NS_IMPL_ISUPPORTS(FinishReportingCallback, nsIFinishReportingCallback)
151 NS_IMETHODIMP MemoryReportRequestClient::Run() {
152 nsCOMPtr<nsIMemoryReporterManager> mgr =
153 do_GetService("@mozilla.org/memory-reporter-manager;1");
155 // Run the reporters. The callback will turn each measurement into a
156 // MemoryReport.
157 RefPtr<HandleReportCallback> handleReport =
158 new HandleReportCallback(mGeneration, mProcessString, mReportCallback);
159 RefPtr<FinishReportingCallback> finishReporting =
160 new FinishReportingCallback(mGeneration, mFinishCallback);
162 nsresult rv = mgr->GetReportsForThisProcessExtended(
163 handleReport, nullptr, mAnonymize, FileDescriptorToFILE(mDMDFile, "wb"),
164 finishReporting, nullptr);
165 NS_WARNING_ASSERTION(NS_SUCCEEDED(rv),
166 "GetReportsForThisProcessExtended failed");
167 return rv;
170 } // namespace mozilla::dom