Skip to content

Commit d79b3fb

Browse files
committed
Bug 1505522: Part 2 - Migrate MemoryTelemetry.jsm to C++. r=erahm,chutten
This has benefits both in terms of performance and memory usage. Aside from the obvious savings of not loading additional JS scripts in every process, this also allows us to move more of our expensive data collection work to a background thread, where it doesn't risk janking both parent and content processes. MozReview-Commit-ID: 2A593R7bIKB Differential Revision: https://phabricator.services.mozilla.com/D13872 --HG-- extra : rebase_source : ec634ee3a3b975809f542aa8077ad32236781452
1 parent 85f61d3 commit d79b3fb

File tree

17 files changed

+743
-557
lines changed

17 files changed

+743
-557
lines changed

browser/base/content/browser.js

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5582,6 +5582,10 @@ nsBrowserAccess.prototype = {
55825582
canClose() {
55835583
return CanCloseWindow();
55845584
},
5585+
5586+
get tabCount() {
5587+
return gBrowser.tabs.length;
5588+
},
55855589
};
55865590

55875591
function onViewToolbarsPopupShowing(aEvent, aInsertPoint) {

browser/base/content/test/performance/browser_startup_content.js

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,6 @@ const whitelist = {
6565

6666
// Telemetry
6767
"resource://gre/modules/TelemetryController.jsm", // bug 1470339
68-
"resource://gre/modules/MemoryTelemetry.jsm", // bug 1481812
6968
"resource://gre/modules/TelemetryUtils.jsm", // bug 1470339
7069

7170
// Extensions

dom/interfaces/base/nsIBrowserDOMWindow.idl

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -173,5 +173,11 @@ interface nsIBrowserDOMWindow : nsISupports
173173
* BrowserUtils.jsm for a simple implementation of this method.
174174
*/
175175
boolean canClose();
176+
177+
/**
178+
* The number browser tabs in the window. This number currently includes
179+
* lazy tabs, though for most uses it probably should not.
180+
*/
181+
readonly attribute unsigned long tabCount;
176182
};
177183

dom/ipc/ContentChild.cpp

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
#include "mozilla/Attributes.h"
1818
#include "mozilla/BackgroundHangMonitor.h"
1919
#include "mozilla/LookAndFeel.h"
20+
#include "mozilla/MemoryTelemetry.h"
2021
#include "mozilla/NullPrincipal.h"
2122
#include "mozilla/Preferences.h"
2223
#include "mozilla/ProcessHangMonitorIPC.h"
@@ -3376,6 +3377,12 @@ mozilla::ipc::IPCResult ContentChild::RecvFlushCodeCoverageCounters(
33763377
#endif
33773378
}
33783379

3380+
mozilla::ipc::IPCResult ContentChild::RecvGetMemoryUniqueSetSize(
3381+
GetMemoryUniqueSetSizeResolver&& aResolver) {
3382+
MemoryTelemetry::Get().GetUniqueSetSize(std::move(aResolver));
3383+
return IPC_OK();
3384+
}
3385+
33793386
mozilla::ipc::IPCResult ContentChild::RecvSetInputEventQueueEnabled() {
33803387
nsThreadManager::get().EnableMainThreadEventPrioritization();
33813388
return IPC_OK();

dom/ipc/ContentChild.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -612,6 +612,9 @@ class ContentChild final : public PContentChild,
612612
virtual mozilla::ipc::IPCResult RecvFlushCodeCoverageCounters(
613613
FlushCodeCoverageCountersResolver&& aResolver) override;
614614

615+
virtual mozilla::ipc::IPCResult RecvGetMemoryUniqueSetSize(
616+
GetMemoryUniqueSetSizeResolver&& aResolver) override;
617+
615618
virtual mozilla::ipc::IPCResult RecvSetInputEventQueueEnabled() override;
616619

617620
virtual mozilla::ipc::IPCResult RecvFlushInputEventQueue() override;

dom/ipc/PContent.ipdl

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -652,6 +652,8 @@ child:
652652
async ShareCodeCoverageMutex(CrossProcessMutexHandle handle);
653653
async FlushCodeCoverageCounters() returns (bool unused);
654654

655+
async GetMemoryUniqueSetSize() returns (int64_t uss);
656+
655657
/*
656658
* IPC message to enable the input event queue on the main thread of the
657659
* content process.

toolkit/components/telemetry/app/TelemetryController.jsm

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,6 @@ XPCOMUtils.defineLazyModuleGetters(this, {
5858
TelemetryEnvironment: "resource://gre/modules/TelemetryEnvironment.jsm",
5959
TelemetryArchive: "resource://gre/modules/TelemetryArchive.jsm",
6060
TelemetrySession: "resource://gre/modules/TelemetrySession.jsm",
61-
MemoryTelemetry: "resource://gre/modules/MemoryTelemetry.jsm",
6261
TelemetrySend: "resource://gre/modules/TelemetrySend.jsm",
6362
TelemetryReportingPolicy: "resource://gre/modules/TelemetryReportingPolicy.jsm",
6463
TelemetryModules: "resource://gre/modules/ModulesPing.jsm",
@@ -639,7 +638,7 @@ var Impl = {
639638
// Perform a lightweight, early initialization for the component, just registering
640639
// a few observers and initializing the session.
641640
TelemetrySession.earlyInit(this._testMode);
642-
MemoryTelemetry.earlyInit(this._testMode);
641+
Services.telemetry.earlyInit();
643642

644643
// Annotate crash reports so that we get pings for startup crashes
645644
TelemetrySend.earlyInit();
@@ -689,7 +688,7 @@ var Impl = {
689688

690689
// Perform TelemetrySession delayed init.
691690
await TelemetrySession.delayedInit();
692-
await MemoryTelemetry.delayedInit();
691+
await Services.telemetry.delayedInit();
693692

694693
if (Services.prefs.getBoolPref(TelemetryUtils.Preferences.NewProfilePingEnabled, false) &&
695694
!TelemetrySession.newProfilePingSent) {
@@ -755,7 +754,15 @@ var Impl = {
755754
this._log.trace("setupContentTelemetry - Content process recording disabled.");
756755
return;
757756
}
758-
MemoryTelemetry.setupContent(testing);
757+
Services.telemetry.earlyInit();
758+
759+
// FIXME: This is a terrible abuse of DeferredTask.
760+
let delayedTask = new DeferredTask(() => {
761+
Services.telemetry.delayedInit();
762+
}, testing ? TELEMETRY_TEST_DELAY : TELEMETRY_DELAY,
763+
testing ? 0 : undefined);
764+
765+
delayedTask.arm();
759766
},
760767

761768
// Do proper shutdown waiting and cleanup.
@@ -788,7 +795,7 @@ var Impl = {
788795
await TelemetryHealthPing.shutdown();
789796

790797
await TelemetrySession.shutdown();
791-
await MemoryTelemetry.shutdown();
798+
await Services.telemetry.shutdown();
792799

793800
// First wait for clients processing shutdown.
794801
await this._shutdownBarrier.wait();

toolkit/components/telemetry/core/Telemetry.cpp

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@
3333
#include "mozilla/Likely.h"
3434
#include "mozilla/MathAlgorithms.h"
3535
#include "mozilla/MemoryReporting.h"
36+
#include "mozilla/MemoryTelemetry.h"
3637
#include "mozilla/ModuleUtils.h"
3738
#include "mozilla/Mutex.h"
3839
#include "mozilla/PoisonIOInterposer.h"
@@ -1736,6 +1737,39 @@ TelemetryImpl::FlushBatchedChildTelemetry() {
17361737
return NS_OK;
17371738
}
17381739

1740+
NS_IMETHODIMP
1741+
TelemetryImpl::EarlyInit() {
1742+
Unused << MemoryTelemetry::Get();
1743+
return NS_OK;
1744+
}
1745+
1746+
NS_IMETHODIMP
1747+
TelemetryImpl::DelayedInit() {
1748+
MemoryTelemetry::Get().DelayedInit();
1749+
return NS_OK;
1750+
}
1751+
1752+
NS_IMETHODIMP
1753+
TelemetryImpl::Shutdown() {
1754+
MemoryTelemetry::Get().Shutdown();
1755+
return NS_OK;
1756+
}
1757+
1758+
NS_IMETHODIMP
1759+
TelemetryImpl::GatherMemory(JSContext* aCx, Promise** aResult) {
1760+
ErrorResult rv;
1761+
RefPtr<Promise> promise = Promise::Create(xpc::CurrentNativeGlobal(aCx), rv);
1762+
if (rv.Failed()) {
1763+
return rv.StealNSResult();
1764+
}
1765+
1766+
MemoryTelemetry::Get().GatherReports(
1767+
[promise]() { promise->MaybeResolve(JS::UndefinedHandleValue); });
1768+
1769+
promise.forget(aResult);
1770+
return NS_OK;
1771+
}
1772+
17391773
} // namespace
17401774

17411775
////////////////////////////////////////////////////////////////////////

toolkit/components/telemetry/core/nsITelemetry.idl

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -603,4 +603,33 @@ interface nsITelemetry : nsISupports
603603
* Please note that this is only intended to be used by GeckoViewTelemetryController.
604604
*/
605605
void clearProbes();
606+
607+
/**
608+
* Does early, cheap initialization for native telemetry data providers.
609+
* Currently, this includes only MemoryTelemetry.
610+
*/
611+
void earlyInit();
612+
613+
/**
614+
* Does late, expensive initialization for native telemetry data providers.
615+
* Currently, this includes only MemoryTelemetry.
616+
*
617+
* This should only be called after startup has completed and the event loop
618+
* is idle.
619+
*/
620+
void delayedInit();
621+
622+
/**
623+
* Shuts down native telemetry providers. Currently, this includes only
624+
* MemoryTelemetry.
625+
*/
626+
void shutdown();
627+
628+
/**
629+
* Gathers telemetry data for memory usage and records it to the data store.
630+
* Returns a promise which resolves when asynchronous data collection has
631+
* completed and all data has been recorded.
632+
*/
633+
[implicit_jscontext]
634+
Promise gatherMemory();
606635
};

toolkit/components/telemetry/moz.build

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@ BROWSER_CHROME_MANIFESTS += ['tests/browser/browser.ini']
4545

4646
XPIDL_SOURCES += [
4747
'core/nsITelemetry.idl',
48+
'other/GCTelemetry.idl',
4849
]
4950

5051
XPIDL_MODULE = 'telemetry'
@@ -107,7 +108,6 @@ EXTRA_JS_MODULES += [
107108
'app/TelemetryTimestamps.jsm',
108109
'app/TelemetryUtils.jsm',
109110
'other/GCTelemetry.jsm',
110-
'other/MemoryTelemetry.jsm',
111111
'other/UITelemetry.jsm',
112112
'pings/CoveragePing.jsm',
113113
'pings/EventPing.jsm',
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
/* -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil; tab-width: 8 -*- */
2+
/* This Source Code Form is subject to the terms of the Mozilla Public
3+
* License, v. 2.0. If a copy of the MPL was not distributed with this
4+
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
5+
6+
#include "nsISupports.idl"
7+
8+
[scriptable, uuid(6ab1c3c1-31cf-4a32-8484-97b5ef0627af)]
9+
interface mozIGCTelemetry : nsISupports {
10+
void init();
11+
12+
void shutdown();
13+
};
14+
15+
[scriptable, uuid(93b2a0ca-6306-41c1-b296-c57cad5175c7)]
16+
interface mozIGCTelemetryJSM : nsISupports {
17+
readonly attribute mozIGCTelemetry GCTelemetry;
18+
};

0 commit comments

Comments
 (0)