Bug 1568514 - Add telemetry histograms to report hyphenation memory footprint and resource load times. r=heycam

Differential Revision: https://phabricator.services.mozilla.com/D39323

--HG--
extra : moz-landing-system : lando
This commit is contained in:
Jonathan Kew 2019-08-16 07:24:46 +00:00
parent 8458d4bcc9
commit 18a14ee562
4 changed files with 71 additions and 24 deletions

View File

@ -18,6 +18,7 @@
#include "mozilla/Preferences.h"
#include "nsZipArchive.h"
#include "mozilla/Services.h"
#include "mozilla/Telemetry.h"
#include "nsIObserverService.h"
#include "nsCRT.h"
#include "nsAppDirectoryServiceDefs.h"
@ -29,6 +30,13 @@ using namespace mozilla;
static const char kIntlHyphenationAliasPrefix[] = "intl.hyphenation-alias.";
static const char kMemoryPressureNotification[] = "memory-pressure";
// To report memory usage via telemetry, we observe a notification when the
// process is about to be shut down; unfortunately, parent and child processes
// receive different notifications, so we have to account for that in order to
// report usage from both process types.
static const char kParentShuttingDownNotification[] = "profile-before-change";
static const char kChildShuttingDownNotification[] = "content-child-shutdown";
class HyphenReporter final : public nsIMemoryReporter,
public CountingAllocatorBase<HyphenReporter> {
private:
@ -37,6 +45,11 @@ class HyphenReporter final : public nsIMemoryReporter,
public:
NS_DECL_ISUPPORTS
// For telemetry, we report the memory rounded up to the nearest KB.
static uint32_t MemoryAllocatedInKB() {
return (MemoryAllocated() + 1023) / 1024;
}
NS_IMETHOD CollectReports(nsIHandleReportCallback* aHandleReport,
nsISupports* aData, bool aAnonymize) override {
size_t total = MemoryAllocated();
@ -78,20 +91,21 @@ void hnj_free(void* aPtr) { HyphenReporter::CountingFree(aPtr); }
nsHyphenationManager* nsHyphenationManager::sInstance = nullptr;
NS_IMPL_ISUPPORTS(nsHyphenationManager::MemoryPressureObserver, nsIObserver)
NS_IMPL_ISUPPORTS(nsHyphenationManager, nsIObserver)
NS_IMETHODIMP
nsHyphenationManager::MemoryPressureObserver::Observe(nsISupports* aSubject,
const char* aTopic,
const char16_t* aData) {
nsHyphenationManager::Observe(nsISupports* aSubject, const char* aTopic,
const char16_t* aData) {
if (!nsCRT::strcmp(aTopic, kMemoryPressureNotification)) {
// We don't call Instance() here, as we don't want to create a hyphenation
// manager if there isn't already one in existence.
// (This observer class is local to the hyphenation manager, so it can use
// the protected members directly.)
if (nsHyphenationManager::sInstance) {
nsHyphenationManager::sInstance->mHyphenators.Clear();
}
// We're going to discard hyphenators; record a telemetry entry for the
// memory usage we reached before doing so.
Telemetry::Accumulate(Telemetry::HYPHENATION_MEMORY,
HyphenReporter::MemoryAllocatedInKB());
nsHyphenationManager::sInstance->mHyphenators.Clear();
} else if (!nsCRT::strcmp(aTopic, kParentShuttingDownNotification) ||
!nsCRT::strcmp(aTopic, kChildShuttingDownNotification)) {
Telemetry::Accumulate(Telemetry::HYPHENATION_MEMORY,
HyphenReporter::MemoryAllocatedInKB());
}
return NS_OK;
}
@ -102,7 +116,10 @@ nsHyphenationManager* nsHyphenationManager::Instance() {
nsCOMPtr<nsIObserverService> obs = mozilla::services::GetObserverService();
if (obs) {
obs->AddObserver(new MemoryPressureObserver, kMemoryPressureNotification,
obs->AddObserver(sInstance, kMemoryPressureNotification, false);
obs->AddObserver(sInstance,
XRE_IsParentProcess() ? kParentShuttingDownNotification
: kChildShuttingDownNotification,
false);
}
@ -112,8 +129,17 @@ nsHyphenationManager* nsHyphenationManager::Instance() {
}
void nsHyphenationManager::Shutdown() {
delete sInstance;
sInstance = nullptr;
if (sInstance) {
nsCOMPtr<nsIObserverService> obs = mozilla::services::GetObserverService();
if (obs) {
obs->RemoveObserver(sInstance, kMemoryPressureNotification);
obs->RemoveObserver(sInstance, XRE_IsParentProcess()
? kParentShuttingDownNotification
: kChildShuttingDownNotification);
}
delete sInstance;
sInstance = nullptr;
}
}
nsHyphenationManager::nsHyphenationManager() {

View File

@ -16,8 +16,11 @@ class nsHyphenator;
class nsAtom;
class nsIURI;
class nsHyphenationManager {
class nsHyphenationManager : public nsIObserver {
public:
NS_DECL_ISUPPORTS
NS_DECL_NSIOBSERVER
nsHyphenationManager();
already_AddRefed<nsHyphenator> GetHyphenator(nsAtom* aLocale);
@ -29,17 +32,9 @@ class nsHyphenationManager {
size_t SizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf);
private:
~nsHyphenationManager();
virtual ~nsHyphenationManager();
protected:
class MemoryPressureObserver final : public nsIObserver {
~MemoryPressureObserver() {}
public:
NS_DECL_ISUPPORTS
NS_DECL_NSIOBSERVER
};
void LoadPatternList();
void LoadPatternListFromOmnijar(mozilla::Omnijar::Type aType);
void LoadPatternListFromDir(nsIFile* aDir);

View File

@ -8,6 +8,7 @@
#include "nsUTF8Utils.h"
#include "nsUnicodeProperties.h"
#include "nsIURI.h"
#include "mozilla/Telemetry.h"
#include "hyphen.h"
@ -18,6 +19,7 @@ nsHyphenator::nsHyphenator(nsIURI* aURI, bool aHyphenateCapitalized)
if (NS_FAILED(rv)) {
return;
}
Telemetry::AutoTimer<Telemetry::HYPHENATION_LOAD_TIME> telemetry;
mDict = hnj_hyphen_load(uriSpec.get());
#ifdef DEBUG
if (mDict) {

View File

@ -15669,5 +15669,29 @@
"high": 100,
"n_buckets": 12,
"description": "Percentages of times for phases in an expensive refresh tick relative to the time spent in the entire tick (REFRESH_DRIVER_TICK)."
},
"HYPHENATION_MEMORY": {
"record_in_processes": ["main", "content"],
"products": ["firefox", "fennec", "geckoview"],
"alert_emails": ["jkew@mozilla.com"],
"bug_numbers": [1568514],
"expires_in_version": "74",
"kind": "exponential",
"high": 8000,
"n_buckets": 100,
"releaseChannelCollection": "opt-out",
"description": "Total per-process memory used by loaded auto-hyphenation tables (KB)."
},
"HYPHENATION_LOAD_TIME": {
"record_in_processes": ["main", "content"],
"products": ["firefox", "fennec", "geckoview"],
"alert_emails": ["jkew@mozilla.com"],
"bug_numbers": [1568514],
"expires_in_version": "74",
"kind": "exponential",
"high": 1000,
"n_buckets": 100,
"releaseChannelCollection": "opt-out",
"description": "How many milliseconds it took to load a hyphenation resource."
}
}