Bug 1452982 part 1 - Use rt->mainContextFromOwnThread() instead of TlsContext.get() in some places. r=jonco

This commit is contained in:
Jan de Mooij 2018-04-12 13:04:13 +02:00
parent 3b5f09b043
commit 040949a5a7
12 changed files with 59 additions and 82 deletions

View File

@ -196,9 +196,6 @@ namespace JS {
template <typename T> class Rooted;
template <typename T> class PersistentRooted;
/* This is exposing internal state of the GC for inlining purposes. */
JS_FRIEND_API(bool) isGCEnabled();
JS_FRIEND_API(void) HeapObjectPostBarrier(JSObject** objp, JSObject* prev, JSObject* next);
JS_FRIEND_API(void) HeapStringPostBarrier(JSString** objp, JSString* prev, JSString* next);

View File

@ -1698,7 +1698,7 @@ void
GCRuntime::callGCCallback(JSGCStatus status) const
{
MOZ_ASSERT(gcCallback.op);
gcCallback.op(TlsContext.get(), status, gcCallback.data);
gcCallback.op(rt->mainContextFromOwnThread(), status, gcCallback.data);
}
void
@ -1713,7 +1713,7 @@ void
GCRuntime::callObjectsTenuredCallback()
{
if (tenuredCallback.op)
tenuredCallback.op(TlsContext.get(), tenuredCallback.data);
tenuredCallback.op(rt->mainContextFromOwnThread(), tenuredCallback.data);
}
bool
@ -1763,8 +1763,9 @@ GCRuntime::removeWeakPointerZonesCallback(JSWeakPointerZonesCallback callback)
void
GCRuntime::callWeakPointerZonesCallbacks() const
{
JSContext* cx = rt->mainContextFromOwnThread();
for (auto const& p : updateWeakPointerZonesCallbacks.ref())
p.op(TlsContext.get(), p.data);
p.op(cx, p.data);
}
bool
@ -1788,8 +1789,9 @@ GCRuntime::removeWeakPointerCompartmentCallback(JSWeakPointerCompartmentCallback
void
GCRuntime::callWeakPointerCompartmentCallbacks(JSCompartment* comp) const
{
JSContext* cx = rt->mainContextFromOwnThread();
for (auto const& p : updateWeakPointerCompartmentCallbacks.ref())
p.op(TlsContext.get(), comp, p.data);
p.op(cx, comp, p.data);
}
JS::GCSliceCallback
@ -2063,7 +2065,7 @@ GCRuntime::shouldCompact()
bool
GCRuntime::isCompactingGCEnabled() const
{
return compactingEnabled && TlsContext.get()->compactingDisabledCount == 0;
return compactingEnabled && rt->mainContextFromOwnThread()->compactingDisabledCount == 0;
}
AutoDisableCompactingGC::AutoDisableCompactingGC(JSContext* cx)
@ -3213,7 +3215,7 @@ GCRuntime::requestMajorGC(JS::gcreason::Reason reason)
// There's no need to use RequestInterruptUrgent here. It's slower because
// it has to interrupt (looping) Ion code, but loops in Ion code that
// affect GC will have an explicit interrupt check.
TlsContext.get()->requestInterrupt(JSContext::RequestInterruptCanWait);
rt->mainContextFromOwnThread()->requestInterrupt(JSContext::RequestInterruptCanWait);
}
void
@ -3228,7 +3230,7 @@ Nursery::requestMinorGC(JS::gcreason::Reason reason) const
minorGCTriggerReason_ = reason;
// See comment in requestMajorGC.
TlsContext.get()->requestInterrupt(JSContext::RequestInterruptCanWait);
runtime()->mainContextFromOwnThread()->requestInterrupt(JSContext::RequestInterruptCanWait);
}
bool
@ -3318,7 +3320,7 @@ GCRuntime::triggerZoneGC(Zone* zone, JS::gcreason::Reason reason, size_t used, s
if (zone->isAtomsZone()) {
/* We can't do a zone GC of the atoms compartment. */
if (TlsContext.get()->keepAtoms || rt->hasHelperThreadZones()) {
if (rt->mainContextFromOwnThread()->keepAtoms || rt->hasHelperThreadZones()) {
/* Skip GC and retrigger later, since atoms zone won't be collected
* if keepAtoms is true. */
fullGCForAtomsRequested_ = true;
@ -3740,7 +3742,7 @@ JSCompartment::destroy(FreeOp* fop)
if (auto callback = rt->destroyCompartmentCallback)
callback(fop, this);
if (principals())
JS_DropPrincipals(TlsContext.get(), principals());
JS_DropPrincipals(rt->mainContextFromOwnThread(), principals());
fop->delete_(this);
rt->gc.stats().sweptCompartment();
}
@ -4077,11 +4079,12 @@ CompartmentCheckTracer::onChild(const JS::GCCellPtr& thing)
void
GCRuntime::checkForCompartmentMismatches()
{
if (TlsContext.get()->disableStrictProxyCheckingCount)
JSContext* cx = rt->mainContextFromOwnThread();
if (cx->disableStrictProxyCheckingCount)
return;
CompartmentCheckTracer trc(rt);
AutoAssertEmptyNursery empty(TlsContext.get());
AutoAssertEmptyNursery empty(cx);
for (ZonesIter zone(rt, SkipAtoms); !zone.done(); zone.next()) {
trc.zone = zone;
for (auto thingKind : AllAllocKinds()) {
@ -4103,9 +4106,9 @@ RelazifyFunctions(Zone* zone, AllocKind kind)
MOZ_ASSERT(kind == AllocKind::FUNCTION ||
kind == AllocKind::FUNCTION_EXTENDED);
AutoAssertEmptyNursery empty(TlsContext.get());
JSRuntime* rt = zone->runtimeFromActiveCooperatingThread();
AutoAssertEmptyNursery empty(rt->mainContextFromOwnThread());
for (auto i = zone->cellIter<JSObject>(kind, empty); !i.done(); i.next()) {
JSFunction* fun = &i->as<JSFunction>();
if (fun->hasScript())
@ -4197,7 +4200,7 @@ GCRuntime::prepareZonesForCollection(JS::gcreason::Reason reason, bool* isFullOu
}
if (!cleanUpEverything && canAllocateMoreCode) {
jit::JitActivationIterator activation(TlsContext.get());
jit::JitActivationIterator activation(rt->mainContextFromOwnThread());
if (!activation.done())
activation->compartment()->zone()->setPreservingCode(true);
}
@ -4946,7 +4949,7 @@ GCRuntime::groupZonesForSweeping(JS::gcreason::Reason reason)
MOZ_ASSERT(zone->gcSweepGroupEdges().empty());
#endif
JSContext* cx = TlsContext.get();
JSContext* cx = rt->mainContextFromOwnThread();
Zone* maybeAtomsZone = atomsZone->wasGCStarted() ? atomsZone.ref() : nullptr;
ZoneComponentFinder finder(cx->nativeStackLimit[JS::StackForSystemCode], maybeAtomsZone);
if (!isIncremental || !findInterZoneEdges())
@ -6597,7 +6600,7 @@ GCRuntime::compactPhase(JS::gcreason::Reason reason, SliceBudget& sliceBudget,
// middle of relocating an arena, invalid JSScript pointers may be
// accessed. Suppress all sampling until a finer-grained solution can be
// found. See bug 1295775.
AutoSuppressProfilerSampling suppressSampling(TlsContext.get());
AutoSuppressProfilerSampling suppressSampling(rt->mainContextFromOwnThread());
ZoneList relocatedZones;
Arena* relocatedArenas = nullptr;
@ -6711,8 +6714,9 @@ AllNurseriesAreEmpty(JSRuntime* rt)
/* Start a new heap session. */
AutoTraceSession::AutoTraceSession(JSRuntime* rt, JS::HeapState heapState)
: runtime(rt),
prevState(TlsContext.get()->heapState),
pseudoFrame(TlsContext.get(), HeapStateToLabel(heapState), ProfileEntry::Category::GC)
prevState(rt->mainContextFromOwnThread()->heapState),
pseudoFrame(rt->mainContextFromOwnThread(), HeapStateToLabel(heapState),
ProfileEntry::Category::GC)
{
MOZ_ASSERT(prevState == JS::HeapState::Idle);
MOZ_ASSERT(heapState != JS::HeapState::Idle);
@ -6721,13 +6725,13 @@ AutoTraceSession::AutoTraceSession(JSRuntime* rt, JS::HeapState heapState)
// Session always begins with lock held, see comment in class definition.
maybeLock.emplace(rt);
TlsContext.get()->heapState = heapState;
rt->mainContextFromOwnThread()->heapState = heapState;
}
AutoTraceSession::~AutoTraceSession()
{
MOZ_ASSERT(JS::CurrentThreadIsHeapBusy());
TlsContext.get()->heapState = prevState;
runtime->mainContextFromOwnThread()->heapState = prevState;
}
JS_PUBLIC_API(JS::HeapState)
@ -6736,20 +6740,6 @@ JS::CurrentThreadHeapState()
return TlsContext.get()->heapState;
}
bool
GCRuntime::canChangeActiveContext(JSContext* cx)
{
// Threads cannot be in the middle of any operation that affects GC
// behavior when execution transfers to another thread for cooperative
// scheduling.
return cx->heapState == JS::HeapState::Idle
&& !cx->suppressGC
&& !cx->inUnsafeRegion
&& !cx->generationalDisabled
&& !cx->compactingDisabledCount
&& !cx->keepAtoms;
}
GCRuntime::IncrementalResult
GCRuntime::resetIncrementalGC(gc::AbortReason reason, AutoTraceSession& session)
{
@ -7141,7 +7131,7 @@ GCRuntime::incrementalCollectSlice(SliceBudget& budget, JS::gcreason::Reason rea
gc::AbortReason
gc::IsIncrementalGCUnsafe(JSRuntime* rt)
{
MOZ_ASSERT(!TlsContext.get()->suppressGC);
MOZ_ASSERT(!rt->mainContextFromOwnThread()->suppressGC);
if (!rt->gc.isIncrementalGCAllowed())
return gc::AbortReason::IncrementalDisabled;
@ -7353,10 +7343,10 @@ GCRuntime::gcCycle(bool nonincrementalByAPI, SliceBudget& budget, JS::gcreason::
// It's ok if threads other than the active thread have suppressGC set, as
// they are operating on zones which will not be collected from here.
MOZ_ASSERT(!TlsContext.get()->suppressGC);
MOZ_ASSERT(!rt->mainContextFromOwnThread()->suppressGC);
// Assert if this is a GC unsafe region.
TlsContext.get()->verifyIsSafeToGC();
rt->mainContextFromOwnThread()->verifyIsSafeToGC();
{
gcstats::AutoPhase ap(stats(), gcstats::PhaseKind::WAIT_BACKGROUND_THREAD);
@ -7476,13 +7466,13 @@ GCRuntime::checkCanCallAPI()
/* If we attempt to invoke the GC while we are running in the GC, assert. */
MOZ_RELEASE_ASSERT(!JS::CurrentThreadIsHeapBusy());
MOZ_ASSERT(TlsContext.get()->isAllocAllowed());
MOZ_ASSERT(rt->mainContextFromOwnThread()->isAllocAllowed());
}
bool
GCRuntime::checkIfGCAllowedInCurrentState(JS::gcreason::Reason reason)
{
if (TlsContext.get()->suppressGC)
if (rt->mainContextFromOwnThread()->suppressGC)
return false;
// Only allow shutdown GCs when we're destroying the runtime. This keeps
@ -7609,7 +7599,7 @@ void
GCRuntime::startGC(JSGCInvocationKind gckind, JS::gcreason::Reason reason, int64_t millis)
{
MOZ_ASSERT(!isIncrementalGCInProgress());
if (!JS::IsIncrementalGCEnabled(TlsContext.get())) {
if (!JS::IsIncrementalGCEnabled(rt->mainContextFromOwnThread())) {
gc(gckind, reason);
return;
}
@ -7649,7 +7639,7 @@ GCRuntime::abortGC()
{
MOZ_ASSERT(isIncrementalGCInProgress());
checkCanCallAPI();
MOZ_ASSERT(!TlsContext.get()->suppressGC);
MOZ_ASSERT(!rt->mainContextFromOwnThread()->suppressGC);
collect(false, SliceBudget::unlimited(), JS::gcreason::ABORT_GC);
}
@ -7729,7 +7719,7 @@ GCRuntime::minorGC(JS::gcreason::Reason reason, gcstats::PhaseKind phase)
{
MOZ_ASSERT(!JS::CurrentThreadIsHeapBusy());
if (TlsContext.get()->suppressGC)
if (rt->mainContextFromOwnThread()->suppressGC)
return;
gcstats::AutoPhase ap(rt->gc.stats(), phase);
@ -7775,7 +7765,7 @@ JS::AutoDisableGenerationalGC::~AutoDisableGenerationalGC()
JS_PUBLIC_API(bool)
JS::IsGenerationalGCEnabled(JSRuntime* rt)
{
return !TlsContext.get()->generationalDisabled;
return !rt->mainContextFromOwnThread()->generationalDisabled;
}
bool
@ -7788,7 +7778,7 @@ GCRuntime::gcIfRequested()
if (majorGCRequested()) {
if (majorGCTriggerReason == JS::gcreason::DELAYED_ATOMS_GC &&
!TlsContext.get()->canCollectAtoms())
!rt->mainContextFromOwnThread()->canCollectAtoms())
{
// A GC was requested to collect the atoms zone, but it's no longer
// possible. Skip this collection.
@ -8108,7 +8098,7 @@ void
GCRuntime::runDebugGC()
{
#ifdef JS_GC_ZEAL
if (TlsContext.get()->suppressGC)
if (rt->mainContextFromOwnThread()->suppressGC)
return;
if (hasZealMode(ZealMode::GenerationalGC))

View File

@ -255,8 +255,6 @@ class GCRuntime
void startDebugGC(JSGCInvocationKind gckind, SliceBudget& budget);
void debugGCSlice(SliceBudget& budget);
bool canChangeActiveContext(JSContext* cx);
void triggerFullGCForAtoms(JSContext* cx);
void runDebugGC();

View File

@ -690,21 +690,20 @@ IsFullStoreBufferReason(JS::gcreason::Reason reason)
void
js::Nursery::collect(JS::gcreason::Reason reason)
{
MOZ_ASSERT(!TlsContext.get()->suppressGC);
JSRuntime* rt = runtime();
MOZ_ASSERT(!rt->mainContextFromOwnThread()->suppressGC);
if (!isEnabled() || isEmpty()) {
// Our barriers are not always exact, and there may be entries in the
// storebuffer even when the nursery is disabled or empty. It's not safe
// to keep these entries as they may refer to tenured cells which may be
// freed after this point.
runtime()->gc.storeBuffer().clear();
rt->gc.storeBuffer().clear();
}
if (!isEnabled())
return;
JSRuntime* rt = runtime();
#ifdef JS_GC_ZEAL
if (rt->gc.hasZealMode(ZealMode::CheckNursery)) {
for (auto canary = lastCanary_; canary; canary = canary->next)
@ -750,7 +749,7 @@ js::Nursery::collect(JS::gcreason::Reason reason)
IsFullStoreBufferReason(reason);
if (shouldPretenure) {
JSContext* cx = TlsContext.get();
JSContext* cx = rt->mainContextFromOwnThread();
for (auto& entry : tenureCounts.entries) {
if (entry.count >= 3000) {
ObjectGroup* group = entry.group;

View File

@ -966,7 +966,7 @@ Statistics::beginNurseryCollection(JS::gcreason::Reason reason)
count(STAT_MINOR_GC);
startingMinorGCNumber = runtime->gc.minorGCCount();
if (nurseryCollectionCallback) {
(*nurseryCollectionCallback)(TlsContext.get(),
(*nurseryCollectionCallback)(runtime->mainContextFromOwnThread(),
JS::GCNurseryProgress::GC_NURSERY_COLLECTION_START,
reason);
}
@ -976,7 +976,7 @@ void
Statistics::endNurseryCollection(JS::gcreason::Reason reason)
{
if (nurseryCollectionCallback) {
(*nurseryCollectionCallback)(TlsContext.get(),
(*nurseryCollectionCallback)(runtime->mainContextFromOwnThread(),
JS::GCNurseryProgress::GC_NURSERY_COLLECTION_END,
reason);
}
@ -1011,7 +1011,7 @@ Statistics::beginSlice(const ZoneGCStats& zoneStats, JSGCInvocationKind gckind,
// Slice callbacks should only fire for the outermost level.
bool wasFullGC = zoneStats.isFullCollection();
if (sliceCallback) {
JSContext* cx = TlsContext.get();
JSContext* cx = runtime->mainContextFromOwnThread();
JS::GCDescription desc(!wasFullGC, false, gckind, reason);
if (first)
(*sliceCallback)(cx, JS::GC_CYCLE_BEGIN, desc);
@ -1082,7 +1082,7 @@ Statistics::endSlice()
if (!aborted) {
bool wasFullGC = zoneStats.isFullCollection();
if (sliceCallback) {
JSContext* cx = TlsContext.get();
JSContext* cx = runtime->mainContextFromOwnThread();
JS::GCDescription desc(!wasFullGC, last, gckind, slices_.back().reason);
(*sliceCallback)(cx, JS::GC_SLICE_END, desc);
if (last)

View File

@ -101,7 +101,7 @@ class js::VerifyPreTracer final : public JS::CallbackTracer
NodeMap nodemap;
explicit VerifyPreTracer(JSRuntime* rt)
: JS::CallbackTracer(rt), noggc(TlsContext.get()), number(rt->gc.gcNumber()),
: JS::CallbackTracer(rt), noggc(rt->mainContextFromOwnThread()), number(rt->gc.gcNumber()),
count(0), curnode(nullptr), root(nullptr), edgeptr(nullptr), term(nullptr)
{}
@ -180,7 +180,7 @@ gc::GCRuntime::startVerifyPreBarriers()
return;
if (IsIncrementalGCUnsafe(rt) != AbortReason::None ||
TlsContext.get()->keepAtoms ||
rt->mainContextFromOwnThread()->keepAtoms ||
rt->hasHelperThreadZones())
{
return;
@ -192,7 +192,7 @@ gc::GCRuntime::startVerifyPreBarriers()
if (!trc)
return;
JSContext* cx = TlsContext.get();
JSContext* cx = rt->mainContextFromOwnThread();
AutoPrepareForTracing prep(cx);
{
@ -357,7 +357,7 @@ gc::GCRuntime::endVerifyPreBarriers()
if (!compartmentCreated &&
IsIncrementalGCUnsafe(rt) == AbortReason::None &&
!TlsContext.get()->keepAtoms &&
!rt->mainContextFromOwnThread()->keepAtoms &&
!rt->hasHelperThreadZones())
{
CheckEdgeTracer cetrc(rt);
@ -418,7 +418,7 @@ gc::GCRuntime::maybeVerifyPreBarriers(bool always)
if (!hasZealMode(ZealMode::VerifierPre))
return;
if (TlsContext.get()->suppressGC)
if (rt->mainContextFromOwnThread()->suppressGC)
return;
if (verifyPreData) {

View File

@ -313,9 +313,11 @@ Zone::canCollect()
void
Zone::notifyObservingDebuggers()
{
JSRuntime* rt = runtimeFromActiveCooperatingThread();
JSContext* cx = rt->mainContextFromOwnThread();
for (CompartmentsInZoneIter comps(this); !comps.done(); comps.next()) {
JSRuntime* rt = runtimeFromAnyThread();
RootedGlobalObject global(TlsContext.get(), comps->unsafeUnbarrieredMaybeGlobal());
RootedGlobalObject global(cx, comps->unsafeUnbarrieredMaybeGlobal());
if (!global)
continue;

View File

@ -48,7 +48,7 @@ bool
irregexp::GrowBacktrackStack(JSRuntime* rt)
{
AutoUnsafeCallWithABI unsafe;
return TlsContext.get()->regexpStack.ref().grow();
return rt->mainContextFromOwnThread()->regexpStack.ref().grow();
}
RegExpStack::RegExpStack()

View File

@ -1311,7 +1311,7 @@ void
UpdateJitActivationsForMinorGC(JSRuntime* rt)
{
MOZ_ASSERT(JS::CurrentThreadIsHeapMinorCollecting());
JSContext* cx = TlsContext.get();
JSContext* cx = rt->mainContextFromOwnThread();
for (JitActivationIterator activations(cx); !activations.done(); ++activations) {
for (OnlyJSJitFrameIter iter(activations); !iter.done(); ++iter) {
if (iter.frame().type() == JitFrame_IonJS)

View File

@ -742,7 +742,8 @@ JitcodeGlobalTable::traceForMinorGC(JSTracer* trc)
MOZ_ASSERT(trc->runtime()->geckoProfiler().enabled());
MOZ_ASSERT(JS::CurrentThreadIsHeapMinorCollecting());
AutoSuppressProfilerSampling suppressSampling(TlsContext.get());
JSContext* cx = trc->runtime()->mainContextFromOwnThread();
AutoSuppressProfilerSampling suppressSampling(cx);
JitcodeGlobalEntry::IonEntry* entry = nurseryEntries_;
while (entry) {
entry->trace<Unconditionally>(trc);
@ -830,7 +831,7 @@ JitcodeGlobalTable::markIteratively(GCMarker* marker)
void
JitcodeGlobalTable::sweep(JSRuntime* rt)
{
AutoSuppressProfilerSampling suppressSampling(TlsContext.get());
AutoSuppressProfilerSampling suppressSampling(rt->mainContextFromOwnThread());
for (Enum e(*this, rt); !e.empty(); e.popFront()) {
JitcodeGlobalEntry* entry = e.front();

View File

@ -459,16 +459,6 @@ JS_GetBoundFunctionTarget(JSFunction* fun)
/************************************************************************/
#ifdef DEBUG
JS_FRIEND_API(bool)
JS::isGCEnabled()
{
return !TlsContext.get()->suppressGC;
}
#else
JS_FRIEND_API(bool) JS::isGCEnabled() { return true; }
#endif
JS_PUBLIC_API(JSContext*)
JS_NewContext(uint32_t maxbytes, uint32_t maxNurseryBytes, JSRuntime* parentRuntime)
{

View File

@ -281,7 +281,7 @@ JSRuntime::destroyRuntime()
* Finish any in-progress GCs first. This ensures the parseWaitingOnGC
* list is empty in CancelOffThreadParses.
*/
JSContext* cx = TlsContext.get();
JSContext* cx = mainContextFromOwnThread();
if (JS::IsIncrementalGCInProgress(cx))
FinishGC(cx);
@ -804,7 +804,7 @@ JSRuntime::clearUsedByHelperThread(Zone* zone)
MOZ_ASSERT(zone->group()->usedByHelperThread());
zone->group()->clearUsedByHelperThread();
numActiveHelperThreadZones--;
JSContext* cx = TlsContext.get();
JSContext* cx = mainContextFromOwnThread();
if (gc.fullGCForAtomsRequested() && cx->canCollectAtoms())
gc.triggerFullGCForAtoms(cx);
}