Bug 1479547 Part 1 - Remove instrumentation related to non-deterministic GCs, r=mccr8.

--HG--
extra : rebase_source : 6dfc65ab83e770da6e1f64003379156c3b863050
This commit is contained in:
Brian Hackett 2018-07-31 19:34:50 +00:00
Родитель de8c2bd891
Коммит 51e310f29a
7 изменённых файлов: 21 добавлений и 117 удалений

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

@ -471,12 +471,6 @@ mozilla::dom::TraceBlackJS(JSTracer* aTrc, bool aIsShutdownGC)
}
if (ProcessGlobal::WasCreated() && nsFrameMessageManager::GetChildProcessManager()) {
// ProcessGlobal::Get() can perform recorded events such as lock accesses,
// which we're not supposed to do here since tracing occurs
// non-deterministically when recording/replaying. Sidestep this by not
// recording these events.
recordreplay::AutoPassThroughThreadEvents pt;
ProcessGlobal* pg = ProcessGlobal::Get();
if (pg) {
mozilla::TraceScriptHolder(ToSupports(pg), aTrc);

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

@ -286,9 +286,6 @@ FindExceptionStackForConsoleReport(nsPIDOMWindowInner* win,
static PRTime
GetCollectionTimeDelta()
{
if (recordreplay::IsRecordingOrReplaying()) {
return 0;
}
PRTime now = PR_Now();
if (sFirstCollectionTime) {
return now - sFirstCollectionTime;
@ -628,7 +625,7 @@ nsJSContext::~nsJSContext()
void
nsJSContext::Destroy()
{
if (mGCOnDestruction && !recordreplay::IsRecordingOrReplaying()) {
if (mGCOnDestruction) {
PokeGC(JS::gcreason::NSJSCONTEXT_DESTROY, mWindowProxy);
}
@ -1626,13 +1623,6 @@ ICCRunnerFired(TimeStamp aDeadline)
return true;
}
// Whether to skip the generation of timers for future GC/CC activity.
static bool
SkipCollectionTimers()
{
return sShuttingDown || recordreplay::IsRecordingOrReplaying();
}
//static
void
nsJSContext::BeginCycleCollectionCallback()
@ -1648,7 +1638,7 @@ nsJSContext::BeginCycleCollectionCallback()
MOZ_ASSERT(!sICCRunner, "Tried to create a new ICC timer when one already existed.");
if (SkipCollectionTimers()) {
if (sShuttingDown) {
return;
}
@ -1880,7 +1870,7 @@ GCTimerFired(nsITimer *aTimer, void *aClosure)
{
nsJSContext::KillGCTimer();
nsJSContext::KillInterSliceGCRunner();
if (SkipCollectionTimers()) {
if (sShuttingDown) {
return;
}
@ -2183,7 +2173,7 @@ nsJSContext::PokeGC(JS::gcreason::Reason aReason,
void
nsJSContext::PokeShrinkingGC()
{
if (sShrinkingGCTimer || SkipCollectionTimers()) {
if (sShrinkingGCTimer || sShuttingDown) {
return;
}
@ -2199,7 +2189,7 @@ nsJSContext::PokeShrinkingGC()
void
nsJSContext::MaybePokeCC()
{
if (sCCRunner || sICCRunner || !sHasRunGC || SkipCollectionTimers()) {
if (sCCRunner || sICCRunner || !sHasRunGC || sShuttingDown) {
return;
}
@ -2370,7 +2360,7 @@ DOMGCSliceCallback(JSContext* aCx, JS::GCProgress aProgress, const JS::GCDescrip
nsJSContext::MaybePokeCC();
if (aDesc.isZone_) {
if (!sFullGCTimer && !SkipCollectionTimers()) {
if (!sFullGCTimer && !sShuttingDown) {
NS_NewTimerWithFuncCallback(&sFullGCTimer,
FullGCTimerFired,
nullptr,
@ -2383,8 +2373,7 @@ DOMGCSliceCallback(JSContext* aCx, JS::GCProgress aProgress, const JS::GCDescrip
nsJSContext::KillFullGCTimer();
}
if (!recordreplay::IsRecordingOrReplaying() &&
ShouldTriggerCC(nsCycleCollector_suspectedCount())) {
if (ShouldTriggerCC(nsCycleCollector_suspectedCount())) {
nsCycleCollector_dispatchDeferredDeletion();
}
@ -2404,7 +2393,7 @@ DOMGCSliceCallback(JSContext* aCx, JS::GCProgress aProgress, const JS::GCDescrip
// Schedule another GC slice if the GC has more work to do.
nsJSContext::KillInterSliceGCRunner();
if (!SkipCollectionTimers() && !aDesc.isComplete_) {
if (!sShuttingDown && !aDesc.isComplete_) {
sInterSliceGCRunner =
IdleTaskRunner::Create([](TimeStamp aDeadline) {
return InterSliceGCRunnerFired(aDeadline, nullptr);
@ -2416,8 +2405,7 @@ DOMGCSliceCallback(JSContext* aCx, JS::GCProgress aProgress, const JS::GCDescrip
TaskCategory::GarbageCollection);
}
if (!recordreplay::IsRecordingOrReplaying() &&
ShouldTriggerCC(nsCycleCollector_suspectedCount())) {
if (ShouldTriggerCC(nsCycleCollector_suspectedCount())) {
nsCycleCollector_dispatchDeferredDeletion();
}

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

@ -972,11 +972,6 @@ public:
NS_WARNING("failed to set workerCx's default locale");
}
}
// Cycle collections must occur at consistent points when recording/replaying.
if (recordreplay::IsRecordingOrReplaying()) {
recordreplay::RegisterTrigger(this, [=]() { nsCycleCollector_collect(nullptr); });
}
}
void Shutdown(JSContext* cx) override
@ -991,10 +986,6 @@ public:
~WorkerJSRuntime()
{
MOZ_COUNT_DTOR_INHERITED(WorkerJSRuntime, CycleCollectedJSRuntime);
if (recordreplay::IsRecordingOrReplaying()) {
recordreplay::UnregisterTrigger(this);
}
}
virtual void
@ -1031,11 +1022,7 @@ public:
mWorkerPrivate->AssertIsOnWorkerThread();
if (aStatus == JSGC_END) {
if (recordreplay::IsRecordingOrReplaying()) {
recordreplay::ActivateTrigger(this);
} else {
nsCycleCollector_collect(nullptr);
}
nsCycleCollector_collect(nullptr);
}
}

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

@ -146,26 +146,8 @@ public:
return NS_OK;
}
// Dispatch() can be called during a GC, which occur at non-deterministic
// points when recording or replaying. This callback is used with the
// record/replay trigger mechanism to make sure the snow white freer executes
// at a consistent point.
void RecordReplayRun()
{
// Make sure state in the freer is consistent with the recording.
mActive = recordreplay::RecordReplayValue(mActive);
mPurge = recordreplay::RecordReplayValue(mPurge);
mContinuation = recordreplay::RecordReplayValue(mContinuation);
Run();
}
nsresult Dispatch()
{
if (recordreplay::IsRecordingOrReplaying()) {
recordreplay::ActivateTrigger(this);
return NS_OK;
}
nsCOMPtr<nsIRunnable> self(this);
return NS_IdleDispatchToCurrentThread(self.forget(), 500);
}
@ -181,28 +163,12 @@ public:
}
}
// Workaround static analysis.
struct RawSelfPtr { AsyncFreeSnowWhite* mPtr; };
AsyncFreeSnowWhite()
: Runnable("AsyncFreeSnowWhite")
, mContinuation(false)
, mActive(false)
, mPurge(false)
{
if (recordreplay::IsRecordingOrReplaying()) {
RawSelfPtr ptr;
ptr.mPtr = this;
recordreplay::RegisterTrigger(this, [=]() { ptr.mPtr->RecordReplayRun(); });
}
}
~AsyncFreeSnowWhite()
{
if (recordreplay::IsRecordingOrReplaying()) {
recordreplay::UnregisterTrigger(this);
}
}
{}
public:
bool mContinuation;

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

@ -433,7 +433,7 @@ void CycleCollectedJSContext::IsIdleGCTaskNeeded()
}
};
if (Runtime()->IsIdleGCTaskNeeded() && !recordreplay::IsRecordingOrReplaying()) {
if (Runtime()->IsIdleGCTaskNeeded()) {
nsCOMPtr<nsIRunnable> gc_task = new IdleTimeGCTaskRunnable();
NS_IdleDispatchToCurrentThread(gc_task.forget());
Runtime()->SetPendingIdleGCTask();

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

@ -572,18 +572,6 @@ CycleCollectedJSRuntime::CycleCollectedJSRuntime(JSContext* aCx)
#ifdef MOZ_JS_DEV_ERROR_INTERCEPTOR
JS_SetErrorInterceptorCallback(mJSRuntime, &mErrorInterceptor);
#endif // MOZ_JS_DEV_ERROR_INTERCEPTOR
if (recordreplay::IsRecordingOrReplaying()) {
// When recording or replaying, the set of deferred things needing
// finalization will be consistent between executions, see
// DeferredFinalize.h. This callback is used with the record/replay trigger
// mechanism to make sure that finalization of those things also happens at
// a consistent point.
recordreplay::RegisterTrigger(this,
[=]() {
FinalizeDeferredThings(CycleCollectedJSContext::FinalizeNow);
});
}
}
void
@ -604,10 +592,6 @@ CycleCollectedJSRuntime::~CycleCollectedJSRuntime()
MOZ_COUNT_DTOR(CycleCollectedJSRuntime);
MOZ_ASSERT(!mDeferredFinalizerTable.Count());
MOZ_ASSERT(mShutdownCalled);
if (recordreplay::IsRecordingOrReplaying()) {
recordreplay::UnregisterTrigger(this);
}
}
void
@ -969,17 +953,14 @@ CycleCollectedJSRuntime::GCNurseryCollectionCallback(JSContext* aContext,
MOZ_ASSERT(CycleCollectedJSContext::Get()->Context() == aContext);
MOZ_ASSERT(NS_IsMainThread());
if (!recordreplay::IsRecordingOrReplaying()) {
RefPtr<TimelineConsumers> timelines = TimelineConsumers::Get();
if (timelines && !timelines->IsEmpty()) {
UniquePtr<AbstractTimelineMarker> abstractMarker(
MakeUnique<MinorGCMarker>(aProgress, aReason));
timelines->AddMarkerForAllObservedDocShells(abstractMarker);
}
RefPtr<TimelineConsumers> timelines = TimelineConsumers::Get();
if (timelines && !timelines->IsEmpty()) {
UniquePtr<AbstractTimelineMarker> abstractMarker(
MakeUnique<MinorGCMarker>(aProgress, aReason));
timelines->AddMarkerForAllObservedDocShells(abstractMarker);
}
if (aProgress == JS::GCNurseryProgress::GC_NURSERY_COLLECTION_START) {
recordreplay::AutoPassThroughThreadEvents pt;
self->mLatestNurseryCollectionStart = TimeStamp::Now();
}
#ifdef MOZ_GECKO_PROFILER
@ -1532,16 +1513,10 @@ CycleCollectedJSRuntime::OnGC(JSContext* aContext,
// non-incremental GC when there is a pending exception, and the finalizers
// are not set up to handle that. In that case, just run them later, after
// we've returned to the event loop.
if (recordreplay::IsRecordingOrReplaying()) {
// Cause deferred things to be finalized soon, at a consistent point in
// the recording and replay, per the earlier registered trigger.
recordreplay::ActivateTrigger(this);
} else {
bool finalizeIncrementally = JS::WasIncrementalGC(mJSRuntime) || JS_IsExceptionPending(aContext);
FinalizeDeferredThings(finalizeIncrementally
? CycleCollectedJSContext::FinalizeIncrementally
: CycleCollectedJSContext::FinalizeNow);
}
bool finalizeIncrementally = JS::WasIncrementalGC(mJSRuntime) || JS_IsExceptionPending(aContext);
FinalizeDeferredThings(finalizeIncrementally
? CycleCollectedJSContext::FinalizeIncrementally
: CycleCollectedJSContext::FinalizeNow);
break;
}

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

@ -17,12 +17,6 @@ namespace mozilla {
/* static */ nsresult
DebuggerOnGCRunnable::Enqueue(JSContext* aCx, const JS::GCDescription& aDesc)
{
// Runnables are not fired when recording or replaying, as GCs can happen at
// non-deterministic points in execution.
if (recordreplay::IsRecordingOrReplaying()) {
return NS_OK;
}
auto gcEvent = aDesc.toGCEvent(aCx);
if (!gcEvent) {
return NS_ERROR_OUT_OF_MEMORY;