Backed out 6 changesets (bug 1358074) for Assertion failure: NS_IsMainThread and valgrind failures

Backed out changeset c3f35f8a1f21 (bug 1358074)
Backed out changeset 1d214f8ac8fd (bug 1358074)
Backed out changeset 3221b215b080 (bug 1358074)
Backed out changeset adec21069065 (bug 1358074)
Backed out changeset 9baa76979a71 (bug 1358074)
Backed out changeset 8375b7a4be08 (bug 1358074)
This commit is contained in:
Iris Hsiao 2017-04-24 16:50:50 +08:00
Родитель 73a19d020e
Коммит 3cfb103f72
6 изменённых файлов: 181 добавлений и 165 удалений

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

@ -90,8 +90,8 @@ private:
// This is only used for the main thread.
mozilla::Maybe<ThreadResponsiveness> mResponsiveness;
// When sampling, this holds the generation number and offset in PS::mBuffer
// of the most recent sample for this thread.
// When sampling, this holds the generation number and offset in
// ProfilerState::mBuffer of the most recent sample for this thread.
ProfileBuffer::LastSample mLastSample;
};

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

@ -279,7 +279,7 @@ ThreadEntry(void* aArg)
return nullptr;
}
SamplerThread::SamplerThread(PSLockRef aLock, uint32_t aActivityGeneration,
SamplerThread::SamplerThread(PS::LockRef aLock, uint32_t aActivityGeneration,
double aIntervalMilliseconds)
: mActivityGeneration(aActivityGeneration)
, mIntervalMicroseconds(
@ -343,7 +343,7 @@ SamplerThread::~SamplerThread()
}
void
SamplerThread::Stop(PSLockRef aLock)
SamplerThread::Stop(PS::LockRef aLock)
{
MOZ_RELEASE_ASSERT(NS_IsMainThread());
@ -356,7 +356,7 @@ SamplerThread::Stop(PSLockRef aLock)
}
void
SamplerThread::SuspendAndSampleAndResumeThread(PSLockRef aLock,
SamplerThread::SuspendAndSampleAndResumeThread(PS::LockRef aLock,
TickSample& aSample)
{
// Only one sampler thread can be sampling at once. So we expect to have
@ -466,7 +466,7 @@ paf_prepare()
MOZ_RELEASE_ASSERT(gPS);
PSAutoLock lock(gPSMutex);
PS::AutoLock lock(gPSMutex);
gPS->SetWasPaused(lock, gPS->IsPaused(lock));
gPS->SetIsPaused(lock, true);
@ -480,14 +480,14 @@ paf_parent()
MOZ_RELEASE_ASSERT(gPS);
PSAutoLock lock(gPSMutex);
PS::AutoLock lock(gPSMutex);
gPS->SetIsPaused(lock, gPS->WasPaused(lock));
gPS->SetWasPaused(lock, false);
}
static void
PlatformInit(PSLockRef aLock)
PlatformInit(PS::LockRef aLock)
{
// Set up the fork handlers.
pthread_atfork(paf_prepare, paf_parent, nullptr);
@ -496,7 +496,7 @@ PlatformInit(PSLockRef aLock)
#else
static void
PlatformInit(PSLockRef aLock)
PlatformInit(PS::LockRef aLock)
{
}

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

@ -101,7 +101,7 @@ ThreadEntry(void* aArg)
return nullptr;
}
SamplerThread::SamplerThread(PSLockRef aLock, uint32_t aActivityGeneration,
SamplerThread::SamplerThread(PS::LockRef aLock, uint32_t aActivityGeneration,
double aIntervalMilliseconds)
: mActivityGeneration(aActivityGeneration)
, mIntervalMicroseconds(
@ -121,13 +121,13 @@ SamplerThread::~SamplerThread()
}
void
SamplerThread::Stop(PSLockRef aLock)
SamplerThread::Stop(PS::LockRef aLock)
{
MOZ_RELEASE_ASSERT(NS_IsMainThread());
}
void
SamplerThread::SuspendAndSampleAndResumeThread(PSLockRef aLock,
SamplerThread::SuspendAndSampleAndResumeThread(PS::LockRef aLock,
TickSample& aSample)
{
thread_act_t samplee_thread = aSample.mPlatformData->ProfiledThread();
@ -204,7 +204,7 @@ SamplerThread::SuspendAndSampleAndResumeThread(PSLockRef aLock,
////////////////////////////////////////////////////////////////////////
static void
PlatformInit(PSLockRef aLock)
PlatformInit(PS::LockRef aLock)
{
}

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

@ -98,7 +98,7 @@ ThreadEntry(void* aArg)
return 0;
}
SamplerThread::SamplerThread(PSLockRef aLock, uint32_t aActivityGeneration,
SamplerThread::SamplerThread(PS::LockRef aLock, uint32_t aActivityGeneration,
double aIntervalMilliseconds)
: mActivityGeneration(aActivityGeneration)
, mIntervalMicroseconds(
@ -139,7 +139,7 @@ SamplerThread::~SamplerThread()
}
void
SamplerThread::Stop(PSLockRef aLock)
SamplerThread::Stop(PS::LockRef aLock)
{
MOZ_RELEASE_ASSERT(NS_IsMainThread());
@ -157,7 +157,7 @@ SamplerThread::Stop(PSLockRef aLock)
}
void
SamplerThread::SuspendAndSampleAndResumeThread(PSLockRef aLock,
SamplerThread::SuspendAndSampleAndResumeThread(PS::LockRef aLock,
TickSample& aSample)
{
HANDLE profiled_thread = aSample.mPlatformData->ProfiledThread();
@ -229,7 +229,7 @@ SamplerThread::SuspendAndSampleAndResumeThread(PSLockRef aLock,
////////////////////////////////////////////////////////////////////////
static void
PlatformInit(PSLockRef aLock)
PlatformInit(PS::LockRef aLock)
{
}

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

@ -110,33 +110,34 @@ class SamplerThread;
// Per-thread state.
MOZ_THREAD_LOCAL(PseudoStack *) tlsPseudoStack;
class PSMutex : public mozilla::StaticMutex {};
typedef mozilla::BaseAutoLock<PSMutex> PSAutoLock;
// Only functions that take a PSLockRef arg can modify this class's fields.
typedef const PSAutoLock& PSLockRef;
// This class contains most of the profiler's global state. gPS is the single
// instance. Most profile operations can't do anything useful when gPS is not
// instantiated, so we release-assert its non-nullness in all such operations.
//
// Accesses to gPS are guarded by gPSMutex. Every getter and setter takes a
// PSAutoLock reference as an argument as proof that the gPSMutex is currently
// locked. This makes it clear when gPSMutex is locked and helps avoid
// accidental unlocked accesses to global state. There are ways to circumvent
// this mechanism, but please don't do so without *very* good reason and a
// detailed explanation.
// PS::AutoLock reference as an argument as proof that the gPSMutex is
// currently locked. This makes it clear when gPSMutex is locked and helps
// avoid accidental unlocked accesses to global state. There are ways to
// circumvent this mechanism, but please don't do so without *very* good reason
// and a detailed explanation.
//
// Other from the lock protection, this class is essentially a thin wrapper and
// contains very little "smarts" itself.
//
class PS
class ProfilerState
{
public:
// Shorter names for local use.
class Mutex : public mozilla::StaticMutex {};
typedef mozilla::BaseAutoLock<Mutex> AutoLock;
// Only functions that take a LockRef arg can modify this class's fields.
typedef const AutoLock& LockRef;
typedef std::vector<ThreadInfo*> ThreadVector;
PS()
ProfilerState()
: mEntries(0)
, mInterval(0)
, mFeatureDisplayListDump(false)
@ -154,7 +155,7 @@ public:
, mFeatureThreads(false)
, mBuffer(nullptr)
, mIsPaused(false)
#if defined(GP_OS_linux)
#if defined(GP_OS_linux) || defined(GP_OS_android)
, mWasPaused(false)
#endif
, mSamplerThread(nullptr)
@ -167,18 +168,18 @@ public:
{}
#define GET_AND_SET(type_, name_) \
type_ name_(PSLockRef) const { return m##name_; } \
void Set##name_(PSLockRef, type_ a##name_) { m##name_ = a##name_; }
type_ name_(LockRef) const { return m##name_; } \
void Set##name_(LockRef, type_ a##name_) { m##name_ = a##name_; }
GET_AND_SET(TimeStamp, ProcessStartTime)
GET_AND_SET(TimeStamp, StartTime)
GET_AND_SET(int, Entries)
GET_AND_SET(double, Interval)
Vector<std::string>& Features(PSLockRef) { return mFeatures; }
Vector<std::string>& Features(LockRef) { return mFeatures; }
Vector<std::string>& Filters(PSLockRef) { return mFilters; }
Vector<std::string>& ThreadNameFilters(LockRef) { return mThreadNameFilters; }
GET_AND_SET(bool, FeatureDisplayListDump)
GET_AND_SET(bool, FeatureGPU)
@ -196,13 +197,13 @@ public:
GET_AND_SET(ProfileBuffer*, Buffer)
ThreadVector& LiveThreads(PSLockRef) { return mLiveThreads; }
ThreadVector& DeadThreads(PSLockRef) { return mDeadThreads; }
ThreadVector& LiveThreads(LockRef) { return mLiveThreads; }
ThreadVector& DeadThreads(LockRef) { return mDeadThreads; }
static bool IsActive(PSLockRef) { return sActivityGeneration > 0; }
static uint32_t ActivityGeneration(PSLockRef) { return sActivityGeneration; }
static void SetInactive(PSLockRef) { sActivityGeneration = 0; }
static void SetActive(PSLockRef)
static bool IsActive(LockRef) { return sActivityGeneration > 0; }
static uint32_t ActivityGeneration(LockRef) { return sActivityGeneration; }
static void SetInactive(LockRef) { sActivityGeneration = 0; }
static void SetActive(LockRef)
{
sActivityGeneration = sNextActivityGeneration;
// On overflow, reset to 1 instead of 0, because 0 means inactive.
@ -213,7 +214,7 @@ public:
GET_AND_SET(bool, IsPaused)
#if defined(GP_OS_linux)
#if defined(GP_OS_linux) || defined(GP_OS_android)
GET_AND_SET(bool, WasPaused)
#endif
@ -231,8 +232,8 @@ public:
#undef GET_AND_SET
private:
// The time that the process started.
mozilla::TimeStamp mProcessStartTime;
// When profiler_init() or profiler_start() was most recently called.
mozilla::TimeStamp mStartTime;
// The number of entries in mBuffer. Zeroed when the profiler is inactive.
int mEntries;
@ -247,7 +248,7 @@ private:
// Substrings of names of threads we want to profile. Cleared when the
// profiler is inactive
Vector<std::string> mFilters;
Vector<std::string> mThreadNameFilters;
// Configuration flags derived from mFeatures. Cleared when the profiler is
// inactive.
@ -305,7 +306,7 @@ private:
// Is the profiler paused? False when the profiler is inactive.
bool mIsPaused;
#if defined(GP_OS_linux)
#if defined(GP_OS_linux) || defined(GP_OS_android)
// Used to record whether the profiler was paused just before forking. False
// at all times except just before/after forking.
bool mWasPaused;
@ -329,17 +330,17 @@ private:
int mLatestRecordedFrameNumber;
};
// A shorter name for use within this compilation unit.
typedef ProfilerState PS;
uint32_t PS::sActivityGeneration = 0;
uint32_t PS::sNextActivityGeneration = 1;
// The core profiler state. Null at process startup, it is set to a non-null
// value in profiler_init() and stays that way until profiler_shutdown() is
// called. Therefore it can be checked to determine if the profiler has been
// initialized but not yet shut down.
static PS* gPS = nullptr;
// The profiler state. Set by profiler_init(), cleared by profiler_shutdown().
PS* gPS = nullptr;
// The mutex that guards accesses to gPS.
static PSMutex gPSMutex;
static PS::Mutex gPSMutex;
// The name of the main thread.
static const char* const kMainThreadName = "GeckoMain";
@ -472,7 +473,7 @@ AddDynamicCodeLocationTag(ProfileBuffer* aBuffer, const char* aStr)
static const int SAMPLER_MAX_STRING_LENGTH = 128;
static void
AddPseudoEntry(PSLockRef aLock, ProfileBuffer* aBuffer,
AddPseudoEntry(PS::LockRef aLock, ProfileBuffer* aBuffer,
volatile js::ProfileEntry& entry, PseudoStack* stack,
void* lastpc)
{
@ -574,7 +575,7 @@ struct AutoWalkJSStack
};
static void
MergeStacksIntoProfile(PSLockRef aLock, ProfileBuffer* aBuffer,
MergeStacksIntoProfile(PS::LockRef aLock, ProfileBuffer* aBuffer,
const TickSample& aSample, NativeStack& aNativeStack)
{
NotNull<PseudoStack*> pseudoStack = aSample.mPseudoStack;
@ -758,7 +759,7 @@ MergeStacksIntoProfile(PSLockRef aLock, ProfileBuffer* aBuffer,
// Update the JS context with the current profile sample buffer generation.
//
// Do not do this for synchronous samples, which use their own
// ProfileBuffers instead of the global one in PS.
// ProfileBuffers instead of the global one in ProfilerState.
if (!aSample.mIsSynchronous && pseudoStack->mContext) {
MOZ_ASSERT(aBuffer->mGeneration >= startBufferGen);
uint32_t lapCount = aBuffer->mGeneration - startBufferGen;
@ -784,7 +785,7 @@ StackWalkCallback(uint32_t aFrameNumber, void* aPC, void* aSP, void* aClosure)
}
static void
DoNativeBacktrace(PSLockRef aLock, ProfileBuffer* aBuffer,
DoNativeBacktrace(PS::LockRef aLock, ProfileBuffer* aBuffer,
const TickSample& aSample)
{
void* pc_array[1000];
@ -826,7 +827,7 @@ DoNativeBacktrace(PSLockRef aLock, ProfileBuffer* aBuffer,
#ifdef USE_EHABI_STACKWALK
static void
DoNativeBacktrace(PSLockRef aLock, ProfileBuffer* aBuffer,
DoNativeBacktrace(PS::LockRef aLock, ProfileBuffer* aBuffer,
const TickSample& aSample)
{
void* pc_array[1000];
@ -915,7 +916,7 @@ ASAN_memcpy(void* aDst, const void* aSrc, size_t aLen)
#endif
static void
DoNativeBacktrace(PSLockRef aLock, ProfileBuffer* aBuffer,
DoNativeBacktrace(PS::LockRef aLock, ProfileBuffer* aBuffer,
const TickSample& aSample)
{
const mcontext_t* mc =
@ -1058,7 +1059,7 @@ DoNativeBacktrace(PSLockRef aLock, ProfileBuffer* aBuffer,
#endif
static void
DoSampleStackTrace(PSLockRef aLock, ProfileBuffer* aBuffer,
DoSampleStackTrace(PS::LockRef aLock, ProfileBuffer* aBuffer,
const TickSample& aSample)
{
NativeStack nativeStack = { nullptr, nullptr, 0, 0 };
@ -1072,12 +1073,11 @@ DoSampleStackTrace(PSLockRef aLock, ProfileBuffer* aBuffer,
// This function is called for each sampling period with the current program
// counter. It is called within a signal and so must be re-entrant.
static void
Tick(PSLockRef aLock, ProfileBuffer* aBuffer, const TickSample& aSample)
Tick(PS::LockRef aLock, ProfileBuffer* aBuffer, const TickSample& aSample)
{
aBuffer->addTagThreadId(aSample.mThreadId, aSample.mLastSample);
mozilla::TimeDuration delta =
aSample.mTimeStamp - gPS->ProcessStartTime(aLock);
mozilla::TimeDuration delta = aSample.mTimeStamp - gPS->StartTime(aLock);
aBuffer->addTag(ProfileBufferEntry::Time(delta.ToMilliseconds()));
NotNull<PseudoStack*> pseudoStack = aSample.mPseudoStack;
@ -1186,13 +1186,13 @@ StreamNameAndThreadId(JSONWriter& aWriter, const char* aName, int aThreadId)
#endif
static void
StreamTaskTracer(PSLockRef aLock, SpliceableJSONWriter& aWriter)
StreamTaskTracer(PS::LockRef aLock, SpliceableJSONWriter& aWriter)
{
#ifdef MOZ_TASK_TRACER
aWriter.StartArrayProperty("data");
{
UniquePtr<nsTArray<nsCString>> data =
mozilla::tasktracer::GetLoggedData(gPS->ProcessStartTime(aLock));
mozilla::tasktracer::GetLoggedData(gPS->StartTime(aLock));
for (uint32_t i = 0; i < data->Length(); ++i) {
aWriter.StringElement((data->ElementAt(i)).get());
}
@ -1221,7 +1221,7 @@ StreamTaskTracer(PSLockRef aLock, SpliceableJSONWriter& aWriter)
}
static void
StreamMetaJSCustomObject(PSLockRef aLock, SpliceableJSONWriter& aWriter)
StreamMetaJSCustomObject(PS::LockRef aLock, SpliceableJSONWriter& aWriter)
{
MOZ_RELEASE_ASSERT(NS_IsMainThread());
@ -1241,10 +1241,10 @@ StreamMetaJSCustomObject(PSLockRef aLock, SpliceableJSONWriter& aWriter)
aWriter.IntProperty("asyncstack", asyncStacks);
// The "startTime" field holds the number of milliseconds since midnight
// January 1, 1970 GMT. This grotty code computes (Now - (Now -
// ProcessStartTime)) to convert gPS->ProcessStartTime() into that form.
// January 1, 1970 GMT. This grotty code computes (Now - (Now - StartTime))
// to convert gPS->StartTime() into that form.
mozilla::TimeDuration delta =
mozilla::TimeStamp::Now() - gPS->ProcessStartTime(aLock);
mozilla::TimeStamp::Now() - gPS->StartTime(aLock);
aWriter.DoubleProperty(
"startTime", static_cast<double>(PR_Now()/1000.0 - delta.ToMilliseconds()));
@ -1353,9 +1353,7 @@ BuildJavaThreadJSObject(SpliceableJSONWriter& aWriter)
#endif
static void
locked_profiler_stream_json_for_this_process(PSLockRef aLock,
SpliceableJSONWriter& aWriter,
double aSinceTime)
locked_profiler_stream_json_for_this_process(PS::LockRef aLock, SpliceableJSONWriter& aWriter, double aSinceTime)
{
LOG("locked_profiler_stream_json_for_this_process");
@ -1386,23 +1384,23 @@ locked_profiler_stream_json_for_this_process(PSLockRef aLock,
{
gPS->SetIsPaused(aLock, true);
const PS::ThreadVector& liveThreads = gPS->LiveThreads(aLock);
for (size_t i = 0; i < liveThreads.size(); i++) {
ThreadInfo* info = liveThreads.at(i);
if (!info->IsBeingProfiled()) {
continue;
const PS::ThreadVector& liveThreads = gPS->LiveThreads(aLock);
for (size_t i = 0; i < liveThreads.size(); i++) {
ThreadInfo* info = liveThreads.at(i);
if (!info->IsBeingProfiled()) {
continue;
}
info->StreamJSON(gPS->Buffer(aLock), aWriter, gPS->StartTime(aLock),
aSinceTime);
}
info->StreamJSON(gPS->Buffer(aLock), aWriter,
gPS->ProcessStartTime(aLock), aSinceTime);
}
const PS::ThreadVector& deadThreads = gPS->DeadThreads(aLock);
for (size_t i = 0; i < deadThreads.size(); i++) {
ThreadInfo* info = deadThreads.at(i);
MOZ_ASSERT(info->IsBeingProfiled());
info->StreamJSON(gPS->Buffer(aLock), aWriter,
gPS->ProcessStartTime(aLock), aSinceTime);
}
const PS::ThreadVector& deadThreads = gPS->DeadThreads(aLock);
for (size_t i = 0; i < deadThreads.size(); i++) {
ThreadInfo* info = deadThreads.at(i);
MOZ_ASSERT(info->IsBeingProfiled());
info->StreamJSON(gPS->Buffer(aLock), aWriter, gPS->StartTime(aLock),
aSinceTime);
}
#if defined(PROFILE_JAVA)
if (gPS->FeatureJava(aLock)) {
@ -1431,7 +1429,7 @@ profiler_stream_json_for_this_process(SpliceableJSONWriter& aWriter, double aSin
MOZ_RELEASE_ASSERT(NS_IsMainThread());
MOZ_RELEASE_ASSERT(gPS);
PSAutoLock lock(gPSMutex);
PS::AutoLock lock(gPSMutex);
if (!gPS->IsActive(lock)) {
return false;
@ -1469,7 +1467,7 @@ ProfilerMarker::GetTime() const {
}
void ProfilerMarker::StreamJSON(SpliceableJSONWriter& aWriter,
const TimeStamp& aProcessStartTime,
const TimeStamp& aStartTime,
UniqueStacks& aUniqueStacks) const
{
// Schema:
@ -1485,7 +1483,7 @@ void ProfilerMarker::StreamJSON(SpliceableJSONWriter& aWriter,
if (mPayload) {
aWriter.StartObjectElement();
{
mPayload->StreamPayload(aWriter, aProcessStartTime, aUniqueStacks);
mPayload->StreamPayload(aWriter, aStartTime, aUniqueStacks);
}
aWriter.EndObject();
}
@ -1560,19 +1558,19 @@ class SamplerThread
{
public:
// Creates a sampler thread, but doesn't start it.
SamplerThread(PSLockRef aLock, uint32_t aActivityGeneration,
SamplerThread(PS::LockRef aLock, uint32_t aActivityGeneration,
double aIntervalMilliseconds);
~SamplerThread();
// This runs on the sampler thread. It suspends and resumes the samplee
// threads.
void SuspendAndSampleAndResumeThread(PSLockRef aLock, TickSample& aSample);
void SuspendAndSampleAndResumeThread(PS::LockRef aLock, TickSample& aSample);
// This runs on (is!) the sampler thread.
void Run();
// This runs on the main thread.
void Stop(PSLockRef aLock);
void Stop(PS::LockRef aLock);
private:
// The activity generation, for detecting when the sampler thread must stop.
@ -1626,7 +1624,7 @@ SamplerThread::Run()
while (true) {
// This scope is for |lock|. It ends before we sleep below.
{
PSAutoLock lock(gPSMutex);
PS::AutoLock lock(gPSMutex);
// At this point profiler_stop() might have been called, and
// profiler_start() might have been called on another thread.
@ -1656,9 +1654,9 @@ SamplerThread::Run()
// cheaper than taking a new sample.
if (info->Stack()->CanDuplicateLastSampleDueToSleep()) {
bool dup_ok =
gPS->Buffer(lock)->DuplicateLastSample(
info->ThreadId(), gPS->ProcessStartTime(lock),
info->LastSample());
gPS->Buffer(lock)->DuplicateLastSample(info->ThreadId(),
gPS->StartTime(lock),
info->LastSample());
if (dup_ok) {
continue;
}
@ -1759,7 +1757,7 @@ GeckoProfilerReporter::CollectReports(nsIHandleReportCallback* aHandleReport,
#endif
{
PSAutoLock lock(gPSMutex);
PS::AutoLock lock(gPSMutex);
if (gPS) {
profSize = GeckoProfilerMallocSizeOf(gPS);
@ -1784,7 +1782,7 @@ GeckoProfilerReporter::CollectReports(nsIHandleReportCallback* aHandleReport,
// Measurement of the following things may be added later if DMD finds it
// is worthwhile:
// - gPS->mFeatures
// - gPS->mFilters
// - gPS->mThreadNameFilters
// - gPS->mLiveThreads itself (its elements' children are measured above)
// - gPS->mDeadThreads itself (ditto)
// - gPS->mInterposeObserver
@ -1798,8 +1796,8 @@ GeckoProfilerReporter::CollectReports(nsIHandleReportCallback* aHandleReport,
MOZ_COLLECT_REPORT(
"explicit/profiler/profiler-state", KIND_HEAP, UNITS_BYTES, profSize,
"Memory used by the Gecko Profiler's global state (excluding memory used "
"by LUL).");
"Memory used by the Gecko Profiler's ProfilerState object (excluding "
"memory used by LUL).");
#if defined(USE_LUL_STACKWALK)
MOZ_COLLECT_REPORT(
@ -1813,23 +1811,23 @@ GeckoProfilerReporter::CollectReports(nsIHandleReportCallback* aHandleReport,
NS_IMPL_ISUPPORTS(GeckoProfilerReporter, nsIMemoryReporter)
static bool
ThreadSelected(PSLockRef aLock, const char* aThreadName)
ThreadSelected(PS::LockRef aLock, const char* aThreadName)
{
// This function runs both on and off the main thread.
MOZ_RELEASE_ASSERT(gPS);
const Vector<std::string>& filters = gPS->Filters(aLock);
const Vector<std::string>& threadNameFilters = gPS->ThreadNameFilters(aLock);
if (filters.empty()) {
if (threadNameFilters.empty()) {
return true;
}
std::string name = aThreadName;
std::transform(name.begin(), name.end(), name.begin(), ::tolower);
for (uint32_t i = 0; i < filters.length(); ++i) {
std::string filter = filters[i];
for (uint32_t i = 0; i < threadNameFilters.length(); ++i) {
std::string filter = threadNameFilters[i];
std::transform(filter.begin(), filter.end(), filter.begin(), ::tolower);
// Crude, non UTF-8 compatible, case insensitive substring search
@ -1842,7 +1840,7 @@ ThreadSelected(PSLockRef aLock, const char* aThreadName)
}
static bool
ShouldProfileThread(PSLockRef aLock, ThreadInfo* aInfo)
ShouldProfileThread(PS::LockRef aLock, ThreadInfo* aInfo)
{
// This function runs both on and off the main thread.
@ -1855,7 +1853,7 @@ ShouldProfileThread(PSLockRef aLock, ThreadInfo* aInfo)
// Find the ThreadInfo for the current thread. On success, *aIndexOut is set to
// the index if it is non-null.
static ThreadInfo*
FindLiveThreadInfo(PSLockRef aLock, int* aIndexOut = nullptr)
FindLiveThreadInfo(PS::LockRef aLock, int* aIndexOut = nullptr)
{
// This function runs both on and off the main thread.
@ -1874,7 +1872,7 @@ FindLiveThreadInfo(PSLockRef aLock, int* aIndexOut = nullptr)
}
static void
locked_register_thread(PSLockRef aLock, const char* aName, void* stackTop)
locked_register_thread(PS::LockRef aLock, const char* aName, void* stackTop)
{
// This function runs both on and off the main thread.
@ -1908,7 +1906,7 @@ locked_register_thread(PSLockRef aLock, const char* aName, void* stackTop)
static void
NotifyProfilerStarted(const int aEntries, double aInterval,
const char** aFeatures, uint32_t aFeatureCount,
const char** aFilters, uint32_t aFilterCount)
const char** aThreadNameFilters, uint32_t aFilterCount)
{
if (!CanNotifyObservers()) {
return;
@ -1924,13 +1922,14 @@ NotifyProfilerStarted(const int aEntries, double aInterval,
featuresArray.AppendElement(aFeatures[i]);
}
nsTArray<nsCString> filtersArray;
nsTArray<nsCString> threadNameFiltersArray;
for (size_t i = 0; i < aFilterCount; ++i) {
filtersArray.AppendElement(aFilters[i]);
threadNameFiltersArray.AppendElement(aThreadNameFilters[i]);
}
nsCOMPtr<nsIProfilerStartParams> params =
new nsProfilerStartParams(aEntries, aInterval, featuresArray, filtersArray);
new nsProfilerStartParams(aEntries, aInterval, featuresArray,
threadNameFiltersArray);
os->NotifyObservers(params, "profiler-started", nullptr);
}
@ -1951,9 +1950,9 @@ NotifyObservers(const char* aTopic)
}
static void
locked_profiler_start(PSLockRef aLock, const int aEntries, double aInterval,
locked_profiler_start(PS::LockRef aLock, const int aEntries, double aInterval,
const char** aFeatures, uint32_t aFeatureCount,
const char** aFilters, uint32_t aFilterCount);
const char** aThreadNameFilters, uint32_t aFilterCount);
void
profiler_init(void* aStackTop)
@ -1980,14 +1979,14 @@ profiler_init(void* aStackTop)
}
{
PSAutoLock lock(gPSMutex);
PS::AutoLock lock(gPSMutex);
// We've passed the possible failure point. Instantiate gPS, which
// indicates that the profiler has initialized successfully.
gPS = new PS();
bool ignore;
gPS->SetProcessStartTime(lock, mozilla::TimeStamp::ProcessCreation(ignore));
gPS->SetStartTime(lock, mozilla::TimeStamp::ProcessCreation(ignore));
locked_register_thread(lock, kMainThreadName, aStackTop);
@ -2053,10 +2052,10 @@ profiler_init(void* aStackTop)
}
static void
locked_profiler_save_profile_to_file(PSLockRef aLock, const char* aFilename);
locked_profiler_save_profile_to_file(PS::LockRef aLock, const char* aFilename);
static SamplerThread*
locked_profiler_stop(PSLockRef aLock);
locked_profiler_stop(PS::LockRef aLock);
void
profiler_shutdown()
@ -2070,7 +2069,7 @@ profiler_shutdown()
// gPS is destroyed, in order to delete it.
SamplerThread* samplerThread = nullptr;
{
PSAutoLock lock(gPSMutex);
PS::AutoLock lock(gPSMutex);
// Save the profile on shutdown if requested.
if (gPS->IsActive(lock)) {
@ -2161,7 +2160,7 @@ profiler_get_start_params(int* aEntries, double* aInterval,
return;
}
PSAutoLock lock(gPSMutex);
PS::AutoLock lock(gPSMutex);
*aEntries = gPS->Entries(lock);
*aInterval = gPS->Interval(lock);
@ -2172,15 +2171,15 @@ profiler_get_start_params(int* aEntries, double* aInterval,
(*aFeatures)[i] = features[i].c_str();
}
const Vector<std::string>& filters = gPS->Filters(lock);
MOZ_ALWAYS_TRUE(aFilters->resize(filters.length()));
for (uint32_t i = 0; i < filters.length(); ++i) {
(*aFilters)[i] = filters[i].c_str();
const Vector<std::string>& threadNameFilters = gPS->ThreadNameFilters(lock);
MOZ_ALWAYS_TRUE(aFilters->resize(threadNameFilters.length()));
for (uint32_t i = 0; i < threadNameFilters.length(); ++i) {
(*aFilters)[i] = threadNameFilters[i].c_str();
}
}
static void
locked_profiler_save_profile_to_file(PSLockRef aLock, const char* aFilename)
locked_profiler_save_profile_to_file(PS::LockRef aLock, const char* aFilename)
{
LOG("locked_profiler_save_profile_to_file(%s)", aFilename);
@ -2214,7 +2213,7 @@ profiler_save_profile_to_file(const char* aFilename)
MOZ_RELEASE_ASSERT(NS_IsMainThread());
MOZ_RELEASE_ASSERT(gPS);
PSAutoLock lock(gPSMutex);
PS::AutoLock lock(gPSMutex);
if (!gPS->IsActive(lock)) {
return;
@ -2278,7 +2277,7 @@ profiler_get_buffer_info_helper(uint32_t* aCurrentPosition,
MOZ_RELEASE_ASSERT(NS_IsMainThread());
MOZ_RELEASE_ASSERT(gPS);
PSAutoLock lock(gPSMutex);
PS::AutoLock lock(gPSMutex);
if (!gPS->IsActive(lock)) {
return;
@ -2301,9 +2300,9 @@ hasFeature(const char** aFeatures, uint32_t aFeatureCount, const char* aFeature)
}
static void
locked_profiler_start(PSLockRef aLock, int aEntries, double aInterval,
locked_profiler_start(PS::LockRef aLock, int aEntries, double aInterval,
const char** aFeatures, uint32_t aFeatureCount,
const char** aFilters, uint32_t aFilterCount)
const char** aThreadNameFilters, uint32_t aFilterCount)
{
if (LOG_TEST) {
LOG("locked_profiler_start");
@ -2313,13 +2312,16 @@ locked_profiler_start(PSLockRef aLock, int aEntries, double aInterval,
LOG("- feature = %s", aFeatures[i]);
}
for (uint32_t i = 0; i < aFilterCount; i++) {
LOG("- threads = %s", aFilters[i]);
LOG("- threads = %s", aThreadNameFilters[i]);
}
}
MOZ_RELEASE_ASSERT(NS_IsMainThread());
MOZ_RELEASE_ASSERT(gPS && !gPS->IsActive(aLock));
bool ignore;
gPS->SetStartTime(aLock, mozilla::TimeStamp::ProcessCreation(ignore));
// Fall back to the default value if the passed-in value is unreasonable.
int entries = aEntries > 0 ? aEntries : PROFILE_DEFAULT_ENTRIES;
gPS->SetEntries(aLock, entries);
@ -2335,11 +2337,12 @@ locked_profiler_start(PSLockRef aLock, int aEntries, double aInterval,
features[i] = aFeatures[i];
}
// Deep copy aFilters. Must precede the ShouldProfileThread() call below.
Vector<std::string>& filters = gPS->Filters(aLock);
MOZ_ALWAYS_TRUE(filters.resize(aFilterCount));
// Deep copy aThreadNameFilters. Must precede the ShouldProfileThread() call
// below.
Vector<std::string>& threadNameFilters = gPS->ThreadNameFilters(aLock);
MOZ_ALWAYS_TRUE(threadNameFilters.resize(aFilterCount));
for (uint32_t i = 0; i < aFilterCount; ++i) {
filters[i] = aFilters[i];
threadNameFilters[i] = aThreadNameFilters[i];
}
#define HAS_FEATURE(feature) hasFeature(aFeatures, aFeatureCount, feature)
@ -2438,7 +2441,7 @@ locked_profiler_start(PSLockRef aLock, int aEntries, double aInterval,
void
profiler_start(int aEntries, double aInterval,
const char** aFeatures, uint32_t aFeatureCount,
const char** aFilters, uint32_t aFilterCount)
const char** aThreadNameFilters, uint32_t aFilterCount)
{
LOG("profiler_start");
@ -2446,7 +2449,7 @@ profiler_start(int aEntries, double aInterval,
SamplerThread* samplerThread = nullptr;
{
PSAutoLock lock(gPSMutex);
PS::AutoLock lock(gPSMutex);
// Initialize if necessary.
if (!gPS) {
@ -2459,7 +2462,7 @@ profiler_start(int aEntries, double aInterval,
}
locked_profiler_start(lock, aEntries, aInterval, aFeatures, aFeatureCount,
aFilters, aFilterCount);
aThreadNameFilters, aFilterCount);
}
// We do these operations with gPSMutex unlocked. The comments in
@ -2469,11 +2472,11 @@ profiler_start(int aEntries, double aInterval,
delete samplerThread;
}
NotifyProfilerStarted(aEntries, aInterval, aFeatures, aFeatureCount,
aFilters, aFilterCount);
aThreadNameFilters, aFilterCount);
}
static MOZ_MUST_USE SamplerThread*
locked_profiler_stop(PSLockRef aLock)
locked_profiler_stop(PS::LockRef aLock)
{
LOG("locked_profiler_stop");
@ -2551,7 +2554,7 @@ locked_profiler_stop(PSLockRef aLock)
gPS->SetFeatureTaskTracer(aLock, false);
gPS->SetFeatureThreads(aLock, false);
gPS->Filters(aLock).clear();
gPS->ThreadNameFilters(aLock).clear();
gPS->Features(aLock).clear();
@ -2572,7 +2575,7 @@ profiler_stop()
SamplerThread* samplerThread;
{
PSAutoLock lock(gPSMutex);
PS::AutoLock lock(gPSMutex);
if (!gPS->IsActive(lock)) {
return;
@ -2604,7 +2607,7 @@ profiler_is_paused()
MOZ_RELEASE_ASSERT(NS_IsMainThread());
MOZ_RELEASE_ASSERT(gPS);
PSAutoLock lock(gPSMutex);
PS::AutoLock lock(gPSMutex);
if (!gPS->IsActive(lock)) {
return false;
@ -2622,7 +2625,7 @@ profiler_pause()
MOZ_RELEASE_ASSERT(gPS);
{
PSAutoLock lock(gPSMutex);
PS::AutoLock lock(gPSMutex);
if (!gPS->IsActive(lock)) {
return;
@ -2643,7 +2646,7 @@ profiler_resume()
MOZ_RELEASE_ASSERT(NS_IsMainThread());
MOZ_RELEASE_ASSERT(gPS);
PSAutoLock lock(gPSMutex);
PS::AutoLock lock(gPSMutex);
{
if (!gPS->IsActive(lock)) {
@ -2664,7 +2667,7 @@ profiler_feature_active(const char* aName)
MOZ_RELEASE_ASSERT(gPS);
PSAutoLock lock(gPSMutex);
PS::AutoLock lock(gPSMutex);
if (!gPS->IsActive(lock)) {
return false;
@ -2696,7 +2699,7 @@ profiler_is_active()
MOZ_RELEASE_ASSERT(gPS);
PSAutoLock lock(gPSMutex);
PS::AutoLock lock(gPSMutex);
return gPS->IsActive(lock);
}
@ -2708,7 +2711,7 @@ profiler_set_frame_number(int aFrameNumber)
MOZ_RELEASE_ASSERT(gPS);
PSAutoLock lock(gPSMutex);
PS::AutoLock lock(gPSMutex);
gPS->SetFrameNumber(lock, aFrameNumber);
}
@ -2721,7 +2724,7 @@ profiler_register_thread(const char* aName, void* aGuessStackTop)
MOZ_RELEASE_ASSERT(!NS_IsMainThread());
MOZ_RELEASE_ASSERT(gPS);
PSAutoLock lock(gPSMutex);
PS::AutoLock lock(gPSMutex);
void* stackTop = GetStackTop(aGuessStackTop);
locked_register_thread(lock, aName, stackTop);
@ -2733,7 +2736,7 @@ profiler_unregister_thread()
MOZ_RELEASE_ASSERT(!NS_IsMainThread());
MOZ_RELEASE_ASSERT(gPS);
PSAutoLock lock(gPSMutex);
PS::AutoLock lock(gPSMutex);
// We don't call PseudoStack::stopJSSampling() here; there's no point doing
// that for a JS thread that is in the process of disappearing.
@ -2831,10 +2834,10 @@ profiler_time()
MOZ_RELEASE_ASSERT(gPS);
PSAutoLock lock(gPSMutex);
PS::AutoLock lock(gPSMutex);
mozilla::TimeDuration delta =
mozilla::TimeStamp::Now() - gPS->ProcessStartTime(lock);
mozilla::TimeStamp::Now() - gPS->StartTime(lock);
return delta.ToMilliseconds();
}
@ -2844,7 +2847,7 @@ profiler_get_backtrace()
MOZ_RELEASE_ASSERT(NS_IsMainThread());
MOZ_RELEASE_ASSERT(gPS);
PSAutoLock lock(gPSMutex);
PS::AutoLock lock(gPSMutex);
if (!gPS->IsActive(lock) || gPS->FeaturePrivacy(lock)) {
return nullptr;
@ -2907,7 +2910,7 @@ profiler_get_backtrace_noalloc(char *output, size_t outputSize)
bool includeDynamicString = true;
{
PSAutoLock lock(gPSMutex);
PS::AutoLock lock(gPSMutex);
includeDynamicString = !gPS->FeaturePrivacy(lock);
}
@ -2944,7 +2947,7 @@ profiler_get_backtrace_noalloc(char *output, size_t outputSize)
}
static void
locked_profiler_add_marker(PSLockRef aLock, const char* aMarker,
locked_profiler_add_marker(PS::LockRef aLock, const char* aMarker,
ProfilerMarkerPayload* aPayload)
{
// This function runs both on and off the main thread.
@ -2963,7 +2966,7 @@ locked_profiler_add_marker(PSLockRef aLock, const char* aMarker,
mozilla::TimeStamp origin = (payload && !payload->GetStartTime().IsNull())
? payload->GetStartTime()
: mozilla::TimeStamp::Now();
mozilla::TimeDuration delta = origin - gPS->ProcessStartTime(aLock);
mozilla::TimeDuration delta = origin - gPS->StartTime(aLock);
stack->addMarker(aMarker, payload.release(), delta.ToMilliseconds());
}
@ -2974,7 +2977,7 @@ profiler_add_marker(const char* aMarker, ProfilerMarkerPayload* aPayload)
MOZ_RELEASE_ASSERT(gPS);
PSAutoLock lock(gPSMutex);
PS::AutoLock lock(gPSMutex);
// aPayload must be freed if we return early.
mozilla::UniquePtr<ProfilerMarkerPayload> payload(aPayload);
@ -2994,7 +2997,7 @@ profiler_tracing(const char* aCategory, const char* aInfo,
MOZ_RELEASE_ASSERT(gPS);
PSAutoLock lock(gPSMutex);
PS::AutoLock lock(gPSMutex);
if (!gPS->IsActive(lock) || gPS->FeaturePrivacy(lock)) {
return;
@ -3012,7 +3015,7 @@ profiler_tracing(const char* aCategory, const char* aInfo,
MOZ_RELEASE_ASSERT(gPS);
PSAutoLock lock(gPSMutex);
PS::AutoLock lock(gPSMutex);
if (!gPS->IsActive(lock) || gPS->FeaturePrivacy(lock)) {
return;
@ -3065,7 +3068,7 @@ profiler_clear_js_context()
// On JS shut down, flush the current buffer as stringifying JIT samples
// requires a live JSContext.
PSAutoLock lock(gPSMutex);
PS::AutoLock lock(gPSMutex);
if (gPS->IsActive(lock)) {
gPS->SetIsPaused(lock, true);
@ -3074,8 +3077,7 @@ profiler_clear_js_context()
ThreadInfo* info = FindLiveThreadInfo(lock);
MOZ_RELEASE_ASSERT(info);
if (info->IsBeingProfiled()) {
info->FlushSamplesAndMarkers(gPS->Buffer(lock),
gPS->ProcessStartTime(lock));
info->FlushSamplesAndMarkers(gPS->Buffer(lock), gPS->StartTime(lock));
}
gPS->SetIsPaused(lock, false);

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

@ -289,8 +289,8 @@ PROFILER_FUNC(bool profiler_thread_is_sleeping(), false)
// not.
PROFILER_FUNC_VOID(profiler_js_interrupt_callback())
// The number of milliseconds since the process started. Operates the same
// whether the profiler is active or inactive.
// Gets the time since the last profiler_init() or profiler_start() call.
// Operates the same whether the profiler is active or inactive.
PROFILER_FUNC(double profiler_time(), 0)
PROFILER_FUNC_VOID(profiler_log(const char *str))
@ -329,6 +329,14 @@ class ProfilerMarkerPayload;
//
extern MOZ_THREAD_LOCAL(PseudoStack*) tlsPseudoStack;
class ProfilerState;
// The core profiler state. Null at process startup, it is set to a non-null
// value in profiler_init() and stays that way until profiler_shutdown() is
// called. Therefore it can be checked to determine if the profiler has been
// initialized but not yet shut down.
extern ProfilerState* gPS;
#ifndef SAMPLE_FUNCTION_NAME
# if defined(__GNUC__) || defined(_MSC_VER)
# define SAMPLE_FUNCTION_NAME __FUNCTION__
@ -347,6 +355,8 @@ profiler_call_enter(const char* aInfo,
{
// This function runs both on and off the main thread.
MOZ_RELEASE_ASSERT(gPS);
PseudoStack* stack = tlsPseudoStack.get();
if (!stack) {
return stack;
@ -363,6 +373,8 @@ profiler_call_exit(void* aHandle)
{
// This function runs both on and off the main thread.
MOZ_RELEASE_ASSERT(gPS);
if (!aHandle) {
return;
}
@ -486,6 +498,8 @@ profiler_get_pseudo_stack(void)
{
// This function runs both on and off the main thread.
MOZ_RELEASE_ASSERT(gPS);
return tlsPseudoStack.get();
}