Bug 1612799 - Make ProcessStreamingContext a FailureLatch - r=canaltinova

This will help with forwarding the chosen FailureLatch to the code and
structures gathering per-thread samples and markers.

Differential Revision: https://phabricator.services.mozilla.com/D155654
This commit is contained in:
Gerald Squelart 2022-09-05 01:19:30 +00:00
Родитель 14f77ee12e
Коммит 892f66577e
4 изменённых файлов: 49 добавлений и 16 удалений

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

@ -95,7 +95,7 @@ static void StreamTables(UniqueStacks&& aUniqueStacks, JSContext* aCx,
mozilla::NotNull<mozilla::UniquePtr<UniqueStacks>>
ProfiledThreadData::PrepareUniqueStacks(
const ProfileBuffer& aBuffer, JSContext* aCx,
ProfilerCodeAddressService* aService,
mozilla::FailureLatch& aFailureLatch, ProfilerCodeAddressService* aService,
mozilla::ProgressLogger aProgressLogger) {
if (mJITFrameInfoForPreviousJSContexts &&
mJITFrameInfoForPreviousJSContexts->HasExpired(
@ -135,7 +135,7 @@ void ProfiledThreadData::StreamJSON(
ProfilerCodeAddressService* aService,
mozilla::ProgressLogger aProgressLogger) {
mozilla::NotNull<mozilla::UniquePtr<UniqueStacks>> uniqueStacks =
PrepareUniqueStacks(aBuffer, aCx, aService,
PrepareUniqueStacks(aBuffer, aCx, aWriter.SourceFailureLatch(), aService,
aProgressLogger.CreateSubLoggerFromTo(
0_pc, "Preparing unique stacks...", 10_pc,
"Prepared Unique stacks"));
@ -380,17 +380,21 @@ void ProfiledThreadData::NotifyAboutToLoseJSContext(
ThreadStreamingContext::ThreadStreamingContext(
ProfiledThreadData& aProfiledThreadData, const ProfileBuffer& aBuffer,
JSContext* aCx, ProfilerCodeAddressService* aService,
JSContext* aCx, mozilla::FailureLatch& aFailureLatch,
ProfilerCodeAddressService* aService,
mozilla::ProgressLogger aProgressLogger)
: mProfiledThreadData(aProfiledThreadData),
mJSContext(aCx),
mSamplesDataWriter(mozilla::FailureLatchInfallibleSource::Singleton()),
mMarkersDataWriter(mozilla::FailureLatchInfallibleSource::Singleton()),
mSamplesDataWriter(aFailureLatch),
mMarkersDataWriter(aFailureLatch),
mUniqueStacks(mProfiledThreadData.PrepareUniqueStacks(
aBuffer, aCx, aService,
aBuffer, aCx, aFailureLatch, aService,
aProgressLogger.CreateSubLoggerFromTo(
0_pc, "Preparing thread streaming context unique stacks...",
99_pc, "Prepared thread streaming context Unique stacks"))) {
if (aFailureLatch.Failed()) {
return;
}
mSamplesDataWriter.SetUniqueStrings(mUniqueStacks->UniqueStrings());
mSamplesDataWriter.StartBareList();
mMarkersDataWriter.SetUniqueStrings(mUniqueStacks->UniqueStrings());
@ -403,14 +407,31 @@ void ThreadStreamingContext::FinalizeWriter() {
}
ProcessStreamingContext::ProcessStreamingContext(
size_t aThreadCount, const mozilla::TimeStamp& aProcessStartTime,
double aSinceTime)
: mProcessStartTime(aProcessStartTime), mSinceTime(aSinceTime) {
MOZ_RELEASE_ASSERT(mTIDList.initCapacity(aThreadCount));
MOZ_RELEASE_ASSERT(mThreadStreamingContextList.initCapacity(aThreadCount));
size_t aThreadCount, mozilla::FailureLatch& aFailureLatch,
const mozilla::TimeStamp& aProcessStartTime, double aSinceTime)
: mFailureLatch(aFailureLatch),
mProcessStartTime(aProcessStartTime),
mSinceTime(aSinceTime) {
if (mFailureLatch.Failed()) {
return;
}
if (!mTIDList.initCapacity(aThreadCount)) {
mFailureLatch.SetFailure(
"OOM in ProcessStreamingContext allocating TID list");
return;
}
if (!mThreadStreamingContextList.initCapacity(aThreadCount)) {
mFailureLatch.SetFailure(
"OOM in ProcessStreamingContext allocating context list");
mTIDList.clear();
return;
}
}
ProcessStreamingContext::~ProcessStreamingContext() {
if (mFailureLatch.Failed()) {
return;
}
MOZ_ASSERT(mTIDList.length() == mThreadStreamingContextList.length());
MOZ_ASSERT(mTIDList.length() == mTIDList.capacity(),
"Didn't pre-allocate exactly right");
@ -420,12 +441,15 @@ void ProcessStreamingContext::AddThreadStreamingContext(
ProfiledThreadData& aProfiledThreadData, const ProfileBuffer& aBuffer,
JSContext* aCx, ProfilerCodeAddressService* aService,
mozilla::ProgressLogger aProgressLogger) {
if (mFailureLatch.Failed()) {
return;
}
MOZ_ASSERT(mTIDList.length() == mThreadStreamingContextList.length());
MOZ_ASSERT(mTIDList.length() < mTIDList.capacity(),
"Didn't pre-allocate enough");
mTIDList.infallibleAppend(aProfiledThreadData.Info().ThreadId());
mThreadStreamingContextList.infallibleEmplaceBack(
aProfiledThreadData, aBuffer, aCx, aService,
aProfiledThreadData, aBuffer, aCx, mFailureLatch, aService,
aProgressLogger.CreateSubLoggerFromTo(
1_pc, "Prepared streaming thread id", 100_pc,
"Added thread streaming context"));

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

@ -11,6 +11,7 @@
#include "ProfileBuffer.h"
#include "ProfileBufferEntry.h"
#include "mozilla/FailureLatch.h"
#include "mozilla/Maybe.h"
#include "mozilla/NotNull.h"
#include "mozilla/ProfileJSONWriter.h"
@ -74,6 +75,7 @@ class ProfiledThreadData final {
mozilla::NotNull<mozilla::UniquePtr<UniqueStacks>> PrepareUniqueStacks(
const ProfileBuffer& aBuffer, JSContext* aCx,
mozilla::FailureLatch& aFailureLatch,
ProfilerCodeAddressService* aService,
mozilla::ProgressLogger aProgressLogger);
@ -161,6 +163,7 @@ struct ThreadStreamingContext {
ThreadStreamingContext(ProfiledThreadData& aProfiledThreadData,
const ProfileBuffer& aBuffer, JSContext* aCx,
mozilla::FailureLatch& aFailureLatch,
ProfilerCodeAddressService* aService,
mozilla::ProgressLogger aProgressLogger);
@ -168,10 +171,11 @@ struct ThreadStreamingContext {
};
// This class will be used when outputting the profile data for all threads.
class ProcessStreamingContext {
class ProcessStreamingContext final : public mozilla::FailureLatch {
public:
// Pre-allocate space for `aThreadCount` threads.
ProcessStreamingContext(size_t aThreadCount,
mozilla::FailureLatch& aFailureLatch,
const mozilla::TimeStamp& aProcessStartTime,
double aSinceTime);
@ -207,6 +211,8 @@ class ProcessStreamingContext {
};
ThreadStreamingContext* end() { return mThreadStreamingContextList.end(); };
FAILURELATCH_IMPL_PROXY(mFailureLatch)
private:
// Separate list of thread ids, it's much faster to do a linear search
// here than a vector of bigger items like mThreadStreamingContextList.
@ -214,6 +220,8 @@ class ProcessStreamingContext {
// Contexts corresponding to the thread id at the same indexes.
mozilla::Vector<ThreadStreamingContext> mThreadStreamingContextList;
mozilla::FailureLatch& mFailureLatch;
const mozilla::TimeStamp mProcessStartTime;
const double mSinceTime;

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

@ -3267,7 +3267,8 @@ static void locked_profiler_stream_json_for_this_process(
// Prepare the streaming context for each thread.
ProcessStreamingContext processStreamingContext(
threadCount, CorePS::ProcessStartTime(), aSinceTime);
threadCount, aWriter.SourceFailureLatch(), CorePS::ProcessStartTime(),
aSinceTime);
for (auto&& [i, progressLogger] : aProgressLogger.CreateLoopSubLoggersTo(
20_pc, threadCount, "Preparing thread streaming contexts...")) {
ActivePS::ProfiledThreadListElement& thread = threads[i];
@ -5346,7 +5347,7 @@ UniquePtr<char[]> profiler_get_profile(double aSinceTime,
return b.ChunkedWriteFunc().CopyData();
}
bool profiler_get_profile_json(
[[nodiscard]] bool profiler_get_profile_json(
SpliceableChunkedJSONWriter& aSpliceableChunkedJSONWriter,
double aSinceTime, bool aIsShuttingDown,
mozilla::ProgressLogger aProgressLogger) {

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

@ -156,7 +156,7 @@ void profiler_mark_thread_awake();
void profiler_mark_thread_asleep();
bool profiler_get_profile_json(
[[nodiscard]] bool profiler_get_profile_json(
SpliceableChunkedJSONWriter& aSpliceableChunkedJSONWriter,
double aSinceTime, bool aIsShuttingDown,
mozilla::ProgressLogger aProgressLogger);