Bug 1766342 - Compute the process creation timestamp lazily r=glandium

This reverts bug 1751041 and adds a separate function to take the first
timestamp that was taken by a process. The latter is then used when
creating JS objects to avoid hazards warnings about allocating memory
when an object is not yet rooted.

Differential Revision: https://phabricator.services.mozilla.com/D144829
This commit is contained in:
Gabriele Svelto 2022-05-13 09:27:58 +00:00
parent 3d44a8f8d1
commit e7bb08dd02
4 changed files with 46 additions and 28 deletions

View file

@ -47,7 +47,7 @@ using namespace js;
static double MillisecondsSinceStartup() {
auto now = mozilla::TimeStamp::Now();
return (now - mozilla::TimeStamp::ProcessCreation()).ToMilliseconds();
return (now - mozilla::TimeStamp::FirstTimeStamp()).ToMilliseconds();
}
enum ResolutionMode { ResolveMode, RejectMode };

View file

@ -622,7 +622,7 @@ void Statistics::log(const char* fmt, ...) {
va_list args;
va_start(args, fmt);
if (gcDebugFile) {
TimeDuration sinceStart = TimeStamp::Now() - TimeStamp::ProcessCreation();
TimeDuration sinceStart = TimeStamp::Now() - TimeStamp::FirstTimeStamp();
fprintf(gcDebugFile, "%12.3f: ", sinceStart.ToMicroseconds());
vfprintf(gcDebugFile, fmt, args);
fprintf(gcDebugFile, "\n");
@ -1427,9 +1427,9 @@ void Statistics::recordPhaseEnd(Phase phase) {
if (phaseEndTimes[kid] > now) {
fprintf(stderr,
"Parent %s ended at %.3fms, before child %s ended at %.3fms?\n",
phases[phase].name, t(now - TimeStamp::ProcessCreation()),
phases[phase].name, t(now - TimeStamp::FirstTimeStamp()),
phases[kid].name,
t(phaseEndTimes[kid] - TimeStamp::ProcessCreation()));
t(phaseEndTimes[kid] - TimeStamp::FirstTimeStamp()));
}
MOZ_ASSERT(phaseEndTimes[kid] <= now,
"Inconsistent time data; see bug 1400153");

View file

@ -34,29 +34,7 @@ struct TimeStampInitialization {
TimeStampInitialization() {
TimeStamp::Startup();
TimeStamp now = TimeStamp::Now();
TimeStamp process_creation;
char* mozAppRestart = getenv("MOZ_APP_RESTART");
/* When calling PR_SetEnv() with an empty value the existing variable may
* be unset or set to the empty string depending on the underlying platform
* thus we have to check if the variable is present and not empty. */
if (mozAppRestart && (strcmp(mozAppRestart, "") != 0)) {
process_creation = now;
} else {
uint64_t uptime = TimeStamp::ComputeProcessUptime();
process_creation =
now - TimeDuration::FromMicroseconds(static_cast<double>(uptime));
if ((process_creation > now) || (uptime == 0)) {
process_creation = now;
}
}
mFirstTimeStamp = now;
mProcessCreation = process_creation;
mFirstTimeStamp = TimeStamp::Now();
// On Windows < 10, initializing the uptime requires `mFirstTimeStamp` to be
// valid.
mozilla::InitializeUptime();
@ -68,11 +46,40 @@ struct TimeStampInitialization {
static TimeStampInitialization sInitOnce;
MFBT_API TimeStamp TimeStamp::ProcessCreation() {
if (sInitOnce.mProcessCreation.IsNull()) {
char* mozAppRestart = getenv("MOZ_APP_RESTART");
TimeStamp ts;
/* When calling PR_SetEnv() with an empty value the existing variable may
* be unset or set to the empty string depending on the underlying platform
* thus we have to check if the variable is present and not empty. */
if (mozAppRestart && (strcmp(mozAppRestart, "") != 0)) {
/* Firefox was restarted, use the first time-stamp we've taken as the new
* process startup time. */
ts = sInitOnce.mFirstTimeStamp;
} else {
TimeStamp now = Now();
uint64_t uptime = ComputeProcessUptime();
ts = now - TimeDuration::FromMicroseconds(static_cast<double>(uptime));
if ((ts > sInitOnce.mFirstTimeStamp) || (uptime == 0)) {
ts = sInitOnce.mFirstTimeStamp;
}
}
sInitOnce.mProcessCreation = ts;
}
return sInitOnce.mProcessCreation;
}
void TimeStamp::RecordProcessRestart() {
sInitOnce.mProcessCreation = TimeStamp::Now();
sInitOnce.mProcessCreation = TimeStamp();
}
MFBT_API TimeStamp TimeStamp::FirstTimeStamp() {
return sInitOnce.mFirstTimeStamp;
}
} // namespace mozilla

View file

@ -428,6 +428,17 @@ class TimeStamp {
*/
static MFBT_API TimeStamp ProcessCreation();
/**
* Return the very first timestamp that was taken. This can be used instead
* of TimeStamp::ProcessCreation() by code that might not allow running the
* complex logic required to compute the real process creation. This will
* necessarily have been recorded sometimes after TimeStamp::ProcessCreation()
* or at best should be equal to it.
*
* @returns The first tiemstamp that was taken by this process
*/
static MFBT_API TimeStamp FirstTimeStamp();
/**
* Records a process restart. After this call ProcessCreation() will return
* the time when the browser was restarted instead of the actual time when