mirror of
https://github.com/mozilla/gecko-dev.git
synced 2025-02-16 05:45:33 +00:00
Bug 1465505: Replace PRMJ_Now() by mozilla::TimeStamp r=jonco
Notice as TimeStamp is not an integral type, it can't be wrapped by mozilla::Atomic. However, we wrap it in MainThreadData to assure it only is accessed from the main thread. Another issue is that TimeStamp class does allow some operations on a Null value, with assertions on debug builds. MozReview-Commit-ID: 9GPNDUooQmI --HG-- extra : rebase_source : e2b5fe81a4c5c696425583a04395f2ae79aeaccc
This commit is contained in:
parent
a892a1e9b1
commit
4c52aa4d3f
@ -141,7 +141,7 @@ typedef enum JSGCParamKey {
|
||||
* See setGCLastBytes in jsgc.cpp.
|
||||
*
|
||||
* Pref: javascript.options.mem.gc_high_frequency_time_limit_ms
|
||||
* Default: HighFrequencyThresholdUsec
|
||||
* Default: HighFrequencyThreshold
|
||||
*/
|
||||
JSGC_HIGH_FREQUENCY_TIME_LIMIT = 11,
|
||||
|
||||
|
@ -7,6 +7,8 @@
|
||||
#ifndef js_SliceBudget_h
|
||||
#define js_SliceBudget_h
|
||||
|
||||
#include "mozilla/TimeStamp.h"
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#include "jstypes.h"
|
||||
@ -35,7 +37,7 @@ struct JS_PUBLIC_API(WorkBudget)
|
||||
*/
|
||||
class JS_PUBLIC_API(SliceBudget)
|
||||
{
|
||||
static const int64_t unlimitedDeadline = INT64_MAX;
|
||||
static const mozilla::TimeStamp unlimitedDeadline;
|
||||
static const intptr_t unlimitedStartCounter = INTPTR_MAX;
|
||||
|
||||
bool checkOverBudget();
|
||||
@ -49,7 +51,7 @@ class JS_PUBLIC_API(SliceBudget)
|
||||
TimeBudget timeBudget;
|
||||
WorkBudget workBudget;
|
||||
|
||||
int64_t deadline; /* in microseconds */
|
||||
mozilla::TimeStamp deadline;
|
||||
intptr_t counter;
|
||||
|
||||
static const intptr_t CounterReset = 1000;
|
||||
@ -81,8 +83,8 @@ class JS_PUBLIC_API(SliceBudget)
|
||||
return checkOverBudget();
|
||||
}
|
||||
|
||||
bool isWorkBudget() const { return deadline == 0; }
|
||||
bool isTimeBudget() const { return deadline > 0 && !isUnlimited(); }
|
||||
bool isWorkBudget() const { return deadline.IsNull(); }
|
||||
bool isTimeBudget() const { return !deadline.IsNull() && !isUnlimited(); }
|
||||
bool isUnlimited() const { return deadline == unlimitedDeadline; }
|
||||
|
||||
int describe(char* buffer, size_t maxlen) const;
|
||||
|
@ -305,7 +305,7 @@ namespace TuningDefaults {
|
||||
static const bool DynamicHeapGrowthEnabled = false;
|
||||
|
||||
/* JSGC_HIGH_FREQUENCY_TIME_LIMIT */
|
||||
static const uint64_t HighFrequencyThresholdUsec = 1000000;
|
||||
static const auto HighFrequencyThreshold = mozilla::TimeDuration::FromSeconds(1);
|
||||
|
||||
/* JSGC_HIGH_FREQUENCY_LOW_LIMIT */
|
||||
static const uint64_t HighFrequencyLowLimitBytes = 100 * 1024 * 1024;
|
||||
@ -346,6 +346,8 @@ namespace TuningDefaults {
|
||||
|
||||
}}} // namespace js::gc::TuningDefaults
|
||||
|
||||
static const auto ONE_SECOND = mozilla::TimeDuration::FromSeconds(1);
|
||||
|
||||
/*
|
||||
* We start to incremental collection for a zone when a proportion of its
|
||||
* threshold is reached. This is configured by the
|
||||
@ -953,7 +955,7 @@ GCRuntime::GCRuntime(JSRuntime* rt) :
|
||||
numArenasFreeCommitted(0),
|
||||
verifyPreData(nullptr),
|
||||
chunkAllocationSinceLastGC(false),
|
||||
lastGCTime(PRMJ_Now()),
|
||||
lastGCTime(mozilla::TimeStamp::Now()),
|
||||
mode(TuningDefaults::Mode),
|
||||
numActiveZoneIters(0),
|
||||
cleanUpEverything(false),
|
||||
@ -1414,7 +1416,7 @@ GCSchedulingTunables::setParameter(JSGCParamKey key, uint32_t value, const AutoL
|
||||
gcMaxNurseryBytes_ = value;
|
||||
break;
|
||||
case JSGC_HIGH_FREQUENCY_TIME_LIMIT:
|
||||
highFrequencyThresholdUsec_ = value * PRMJ_USEC_PER_MSEC;
|
||||
highFrequencyThreshold_ = mozilla::TimeDuration::FromMilliseconds(value);
|
||||
break;
|
||||
case JSGC_HIGH_FREQUENCY_LOW_LIMIT: {
|
||||
uint64_t newLimit = (uint64_t)value * 1024 * 1024;
|
||||
@ -1570,7 +1572,7 @@ GCSchedulingTunables::GCSchedulingTunables()
|
||||
allocThresholdFactorAvoidInterrupt_(TuningDefaults::AllocThresholdFactorAvoidInterrupt),
|
||||
zoneAllocDelayBytes_(TuningDefaults::ZoneAllocDelayBytes),
|
||||
dynamicHeapGrowthEnabled_(TuningDefaults::DynamicHeapGrowthEnabled),
|
||||
highFrequencyThresholdUsec_(TuningDefaults::HighFrequencyThresholdUsec),
|
||||
highFrequencyThreshold_(TuningDefaults::HighFrequencyThreshold),
|
||||
highFrequencyLowLimitBytes_(TuningDefaults::HighFrequencyLowLimitBytes),
|
||||
highFrequencyHighLimitBytes_(TuningDefaults::HighFrequencyHighLimitBytes),
|
||||
highFrequencyHeapGrowthMax_(TuningDefaults::HighFrequencyHeapGrowthMax),
|
||||
@ -1621,8 +1623,8 @@ GCSchedulingTunables::resetParameter(JSGCParamKey key, const AutoLockGC& lock)
|
||||
gcMaxNurseryBytes_ = JS::DefaultNurseryBytes;
|
||||
break;
|
||||
case JSGC_HIGH_FREQUENCY_TIME_LIMIT:
|
||||
highFrequencyThresholdUsec_ =
|
||||
TuningDefaults::HighFrequencyThresholdUsec;
|
||||
highFrequencyThreshold_ =
|
||||
TuningDefaults::HighFrequencyThreshold;
|
||||
break;
|
||||
case JSGC_HIGH_FREQUENCY_LOW_LIMIT:
|
||||
setHighFrequencyLowLimit(TuningDefaults::HighFrequencyLowLimitBytes);
|
||||
@ -1698,7 +1700,7 @@ GCRuntime::getParameter(JSGCParamKey key, const AutoLockGC& lock)
|
||||
case JSGC_MARK_STACK_LIMIT:
|
||||
return marker.maxCapacity();
|
||||
case JSGC_HIGH_FREQUENCY_TIME_LIMIT:
|
||||
return tunables.highFrequencyThresholdUsec() / PRMJ_USEC_PER_MSEC;
|
||||
return tunables.highFrequencyThreshold().ToMilliseconds();
|
||||
case JSGC_HIGH_FREQUENCY_LOW_LIMIT:
|
||||
return tunables.highFrequencyLowLimitBytes() / 1024 / 1024;
|
||||
case JSGC_HIGH_FREQUENCY_HIGH_LIMIT:
|
||||
@ -2142,7 +2144,8 @@ GCRuntime::shouldCompact()
|
||||
return true;
|
||||
}
|
||||
|
||||
return !isIncremental || rt->lastAnimationTime + PRMJ_USEC_PER_SEC < PRMJ_Now();
|
||||
const auto &lastAnimationTime = rt->lastAnimationTime.ref();
|
||||
return !isIncremental || lastAnimationTime.IsNull() || lastAnimationTime + ONE_SECOND < mozilla::TimeStamp::Now();
|
||||
}
|
||||
|
||||
bool
|
||||
@ -3248,6 +3251,8 @@ ArenaLists::queueForegroundThingsForSweep()
|
||||
gcScriptArenasToUpdate = arenaListsToSweep(AllocKind::SCRIPT);
|
||||
}
|
||||
|
||||
const mozilla::TimeStamp SliceBudget::unlimitedDeadline = mozilla::TimeStamp::Now() + mozilla::TimeDuration::Forever();
|
||||
|
||||
SliceBudget::SliceBudget()
|
||||
: timeBudget(UnlimitedTimeBudget), workBudget(UnlimitedWorkBudget)
|
||||
{
|
||||
@ -3261,7 +3266,7 @@ SliceBudget::SliceBudget(TimeBudget time)
|
||||
makeUnlimited();
|
||||
} else {
|
||||
// Note: TimeBudget(0) is equivalent to WorkBudget(CounterReset).
|
||||
deadline = PRMJ_Now() + time.budget * PRMJ_USEC_PER_MSEC;
|
||||
deadline = mozilla::TimeStamp::Now() + mozilla::TimeDuration::FromMilliseconds(time.budget);
|
||||
counter = CounterReset;
|
||||
}
|
||||
}
|
||||
@ -3272,7 +3277,7 @@ SliceBudget::SliceBudget(WorkBudget work)
|
||||
if (work.budget < 0) {
|
||||
makeUnlimited();
|
||||
} else {
|
||||
deadline = 0;
|
||||
deadline = mozilla::TimeStamp();
|
||||
counter = work.budget;
|
||||
}
|
||||
}
|
||||
@ -3291,7 +3296,10 @@ SliceBudget::describe(char* buffer, size_t maxlen) const
|
||||
bool
|
||||
SliceBudget::checkOverBudget()
|
||||
{
|
||||
bool over = PRMJ_Now() >= deadline;
|
||||
if (deadline.IsNull())
|
||||
return true;
|
||||
|
||||
bool over = mozilla::TimeStamp::Now() >= deadline;
|
||||
if (!over)
|
||||
counter = CounterReset;
|
||||
return over;
|
||||
@ -4053,9 +4061,10 @@ GCRuntime::purgeRuntime()
|
||||
}
|
||||
|
||||
bool
|
||||
GCRuntime::shouldPreserveJITCode(Realm* realm, int64_t currentTime,
|
||||
GCRuntime::shouldPreserveJITCode(Realm* realm, const mozilla::TimeStamp ¤tTime,
|
||||
JS::gcreason::Reason reason, bool canAllocateMoreCode)
|
||||
{
|
||||
|
||||
if (cleanUpEverything)
|
||||
return false;
|
||||
if (!canAllocateMoreCode)
|
||||
@ -4065,8 +4074,11 @@ GCRuntime::shouldPreserveJITCode(Realm* realm, int64_t currentTime,
|
||||
return true;
|
||||
if (realm->preserveJitCode())
|
||||
return true;
|
||||
if (realm->lastAnimationTime + PRMJ_USEC_PER_SEC >= currentTime)
|
||||
|
||||
const auto &lastAnimationTime = realm->lastAnimationTime.ref();
|
||||
if (!lastAnimationTime.IsNull() && lastAnimationTime + ONE_SECOND >= currentTime)
|
||||
return true;
|
||||
|
||||
if (reason == JS::gcreason::DEBUG_GC)
|
||||
return true;
|
||||
|
||||
@ -4240,7 +4252,7 @@ GCRuntime::prepareZonesForCollection(JS::gcreason::Reason reason, bool* isFullOu
|
||||
*isFullOut = true;
|
||||
bool any = false;
|
||||
|
||||
int64_t currentTime = PRMJ_Now();
|
||||
auto currentTime = mozilla::TimeStamp::Now();
|
||||
|
||||
for (ZonesIter zone(rt, WithAtoms); !zone.done(); zone.next()) {
|
||||
/* Set up which zones will be collected. */
|
||||
@ -6784,7 +6796,7 @@ GCRuntime::finishCollection()
|
||||
marker.stop();
|
||||
clearBufferedGrayRoots();
|
||||
|
||||
uint64_t currentTime = PRMJ_Now();
|
||||
auto currentTime = mozilla::TimeStamp::Now();
|
||||
schedulingState.updateHighFrequencyMode(lastGCTime, currentTime, tunables);
|
||||
|
||||
for (ZonesIter zone(rt, WithAtoms); !zone.done(); zone.next()) {
|
||||
|
@ -10,6 +10,7 @@
|
||||
#include "mozilla/Atomics.h"
|
||||
#include "mozilla/EnumSet.h"
|
||||
#include "mozilla/Maybe.h"
|
||||
#include "mozilla/TimeStamp.h"
|
||||
|
||||
#include "gc/ArenaList.h"
|
||||
#include "gc/AtomMarking.h"
|
||||
@ -600,7 +601,7 @@ class GCRuntime
|
||||
void purgeRuntime();
|
||||
MOZ_MUST_USE bool beginMarkPhase(JS::gcreason::Reason reason, AutoGCSession& session);
|
||||
bool prepareZonesForCollection(JS::gcreason::Reason reason, bool* isFullOut);
|
||||
bool shouldPreserveJITCode(JS::Realm* realm, int64_t currentTime,
|
||||
bool shouldPreserveJITCode(JS::Realm* realm, const mozilla::TimeStamp ¤tTime,
|
||||
JS::gcreason::Reason reason, bool canAllocateMoreCode);
|
||||
void traceRuntimeForMajorGC(JSTracer* trc, AutoGCSession& session);
|
||||
void traceRuntimeAtoms(JSTracer* trc, const AutoAccessAtomsZone& atomsAccess);
|
||||
@ -748,7 +749,7 @@ class GCRuntime
|
||||
|
||||
private:
|
||||
UnprotectedData<bool> chunkAllocationSinceLastGC;
|
||||
MainThreadData<int64_t> lastGCTime;
|
||||
MainThreadData<mozilla::TimeStamp> lastGCTime;
|
||||
|
||||
/*
|
||||
* JSGC_MODE
|
||||
|
@ -389,9 +389,9 @@ class GCSchedulingTunables
|
||||
* JSGC_HIGH_FREQUENCY_TIME_LIMIT
|
||||
*
|
||||
* We enter high-frequency mode if we GC a twice within this many
|
||||
* microseconds. This value is stored directly in microseconds.
|
||||
* microseconds.
|
||||
*/
|
||||
MainThreadData<uint64_t> highFrequencyThresholdUsec_;
|
||||
MainThreadData<mozilla::TimeDuration> highFrequencyThreshold_;
|
||||
|
||||
/*
|
||||
* JSGC_HIGH_FREQUENCY_LOW_LIMIT
|
||||
@ -450,7 +450,7 @@ class GCSchedulingTunables
|
||||
double allocThresholdFactorAvoidInterrupt() const { return allocThresholdFactorAvoidInterrupt_; }
|
||||
size_t zoneAllocDelayBytes() const { return zoneAllocDelayBytes_; }
|
||||
bool isDynamicHeapGrowthEnabled() const { return dynamicHeapGrowthEnabled_; }
|
||||
uint64_t highFrequencyThresholdUsec() const { return highFrequencyThresholdUsec_; }
|
||||
const mozilla::TimeDuration &highFrequencyThreshold() const { return highFrequencyThreshold_; }
|
||||
uint64_t highFrequencyLowLimitBytes() const { return highFrequencyLowLimitBytes_; }
|
||||
uint64_t highFrequencyHighLimitBytes() const { return highFrequencyHighLimitBytes_; }
|
||||
double highFrequencyHeapGrowthMax() const { return highFrequencyHeapGrowthMax_; }
|
||||
@ -495,11 +495,11 @@ class GCSchedulingState
|
||||
|
||||
bool inHighFrequencyGCMode() const { return inHighFrequencyGCMode_; }
|
||||
|
||||
void updateHighFrequencyMode(uint64_t lastGCTime, uint64_t currentTime,
|
||||
void updateHighFrequencyMode(const mozilla::TimeStamp &lastGCTime, const mozilla::TimeStamp ¤tTime,
|
||||
const GCSchedulingTunables& tunables) {
|
||||
inHighFrequencyGCMode_ =
|
||||
tunables.isDynamicHeapGrowthEnabled() && lastGCTime &&
|
||||
lastGCTime + tunables.highFrequencyThresholdUsec() > currentTime;
|
||||
tunables.isDynamicHeapGrowthEnabled() && !lastGCTime.IsNull() &&
|
||||
lastGCTime + tunables.highFrequencyThreshold() > currentTime;
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -8,6 +8,7 @@
|
||||
|
||||
#include "mozilla/Atomics.h"
|
||||
#include "mozilla/PodOperations.h"
|
||||
#include "mozilla/TimeStamp.h"
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
@ -420,7 +421,7 @@ js::NotifyAnimationActivity(JSObject* obj)
|
||||
{
|
||||
MOZ_ASSERT(obj->is<GlobalObject>());
|
||||
|
||||
int64_t timeNow = PRMJ_Now();
|
||||
auto timeNow = mozilla::TimeStamp::Now();
|
||||
obj->as<GlobalObject>().realm()->lastAnimationTime = timeNow;
|
||||
obj->runtimeFromMainThread()->lastAnimationTime = timeNow;
|
||||
}
|
||||
|
@ -10,6 +10,7 @@
|
||||
#include "mozilla/LinkedList.h"
|
||||
#include "mozilla/Maybe.h"
|
||||
#include "mozilla/MemoryReporting.h"
|
||||
#include "mozilla/TimeStamp.h"
|
||||
#include "mozilla/Tuple.h"
|
||||
#include "mozilla/Variant.h"
|
||||
#include "mozilla/XorShift128PlusRNG.h"
|
||||
@ -422,7 +423,7 @@ class JS::Realm : public JS::shadow::Realm
|
||||
js::ReadBarrieredScriptSourceObject selfHostingScriptSource { nullptr };
|
||||
|
||||
// Last time at which an animation was played for this realm.
|
||||
int64_t lastAnimationTime = 0;
|
||||
js::MainThreadData<mozilla::TimeStamp> lastAnimationTime;
|
||||
|
||||
/*
|
||||
* For generational GC, record whether a write barrier has added this
|
||||
|
@ -173,7 +173,6 @@ JSRuntime::JSRuntime(JSRuntime* parentRuntime)
|
||||
autoWritableJitCodeActive_(false),
|
||||
oomCallback(nullptr),
|
||||
debuggerMallocSizeOf(ReturnZeroSize),
|
||||
lastAnimationTime(0),
|
||||
performanceMonitoring_(),
|
||||
stackFormat_(parentRuntime ? js::StackFormat::Default
|
||||
: js::StackFormat::SpiderMonkey),
|
||||
|
@ -16,6 +16,7 @@
|
||||
#include "mozilla/MemoryReporting.h"
|
||||
#include "mozilla/Scoped.h"
|
||||
#include "mozilla/ThreadLocal.h"
|
||||
#include "mozilla/TimeStamp.h"
|
||||
#include "mozilla/Vector.h"
|
||||
|
||||
#include <algorithm>
|
||||
@ -934,7 +935,7 @@ struct JSRuntime : public js::MallocProvider<JSRuntime>
|
||||
js::MainThreadData<mozilla::MallocSizeOf> debuggerMallocSizeOf;
|
||||
|
||||
/* Last time at which an animation was played for this runtime. */
|
||||
mozilla::Atomic<int64_t> lastAnimationTime;
|
||||
js::MainThreadData<mozilla::TimeStamp> lastAnimationTime;
|
||||
|
||||
private:
|
||||
js::MainThreadData<js::PerformanceMonitoring> performanceMonitoring_;
|
||||
|
Loading…
x
Reference in New Issue
Block a user