Bug 1587329 - MOZ_ASSERT(sInstance) in all functions that dereference sInstance - r=canaltinova

Add assertions that all `sInstance` pointers (from both `CorePS` and `ActivePS`)
are not null before being dereferenced.

This is probably more than needed, but it's only `MOZ_ASSERT`s limited to
Nightly, and it should give better feedback in case something goes wrong.

Eventually, I think it would be better to make most methods non-static, and have
a checked reference-to-instance getter.

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

--HG--
extra : moz-landing-system : lando
This commit is contained in:
Gerald Squelart 2019-10-10 10:51:50 +00:00
Родитель dfdd58ed51
Коммит dff1750481
2 изменённых файлов: 117 добавлений и 21 удалений

Просмотреть файл

@ -224,15 +224,22 @@ detail::BaseProfilerMutex PSAutoLock::gPSMutex;
// fields.
typedef const PSAutoLock& PSLockRef;
# define PS_GET(type_, name_) \
static type_ name_(PSLockRef) { return sInstance->m##name_; }
# define PS_GET(type_, name_) \
static type_ name_(PSLockRef) { \
MOZ_ASSERT(sInstance); \
return sInstance->m##name_; \
}
# define PS_GET_LOCKLESS(type_, name_) \
static type_ name_() { return sInstance->m##name_; }
static type_ name_() { \
MOZ_ASSERT(sInstance); \
return sInstance->m##name_; \
}
# define PS_GET_AND_SET(type_, name_) \
PS_GET(type_, name_) \
static void Set##name_(PSLockRef, type_ a##name_) { \
MOZ_ASSERT(sInstance); \
sInstance->m##name_ = a##name_; \
}
@ -277,9 +284,13 @@ class CorePS {
~CorePS() {}
public:
static void Create(PSLockRef aLock) { sInstance = new CorePS(); }
static void Create(PSLockRef aLock) {
MOZ_ASSERT(!sInstance);
sInstance = new CorePS();
}
static void Destroy(PSLockRef aLock) {
MOZ_ASSERT(sInstance);
delete sInstance;
sInstance = nullptr;
}
@ -290,12 +301,14 @@ class CorePS {
static bool Exists() { return !!sInstance; }
static bool IsMainThread() {
MOZ_RELEASE_ASSERT(Exists());
MOZ_ASSERT(sInstance);
return profiler_current_thread_id() == sInstance->mMainThreadId;
}
static void AddSizeOf(PSLockRef, MallocSizeOf aMallocSizeOf,
size_t& aProfSize, size_t& aLulSize) {
MOZ_ASSERT(sInstance);
aProfSize += aMallocSizeOf(sInstance);
for (auto& registeredThread : sInstance->mRegisteredThreads) {
@ -331,12 +344,14 @@ class CorePS {
static void AppendRegisteredThread(
PSLockRef, UniquePtr<RegisteredThread>&& aRegisteredThread) {
MOZ_ASSERT(sInstance);
MOZ_RELEASE_ASSERT(
sInstance->mRegisteredThreads.append(std::move(aRegisteredThread)));
}
static void RemoveRegisteredThread(PSLockRef,
RegisteredThread* aRegisteredThread) {
MOZ_ASSERT(sInstance);
// Remove aRegisteredThread from mRegisteredThreads.
for (UniquePtr<RegisteredThread>& rt : sInstance->mRegisteredThreads) {
if (rt.get() == aRegisteredThread) {
@ -350,6 +365,7 @@ class CorePS {
static void AppendRegisteredPage(PSLockRef,
RefPtr<PageInformation>&& aRegisteredPage) {
MOZ_ASSERT(sInstance);
struct RegisteredPageComparator {
PageInformation* aA;
bool operator()(PageInformation* aB) const { return aA->Equals(aB); }
@ -377,6 +393,7 @@ class CorePS {
static void RemoveRegisteredPage(PSLockRef,
uint64_t aRegisteredInnerWindowID) {
MOZ_ASSERT(sInstance);
// Remove RegisteredPage from mRegisteredPages by given inner window ID.
sInstance->mRegisteredPages.eraseIf([&](const RefPtr<PageInformation>& rd) {
return rd->InnerWindowID() == aRegisteredInnerWindowID;
@ -384,12 +401,14 @@ class CorePS {
}
static void ClearRegisteredPages(PSLockRef) {
MOZ_ASSERT(sInstance);
sInstance->mRegisteredPages.clear();
}
PS_GET(const Vector<BaseProfilerCount*>&, Counters)
static void AppendCounter(PSLockRef, BaseProfilerCount* aCounter) {
MOZ_ASSERT(sInstance);
// we don't own the counter; they may be stored in static objects
MOZ_RELEASE_ASSERT(sInstance->mCounters.append(aCounter));
}
@ -406,8 +425,12 @@ class CorePS {
}
# ifdef USE_LUL_STACKWALK
static lul::LUL* Lul(PSLockRef) { return sInstance->mLul.get(); }
static lul::LUL* Lul(PSLockRef) {
MOZ_ASSERT(sInstance);
return sInstance->mLul.get();
}
static void SetLul(PSLockRef, UniquePtr<lul::LUL> aLul) {
MOZ_ASSERT(sInstance);
sInstance->mLul = std::move(aLul);
}
# endif
@ -523,8 +546,6 @@ class ActivePS {
~ActivePS() {}
bool ThreadSelected(const char* aThreadName) {
MOZ_RELEASE_ASSERT(sInstance);
if (mFilters.empty()) {
return true;
}
@ -557,11 +578,13 @@ class ActivePS {
static void Create(PSLockRef aLock, PowerOfTwo32 aCapacity, double aInterval,
uint32_t aFeatures, const char** aFilters,
uint32_t aFilterCount, const Maybe<double>& aDuration) {
MOZ_ASSERT(!sInstance);
sInstance = new ActivePS(aLock, aCapacity, aInterval, aFeatures, aFilters,
aFilterCount, aDuration);
}
static MOZ_MUST_USE SamplerThread* Destroy(PSLockRef aLock) {
MOZ_ASSERT(sInstance);
auto samplerThread = sInstance->mSamplerThread;
delete sInstance;
sInstance = nullptr;
@ -575,6 +598,7 @@ class ActivePS {
const Maybe<double>& aDuration, double aInterval,
uint32_t aFeatures, const char** aFilters,
uint32_t aFilterCount) {
MOZ_ASSERT(sInstance);
if (sInstance->mCapacity != aCapacity ||
sInstance->mDuration != aDuration ||
sInstance->mInterval != aInterval ||
@ -592,6 +616,8 @@ class ActivePS {
}
static size_t SizeOf(PSLockRef, MallocSizeOf aMallocSizeOf) {
MOZ_ASSERT(sInstance);
size_t n = aMallocSizeOf(sInstance);
n += sInstance->mProfileBuffer->SizeOfIncludingThis(aMallocSizeOf);
@ -606,8 +632,7 @@ class ActivePS {
}
static bool ShouldProfileThread(PSLockRef aLock, ThreadInfo* aInfo) {
MOZ_RELEASE_ASSERT(sInstance);
MOZ_ASSERT(sInstance);
return ((aInfo->IsMainThread() || FeatureThreads(aLock)) &&
sInstance->ThreadSelected(aInfo->Name()));
}
@ -624,6 +649,7 @@ class ActivePS {
# define PS_GET_FEATURE(n_, str_, Name_, desc_) \
static bool Feature##Name_(PSLockRef) { \
MOZ_ASSERT(sInstance); \
return ProfilerFeature::Has##Name_(sInstance->mFeatures); \
}
@ -633,9 +659,13 @@ class ActivePS {
PS_GET(const Vector<std::string>&, Filters)
static ProfileBuffer& Buffer(PSLockRef) { return *sInstance->mProfileBuffer; }
static ProfileBuffer& Buffer(PSLockRef) {
MOZ_ASSERT(sInstance);
return *sInstance->mProfileBuffer;
}
static const Vector<LiveProfiledThreadData>& LiveProfiledThreads(PSLockRef) {
MOZ_ASSERT(sInstance);
return sInstance->mLiveProfiledThreads;
}
@ -650,6 +680,7 @@ class ActivePS {
// restarts.
static Vector<Pair<RegisteredThread*, ProfiledThreadData*>> ProfiledThreads(
PSLockRef) {
MOZ_ASSERT(sInstance);
Vector<Pair<RegisteredThread*, ProfiledThreadData*>> array;
MOZ_RELEASE_ASSERT(
array.initCapacity(sInstance->mLiveProfiledThreads.length() +
@ -673,6 +704,7 @@ class ActivePS {
}
static Vector<RefPtr<PageInformation>> ProfiledPages(PSLockRef aLock) {
MOZ_ASSERT(sInstance);
Vector<RefPtr<PageInformation>> array;
for (auto& d : CorePS::RegisteredPages(aLock)) {
MOZ_RELEASE_ASSERT(array.append(d));
@ -689,6 +721,7 @@ class ActivePS {
// ProfiledThreadData object for a RegisteredThread.
static ProfiledThreadData* GetProfiledThreadData(
PSLockRef, RegisteredThread* aRegisteredThread) {
MOZ_ASSERT(sInstance);
for (const LiveProfiledThreadData& thread :
sInstance->mLiveProfiledThreads) {
if (thread.mRegisteredThread == aRegisteredThread) {
@ -701,6 +734,7 @@ class ActivePS {
static ProfiledThreadData* AddLiveProfiledThread(
PSLockRef, RegisteredThread* aRegisteredThread,
UniquePtr<ProfiledThreadData>&& aProfiledThreadData) {
MOZ_ASSERT(sInstance);
MOZ_RELEASE_ASSERT(
sInstance->mLiveProfiledThreads.append(LiveProfiledThreadData{
aRegisteredThread, std::move(aProfiledThreadData)}));
@ -711,6 +745,8 @@ class ActivePS {
static void UnregisterThread(PSLockRef aLockRef,
RegisteredThread* aRegisteredThread) {
MOZ_ASSERT(sInstance);
DiscardExpiredDeadProfiledThreads(aLockRef);
// Find the right entry in the mLiveProfiledThreads array and remove the
@ -738,6 +774,7 @@ class ActivePS {
# endif
static void DiscardExpiredDeadProfiledThreads(PSLockRef) {
MOZ_ASSERT(sInstance);
uint64_t bufferRangeStart = sInstance->mProfileBuffer->BufferRangeStart();
// Discard any dead threads that were unregistered before bufferRangeStart.
sInstance->mDeadProfiledThreads.eraseIf(
@ -753,6 +790,7 @@ class ActivePS {
static void UnregisterPage(PSLockRef aLock,
uint64_t aRegisteredInnerWindowID) {
MOZ_ASSERT(sInstance);
auto& registeredPages = CorePS::RegisteredPages(aLock);
for (size_t i = 0; i < registeredPages.length(); i++) {
RefPtr<PageInformation>& page = registeredPages[i];
@ -766,6 +804,7 @@ class ActivePS {
}
static void DiscardExpiredPages(PSLockRef) {
MOZ_ASSERT(sInstance);
uint64_t bufferRangeStart = sInstance->mProfileBuffer->BufferRangeStart();
// Discard any dead pages that were unregistered before
// bufferRangeStart.
@ -780,10 +819,12 @@ class ActivePS {
}
static void ClearUnregisteredPages(PSLockRef) {
MOZ_ASSERT(sInstance);
sInstance->mDeadProfiledPages.clear();
}
static void ClearExpiredExitProfiles(PSLockRef) {
MOZ_ASSERT(sInstance);
uint64_t bufferRangeStart = sInstance->mProfileBuffer->BufferRangeStart();
// Discard exit profiles that were gathered before our buffer RangeStart.
sInstance->mExitProfiles.eraseIf(
@ -793,6 +834,8 @@ class ActivePS {
}
static void AddExitProfile(PSLockRef aLock, const std::string& aExitProfile) {
MOZ_ASSERT(sInstance);
ClearExpiredExitProfiles(aLock);
MOZ_RELEASE_ASSERT(sInstance->mExitProfiles.append(ExitProfile{
@ -800,6 +843,8 @@ class ActivePS {
}
static Vector<std::string> MoveExitProfiles(PSLockRef aLock) {
MOZ_ASSERT(sInstance);
ClearExpiredExitProfiles(aLock);
Vector<std::string> profiles;

Просмотреть файл

@ -303,15 +303,22 @@ class MOZ_RAII PSAutoLock {
// fields.
typedef const PSAutoLock& PSLockRef;
#define PS_GET(type_, name_) \
static type_ name_(PSLockRef) { return sInstance->m##name_; }
#define PS_GET(type_, name_) \
static type_ name_(PSLockRef) { \
MOZ_ASSERT(sInstance); \
return sInstance->m##name_; \
}
#define PS_GET_LOCKLESS(type_, name_) \
static type_ name_() { return sInstance->m##name_; }
static type_ name_() { \
MOZ_ASSERT(sInstance); \
return sInstance->m##name_; \
}
#define PS_GET_AND_SET(type_, name_) \
PS_GET(type_, name_) \
static void Set##name_(PSLockRef, type_ a##name_) { \
MOZ_ASSERT(sInstance); \
sInstance->m##name_ = a##name_; \
}
@ -355,9 +362,13 @@ class CorePS {
~CorePS() {}
public:
static void Create(PSLockRef aLock) { sInstance = new CorePS(); }
static void Create(PSLockRef aLock) {
MOZ_ASSERT(!sInstance);
sInstance = new CorePS();
}
static void Destroy(PSLockRef aLock) {
MOZ_ASSERT(sInstance);
delete sInstance;
sInstance = nullptr;
}
@ -369,6 +380,8 @@ class CorePS {
static void AddSizeOf(PSLockRef, MallocSizeOf aMallocSizeOf,
size_t& aProfSize, size_t& aLulSize) {
MOZ_ASSERT(sInstance);
aProfSize += aMallocSizeOf(sInstance);
for (auto& registeredThread : sInstance->mRegisteredThreads) {
@ -404,12 +417,14 @@ class CorePS {
static void AppendRegisteredThread(
PSLockRef, UniquePtr<RegisteredThread>&& aRegisteredThread) {
MOZ_ASSERT(sInstance);
MOZ_RELEASE_ASSERT(
sInstance->mRegisteredThreads.append(std::move(aRegisteredThread)));
}
static void RemoveRegisteredThread(PSLockRef,
RegisteredThread* aRegisteredThread) {
MOZ_ASSERT(sInstance);
// Remove aRegisteredThread from mRegisteredThreads.
for (UniquePtr<RegisteredThread>& rt : sInstance->mRegisteredThreads) {
if (rt.get() == aRegisteredThread) {
@ -423,6 +438,7 @@ class CorePS {
static void AppendRegisteredPage(PSLockRef,
RefPtr<PageInformation>&& aRegisteredPage) {
MOZ_ASSERT(sInstance);
struct RegisteredPageComparator {
PageInformation* aA;
bool operator()(PageInformation* aB) const { return aA->Equals(aB); }
@ -451,6 +467,7 @@ class CorePS {
static void RemoveRegisteredPage(PSLockRef,
uint64_t aRegisteredInnerWindowID) {
MOZ_ASSERT(sInstance);
// Remove RegisteredPage from mRegisteredPages by given inner window ID.
sInstance->mRegisteredPages.eraseIf([&](const RefPtr<PageInformation>& rd) {
return rd->InnerWindowID() == aRegisteredInnerWindowID;
@ -458,12 +475,14 @@ class CorePS {
}
static void ClearRegisteredPages(PSLockRef) {
MOZ_ASSERT(sInstance);
sInstance->mRegisteredPages.clear();
}
PS_GET(const Vector<BaseProfilerCount*>&, Counters)
static void AppendCounter(PSLockRef, BaseProfilerCount* aCounter) {
MOZ_ASSERT(sInstance);
// we don't own the counter; they may be stored in static objects
MOZ_RELEASE_ASSERT(sInstance->mCounters.append(aCounter));
}
@ -480,8 +499,12 @@ class CorePS {
}
#ifdef USE_LUL_STACKWALK
static lul::LUL* Lul(PSLockRef) { return sInstance->mLul.get(); }
static lul::LUL* Lul(PSLockRef) {
MOZ_ASSERT(sInstance);
return sInstance->mLul.get();
}
static void SetLul(PSLockRef, UniquePtr<lul::LUL> aLul) {
MOZ_ASSERT(sInstance);
sInstance->mLul = std::move(aLul);
}
#endif
@ -632,8 +655,6 @@ class ActivePS {
}
bool ThreadSelected(const char* aThreadName) {
MOZ_RELEASE_ASSERT(sInstance);
if (mFilters.empty()) {
return true;
}
@ -666,11 +687,13 @@ class ActivePS {
static void Create(PSLockRef aLock, PowerOfTwo32 aCapacity, double aInterval,
uint32_t aFeatures, const char** aFilters,
uint32_t aFilterCount, const Maybe<double>& aDuration) {
MOZ_ASSERT(!sInstance);
sInstance = new ActivePS(aLock, aCapacity, aInterval, aFeatures, aFilters,
aFilterCount, aDuration);
}
static MOZ_MUST_USE SamplerThread* Destroy(PSLockRef aLock) {
MOZ_ASSERT(sInstance);
auto samplerThread = sInstance->mSamplerThread;
delete sInstance;
sInstance = nullptr;
@ -684,6 +707,7 @@ class ActivePS {
const Maybe<double>& aDuration, double aInterval,
uint32_t aFeatures, const char** aFilters,
uint32_t aFilterCount) {
MOZ_ASSERT(sInstance);
if (sInstance->mCapacity != aCapacity ||
sInstance->mDuration != aDuration ||
sInstance->mInterval != aInterval ||
@ -701,6 +725,8 @@ class ActivePS {
}
static size_t SizeOf(PSLockRef, MallocSizeOf aMallocSizeOf) {
MOZ_ASSERT(sInstance);
size_t n = aMallocSizeOf(sInstance);
n += sInstance->mProfileBuffer->SizeOfIncludingThis(aMallocSizeOf);
@ -715,8 +741,7 @@ class ActivePS {
}
static bool ShouldProfileThread(PSLockRef aLock, ThreadInfo* aInfo) {
MOZ_RELEASE_ASSERT(sInstance);
MOZ_ASSERT(sInstance);
return ((aInfo->IsMainThread() || FeatureThreads(aLock)) &&
sInstance->ThreadSelected(aInfo->Name()));
}
@ -733,6 +758,7 @@ class ActivePS {
#define PS_GET_FEATURE(n_, str_, Name_, desc_) \
static bool Feature##Name_(PSLockRef) { \
MOZ_ASSERT(sInstance); \
return ProfilerFeature::Has##Name_(sInstance->mFeatures); \
}
@ -758,9 +784,13 @@ class ActivePS {
PS_GET(const Vector<std::string>&, Filters)
static ProfileBuffer& Buffer(PSLockRef) { return *sInstance->mProfileBuffer; }
static ProfileBuffer& Buffer(PSLockRef) {
MOZ_ASSERT(sInstance);
return *sInstance->mProfileBuffer;
}
static const Vector<LiveProfiledThreadData>& LiveProfiledThreads(PSLockRef) {
MOZ_ASSERT(sInstance);
return sInstance->mLiveProfiledThreads;
}
@ -775,6 +805,7 @@ class ActivePS {
// restarts.
static Vector<Pair<RegisteredThread*, ProfiledThreadData*>> ProfiledThreads(
PSLockRef) {
MOZ_ASSERT(sInstance);
Vector<Pair<RegisteredThread*, ProfiledThreadData*>> array;
MOZ_RELEASE_ASSERT(
array.initCapacity(sInstance->mLiveProfiledThreads.length() +
@ -798,6 +829,7 @@ class ActivePS {
}
static Vector<RefPtr<PageInformation>> ProfiledPages(PSLockRef aLock) {
MOZ_ASSERT(sInstance);
Vector<RefPtr<PageInformation>> array;
for (auto& d : CorePS::RegisteredPages(aLock)) {
MOZ_RELEASE_ASSERT(array.append(d));
@ -814,6 +846,7 @@ class ActivePS {
// ProfiledThreadData object for a RegisteredThread.
static ProfiledThreadData* GetProfiledThreadData(
PSLockRef, RegisteredThread* aRegisteredThread) {
MOZ_ASSERT(sInstance);
for (const LiveProfiledThreadData& thread :
sInstance->mLiveProfiledThreads) {
if (thread.mRegisteredThread == aRegisteredThread) {
@ -826,6 +859,7 @@ class ActivePS {
static ProfiledThreadData* AddLiveProfiledThread(
PSLockRef, RegisteredThread* aRegisteredThread,
UniquePtr<ProfiledThreadData>&& aProfiledThreadData) {
MOZ_ASSERT(sInstance);
MOZ_RELEASE_ASSERT(
sInstance->mLiveProfiledThreads.append(LiveProfiledThreadData{
aRegisteredThread, std::move(aProfiledThreadData)}));
@ -836,6 +870,8 @@ class ActivePS {
static void UnregisterThread(PSLockRef aLockRef,
RegisteredThread* aRegisteredThread) {
MOZ_ASSERT(sInstance);
DiscardExpiredDeadProfiledThreads(aLockRef);
// Find the right entry in the mLiveProfiledThreads array and remove the
@ -863,6 +899,7 @@ class ActivePS {
#endif
static void DiscardExpiredDeadProfiledThreads(PSLockRef) {
MOZ_ASSERT(sInstance);
uint64_t bufferRangeStart = sInstance->mProfileBuffer->BufferRangeStart();
// Discard any dead threads that were unregistered before bufferRangeStart.
sInstance->mDeadProfiledThreads.eraseIf(
@ -878,6 +915,7 @@ class ActivePS {
static void UnregisterPage(PSLockRef aLock,
uint64_t aRegisteredInnerWindowID) {
MOZ_ASSERT(sInstance);
auto& registeredPages = CorePS::RegisteredPages(aLock);
for (size_t i = 0; i < registeredPages.length(); i++) {
RefPtr<PageInformation>& page = registeredPages[i];
@ -891,6 +929,7 @@ class ActivePS {
}
static void DiscardExpiredPages(PSLockRef) {
MOZ_ASSERT(sInstance);
uint64_t bufferRangeStart = sInstance->mProfileBuffer->BufferRangeStart();
// Discard any dead pages that were unregistered before
// bufferRangeStart.
@ -905,11 +944,13 @@ class ActivePS {
}
static void ClearUnregisteredPages(PSLockRef) {
MOZ_ASSERT(sInstance);
sInstance->mDeadProfiledPages.clear();
}
#if !defined(RELEASE_OR_BETA)
static void UnregisterIOInterposer(PSLockRef) {
MOZ_ASSERT(sInstance);
if (!sInstance->mInterposeObserver) {
return;
}
@ -921,6 +962,7 @@ class ActivePS {
}
static void PauseIOInterposer(PSLockRef) {
MOZ_ASSERT(sInstance);
if (!sInstance->mInterposeObserver) {
return;
}
@ -930,6 +972,7 @@ class ActivePS {
}
static void ResumeIOInterposer(PSLockRef) {
MOZ_ASSERT(sInstance);
if (!sInstance->mInterposeObserver) {
return;
}
@ -940,6 +983,7 @@ class ActivePS {
#endif
static void ClearExpiredExitProfiles(PSLockRef) {
MOZ_ASSERT(sInstance);
uint64_t bufferRangeStart = sInstance->mProfileBuffer->BufferRangeStart();
// Discard exit profiles that were gathered before our buffer RangeStart.
#ifdef MOZ_BASE_PROFILER
@ -956,10 +1000,13 @@ class ActivePS {
#ifdef MOZ_BASE_PROFILER
static void AddBaseProfileThreads(PSLockRef aLock,
UniquePtr<char[]> aBaseProfileThreads) {
MOZ_ASSERT(sInstance);
sInstance->mBaseProfileThreads = std::move(aBaseProfileThreads);
}
static UniquePtr<char[]> MoveBaseProfileThreads(PSLockRef aLock) {
MOZ_ASSERT(sInstance);
ClearExpiredExitProfiles(aLock);
return std::move(sInstance->mBaseProfileThreads);
@ -967,6 +1014,8 @@ class ActivePS {
#endif
static void AddExitProfile(PSLockRef aLock, const nsCString& aExitProfile) {
MOZ_ASSERT(sInstance);
ClearExpiredExitProfiles(aLock);
MOZ_RELEASE_ASSERT(sInstance->mExitProfiles.append(ExitProfile{
@ -974,6 +1023,8 @@ class ActivePS {
}
static Vector<nsCString> MoveExitProfiles(PSLockRef aLock) {
MOZ_ASSERT(sInstance);
ClearExpiredExitProfiles(aLock);
Vector<nsCString> profiles;