Bug 1431179 - Keep all exit profiles that overlap with the parent process's buffer time range. r=mconley

MozReview-Commit-ID: 1DIYQZ70ckR

--HG--
extra : rebase_source : f7f5e8e2d0380b54c50cb20b3d109cb476a2530f
extra : source : 612e54e7001a5907761d831b92aed5cee0deb017
This commit is contained in:
Markus Stange 2018-02-06 15:29:05 -05:00
parent 125c79a8ce
commit 7e880fe1f8
2 changed files with 24 additions and 25 deletions

View File

@ -539,12 +539,6 @@ nsProfiler::GatheredOOPProfile(const nsACString& aProfile)
}
}
// When a subprocess exits before we've gathered profiles, we'll store profiles
// for those processes until gathering starts. We'll only store up to
// MAX_SUBPROCESS_EXIT_PROFILES. The buffer is circular, so as soon as we
// receive another exit profile, we'll bump the oldest one out of the buffer.
static const uint32_t MAX_SUBPROCESS_EXIT_PROFILES = 5;
void
nsProfiler::ReceiveShutdownProfile(const nsCString& aProfile)
{
@ -556,16 +550,14 @@ nsProfiler::ReceiveShutdownProfile(const nsCString& aProfile)
return;
}
// Append the exit profile to mExitProfiles so that it can be picked up the
// next time a profile is requested. If we're currently gathering a profile,
// do not add this exit profile to it; chances are that we already have a
// profile from the exiting process and we don't want another one.
// We only keep around at most MAX_SUBPROCESS_EXIT_PROFILES exit profiles.
if (mExitProfiles.Length() >= MAX_SUBPROCESS_EXIT_PROFILES) {
mExitProfiles.RemoveElementAt(0);
}
// Append the exit profile to mExitProfiles so that it can be picked up when
// a profile is requested.
uint64_t bufferPosition = bufferInfo->mRangeEnd;
mExitProfiles.AppendElement(ExitProfile{ aProfile, bufferPosition });
// This is a good time to clear out exit profiles whose time ranges have no
// overlap with this process's profile buffer contents any more.
ClearExpiredExitProfiles();
}
RefPtr<nsProfiler::GatheringPromise>
@ -592,8 +584,6 @@ nsProfiler::StartGathering(double aSinceTime)
mWriter.emplace();
Maybe<ProfilerBufferInfo> bufferInfo = profiler_get_buffer_info();
// Start building up the JSON result and grab the profile from this process.
mWriter->Start();
if (!profiler_stream_json_for_this_process(*mWriter, aSinceTime,
@ -607,20 +597,14 @@ nsProfiler::StartGathering(double aSinceTime)
mWriter->StartArrayProperty("processes");
// If we have any process exit profiles, add them immediately, and clear
// mExitProfiles.
ClearExpiredExitProfiles();
// If we have any process exit profiles, add them immediately.
for (auto& exitProfile : mExitProfiles) {
if (bufferInfo &&
exitProfile.mBufferPositionAtGatherTime < bufferInfo->mRangeStart) {
// Don't include exit profiles that have no overlap with the profile
// from our own process.
continue;
}
if (!exitProfile.mJSON.IsEmpty()) {
mWriter->Splice(exitProfile.mJSON.get());
}
}
mExitProfiles.Clear();
mPromiseHolder.emplace();
RefPtr<GatheringPromise> promise = mPromiseHolder->Ensure(__func__);
@ -676,3 +660,15 @@ nsProfiler::ResetGathering()
mGathering = false;
mWriter.reset();
}
void
nsProfiler::ClearExpiredExitProfiles()
{
Maybe<ProfilerBufferInfo> bufferInfo = profiler_get_buffer_info();
MOZ_RELEASE_ASSERT(bufferInfo, "the profiler should be running at the moment");
uint64_t bufferRangeStart = bufferInfo->mRangeStart;
// Discard any exit profiles that were gathered before bufferRangeStart.
mExitProfiles.RemoveElementsBy([bufferRangeStart](ExitProfile& aExitProfile){
return aExitProfile.mBufferPositionAtGatherTime < bufferRangeStart;
});
}

View File

@ -12,6 +12,7 @@
#include "mozilla/Attributes.h"
#include "mozilla/Maybe.h"
#include "mozilla/MozPromise.h"
#include "mozilla/TimeStamp.h"
#include "nsServiceManagerUtils.h"
#include "ProfileJSONWriter.h"
@ -44,6 +45,8 @@ private:
void FinishGathering();
void ResetGathering();
void ClearExpiredExitProfiles();
bool mLockedForPrivateBrowsing;
struct ExitProfile {