mirror of
https://github.com/mozilla/gecko-dev.git
synced 2025-02-11 01:57:00 +00:00
Bug 1128768: Part 2 - Refactor hang annotation code; r=vladan
--HG-- extra : rebase_source : f492ff9a5aa78afd2121afc8fd18c08b6831cdc3
This commit is contained in:
parent
d186a94983
commit
0f6fdabeee
@ -2553,9 +2553,9 @@ TelemetryImpl::GetChromeHangs(JSContext *cx, JS::MutableHandle<JS::Value> ret)
|
||||
if (!jsAnnotation) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
nsAutoPtr<HangAnnotations::Enumerator> annotationsEnum;
|
||||
if (!annotationInfo[iterIndex].mAnnotations->GetEnumerator(
|
||||
annotationsEnum.StartAssignment())) {
|
||||
UniquePtr<HangAnnotations::Enumerator> annotationsEnum =
|
||||
annotationInfo[iterIndex].mAnnotations->GetEnumerator();
|
||||
if (!annotationsEnum) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
nsAutoString key;
|
||||
|
262
xpcom/threads/HangAnnotations.cpp
Normal file
262
xpcom/threads/HangAnnotations.cpp
Normal file
@ -0,0 +1,262 @@
|
||||
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
|
||||
/* 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/HangAnnotations.h"
|
||||
|
||||
#include <vector>
|
||||
|
||||
#include "MainThreadUtils.h"
|
||||
#include "mozilla/DebugOnly.h"
|
||||
#include "nsXULAppAPI.h"
|
||||
|
||||
namespace mozilla {
|
||||
namespace HangMonitor {
|
||||
|
||||
// Chrome hang annotators. This can go away once BHR has completely replaced
|
||||
// ChromeHangs.
|
||||
static StaticAutoPtr<Observer::Annotators> gChromehangAnnotators;
|
||||
|
||||
class BrowserHangAnnotations : public HangAnnotations
|
||||
{
|
||||
public:
|
||||
BrowserHangAnnotations();
|
||||
~BrowserHangAnnotations();
|
||||
|
||||
void AddAnnotation(const nsAString& aName, const int32_t aData) MOZ_OVERRIDE;
|
||||
void AddAnnotation(const nsAString& aName, const double aData) MOZ_OVERRIDE;
|
||||
void AddAnnotation(const nsAString& aName, const nsAString& aData) MOZ_OVERRIDE;
|
||||
void AddAnnotation(const nsAString& aName, const nsACString& aData) MOZ_OVERRIDE;
|
||||
void AddAnnotation(const nsAString& aName, const bool aData) MOZ_OVERRIDE;
|
||||
|
||||
size_t SizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf) const MOZ_OVERRIDE;
|
||||
bool IsEmpty() const MOZ_OVERRIDE;
|
||||
UniquePtr<Enumerator> GetEnumerator() MOZ_OVERRIDE;
|
||||
|
||||
typedef std::pair<nsString, nsString> AnnotationType;
|
||||
typedef std::vector<AnnotationType> VectorType;
|
||||
typedef VectorType::const_iterator IteratorType;
|
||||
|
||||
private:
|
||||
VectorType mAnnotations;
|
||||
};
|
||||
|
||||
BrowserHangAnnotations::BrowserHangAnnotations()
|
||||
{
|
||||
MOZ_COUNT_CTOR(BrowserHangAnnotations);
|
||||
}
|
||||
|
||||
BrowserHangAnnotations::~BrowserHangAnnotations()
|
||||
{
|
||||
MOZ_COUNT_DTOR(BrowserHangAnnotations);
|
||||
}
|
||||
|
||||
void
|
||||
BrowserHangAnnotations::AddAnnotation(const nsAString& aName, const int32_t aData)
|
||||
{
|
||||
nsString dataString;
|
||||
dataString.AppendInt(aData);
|
||||
AnnotationType annotation = std::make_pair(nsString(aName), dataString);
|
||||
mAnnotations.push_back(annotation);
|
||||
}
|
||||
|
||||
void
|
||||
BrowserHangAnnotations::AddAnnotation(const nsAString& aName, const double aData)
|
||||
{
|
||||
nsString dataString;
|
||||
dataString.AppendFloat(aData);
|
||||
AnnotationType annotation = std::make_pair(nsString(aName), dataString);
|
||||
mAnnotations.push_back(annotation);
|
||||
}
|
||||
|
||||
void
|
||||
BrowserHangAnnotations::AddAnnotation(const nsAString& aName, const nsAString& aData)
|
||||
{
|
||||
AnnotationType annotation = std::make_pair(nsString(aName), nsString(aData));
|
||||
mAnnotations.push_back(annotation);
|
||||
}
|
||||
|
||||
void
|
||||
BrowserHangAnnotations::AddAnnotation(const nsAString& aName, const nsACString& aData)
|
||||
{
|
||||
nsString dataString;
|
||||
AppendUTF8toUTF16(aData, dataString);
|
||||
AnnotationType annotation = std::make_pair(nsString(aName), dataString);
|
||||
mAnnotations.push_back(annotation);
|
||||
}
|
||||
|
||||
void
|
||||
BrowserHangAnnotations::AddAnnotation(const nsAString& aName, const bool aData)
|
||||
{
|
||||
nsString dataString;
|
||||
dataString += aData ? NS_LITERAL_STRING("true") : NS_LITERAL_STRING("false");
|
||||
AnnotationType annotation = std::make_pair(nsString(aName), dataString);
|
||||
mAnnotations.push_back(annotation);
|
||||
}
|
||||
|
||||
/**
|
||||
* This class itself does not use synchronization but it (and its parent object)
|
||||
* should be protected by mutual exclusion in some way. In Telemetry the chrome
|
||||
* hang data is protected via TelemetryImpl::mHangReportsMutex.
|
||||
*/
|
||||
class ChromeHangAnnotationEnumerator : public HangAnnotations::Enumerator
|
||||
{
|
||||
public:
|
||||
explicit ChromeHangAnnotationEnumerator(const BrowserHangAnnotations::VectorType& aAnnotations);
|
||||
~ChromeHangAnnotationEnumerator();
|
||||
|
||||
virtual bool Next(nsAString& aOutName, nsAString& aOutValue);
|
||||
|
||||
private:
|
||||
BrowserHangAnnotations::IteratorType mIterator;
|
||||
BrowserHangAnnotations::IteratorType mEnd;
|
||||
};
|
||||
|
||||
ChromeHangAnnotationEnumerator::ChromeHangAnnotationEnumerator(
|
||||
const BrowserHangAnnotations::VectorType& aAnnotations)
|
||||
: mIterator(aAnnotations.begin())
|
||||
, mEnd(aAnnotations.end())
|
||||
{
|
||||
MOZ_COUNT_CTOR(ChromeHangAnnotationEnumerator);
|
||||
}
|
||||
|
||||
ChromeHangAnnotationEnumerator::~ChromeHangAnnotationEnumerator()
|
||||
{
|
||||
MOZ_COUNT_DTOR(ChromeHangAnnotationEnumerator);
|
||||
}
|
||||
|
||||
bool
|
||||
ChromeHangAnnotationEnumerator::Next(nsAString& aOutName, nsAString& aOutValue)
|
||||
{
|
||||
aOutName.Truncate();
|
||||
aOutValue.Truncate();
|
||||
if (mIterator == mEnd) {
|
||||
return false;
|
||||
}
|
||||
aOutName = mIterator->first;
|
||||
aOutValue = mIterator->second;
|
||||
++mIterator;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
BrowserHangAnnotations::IsEmpty() const
|
||||
{
|
||||
return mAnnotations.empty();
|
||||
}
|
||||
|
||||
size_t
|
||||
BrowserHangAnnotations::SizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf) const
|
||||
{
|
||||
size_t result = sizeof(mAnnotations) +
|
||||
mAnnotations.capacity() * sizeof(AnnotationType);
|
||||
for (IteratorType i = mAnnotations.begin(), e = mAnnotations.end(); i != e;
|
||||
++i) {
|
||||
result += i->first.SizeOfExcludingThisIfUnshared(aMallocSizeOf);
|
||||
result += i->second.SizeOfExcludingThisIfUnshared(aMallocSizeOf);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
UniquePtr<HangAnnotations::Enumerator>
|
||||
BrowserHangAnnotations::GetEnumerator()
|
||||
{
|
||||
if (mAnnotations.empty()) {
|
||||
return nullptr;
|
||||
}
|
||||
return MakeUnique<ChromeHangAnnotationEnumerator>(mAnnotations);
|
||||
}
|
||||
|
||||
namespace Observer {
|
||||
|
||||
Annotators::Annotators()
|
||||
: mMutex("HangMonitor::Annotators::mMutex")
|
||||
{
|
||||
MOZ_COUNT_CTOR(Annotators);
|
||||
}
|
||||
|
||||
Annotators::~Annotators()
|
||||
{
|
||||
MOZ_ASSERT(mAnnotators.empty());
|
||||
MOZ_COUNT_DTOR(Annotators);
|
||||
}
|
||||
|
||||
bool
|
||||
Annotators::Register(Annotator& aAnnotator)
|
||||
{
|
||||
MutexAutoLock lock(mMutex);
|
||||
auto result = mAnnotators.insert(&aAnnotator);
|
||||
return result.second;
|
||||
}
|
||||
|
||||
bool
|
||||
Annotators::Unregister(Annotator& aAnnotator)
|
||||
{
|
||||
MutexAutoLock lock(mMutex);
|
||||
DebugOnly<std::set<Annotator*>::size_type> numErased;
|
||||
numErased = mAnnotators.erase(&aAnnotator);
|
||||
MOZ_ASSERT(numErased == 1);
|
||||
return mAnnotators.empty();
|
||||
}
|
||||
|
||||
UniquePtr<HangAnnotations>
|
||||
Annotators::GatherAnnotations()
|
||||
{
|
||||
auto annotations = MakeUnique<BrowserHangAnnotations>();
|
||||
{ // Scope for lock
|
||||
MutexAutoLock lock(mMutex);
|
||||
for (std::set<Annotator*>::iterator i = mAnnotators.begin(),
|
||||
e = mAnnotators.end();
|
||||
i != e; ++i) {
|
||||
(*i)->AnnotateHang(*annotations);
|
||||
}
|
||||
}
|
||||
if (annotations->IsEmpty()) {
|
||||
return nullptr;
|
||||
}
|
||||
return Move(annotations);
|
||||
}
|
||||
|
||||
} // namespace Observer
|
||||
|
||||
void
|
||||
RegisterAnnotator(Annotator& aAnnotator)
|
||||
{
|
||||
BackgroundHangMonitor::RegisterAnnotator(aAnnotator);
|
||||
// We still register annotators for ChromeHangs
|
||||
if (NS_IsMainThread() &&
|
||||
GeckoProcessType_Default == XRE_GetProcessType()) {
|
||||
if (!gChromehangAnnotators) {
|
||||
gChromehangAnnotators = new Observer::Annotators();
|
||||
}
|
||||
gChromehangAnnotators->Register(aAnnotator);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
UnregisterAnnotator(Annotator& aAnnotator)
|
||||
{
|
||||
BackgroundHangMonitor::UnregisterAnnotator(aAnnotator);
|
||||
// We still register annotators for ChromeHangs
|
||||
if (NS_IsMainThread() &&
|
||||
GeckoProcessType_Default == XRE_GetProcessType()) {
|
||||
if (gChromehangAnnotators->Unregister(aAnnotator)) {
|
||||
gChromehangAnnotators = nullptr;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
UniquePtr<HangAnnotations>
|
||||
ChromeHangAnnotatorCallout()
|
||||
{
|
||||
if (!gChromehangAnnotators) {
|
||||
return nullptr;
|
||||
}
|
||||
return gChromehangAnnotators->GatherAnnotations();
|
||||
}
|
||||
|
||||
} // namespace HangMonitor
|
||||
} // namespace mozilla
|
104
xpcom/threads/HangAnnotations.h
Normal file
104
xpcom/threads/HangAnnotations.h
Normal file
@ -0,0 +1,104 @@
|
||||
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
|
||||
/* 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/. */
|
||||
|
||||
#ifndef mozilla_HangAnnotations_h
|
||||
#define mozilla_HangAnnotations_h
|
||||
|
||||
#include <set>
|
||||
|
||||
#include "mozilla/MemoryReporting.h"
|
||||
#include "mozilla/Mutex.h"
|
||||
#include "mozilla/UniquePtr.h"
|
||||
#include "mozilla/Vector.h"
|
||||
#include "nsString.h"
|
||||
|
||||
namespace mozilla {
|
||||
namespace HangMonitor {
|
||||
|
||||
/**
|
||||
* This class declares an abstraction for a data type that encapsulates all
|
||||
* of the annotations being reported by a registered hang Annotator.
|
||||
*/
|
||||
class HangAnnotations
|
||||
{
|
||||
public:
|
||||
virtual ~HangAnnotations() {}
|
||||
|
||||
virtual void AddAnnotation(const nsAString& aName, const int32_t aData) = 0;
|
||||
virtual void AddAnnotation(const nsAString& aName, const double aData) = 0;
|
||||
virtual void AddAnnotation(const nsAString& aName, const nsAString& aData) = 0;
|
||||
virtual void AddAnnotation(const nsAString& aName, const nsACString& aData) = 0;
|
||||
virtual void AddAnnotation(const nsAString& aName, const bool aData) = 0;
|
||||
|
||||
class Enumerator
|
||||
{
|
||||
public:
|
||||
virtual ~Enumerator() {}
|
||||
virtual bool Next(nsAString& aOutName, nsAString& aOutValue) = 0;
|
||||
};
|
||||
|
||||
virtual size_t SizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf) const = 0;
|
||||
virtual bool IsEmpty() const = 0;
|
||||
virtual UniquePtr<Enumerator> GetEnumerator() = 0;
|
||||
};
|
||||
|
||||
typedef UniquePtr<HangAnnotations> HangAnnotationsPtr;
|
||||
typedef Vector<HangAnnotationsPtr> HangAnnotationsVector;
|
||||
|
||||
class Annotator
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* NB: This function is always called by the HangMonitor thread.
|
||||
* Plan accordingly.
|
||||
*/
|
||||
virtual void AnnotateHang(HangAnnotations& aAnnotations) = 0;
|
||||
};
|
||||
|
||||
/**
|
||||
* Registers an Annotator to be called when a hang is detected.
|
||||
* @param aAnnotator Reference to an object that implements the
|
||||
* HangMonitor::Annotator interface.
|
||||
*/
|
||||
void RegisterAnnotator(Annotator& aAnnotator);
|
||||
|
||||
/**
|
||||
* Registers an Annotator that was previously registered via RegisterAnnotator.
|
||||
* @param aAnnotator Reference to an object that implements the
|
||||
* HangMonitor::Annotator interface.
|
||||
*/
|
||||
void UnregisterAnnotator(Annotator& aAnnotator);
|
||||
|
||||
/**
|
||||
* Gathers annotations. This function should be called by ChromeHangs.
|
||||
* @return UniquePtr to HangAnnotations object or nullptr if none.
|
||||
*/
|
||||
HangAnnotationsPtr ChromeHangAnnotatorCallout();
|
||||
|
||||
namespace Observer {
|
||||
|
||||
class Annotators
|
||||
{
|
||||
public:
|
||||
Annotators();
|
||||
~Annotators();
|
||||
|
||||
bool Register(Annotator& aAnnotator);
|
||||
bool Unregister(Annotator& aAnnotator);
|
||||
|
||||
HangAnnotationsPtr GatherAnnotations();
|
||||
|
||||
private:
|
||||
Mutex mMutex;
|
||||
std::set<Annotator*> mAnnotators;
|
||||
};
|
||||
|
||||
} // namespace Observer
|
||||
|
||||
} // namespace HangMonitor
|
||||
} // namespace mozilla
|
||||
|
||||
#endif // mozilla_HangAnnotations_h
|
@ -6,8 +6,6 @@
|
||||
|
||||
#include "mozilla/HangMonitor.h"
|
||||
|
||||
#include <set>
|
||||
|
||||
#include "mozilla/Atomics.h"
|
||||
#include "mozilla/BackgroundHangMonitor.h"
|
||||
#include "mozilla/Monitor.h"
|
||||
@ -74,9 +72,6 @@ static const int32_t DEFAULT_CHROME_HANG_INTERVAL = 5;
|
||||
|
||||
// Maximum number of PCs to gather from the stack
|
||||
static const int32_t MAX_CALL_STACK_PCS = 400;
|
||||
|
||||
// Chrome hang annotators
|
||||
static StaticAutoPtr<std::set<Annotator*>> gAnnotators;
|
||||
#endif
|
||||
|
||||
// PrefChangedFunc
|
||||
@ -122,161 +117,6 @@ Crash()
|
||||
}
|
||||
|
||||
#ifdef REPORT_CHROME_HANGS
|
||||
class ChromeHangAnnotations : public HangAnnotations
|
||||
{
|
||||
public:
|
||||
ChromeHangAnnotations();
|
||||
~ChromeHangAnnotations();
|
||||
|
||||
void AddAnnotation(const nsAString& aName, const int32_t aData) MOZ_OVERRIDE;
|
||||
void AddAnnotation(const nsAString& aName, const double aData) MOZ_OVERRIDE;
|
||||
void AddAnnotation(const nsAString& aName, const nsAString& aData) MOZ_OVERRIDE;
|
||||
void AddAnnotation(const nsAString& aName, const nsACString& aData) MOZ_OVERRIDE;
|
||||
void AddAnnotation(const nsAString& aName, const bool aData) MOZ_OVERRIDE;
|
||||
|
||||
size_t SizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf) const MOZ_OVERRIDE;
|
||||
bool IsEmpty() const MOZ_OVERRIDE;
|
||||
bool GetEnumerator(Enumerator** aOutEnum) MOZ_OVERRIDE;
|
||||
|
||||
typedef std::pair<nsString, nsString> AnnotationType;
|
||||
typedef std::vector<AnnotationType> VectorType;
|
||||
typedef VectorType::const_iterator IteratorType;
|
||||
|
||||
private:
|
||||
VectorType mAnnotations;
|
||||
};
|
||||
|
||||
ChromeHangAnnotations::ChromeHangAnnotations()
|
||||
{
|
||||
MOZ_COUNT_CTOR(ChromeHangAnnotations);
|
||||
}
|
||||
|
||||
ChromeHangAnnotations::~ChromeHangAnnotations()
|
||||
{
|
||||
MOZ_COUNT_DTOR(ChromeHangAnnotations);
|
||||
}
|
||||
|
||||
void
|
||||
ChromeHangAnnotations::AddAnnotation(const nsAString& aName, const int32_t aData)
|
||||
{
|
||||
nsString dataString;
|
||||
dataString.AppendInt(aData);
|
||||
AnnotationType annotation = std::make_pair(nsString(aName), dataString);
|
||||
mAnnotations.push_back(annotation);
|
||||
}
|
||||
|
||||
void
|
||||
ChromeHangAnnotations::AddAnnotation(const nsAString& aName, const double aData)
|
||||
{
|
||||
nsString dataString;
|
||||
dataString.AppendFloat(aData);
|
||||
AnnotationType annotation = std::make_pair(nsString(aName), dataString);
|
||||
mAnnotations.push_back(annotation);
|
||||
}
|
||||
|
||||
void
|
||||
ChromeHangAnnotations::AddAnnotation(const nsAString& aName, const nsAString& aData)
|
||||
{
|
||||
AnnotationType annotation = std::make_pair(nsString(aName), nsString(aData));
|
||||
mAnnotations.push_back(annotation);
|
||||
}
|
||||
|
||||
void
|
||||
ChromeHangAnnotations::AddAnnotation(const nsAString& aName, const nsACString& aData)
|
||||
{
|
||||
nsString dataString;
|
||||
AppendUTF8toUTF16(aData, dataString);
|
||||
AnnotationType annotation = std::make_pair(nsString(aName), dataString);
|
||||
mAnnotations.push_back(annotation);
|
||||
}
|
||||
|
||||
void
|
||||
ChromeHangAnnotations::AddAnnotation(const nsAString& aName, const bool aData)
|
||||
{
|
||||
nsString dataString;
|
||||
dataString += aData ? NS_LITERAL_STRING("true") : NS_LITERAL_STRING("false");
|
||||
AnnotationType annotation = std::make_pair(nsString(aName), dataString);
|
||||
mAnnotations.push_back(annotation);
|
||||
}
|
||||
|
||||
/**
|
||||
* This class itself does not use synchronization but it (and its parent object)
|
||||
* should be protected by mutual exclusion in some way. In Telemetry the chrome
|
||||
* hang data is protected via TelemetryImpl::mHangReportsMutex.
|
||||
*/
|
||||
class ChromeHangAnnotationEnumerator : public HangAnnotations::Enumerator
|
||||
{
|
||||
public:
|
||||
ChromeHangAnnotationEnumerator(const ChromeHangAnnotations::VectorType& aAnnotations);
|
||||
~ChromeHangAnnotationEnumerator();
|
||||
|
||||
virtual bool Next(nsAString& aOutName, nsAString& aOutValue);
|
||||
|
||||
private:
|
||||
ChromeHangAnnotations::IteratorType mIterator;
|
||||
ChromeHangAnnotations::IteratorType mEnd;
|
||||
};
|
||||
|
||||
ChromeHangAnnotationEnumerator::ChromeHangAnnotationEnumerator(
|
||||
const ChromeHangAnnotations::VectorType& aAnnotations)
|
||||
: mIterator(aAnnotations.begin())
|
||||
, mEnd(aAnnotations.end())
|
||||
{
|
||||
MOZ_COUNT_CTOR(ChromeHangAnnotationEnumerator);
|
||||
}
|
||||
|
||||
ChromeHangAnnotationEnumerator::~ChromeHangAnnotationEnumerator()
|
||||
{
|
||||
MOZ_COUNT_DTOR(ChromeHangAnnotationEnumerator);
|
||||
}
|
||||
|
||||
bool
|
||||
ChromeHangAnnotationEnumerator::Next(nsAString& aOutName, nsAString& aOutValue)
|
||||
{
|
||||
aOutName.Truncate();
|
||||
aOutValue.Truncate();
|
||||
if (mIterator == mEnd) {
|
||||
return false;
|
||||
}
|
||||
aOutName = mIterator->first;
|
||||
aOutValue = mIterator->second;
|
||||
++mIterator;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
ChromeHangAnnotations::IsEmpty() const
|
||||
{
|
||||
return mAnnotations.empty();
|
||||
}
|
||||
|
||||
size_t
|
||||
ChromeHangAnnotations::SizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf) const
|
||||
{
|
||||
size_t result = sizeof(mAnnotations) +
|
||||
mAnnotations.capacity() * sizeof(AnnotationType);
|
||||
for (IteratorType i = mAnnotations.begin(), e = mAnnotations.end(); i != e;
|
||||
++i) {
|
||||
result += i->first.SizeOfExcludingThisIfUnshared(aMallocSizeOf);
|
||||
result += i->second.SizeOfExcludingThisIfUnshared(aMallocSizeOf);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
bool
|
||||
ChromeHangAnnotations::GetEnumerator(HangAnnotations::Enumerator** aOutEnum)
|
||||
{
|
||||
if (!aOutEnum) {
|
||||
return false;
|
||||
}
|
||||
*aOutEnum = nullptr;
|
||||
if (mAnnotations.empty()) {
|
||||
return false;
|
||||
}
|
||||
*aOutEnum = new ChromeHangAnnotationEnumerator(mAnnotations);
|
||||
return true;
|
||||
}
|
||||
|
||||
static void
|
||||
ChromeStackWalker(uint32_t aFrameNumber, void* aPC, void* aSP, void* aClosure)
|
||||
@ -329,21 +169,6 @@ GetChromeHangReport(Telemetry::ProcessedStack& aStack,
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
ChromeHangAnnotatorCallout(ChromeHangAnnotations& aAnnotations)
|
||||
{
|
||||
gMonitor->AssertCurrentThreadOwns();
|
||||
MOZ_ASSERT(gAnnotators);
|
||||
if (!gAnnotators) {
|
||||
return;
|
||||
}
|
||||
for (std::set<Annotator*>::iterator i = gAnnotators->begin(),
|
||||
e = gAnnotators->end();
|
||||
i != e; ++i) {
|
||||
(*i)->AnnotateHang(aAnnotations);
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
void
|
||||
@ -363,7 +188,7 @@ ThreadMain(void*)
|
||||
Telemetry::ProcessedStack stack;
|
||||
int32_t systemUptime = -1;
|
||||
int32_t firefoxUptime = -1;
|
||||
auto annotations = MakeUnique<ChromeHangAnnotations>();
|
||||
UniquePtr<HangAnnotations> annotations;
|
||||
#endif
|
||||
|
||||
while (true) {
|
||||
@ -391,7 +216,7 @@ ThreadMain(void*)
|
||||
// the minimum hang duration has been reached (not when the hang ends)
|
||||
if (waitCount == 2) {
|
||||
GetChromeHangReport(stack, systemUptime, firefoxUptime);
|
||||
ChromeHangAnnotatorCallout(*annotations);
|
||||
annotations = ChromeHangAnnotatorCallout();
|
||||
}
|
||||
#else
|
||||
// This is the crash-on-hang feature.
|
||||
@ -412,7 +237,6 @@ ThreadMain(void*)
|
||||
Telemetry::RecordChromeHang(hangDuration, stack, systemUptime,
|
||||
firefoxUptime, Move(annotations));
|
||||
stack.Clear();
|
||||
annotations = MakeUnique<ChromeHangAnnotations>();
|
||||
}
|
||||
#endif
|
||||
lastTimestamp = timestamp;
|
||||
@ -452,7 +276,6 @@ Startup()
|
||||
if (!winMainThreadHandle) {
|
||||
return;
|
||||
}
|
||||
gAnnotators = new std::set<Annotator*>();
|
||||
#endif
|
||||
|
||||
// Don't actually start measuring hangs until we hit the main event loop.
|
||||
@ -491,11 +314,6 @@ Shutdown()
|
||||
|
||||
delete gMonitor;
|
||||
gMonitor = nullptr;
|
||||
|
||||
#ifdef REPORT_CHROME_HANGS
|
||||
// gAnnotators is a StaticAutoPtr, so we just need to null it out.
|
||||
gAnnotators = nullptr;
|
||||
#endif
|
||||
}
|
||||
|
||||
static bool
|
||||
@ -584,31 +402,5 @@ Suspend()
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
RegisterAnnotator(Annotator& aAnnotator)
|
||||
{
|
||||
#ifdef REPORT_CHROME_HANGS
|
||||
if (GeckoProcessType_Default != XRE_GetProcessType()) {
|
||||
return;
|
||||
}
|
||||
MonitorAutoLock lock(*gMonitor);
|
||||
MOZ_ASSERT(gAnnotators);
|
||||
gAnnotators->insert(&aAnnotator);
|
||||
#endif
|
||||
}
|
||||
|
||||
void
|
||||
UnregisterAnnotator(Annotator& aAnnotator)
|
||||
{
|
||||
#ifdef REPORT_CHROME_HANGS
|
||||
if (GeckoProcessType_Default != XRE_GetProcessType()) {
|
||||
return;
|
||||
}
|
||||
MonitorAutoLock lock(*gMonitor);
|
||||
MOZ_ASSERT(gAnnotators);
|
||||
gAnnotators->erase(&aAnnotator);
|
||||
#endif
|
||||
}
|
||||
|
||||
} // namespace HangMonitor
|
||||
} // namespace mozilla
|
||||
|
@ -7,9 +7,6 @@
|
||||
#ifndef mozilla_HangMonitor_h
|
||||
#define mozilla_HangMonitor_h
|
||||
|
||||
#include "mozilla/MemoryReporting.h"
|
||||
#include "nsString.h"
|
||||
|
||||
namespace mozilla {
|
||||
namespace HangMonitor {
|
||||
|
||||
@ -41,57 +38,6 @@ void Startup();
|
||||
*/
|
||||
void Shutdown();
|
||||
|
||||
/**
|
||||
* This class declares an abstraction for a data type that encapsulates all
|
||||
* of the annotations being reported by a registered hang Annotator.
|
||||
*/
|
||||
class HangAnnotations
|
||||
{
|
||||
public:
|
||||
virtual ~HangAnnotations() {}
|
||||
|
||||
virtual void AddAnnotation(const nsAString& aName, const int32_t aData) = 0;
|
||||
virtual void AddAnnotation(const nsAString& aName, const double aData) = 0;
|
||||
virtual void AddAnnotation(const nsAString& aName, const nsAString& aData) = 0;
|
||||
virtual void AddAnnotation(const nsAString& aName, const nsACString& aData) = 0;
|
||||
virtual void AddAnnotation(const nsAString& aName, const bool aData) = 0;
|
||||
|
||||
class Enumerator
|
||||
{
|
||||
public:
|
||||
virtual ~Enumerator() {}
|
||||
virtual bool Next(nsAString& aOutName, nsAString& aOutValue) = 0;
|
||||
};
|
||||
|
||||
virtual size_t SizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf) const = 0;
|
||||
virtual bool IsEmpty() const = 0;
|
||||
virtual bool GetEnumerator(Enumerator **aOutEnum) = 0;
|
||||
};
|
||||
|
||||
class Annotator
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* NB: This function is always called by the HangMonitor thread.
|
||||
* Plan accordingly.
|
||||
*/
|
||||
virtual void AnnotateHang(HangAnnotations& aAnnotations) = 0;
|
||||
};
|
||||
|
||||
/**
|
||||
* Registers an Annotator to be called when a hang is detected.
|
||||
* @param aAnnotator Reference to an object that implements the
|
||||
* HangMonitor::Annotator interface.
|
||||
*/
|
||||
void RegisterAnnotator(Annotator& aAnnotator);
|
||||
|
||||
/**
|
||||
* Registers an Annotator that was previously registered via RegisterAnnotator.
|
||||
* @param aAnnotator Reference to an object that implements the
|
||||
* HangMonitor::Annotator interface.
|
||||
*/
|
||||
void UnregisterAnnotator(Annotator& aAnnotator);
|
||||
|
||||
/**
|
||||
* Notify the hang monitor of activity which will reset its internal timer.
|
||||
*
|
||||
|
@ -29,6 +29,7 @@ EXPORTS += [
|
||||
|
||||
EXPORTS.mozilla += [
|
||||
'BackgroundHangMonitor.h',
|
||||
'HangAnnotations.h',
|
||||
'HangMonitor.h',
|
||||
'LazyIdleThread.h',
|
||||
'SyncRunnable.h',
|
||||
@ -36,6 +37,7 @@ EXPORTS.mozilla += [
|
||||
|
||||
UNIFIED_SOURCES += [
|
||||
'BackgroundHangMonitor.cpp',
|
||||
'HangAnnotations.cpp',
|
||||
'HangMonitor.cpp',
|
||||
'LazyIdleThread.cpp',
|
||||
'nsEnvironment.cpp',
|
||||
|
Loading…
x
Reference in New Issue
Block a user