mirror of
https://github.com/mozilla/gecko-dev.git
synced 2025-03-09 04:25:38 +00:00
Backed out changeset dc66d16f19c8 (bug 1052422) for hazard analysis failures
This commit is contained in:
parent
c89334b523
commit
28007bed9c
@ -90,7 +90,7 @@ namespace JS {
|
||||
D(REFRESH_FRAME) \
|
||||
D(FULL_GC_TIMER) \
|
||||
D(SHUTDOWN_CC) \
|
||||
D(FINISH_LARGE_EVALUATE)
|
||||
D(FINISH_LARGE_EVALUTE)
|
||||
|
||||
namespace gcreason {
|
||||
|
||||
|
@ -268,7 +268,7 @@ MinorGC(JSContext *cx, unsigned argc, jsval *vp)
|
||||
if (args.get(0) == BooleanValue(true))
|
||||
cx->runtime()->gc.storeBuffer.setAboutToOverflow();
|
||||
|
||||
cx->minorGC(gcreason::API);
|
||||
MinorGC(cx, gcreason::API);
|
||||
#endif
|
||||
args.rval().setUndefined();
|
||||
return true;
|
||||
@ -519,7 +519,7 @@ SelectForGC(JSContext *cx, unsigned argc, Value *vp)
|
||||
* to be in the set, so evict the nursery before adding items.
|
||||
*/
|
||||
JSRuntime *rt = cx->runtime();
|
||||
rt->gc.evictNursery();
|
||||
MinorGC(rt, JS::gcreason::EVICT_NURSERY);
|
||||
|
||||
for (unsigned i = 0; i < args.length(); i++) {
|
||||
if (args[i].isObject()) {
|
||||
@ -628,7 +628,7 @@ GCSlice(JSContext *cx, unsigned argc, Value *vp)
|
||||
limit = false;
|
||||
}
|
||||
|
||||
cx->runtime()->gc.gcDebugSlice(limit, budget);
|
||||
GCDebugSlice(cx->runtime(), limit, budget);
|
||||
args.rval().setUndefined();
|
||||
return true;
|
||||
}
|
||||
|
@ -278,13 +278,10 @@ class GCRuntime
|
||||
void maybePeriodicFullGC();
|
||||
void minorGC(JS::gcreason::Reason reason);
|
||||
void minorGC(JSContext *cx, JS::gcreason::Reason reason);
|
||||
void evictNursery(JS::gcreason::Reason reason = JS::gcreason::EVICT_NURSERY) { minorGC(reason); }
|
||||
void gcIfNeeded(JSContext *cx);
|
||||
void gc(JSGCInvocationKind gckind, JS::gcreason::Reason reason);
|
||||
void collect(bool incremental, int64_t budget, JSGCInvocationKind gckind,
|
||||
JS::gcreason::Reason reason);
|
||||
void gcSlice(JSGCInvocationKind gckind, JS::gcreason::Reason reason, int64_t millis = 0);
|
||||
void gcFinalSlice(JSGCInvocationKind gckind, JS::gcreason::Reason reason);
|
||||
void gcDebugSlice(bool limit, int64_t objCount);
|
||||
|
||||
void runDebugGC();
|
||||
inline void poke();
|
||||
|
||||
@ -468,8 +465,6 @@ class GCRuntime
|
||||
|
||||
bool initZeal();
|
||||
void requestInterrupt(JS::gcreason::Reason reason);
|
||||
void collect(bool incremental, int64_t budget, JSGCInvocationKind gckind,
|
||||
JS::gcreason::Reason reason);
|
||||
bool gcCycle(bool incremental, int64_t budget, JSGCInvocationKind gckind,
|
||||
JS::gcreason::Reason reason);
|
||||
gcstats::ZoneGCStats scanZonesBeforeGC();
|
||||
|
@ -23,7 +23,7 @@ js::TraceRuntime(JSTracer *trc)
|
||||
JS_ASSERT(!IS_GC_MARKING_TRACER(trc));
|
||||
|
||||
JSRuntime *rt = trc->runtime();
|
||||
rt->gc.evictNursery();
|
||||
MinorGC(rt, JS::gcreason::EVICT_NURSERY);
|
||||
AutoPrepareForTracing prep(rt, WithAtoms);
|
||||
rt->gc.markRuntime(trc);
|
||||
}
|
||||
@ -93,7 +93,7 @@ void
|
||||
js::IterateScripts(JSRuntime *rt, JSCompartment *compartment,
|
||||
void *data, IterateScriptCallback scriptCallback)
|
||||
{
|
||||
rt->gc.evictNursery();
|
||||
MinorGC(rt, JS::gcreason::EVICT_NURSERY);
|
||||
AutoPrepareForTracing prep(rt, SkipAtoms);
|
||||
|
||||
if (compartment) {
|
||||
@ -113,7 +113,7 @@ js::IterateScripts(JSRuntime *rt, JSCompartment *compartment,
|
||||
void
|
||||
js::IterateGrayObjects(Zone *zone, GCThingCallback cellCallback, void *data)
|
||||
{
|
||||
zone->runtimeFromMainThread()->gc.evictNursery();
|
||||
MinorGC(zone->runtimeFromMainThread(), JS::gcreason::EVICT_NURSERY);
|
||||
AutoPrepareForTracing prep(zone->runtimeFromMainThread(), SkipAtoms);
|
||||
|
||||
for (size_t finalizeKind = 0; finalizeKind <= FINALIZE_OBJECT_LAST; finalizeKind++) {
|
||||
|
@ -182,7 +182,7 @@ gc::GCRuntime::startVerifyPreBarriers()
|
||||
if (verifyPostData)
|
||||
return;
|
||||
|
||||
evictNursery();
|
||||
MinorGC(rt, JS::gcreason::EVICT_NURSERY);
|
||||
|
||||
AutoPrepareForTracing prep(rt, WithAtoms);
|
||||
|
||||
@ -410,7 +410,7 @@ gc::GCRuntime::startVerifyPostBarriers()
|
||||
return;
|
||||
}
|
||||
|
||||
evictNursery();
|
||||
MinorGC(rt, JS::gcreason::EVICT_NURSERY);
|
||||
|
||||
number++;
|
||||
|
||||
|
@ -97,10 +97,8 @@ Zone::setGCMaxMallocBytes(size_t value)
|
||||
void
|
||||
Zone::onTooMuchMalloc()
|
||||
{
|
||||
if (!gcMallocGCTriggered) {
|
||||
GCRuntime &gc = runtimeFromAnyThread()->gc;
|
||||
gcMallocGCTriggered = gc.triggerZoneGC(this, JS::gcreason::TOO_MUCH_MALLOC);
|
||||
}
|
||||
if (!gcMallocGCTriggered)
|
||||
gcMallocGCTriggered = TriggerZoneGC(this, JS::gcreason::TOO_MUCH_MALLOC);
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -658,7 +658,7 @@ jit::RecompileOnStackBaselineScriptsForDebugMode(JSContext *cx, JSCompartment *c
|
||||
#ifdef JSGC_GENERATIONAL
|
||||
// Scripts can entrain nursery things. See note in js::ReleaseAllJITCode.
|
||||
if (!entries.empty())
|
||||
cx->runtime()->gc.evictNursery();
|
||||
MinorGC(cx->runtime(), JS::gcreason::EVICT_NURSERY);
|
||||
#endif
|
||||
|
||||
// When the profiler is enabled, we need to suppress sampling from here until
|
||||
|
@ -88,12 +88,12 @@ BEGIN_TEST(testGCFinalizeCallback)
|
||||
FinalizeCalls = 0;
|
||||
JS_SetGCZeal(cx, 9, 1000000);
|
||||
JS::PrepareForFullGC(rt);
|
||||
rt->gc.gcDebugSlice(true, 1);
|
||||
js::GCDebugSlice(rt, true, 1);
|
||||
CHECK(rt->gc.state() == js::gc::MARK);
|
||||
CHECK(rt->gc.isFullGc());
|
||||
|
||||
JS::RootedObject global4(cx, createGlobal());
|
||||
rt->gc.gcDebugSlice(true, 1);
|
||||
js::GCDebugSlice(rt, true, 1);
|
||||
CHECK(rt->gc.state() == js::gc::NO_INCREMENTAL);
|
||||
CHECK(!rt->gc.isFullGc());
|
||||
CHECK(checkMultipleGroups());
|
||||
|
@ -51,7 +51,7 @@ TestHeapPostBarriers(T initialObj)
|
||||
uintptr_t initialObjAsInt = uintptr_t(initialObj);
|
||||
|
||||
/* Perform minor GC and check heap wrapper is udated with new pointer. */
|
||||
cx->minorGC(JS::gcreason::API);
|
||||
js::MinorGC(cx, JS::gcreason::API);
|
||||
CHECK(uintptr_t(heapData->get()) != initialObjAsInt);
|
||||
CHECK(!js::gc::IsInsideNursery(heapData->get()));
|
||||
|
||||
|
@ -87,7 +87,7 @@ BEGIN_TEST(testWeakMap_keyDelegates)
|
||||
* zone to finish marking before the delegate zone.
|
||||
*/
|
||||
CHECK(newCCW(map, delegate));
|
||||
rt->gc.gcDebugSlice(true, 1000000);
|
||||
GCDebugSlice(rt, true, 1000000);
|
||||
#ifdef DEBUG
|
||||
CHECK(map->zone()->lastZoneGroupIndex() < delegate->zone()->lastZoneGroupIndex());
|
||||
#endif
|
||||
@ -100,7 +100,7 @@ BEGIN_TEST(testWeakMap_keyDelegates)
|
||||
/* Check the delegate keeps the entry alive even if the key is not reachable. */
|
||||
key = nullptr;
|
||||
CHECK(newCCW(map, delegate));
|
||||
rt->gc.gcDebugSlice(true, 100000);
|
||||
GCDebugSlice(rt, true, 100000);
|
||||
CHECK(checkSize(map, 1));
|
||||
|
||||
/*
|
||||
|
@ -1873,7 +1873,7 @@ JS_GC(JSRuntime *rt)
|
||||
{
|
||||
AssertHeapIsIdle(rt);
|
||||
JS::PrepareForFullGC(rt);
|
||||
rt->gc.gc(GC_NORMAL, JS::gcreason::API);
|
||||
GC(rt, GC_NORMAL, JS::gcreason::API);
|
||||
}
|
||||
|
||||
JS_PUBLIC_API(void)
|
||||
@ -4807,7 +4807,7 @@ Evaluate(JSContext *cx, HandleObject obj, const ReadOnlyCompileOptions &optionsA
|
||||
if (script->length() > LARGE_SCRIPT_LENGTH) {
|
||||
script = nullptr;
|
||||
PrepareZoneForGC(cx->zone());
|
||||
cx->runtime()->gc.gc(GC_NORMAL, JS::gcreason::FINISH_LARGE_EVALUATE);
|
||||
GC(cx->runtime(), GC_NORMAL, JS::gcreason::FINISH_LARGE_EVALUTE);
|
||||
}
|
||||
|
||||
return result;
|
||||
|
@ -251,7 +251,7 @@ js::DestroyContext(JSContext *cx, DestroyContextMode mode)
|
||||
if (mode == DCM_FORCE_GC) {
|
||||
JS_ASSERT(!rt->isHeapBusy());
|
||||
JS::PrepareForFullGC(rt);
|
||||
rt->gc.gc(GC_NORMAL, JS::gcreason::DESTROY_CONTEXT);
|
||||
GC(rt, GC_NORMAL, JS::gcreason::DESTROY_CONTEXT);
|
||||
}
|
||||
js_delete_poison(cx);
|
||||
}
|
||||
@ -986,7 +986,7 @@ js::InvokeInterruptCallback(JSContext *cx)
|
||||
// callbacks.
|
||||
rt->resetJitStackLimit();
|
||||
|
||||
cx->gcIfNeeded();
|
||||
js::gc::GCIfNeeded(cx);
|
||||
|
||||
rt->interruptPar = false;
|
||||
|
||||
|
@ -548,14 +548,6 @@ struct JSContext : public js::ExclusiveContext,
|
||||
}
|
||||
#endif
|
||||
|
||||
void minorGC(JS::gcreason::Reason reason) {
|
||||
runtime_->gc.minorGC(this, reason);
|
||||
}
|
||||
|
||||
void gcIfNeeded() {
|
||||
runtime_->gc.gcIfNeeded(this);
|
||||
}
|
||||
|
||||
private:
|
||||
/* Innermost-executing generator or null if no generator are executing. */
|
||||
JSGenerator *innermostGenerator_;
|
||||
|
@ -197,25 +197,25 @@ JS::SkipZoneForGC(Zone *zone)
|
||||
JS_FRIEND_API(void)
|
||||
JS::GCForReason(JSRuntime *rt, gcreason::Reason reason)
|
||||
{
|
||||
rt->gc.gc(GC_NORMAL, reason);
|
||||
GC(rt, GC_NORMAL, reason);
|
||||
}
|
||||
|
||||
JS_FRIEND_API(void)
|
||||
JS::ShrinkingGC(JSRuntime *rt, gcreason::Reason reason)
|
||||
{
|
||||
rt->gc.gc(GC_SHRINK, reason);
|
||||
GC(rt, GC_SHRINK, reason);
|
||||
}
|
||||
|
||||
JS_FRIEND_API(void)
|
||||
JS::IncrementalGC(JSRuntime *rt, gcreason::Reason reason, int64_t millis)
|
||||
{
|
||||
rt->gc.gcSlice(GC_NORMAL, reason, millis);
|
||||
GCSlice(rt, GC_NORMAL, reason, millis);
|
||||
}
|
||||
|
||||
JS_FRIEND_API(void)
|
||||
JS::FinishIncrementalGC(JSRuntime *rt, gcreason::Reason reason)
|
||||
{
|
||||
rt->gc.gcFinalSlice(GC_NORMAL, reason);
|
||||
GCFinalSlice(rt, GC_NORMAL, reason);
|
||||
}
|
||||
|
||||
JS_FRIEND_API(JSPrincipals *)
|
||||
@ -810,7 +810,7 @@ js::DumpHeapComplete(JSRuntime *rt, FILE *fp, js::DumpHeapNurseryBehaviour nurse
|
||||
{
|
||||
#ifdef JSGC_GENERATIONAL
|
||||
if (nurseryBehaviour == js::CollectNurseryBeforeDump)
|
||||
rt->gc.evictNursery(JS::gcreason::API);
|
||||
MinorGC(rt, JS::gcreason::API);
|
||||
#endif
|
||||
|
||||
DumpHeapTracer dtrc(fp, rt, DumpHeapVisitRoot, TraceWeakMapKeysValues);
|
||||
|
@ -939,7 +939,7 @@ Chunk::allocateArena(Zone *zone, AllocKind thingKind)
|
||||
|
||||
if (zone->usage.gcBytes() >= zone->threshold.gcTriggerBytes()) {
|
||||
AutoUnlockGC unlock(rt);
|
||||
rt->gc.triggerZoneGC(zone, JS::gcreason::ALLOC_TRIGGER);
|
||||
TriggerZoneGC(zone, JS::gcreason::ALLOC_TRIGGER);
|
||||
}
|
||||
|
||||
return aheader;
|
||||
@ -1186,7 +1186,7 @@ GCRuntime::setZeal(uint8_t zeal, uint32_t frequency)
|
||||
|
||||
#ifdef JSGC_GENERATIONAL
|
||||
if (zealMode == ZealGenerationalGCValue) {
|
||||
evictNursery(JS::gcreason::DEBUG_GC);
|
||||
minorGC(JS::gcreason::DEBUG_GC);
|
||||
nursery.leaveZealMode();
|
||||
}
|
||||
|
||||
@ -2169,7 +2169,7 @@ RunLastDitchGC(JSContext *cx, JS::Zone *zone, AllocKind thingKind)
|
||||
|
||||
/* The last ditch GC preserves all atoms. */
|
||||
AutoKeepAtoms keepAtoms(cx->perThreadData);
|
||||
rt->gc.gc(GC_NORMAL, JS::gcreason::LAST_DITCH);
|
||||
GC(rt, GC_NORMAL, JS::gcreason::LAST_DITCH);
|
||||
|
||||
/*
|
||||
* The JSGC_END callback can legitimately allocate new GC
|
||||
@ -2271,6 +2271,12 @@ ArenaLists::refillFreeList<NoGC>(ThreadSafeContext *cx, AllocKind thingKind);
|
||||
template void *
|
||||
ArenaLists::refillFreeList<CanGC>(ThreadSafeContext *cx, AllocKind thingKind);
|
||||
|
||||
JSGCTraceKind
|
||||
js_GetGCThingTraceKind(void *thing)
|
||||
{
|
||||
return GetGCThingTraceKind(thing);
|
||||
}
|
||||
|
||||
/* static */ int64_t
|
||||
SliceBudget::TimeBudget(int64_t millis)
|
||||
{
|
||||
@ -2328,6 +2334,12 @@ GCRuntime::requestInterrupt(JS::gcreason::Reason reason)
|
||||
rt->requestInterrupt(JSRuntime::RequestInterruptMainThread);
|
||||
}
|
||||
|
||||
bool
|
||||
js::TriggerGC(JSRuntime *rt, JS::gcreason::Reason reason)
|
||||
{
|
||||
return rt->gc.triggerGC(reason);
|
||||
}
|
||||
|
||||
bool
|
||||
GCRuntime::triggerGC(JS::gcreason::Reason reason)
|
||||
{
|
||||
@ -2357,6 +2369,12 @@ GCRuntime::triggerGC(JS::gcreason::Reason reason)
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
js::TriggerZoneGC(Zone *zone, JS::gcreason::Reason reason)
|
||||
{
|
||||
return zone->runtimeFromAnyThread()->gc.triggerZoneGC(zone, reason);
|
||||
}
|
||||
|
||||
bool
|
||||
GCRuntime::triggerZoneGC(Zone *zone, JS::gcreason::Reason reason)
|
||||
{
|
||||
@ -2383,14 +2401,14 @@ GCRuntime::triggerZoneGC(Zone *zone, JS::gcreason::Reason reason)
|
||||
|
||||
#ifdef JS_GC_ZEAL
|
||||
if (zealMode == ZealAllocValue) {
|
||||
triggerGC(reason);
|
||||
TriggerGC(rt, reason);
|
||||
return true;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (rt->isAtomsZone(zone)) {
|
||||
/* We can't do a zone GC of the atoms compartment. */
|
||||
triggerGC(reason);
|
||||
TriggerGC(rt, reason);
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -2407,13 +2425,13 @@ GCRuntime::maybeGC(Zone *zone)
|
||||
#ifdef JS_GC_ZEAL
|
||||
if (zealMode == ZealAllocValue || zealMode == ZealPokeValue) {
|
||||
JS::PrepareForFullGC(rt);
|
||||
gc(GC_NORMAL, JS::gcreason::MAYBEGC);
|
||||
GC(rt, GC_NORMAL, JS::gcreason::MAYBEGC);
|
||||
return true;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (isNeeded) {
|
||||
gcSlice(GC_NORMAL, JS::gcreason::MAYBEGC);
|
||||
GCSlice(rt, GC_NORMAL, JS::gcreason::MAYBEGC);
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -2424,7 +2442,7 @@ GCRuntime::maybeGC(Zone *zone)
|
||||
!isBackgroundSweeping())
|
||||
{
|
||||
PrepareZoneForGC(zone);
|
||||
gcSlice(GC_NORMAL, JS::gcreason::MAYBEGC);
|
||||
GCSlice(rt, GC_NORMAL, JS::gcreason::MAYBEGC);
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -2450,7 +2468,7 @@ GCRuntime::maybePeriodicFullGC()
|
||||
numArenasFreeCommitted > decommitThreshold)
|
||||
{
|
||||
JS::PrepareForFullGC(rt);
|
||||
gcSlice(GC_SHRINK, JS::gcreason::MAYBEGC);
|
||||
GCSlice(rt, GC_SHRINK, JS::gcreason::MAYBEGC);
|
||||
} else {
|
||||
nextFullGCTime = now + GC_IDLE_FULL_SPAN;
|
||||
}
|
||||
@ -4749,7 +4767,7 @@ GCRuntime::incrementalCollectSlice(int64_t budget,
|
||||
if (reason == JS::gcreason::DEBUG_GC && budget != SliceBudget::Unlimited) {
|
||||
/*
|
||||
* Do the incremental collection type specified by zeal mode if the
|
||||
* collection was triggered by runDebugGC() and incremental GC has not
|
||||
* collection was triggered by RunDebugGC() and incremental GC has not
|
||||
* been cancelled by resetIncrementalGC().
|
||||
*/
|
||||
zeal = zealMode;
|
||||
@ -5182,9 +5200,15 @@ GCRuntime::collect(bool incremental, int64_t budget, JSGCInvocationKind gckind,
|
||||
}
|
||||
|
||||
void
|
||||
GCRuntime::gc(JSGCInvocationKind gckind, JS::gcreason::Reason reason)
|
||||
js::GC(JSRuntime *rt, JSGCInvocationKind gckind, JS::gcreason::Reason reason)
|
||||
{
|
||||
collect(false, SliceBudget::Unlimited, gckind, reason);
|
||||
rt->gc.collect(false, SliceBudget::Unlimited, gckind, reason);
|
||||
}
|
||||
|
||||
void
|
||||
js::GCSlice(JSRuntime *rt, JSGCInvocationKind gckind, JS::gcreason::Reason reason, int64_t millis)
|
||||
{
|
||||
rt->gc.gcSlice(gckind, reason, millis);
|
||||
}
|
||||
|
||||
void
|
||||
@ -5202,9 +5226,9 @@ GCRuntime::gcSlice(JSGCInvocationKind gckind, JS::gcreason::Reason reason, int64
|
||||
}
|
||||
|
||||
void
|
||||
GCRuntime::gcFinalSlice(JSGCInvocationKind gckind, JS::gcreason::Reason reason)
|
||||
js::GCFinalSlice(JSRuntime *rt, JSGCInvocationKind gckind, JS::gcreason::Reason reason)
|
||||
{
|
||||
collect(true, SliceBudget::Unlimited, gckind, reason);
|
||||
rt->gc.collect(true, SliceBudget::Unlimited, gckind, reason);
|
||||
}
|
||||
|
||||
void
|
||||
@ -5247,7 +5271,7 @@ ZonesSelected(JSRuntime *rt)
|
||||
}
|
||||
|
||||
void
|
||||
GCRuntime::gcDebugSlice(bool limit, int64_t objCount)
|
||||
js::GCDebugSlice(JSRuntime *rt, bool limit, int64_t objCount)
|
||||
{
|
||||
int64_t budget = limit ? SliceBudget::WorkBudget(objCount) : SliceBudget::Unlimited;
|
||||
if (!ZonesSelected(rt)) {
|
||||
@ -5256,7 +5280,7 @@ GCRuntime::gcDebugSlice(bool limit, int64_t objCount)
|
||||
else
|
||||
JS::PrepareForFullGC(rt);
|
||||
}
|
||||
collect(true, budget, GC_NORMAL, JS::gcreason::DEBUG_GC);
|
||||
rt->gc.collect(true, budget, GC_NORMAL, JS::gcreason::DEBUG_GC);
|
||||
}
|
||||
|
||||
/* Schedule a full GC unless a zone will already be collected. */
|
||||
@ -5286,6 +5310,12 @@ GCRuntime::shrinkBuffers()
|
||||
expireChunksAndArenas(true);
|
||||
}
|
||||
|
||||
void
|
||||
js::MinorGC(JSRuntime *rt, JS::gcreason::Reason reason)
|
||||
{
|
||||
rt->gc.minorGC(reason);
|
||||
}
|
||||
|
||||
void
|
||||
GCRuntime::minorGC(JS::gcreason::Reason reason)
|
||||
{
|
||||
@ -5298,10 +5328,16 @@ GCRuntime::minorGC(JS::gcreason::Reason reason)
|
||||
}
|
||||
|
||||
void
|
||||
GCRuntime::minorGC(JSContext *cx, JS::gcreason::Reason reason)
|
||||
js::MinorGC(JSContext *cx, JS::gcreason::Reason reason)
|
||||
{
|
||||
// Alternate to the runtime-taking form above which allows marking type
|
||||
// objects as needing pretenuring.
|
||||
cx->runtime()->gc.minorGC(cx, reason);
|
||||
}
|
||||
|
||||
void
|
||||
GCRuntime::minorGC(JSContext *cx, JS::gcreason::Reason reason)
|
||||
{
|
||||
#ifdef JSGC_GENERATIONAL
|
||||
TraceLogger *logger = TraceLoggerForMainThread(rt);
|
||||
AutoTraceLog logMinorGC(logger, TraceLogger::MinorGC);
|
||||
@ -5341,6 +5377,12 @@ GCRuntime::enableGenerationalGC()
|
||||
#endif
|
||||
}
|
||||
|
||||
void
|
||||
js::gc::GCIfNeeded(JSContext *cx)
|
||||
{
|
||||
cx->runtime()->gc.gcIfNeeded(cx);
|
||||
}
|
||||
|
||||
void
|
||||
GCRuntime::gcIfNeeded(JSContext *cx)
|
||||
{
|
||||
@ -5357,6 +5399,12 @@ GCRuntime::gcIfNeeded(JSContext *cx)
|
||||
gcSlice(GC_NORMAL, rt->gc.triggerReason, 0);
|
||||
}
|
||||
|
||||
void
|
||||
js::gc::FinishBackgroundFinalize(JSRuntime *rt)
|
||||
{
|
||||
rt->gc.waitBackgroundSweepEnd();
|
||||
}
|
||||
|
||||
AutoFinishGC::AutoFinishGC(JSRuntime *rt)
|
||||
{
|
||||
if (JS::IsIncrementalGCInProgress(rt)) {
|
||||
@ -5364,7 +5412,7 @@ AutoFinishGC::AutoFinishGC(JSRuntime *rt)
|
||||
JS::FinishIncrementalGC(rt, JS::gcreason::API);
|
||||
}
|
||||
|
||||
rt->gc.waitBackgroundSweepEnd();
|
||||
gc::FinishBackgroundFinalize(rt);
|
||||
}
|
||||
|
||||
AutoPrepareForTracing::AutoPrepareForTracing(JSRuntime *rt, ZoneSelector selector)
|
||||
@ -5472,6 +5520,12 @@ gc::MergeCompartments(JSCompartment *source, JSCompartment *target)
|
||||
target->zone()->types.typeLifoAlloc.transferFrom(&source->zone()->types.typeLifoAlloc);
|
||||
}
|
||||
|
||||
void
|
||||
gc::RunDebugGC(JSContext *cx)
|
||||
{
|
||||
cx->runtime()->gc.runDebugGC();
|
||||
}
|
||||
|
||||
void
|
||||
GCRuntime::runDebugGC()
|
||||
{
|
||||
@ -5482,7 +5536,7 @@ GCRuntime::runDebugGC()
|
||||
return;
|
||||
|
||||
if (type == js::gc::ZealGenerationalGCValue)
|
||||
return minorGC(JS::gcreason::DEBUG_GC);
|
||||
return MinorGC(rt, JS::gcreason::DEBUG_GC);
|
||||
|
||||
PrepareForDebugGC(rt);
|
||||
|
||||
@ -5580,7 +5634,7 @@ js::ReleaseAllJITCode(FreeOp *fop)
|
||||
* Scripts can entrain nursery things, inserting references to the script
|
||||
* into the store buffer. Clear the store buffer before discarding scripts.
|
||||
*/
|
||||
fop->runtime()->gc.evictNursery();
|
||||
MinorGC(fop->runtime(), JS::gcreason::EVICT_NURSERY);
|
||||
#endif
|
||||
|
||||
for (ZonesIter zone(fop->runtime(), SkipAtoms); !zone.done(); zone.next()) {
|
||||
|
@ -963,6 +963,14 @@ MarkCompartmentActive(js::InterpreterFrame *fp);
|
||||
extern void
|
||||
TraceRuntime(JSTracer *trc);
|
||||
|
||||
/* Must be called with GC lock taken. */
|
||||
extern bool
|
||||
TriggerGC(JSRuntime *rt, JS::gcreason::Reason reason);
|
||||
|
||||
/* Must be called with GC lock taken. */
|
||||
extern bool
|
||||
TriggerZoneGC(Zone *zone, JS::gcreason::Reason reason);
|
||||
|
||||
extern void
|
||||
ReleaseAllJITCode(FreeOp *op);
|
||||
|
||||
@ -977,9 +985,27 @@ typedef enum JSGCInvocationKind {
|
||||
GC_SHRINK = 1
|
||||
} JSGCInvocationKind;
|
||||
|
||||
extern void
|
||||
GC(JSRuntime *rt, JSGCInvocationKind gckind, JS::gcreason::Reason reason);
|
||||
|
||||
extern void
|
||||
GCSlice(JSRuntime *rt, JSGCInvocationKind gckind, JS::gcreason::Reason reason, int64_t millis = 0);
|
||||
|
||||
extern void
|
||||
GCFinalSlice(JSRuntime *rt, JSGCInvocationKind gckind, JS::gcreason::Reason reason);
|
||||
|
||||
extern void
|
||||
GCDebugSlice(JSRuntime *rt, bool limit, int64_t objCount);
|
||||
|
||||
extern void
|
||||
PrepareForDebugGC(JSRuntime *rt);
|
||||
|
||||
extern void
|
||||
MinorGC(JSRuntime *rt, JS::gcreason::Reason reason);
|
||||
|
||||
extern void
|
||||
MinorGC(JSContext *cx, JS::gcreason::Reason reason);
|
||||
|
||||
/* Functions for managing cross compartment gray pointers. */
|
||||
|
||||
extern void
|
||||
@ -1199,6 +1225,17 @@ NewCompartment(JSContext *cx, JS::Zone *zone, JSPrincipals *principals,
|
||||
|
||||
namespace gc {
|
||||
|
||||
extern void
|
||||
GCIfNeeded(JSContext *cx);
|
||||
|
||||
/* Tries to run a GC no matter what (used for GC zeal). */
|
||||
void
|
||||
RunDebugGC(JSContext *cx);
|
||||
|
||||
/* Wait for the background thread to finish sweeping if it is running. */
|
||||
void
|
||||
FinishBackgroundFinalize(JSRuntime *rt);
|
||||
|
||||
/*
|
||||
* Merge all contents of source into target. This can only be used if source is
|
||||
* the only compartment in its zone.
|
||||
|
@ -368,13 +368,14 @@ class ZoneCellIter : public ZoneCellIterImpl
|
||||
if (IsBackgroundFinalized(kind) &&
|
||||
zone->allocator.arenas.needBackgroundFinalizeWait(kind))
|
||||
{
|
||||
zone->runtimeFromMainThread()->gc.waitBackgroundSweepEnd();
|
||||
gc::FinishBackgroundFinalize(zone->runtimeFromMainThread());
|
||||
}
|
||||
|
||||
#ifdef JSGC_GENERATIONAL
|
||||
/* Evict the nursery before iterating so we can see all things. */
|
||||
JSRuntime *rt = zone->runtimeFromMainThread();
|
||||
rt->gc.evictNursery();
|
||||
if (!rt->gc.nursery.isEmpty())
|
||||
MinorGC(rt, JS::gcreason::EVICT_NURSERY);
|
||||
#endif
|
||||
|
||||
if (lists->isSynchronizedFreeList(kind)) {
|
||||
@ -472,7 +473,7 @@ TryNewNurseryObject(JSContext *cx, size_t thingSize, size_t nDynamicSlots)
|
||||
if (obj)
|
||||
return obj;
|
||||
if (allowGC && !rt->mainThread.suppressGC) {
|
||||
cx->minorGC(JS::gcreason::OUT_OF_NURSERY);
|
||||
MinorGC(cx, JS::gcreason::OUT_OF_NURSERY);
|
||||
|
||||
/* Exceeding gcMaxBytes while tenuring can disable the Nursery. */
|
||||
if (nursery.isEnabled()) {
|
||||
@ -546,13 +547,13 @@ CheckAllocatorState(ThreadSafeContext *cx, AllocKind kind)
|
||||
if (allowGC) {
|
||||
#ifdef JS_GC_ZEAL
|
||||
if (rt->gc.needZealousGC())
|
||||
rt->gc.runDebugGC();
|
||||
js::gc::RunDebugGC(ncx);
|
||||
#endif
|
||||
|
||||
if (rt->interrupt) {
|
||||
// Invoking the interrupt callback can fail and we can't usefully
|
||||
// handle that here. Just check in case we need to collect instead.
|
||||
ncx->gcIfNeeded();
|
||||
js::gc::GCIfNeeded(ncx);
|
||||
}
|
||||
}
|
||||
|
||||
@ -681,7 +682,7 @@ AllocateObjectForCacheHit(JSContext *cx, AllocKind kind, InitialHeap heap)
|
||||
|
||||
JSObject *obj = TryNewNurseryObject<NoGC>(cx, thingSize, 0);
|
||||
if (!obj && allowGC) {
|
||||
cx->minorGC(JS::gcreason::OUT_OF_NURSERY);
|
||||
MinorGC(cx, JS::gcreason::OUT_OF_NURSERY);
|
||||
return nullptr;
|
||||
}
|
||||
return obj;
|
||||
|
@ -355,7 +355,7 @@ ForkJoinActivation::ForkJoinActivation(JSContext *cx)
|
||||
JS::FinishIncrementalGC(cx->runtime(), JS::gcreason::API);
|
||||
}
|
||||
|
||||
cx->runtime()->gc.evictNursery();
|
||||
MinorGC(cx->runtime(), JS::gcreason::API);
|
||||
|
||||
cx->runtime()->gc.waitBackgroundSweepEnd();
|
||||
|
||||
@ -1492,11 +1492,10 @@ ForkJoinShared::transferArenasToCompartmentAndProcessGCRequests()
|
||||
|
||||
if (gcRequested_) {
|
||||
Spew(SpewGC, "Triggering garbage collection in SpiderMonkey heap");
|
||||
gc::GCRuntime &gc = cx_->runtime()->gc;
|
||||
if (!gcZone_)
|
||||
gc.triggerGC(gcReason_);
|
||||
TriggerGC(cx_->runtime(), gcReason_);
|
||||
else
|
||||
gc.triggerZoneGC(gcZone_, gcReason_);
|
||||
TriggerZoneGC(gcZone_, gcReason_);
|
||||
gcRequested_ = false;
|
||||
gcZone_ = nullptr;
|
||||
}
|
||||
|
@ -415,7 +415,7 @@ struct AutoGCIfNeeded
|
||||
{
|
||||
JSContext *cx_;
|
||||
explicit AutoGCIfNeeded(JSContext *cx) : cx_(cx) {}
|
||||
~AutoGCIfNeeded() { cx_->gcIfNeeded(); }
|
||||
~AutoGCIfNeeded() { js::gc::GCIfNeeded(cx_); }
|
||||
};
|
||||
|
||||
/*
|
||||
|
@ -376,7 +376,7 @@ JSRuntime::~JSRuntime()
|
||||
profilingScripts = false;
|
||||
|
||||
JS::PrepareForFullGC(this);
|
||||
gc.gc(GC_NORMAL, JS::gcreason::DESTROY_RUNTIME);
|
||||
GC(this, GC_NORMAL, JS::gcreason::DESTROY_RUNTIME);
|
||||
}
|
||||
|
||||
/*
|
||||
|
Loading…
x
Reference in New Issue
Block a user