diff options
Diffstat (limited to 'js/src/jsgc.cpp')
-rw-r--r-- | js/src/jsgc.cpp | 661 |
1 files changed, 3 insertions, 658 deletions
diff --git a/js/src/jsgc.cpp b/js/src/jsgc.cpp index 42d10283c..45301dac8 100644 --- a/js/src/jsgc.cpp +++ b/js/src/jsgc.cpp @@ -844,9 +844,6 @@ GCRuntime::GCRuntime(JSRuntime* rt) : arenasAllocatedDuringSweep(nullptr), startedCompacting(false), relocatedArenasToRelease(nullptr), -#ifdef JS_GC_ZEAL - markingValidator(nullptr), -#endif interFrameGC(false), defaultTimeBudget_(SliceBudget::UnlimitedTimeBudget), incrementalAllowed(true), @@ -856,13 +853,6 @@ GCRuntime::GCRuntime(JSRuntime* rt) : manipulatingDeadZones(false), objectsMarkedInDeadZones(0), poked(false), -#ifdef JS_GC_ZEAL - zealModeBits(0), - zealFrequency(0), - nextScheduled(0), - deterministicOnly(false), - incrementalLimit(0), -#endif fullCompartmentChecks(false), mallocBytesUntilGC(0), mallocGCTriggered(false), @@ -881,147 +871,6 @@ GCRuntime::GCRuntime(JSRuntime* rt) : setGCMode(JSGC_MODE_GLOBAL); } -#ifdef JS_GC_ZEAL - -void -GCRuntime::getZealBits(uint32_t* zealBits, uint32_t* frequency, uint32_t* scheduled) -{ - *zealBits = zealModeBits; - *frequency = zealFrequency; - *scheduled = nextScheduled; -} - -const char* gc::ZealModeHelpText = - " Specifies how zealous the garbage collector should be. Some of these modes can\n" - " be set simultaneously, by passing multiple level options, e.g. \"2;4\" will activate\n" - " both modes 2 and 4. Modes can be specified by name or number.\n" - " \n" - " Values:\n" - " 0: (None) Normal amount of collection (resets all modes)\n" - " 1: (Poke) Collect when roots are added or removed\n" - " 2: (Alloc) Collect when every N allocations (default: 100)\n" - " 3: (FrameGC) Collect when the window paints (browser only)\n" - " 4: (VerifierPre) Verify pre write barriers between instructions\n" - " 5: (FrameVerifierPre) Verify pre write barriers between paints\n" - " 6: (StackRooting) Verify stack rooting\n" - " 7: (GenerationalGC) Collect the nursery every N nursery allocations\n" - " 8: (IncrementalRootsThenFinish) Incremental GC in two slices: 1) mark roots 2) finish collection\n" - " 9: (IncrementalMarkAllThenFinish) Incremental GC in two slices: 1) mark all 2) new marking and finish\n" - " 10: (IncrementalMultipleSlices) Incremental GC in multiple slices\n" - " 11: (IncrementalMarkingValidator) Verify incremental marking\n" - " 12: (ElementsBarrier) Always use the individual element post-write barrier, regardless of elements size\n" - " 13: (CheckHashTablesOnMinorGC) Check internal hashtables on minor GC\n" - " 14: (Compact) Perform a shrinking collection every N allocations\n" - " 15: (CheckHeapAfterGC) Walk the heap to check its integrity after every GC\n" - " 16: (CheckNursery) Check nursery integrity on minor GC\n"; - -void -GCRuntime::setZeal(uint8_t zeal, uint32_t frequency) -{ - MOZ_ASSERT(zeal <= unsigned(ZealMode::Limit)); - - if (verifyPreData) - VerifyBarriers(rt, PreBarrierVerifier); - - if (zeal == 0 && hasZealMode(ZealMode::GenerationalGC)) { - evictNursery(JS::gcreason::DEBUG_GC); - nursery.leaveZealMode(); - } - - ZealMode zealMode = ZealMode(zeal); - if (zealMode == ZealMode::GenerationalGC) - nursery.enterZealMode(); - - // Zeal modes 8-10 are mutually exclusive. If we're setting one of those, - // we first reset all of them. - if (zealMode >= ZealMode::IncrementalRootsThenFinish && - zealMode <= ZealMode::IncrementalMultipleSlices) - { - clearZealMode(ZealMode::IncrementalRootsThenFinish); - clearZealMode(ZealMode::IncrementalMarkAllThenFinish); - clearZealMode(ZealMode::IncrementalMultipleSlices); - } - - bool schedule = zealMode >= ZealMode::Alloc; - if (zeal != 0) - zealModeBits |= 1 << unsigned(zeal); - else - zealModeBits = 0; - zealFrequency = frequency; - nextScheduled = schedule ? frequency : 0; -} - -void -GCRuntime::setNextScheduled(uint32_t count) -{ - nextScheduled = count; -} - -bool -GCRuntime::parseAndSetZeal(const char* str) -{ - int frequency = -1; - bool foundFrequency = false; - mozilla::Vector<int, 0, SystemAllocPolicy> zeals; - - static const struct { - const char* const zealMode; - size_t length; - uint32_t zeal; - } zealModes[] = { -#define ZEAL_MODE(name, value) {#name, sizeof(#name) - 1, value}, - JS_FOR_EACH_ZEAL_MODE(ZEAL_MODE) -#undef ZEAL_MODE - {"None", 4, 0} - }; - - do { - int zeal = -1; - - const char* p = nullptr; - if (isdigit(str[0])) { - zeal = atoi(str); - - size_t offset = strspn(str, "0123456789"); - p = str + offset; - } else { - for (auto z : zealModes) { - if (!strncmp(str, z.zealMode, z.length)) { - zeal = z.zeal; - p = str + z.length; - break; - } - } - } - if (p) { - if (!*p || *p == ';') { - frequency = JS_DEFAULT_ZEAL_FREQ; - } else if (*p == ',') { - frequency = atoi(p + 1); - foundFrequency = true; - } - } - - if (zeal < 0 || zeal > int(ZealMode::Limit) || frequency <= 0) { - fprintf(stderr, "Format: JS_GC_ZEAL=level(;level)*[,N]\n"); - fputs(ZealModeHelpText, stderr); - return false; - } - - if (!zeals.emplaceBack(zeal)) { - return false; - } - } while (!foundFrequency && - (str = strchr(str, ';')) != nullptr && - str++); - - for (auto z : zeals) - setZeal(z, frequency); - return true; -} - -#endif - /* * Lifetime in number of major GCs for type sets attached to scripts containing * observed types. @@ -1063,12 +912,6 @@ GCRuntime::init(uint32_t maxbytes, uint32_t maxNurseryBytes) } } -#ifdef JS_GC_ZEAL - const char* zealSpec = getenv("JS_GC_ZEAL"); - if (zealSpec && zealSpec[0] && !parseAndSetZeal(zealSpec)) - return false; -#endif - if (!InitTrace(*this)) return false; @@ -1094,11 +937,6 @@ GCRuntime::finish() allocTask.cancel(GCParallelTask::CancelAndWait); decommitTask.cancel(GCParallelTask::CancelAndWait); -#ifdef JS_GC_ZEAL - /* Free memory associated with GC verification. */ - finishVerifier(); -#endif - /* Delete all remaining zones. */ if (rt->gcInitialized) { AutoSetThreadIsSweeping threadIsSweeping; @@ -1315,7 +1153,6 @@ GCRuntime::setMarkStackLimit(size_t limit, AutoLockGC& lock) { MOZ_ASSERT(!rt->isHeapBusy()); AutoUnlockGC unlock(lock); - AutoStopVerifyingBarriers pauseVerification(rt, false); marker.setMaxCapacity(limit); } @@ -2635,7 +2472,7 @@ GCRuntime::releaseRelocatedArenasWithoutUnlocking(Arena* arenaList, const AutoLo // Mark arena as empty arena->setAsFullyUnused(); -#if defined(JS_CRASH_DIAGNOSTICS) || defined(JS_GC_ZEAL) +#if defined(JS_CRASH_DIAGNOSTICS) JS_POISON(reinterpret_cast<void*>(arena->thingsStart()), JS_MOVED_TENURED_PATTERN, arena->getThingsSpan()); #endif @@ -3048,13 +2885,6 @@ GCRuntime::triggerZoneGC(Zone* zone, JS::gcreason::Reason reason) if (rt->isHeapCollecting()) return false; -#ifdef JS_GC_ZEAL - if (hasZealMode(ZealMode::Alloc)) { - MOZ_RELEASE_ASSERT(triggerGC(reason)); - return true; - } -#endif - if (zone->isAtomsZone()) { /* We can't do a zone GC of the atoms compartment. */ if (rt->keepAtoms()) { @@ -3077,14 +2907,6 @@ GCRuntime::maybeGC(Zone* zone) { MOZ_ASSERT(CurrentThreadCanAccessRuntime(rt)); -#ifdef JS_GC_ZEAL - if (hasZealMode(ZealMode::Alloc) || hasZealMode(ZealMode::Poke)) { - JS::PrepareForFullGC(rt->contextFromMainThread()); - gc(GC_NORMAL, JS::gcreason::DEBUG_GC); - return; - } -#endif - if (gcIfRequested()) return; @@ -3418,11 +3240,6 @@ GCRuntime::shouldReleaseObservedTypes() { bool releaseTypes = false; -#ifdef JS_GC_ZEAL - if (zealModeBits != 0) - releaseTypes = true; -#endif - /* We may miss the exact target GC due to resets. */ if (majorGCNumber >= jitReleaseNumber) releaseTypes = true; @@ -4068,292 +3885,6 @@ GCRuntime::markAllGrayReferences(gcstats::Phase phase) markGrayReferences<GCZonesIter, GCCompartmentsIter>(phase); } -#ifdef JS_GC_ZEAL - -struct GCChunkHasher { - typedef gc::Chunk* Lookup; - - /* - * Strip zeros for better distribution after multiplying by the golden - * ratio. - */ - static HashNumber hash(gc::Chunk* chunk) { - MOZ_ASSERT(!(uintptr_t(chunk) & gc::ChunkMask)); - return HashNumber(uintptr_t(chunk) >> gc::ChunkShift); - } - - static bool match(gc::Chunk* k, gc::Chunk* l) { - MOZ_ASSERT(!(uintptr_t(k) & gc::ChunkMask)); - MOZ_ASSERT(!(uintptr_t(l) & gc::ChunkMask)); - return k == l; - } -}; - -class js::gc::MarkingValidator -{ - public: - explicit MarkingValidator(GCRuntime* gc); - ~MarkingValidator(); - void nonIncrementalMark(AutoLockForExclusiveAccess& lock); - void validate(); - - private: - GCRuntime* gc; - bool initialized; - - typedef HashMap<Chunk*, ChunkBitmap*, GCChunkHasher, SystemAllocPolicy> BitmapMap; - BitmapMap map; -}; - -js::gc::MarkingValidator::MarkingValidator(GCRuntime* gc) - : gc(gc), - initialized(false) -{} - -js::gc::MarkingValidator::~MarkingValidator() -{ - if (!map.initialized()) - return; - - for (BitmapMap::Range r(map.all()); !r.empty(); r.popFront()) - js_delete(r.front().value()); -} - -void -js::gc::MarkingValidator::nonIncrementalMark(AutoLockForExclusiveAccess& lock) -{ - /* - * Perform a non-incremental mark for all collecting zones and record - * the results for later comparison. - * - * Currently this does not validate gray marking. - */ - - if (!map.init()) - return; - - JSRuntime* runtime = gc->rt; - GCMarker* gcmarker = &gc->marker; - - gc->waitBackgroundSweepEnd(); - - /* Save existing mark bits. */ - for (auto chunk = gc->allNonEmptyChunks(); !chunk.done(); chunk.next()) { - ChunkBitmap* bitmap = &chunk->bitmap; - ChunkBitmap* entry = js_new<ChunkBitmap>(); - if (!entry) - return; - - memcpy((void*)entry->bitmap, (void*)bitmap->bitmap, sizeof(bitmap->bitmap)); - if (!map.putNew(chunk, entry)) - return; - } - - /* - * Temporarily clear the weakmaps' mark flags for the compartments we are - * collecting. - */ - - WeakMapSet markedWeakMaps; - if (!markedWeakMaps.init()) - return; - - /* - * For saving, smush all of the keys into one big table and split them back - * up into per-zone tables when restoring. - */ - gc::WeakKeyTable savedWeakKeys(SystemAllocPolicy(), runtime->randomHashCodeScrambler()); - if (!savedWeakKeys.init()) - return; - - for (GCZonesIter zone(runtime); !zone.done(); zone.next()) { - if (!WeakMapBase::saveZoneMarkedWeakMaps(zone, markedWeakMaps)) - return; - - AutoEnterOOMUnsafeRegion oomUnsafe; - for (gc::WeakKeyTable::Range r = zone->gcWeakKeys.all(); !r.empty(); r.popFront()) { - if (!savedWeakKeys.put(Move(r.front().key), Move(r.front().value))) - oomUnsafe.crash("saving weak keys table for validator"); - } - - if (!zone->gcWeakKeys.clear()) - oomUnsafe.crash("clearing weak keys table for validator"); - } - - /* - * After this point, the function should run to completion, so we shouldn't - * do anything fallible. - */ - initialized = true; - - /* Re-do all the marking, but non-incrementally. */ - js::gc::State state = gc->incrementalState; - gc->incrementalState = State::MarkRoots; - - { - gcstats::AutoPhase ap(gc->stats, gcstats::PHASE_MARK); - - { - gcstats::AutoPhase ap(gc->stats, gcstats::PHASE_UNMARK); - - for (GCZonesIter zone(runtime); !zone.done(); zone.next()) - WeakMapBase::unmarkZone(zone); - - MOZ_ASSERT(gcmarker->isDrained()); - gcmarker->reset(); - - for (auto chunk = gc->allNonEmptyChunks(); !chunk.done(); chunk.next()) - chunk->bitmap.clear(); - } - - gc->traceRuntimeForMajorGC(gcmarker, lock); - - gc->incrementalState = State::Mark; - auto unlimited = SliceBudget::unlimited(); - MOZ_RELEASE_ASSERT(gc->marker.drainMarkStack(unlimited)); - } - - gc->incrementalState = State::Sweep; - { - gcstats::AutoPhase ap1(gc->stats, gcstats::PHASE_SWEEP); - gcstats::AutoPhase ap2(gc->stats, gcstats::PHASE_SWEEP_MARK); - - gc->markAllWeakReferences(gcstats::PHASE_SWEEP_MARK_WEAK); - - /* Update zone state for gray marking. */ - for (GCZonesIter zone(runtime); !zone.done(); zone.next()) { - MOZ_ASSERT(zone->isGCMarkingBlack()); - zone->setGCState(Zone::MarkGray); - } - gc->marker.setMarkColorGray(); - - gc->markAllGrayReferences(gcstats::PHASE_SWEEP_MARK_GRAY); - gc->markAllWeakReferences(gcstats::PHASE_SWEEP_MARK_GRAY_WEAK); - - /* Restore zone state. */ - for (GCZonesIter zone(runtime); !zone.done(); zone.next()) { - MOZ_ASSERT(zone->isGCMarkingGray()); - zone->setGCState(Zone::Mark); - } - MOZ_ASSERT(gc->marker.isDrained()); - gc->marker.setMarkColorBlack(); - } - - /* Take a copy of the non-incremental mark state and restore the original. */ - for (auto chunk = gc->allNonEmptyChunks(); !chunk.done(); chunk.next()) { - ChunkBitmap* bitmap = &chunk->bitmap; - ChunkBitmap* entry = map.lookup(chunk)->value(); - Swap(*entry, *bitmap); - } - - for (GCZonesIter zone(runtime); !zone.done(); zone.next()) { - WeakMapBase::unmarkZone(zone); - AutoEnterOOMUnsafeRegion oomUnsafe; - if (!zone->gcWeakKeys.clear()) - oomUnsafe.crash("clearing weak keys table for validator"); - } - - WeakMapBase::restoreMarkedWeakMaps(markedWeakMaps); - - for (gc::WeakKeyTable::Range r = savedWeakKeys.all(); !r.empty(); r.popFront()) { - AutoEnterOOMUnsafeRegion oomUnsafe; - Zone* zone = gc::TenuredCell::fromPointer(r.front().key.asCell())->zone(); - if (!zone->gcWeakKeys.put(Move(r.front().key), Move(r.front().value))) - oomUnsafe.crash("restoring weak keys table for validator"); - } - - gc->incrementalState = state; -} - -void -js::gc::MarkingValidator::validate() -{ - /* - * Validates the incremental marking for a single compartment by comparing - * the mark bits to those previously recorded for a non-incremental mark. - */ - - if (!initialized) - return; - - gc->waitBackgroundSweepEnd(); - - for (auto chunk = gc->allNonEmptyChunks(); !chunk.done(); chunk.next()) { - BitmapMap::Ptr ptr = map.lookup(chunk); - if (!ptr) - continue; /* Allocated after we did the non-incremental mark. */ - - ChunkBitmap* bitmap = ptr->value(); - ChunkBitmap* incBitmap = &chunk->bitmap; - - for (size_t i = 0; i < ArenasPerChunk; i++) { - if (chunk->decommittedArenas.get(i)) - continue; - Arena* arena = &chunk->arenas[i]; - if (!arena->allocated()) - continue; - if (!arena->zone->isGCSweeping()) - continue; - if (arena->allocatedDuringIncremental) - continue; - - AllocKind kind = arena->getAllocKind(); - uintptr_t thing = arena->thingsStart(); - uintptr_t end = arena->thingsEnd(); - while (thing < end) { - Cell* cell = (Cell*)thing; - - /* - * If a non-incremental GC wouldn't have collected a cell, then - * an incremental GC won't collect it. - */ - MOZ_ASSERT_IF(bitmap->isMarked(cell, BLACK), incBitmap->isMarked(cell, BLACK)); - - /* - * If the cycle collector isn't allowed to collect an object - * after a non-incremental GC has run, then it isn't allowed to - * collected it after an incremental GC. - */ - MOZ_ASSERT_IF(!bitmap->isMarked(cell, GRAY), !incBitmap->isMarked(cell, GRAY)); - - thing += Arena::thingSize(kind); - } - } - } -} - -#endif // JS_GC_ZEAL - -void -GCRuntime::computeNonIncrementalMarkingForValidation(AutoLockForExclusiveAccess& lock) -{ -#ifdef JS_GC_ZEAL - MOZ_ASSERT(!markingValidator); - if (isIncremental && hasZealMode(ZealMode::IncrementalMarkingValidator)) - markingValidator = js_new<MarkingValidator>(this); - if (markingValidator) - markingValidator->nonIncrementalMark(lock); -#endif -} - -void -GCRuntime::validateIncrementalMarking() -{ -#ifdef JS_GC_ZEAL - if (markingValidator) - markingValidator->validate(); -#endif -} - -void -GCRuntime::finishMarkingValidation() -{ -#ifdef JS_GC_ZEAL - js_delete(markingValidator); - markingValidator = nullptr; -#endif -} - static void DropStringWrappers(JSRuntime* rt) { @@ -4988,8 +4519,6 @@ GCRuntime::beginSweepingZoneGroup(AutoLockForExclusiveAccess& lock) #endif } - validateIncrementalMarking(); - FreeOp fop(rt); SweepAtomsTask sweepAtomsTask(rt); SweepCCWrappersTask sweepCCWrappersTask(rt); @@ -5215,8 +4744,6 @@ GCRuntime::beginSweepPhase(bool destroyingRuntime, AutoLockForExclusiveAccess& l releaseHeldRelocatedArenas(); - computeNonIncrementalMarkingForValidation(lock); - gcstats::AutoPhase ap(stats, gcstats::PHASE_SWEEP); sweepOnBackgroundThread = @@ -5462,8 +4989,6 @@ GCRuntime::endSweepPhase(bool destroyingRuntime, AutoLockForExclusiveAccess& loc rt->setGCGrayBitsValid(true); } - finishMarkingValidation(); - #ifdef DEBUG for (ZonesIter zone(rt, WithAtoms); !zone.done(); zone.next()) { for (auto i : AllAllocKinds()) { @@ -5782,16 +5307,6 @@ AutoGCSlice::~AutoGCSlice() } } -void -GCRuntime::pushZealSelectedObjects() -{ -#ifdef JS_GC_ZEAL - /* Push selected objects onto the mark stack and clear the list. */ - for (JSObject** obj = selectedForMarking.begin(); obj != selectedForMarking.end(); obj++) - TraceManuallyBarrieredEdge(&marker, obj, "selected obj"); -#endif -} - static bool IsShutdownGC(JS::gcreason::Reason reason) { @@ -5817,31 +5332,9 @@ GCRuntime::incrementalCollectSlice(SliceBudget& budget, JS::gcreason::Reason rea gc::State initialState = incrementalState; - bool useZeal = false; -#ifdef JS_GC_ZEAL - if (reason == JS::gcreason::DEBUG_GC && !budget.isUnlimited()) { - /* - * Do the incremental collection type specified by zeal mode if the - * collection was triggered by runDebugGC() and incremental GC has not - * been cancelled by resetIncrementalGC(). - */ - useZeal = true; - } -#endif - MOZ_ASSERT_IF(isIncrementalGCInProgress(), isIncremental); isIncremental = !budget.isUnlimited(); - if (useZeal && (hasZealMode(ZealMode::IncrementalRootsThenFinish) || - hasZealMode(ZealMode::IncrementalMarkAllThenFinish))) - { - /* - * Yields between slices occurs at predetermined points in these modes; - * the budget is not used. - */ - budget.makeUnlimited(); - } - switch (incrementalState) { case State::NotActive: initialReason = reason; @@ -5859,14 +5352,8 @@ GCRuntime::incrementalCollectSlice(SliceBudget& budget, JS::gcreason::Reason rea return; } - if (!destroyingRuntime) - pushZealSelectedObjects(); - incrementalState = State::Mark; - if (isIncremental && useZeal && hasZealMode(ZealMode::IncrementalRootsThenFinish)) - break; - MOZ_FALLTHROUGH; case State::Mark: @@ -5895,10 +5382,7 @@ GCRuntime::incrementalCollectSlice(SliceBudget& budget, JS::gcreason::Reason rea * We will need to mark anything new on the stack when we resume, so * we stay in Mark state. */ - if (!lastMarkSlice && isIncremental && - ((initialState == State::Mark && - !(useZeal && hasZealMode(ZealMode::IncrementalRootsThenFinish))) || - (useZeal && hasZealMode(ZealMode::IncrementalMarkAllThenFinish)))) + if (!lastMarkSlice && isIncremental && initialState == State::Mark) { lastMarkSlice = true; break; @@ -5914,13 +5398,6 @@ GCRuntime::incrementalCollectSlice(SliceBudget& budget, JS::gcreason::Reason rea if (budget.isOverBudget()) break; - /* - * Always yield here when running in incremental multi-slice zeal - * mode, so RunDebugGC can reset the slice buget. - */ - if (isIncremental && useZeal && hasZealMode(ZealMode::IncrementalMultipleSlices)) - break; - MOZ_FALLTHROUGH; case State::Sweep: @@ -6202,11 +5679,6 @@ GCRuntime::gcCycle(bool nonincrementalByAPI, SliceBudget& budget, JS::gcreason:: chunkAllocationSinceLastGC = false; -#ifdef JS_GC_ZEAL - /* Keeping these around after a GC is dangerous. */ - clearSelectedForMarking(); -#endif - /* Clear gcMallocBytes for all zones. */ for (ZonesIter zone(rt, WithAtoms); !zone.done(); zone.next()) zone->resetGCMallocBytes(); @@ -6218,23 +5690,6 @@ GCRuntime::gcCycle(bool nonincrementalByAPI, SliceBudget& budget, JS::gcreason:: return false; } -#ifdef JS_GC_ZEAL -static bool -IsDeterministicGCReason(JS::gcreason::Reason reason) -{ - if (reason > JS::gcreason::DEBUG_GC && - reason != JS::gcreason::CC_FORCED && reason != JS::gcreason::SHUTDOWN_CC) - { - return false; - } - - if (reason == JS::gcreason::EAGER_ALLOC_TRIGGER) - return false; - - return true; -} -#endif - gcstats::ZoneGCStats GCRuntime::scanZonesBeforeGC() { @@ -6300,11 +5755,6 @@ GCRuntime::checkIfGCAllowedInCurrentState(JS::gcreason::Reason reason) if (rt->isBeingDestroyed() && !IsShutdownGC(reason)) return false; -#ifdef JS_GC_ZEAL - if (deterministicOnly && !IsDeterministicGCReason(reason)) - return false; -#endif - return true; } @@ -6319,7 +5769,6 @@ GCRuntime::collect(bool nonincrementalByAPI, SliceBudget budget, JS::gcreason::R return; AutoTraceLog logGC(TraceLoggerForMainThread(rt), TraceLogger_GC); - AutoStopVerifyingBarriers av(rt, IsShutdownGC(reason)); AutoEnqueuePendingParseTasksAfterGC aept(*this); AutoScheduleZonesForGC asz(rt); @@ -6360,13 +5809,6 @@ GCRuntime::collect(bool nonincrementalByAPI, SliceBudget budget, JS::gcreason::R if (reason == JS::gcreason::COMPARTMENT_REVIVED) maybeDoCycleCollection(); - -#ifdef JS_GC_ZEAL - if (rt->hasZealMode(ZealMode::CheckHeapAfterGC)) { - gcstats::AutoPhase ap(rt->gc.stats, gcstats::PHASE_TRACE_HEAP); - CheckHeapAfterGC(rt); - } -#endif } js::AutoEnqueuePendingParseTasksAfterGC::~AutoEnqueuePendingParseTasksAfterGC() @@ -6442,7 +5884,6 @@ GCRuntime::abortGC() checkCanCallAPI(); MOZ_ASSERT(!rt->mainThread.suppressGC); - AutoStopVerifyingBarriers av(rt, false); AutoEnqueuePendingParseTasksAfterGC aept(*this); gcstats::AutoGCSlice agc(stats, scanZonesBeforeGC(), invocationKind, @@ -6460,17 +5901,6 @@ GCRuntime::notifyDidPaint() { MOZ_ASSERT(CurrentThreadCanAccessRuntime(rt)); -#ifdef JS_GC_ZEAL - if (hasZealMode(ZealMode::FrameVerifierPre)) - verifyPreBarriers(); - - if (hasZealMode(ZealMode::FrameGC)) { - JS::PrepareForFullGC(rt->contextFromMainThread()); - gc(GC_NORMAL, JS::gcreason::REFRESH_FRAME); - return; - } -#endif - if (isIncrementalGCInProgress() && !interFrameGC && tunables.areRefreshFrameSlicesEnabled()) { JS::PrepareForIncrementalGC(rt->contextFromMainThread()); gcSlice(JS::gcreason::REFRESH_FRAME); @@ -6566,11 +5996,6 @@ GCRuntime::minorGC(JS::gcreason::Reason reason, gcstats::Phase phase) blocksToFreeAfterMinorGC.freeAll(); -#ifdef JS_GC_ZEAL - if (rt->hasZealMode(ZealMode::CheckHeapAfterGC)) - CheckHeapAfterGC(rt); -#endif - { AutoLockGC lock(rt); for (ZonesIter zone(rt, WithAtoms); !zone.done(); zone.next()) @@ -6754,92 +6179,12 @@ gc::MergeCompartments(JSCompartment* source, JSCompartment* target) } void -GCRuntime::runDebugGC() -{ -#ifdef JS_GC_ZEAL - if (rt->mainThread.suppressGC) - return; - - if (hasZealMode(ZealMode::GenerationalGC)) - return minorGC(JS::gcreason::DEBUG_GC); - - PrepareForDebugGC(rt); - - auto budget = SliceBudget::unlimited(); - if (hasZealMode(ZealMode::IncrementalRootsThenFinish) || - hasZealMode(ZealMode::IncrementalMarkAllThenFinish) || - hasZealMode(ZealMode::IncrementalMultipleSlices)) - { - js::gc::State initialState = incrementalState; - if (hasZealMode(ZealMode::IncrementalMultipleSlices)) { - /* - * Start with a small slice limit and double it every slice. This - * ensure that we get multiple slices, and collection runs to - * completion. - */ - if (!isIncrementalGCInProgress()) - incrementalLimit = zealFrequency / 2; - else - incrementalLimit *= 2; - budget = SliceBudget(WorkBudget(incrementalLimit)); - } else { - // This triggers incremental GC but is actually ignored by IncrementalMarkSlice. - budget = SliceBudget(WorkBudget(1)); - } - - if (!isIncrementalGCInProgress()) - invocationKind = GC_SHRINK; - collect(false, budget, JS::gcreason::DEBUG_GC); - - /* - * For multi-slice zeal, reset the slice size when we get to the sweep - * or compact phases. - */ - if (hasZealMode(ZealMode::IncrementalMultipleSlices)) { - if ((initialState == State::Mark && incrementalState == State::Sweep) || - (initialState == State::Sweep && incrementalState == State::Compact)) - { - incrementalLimit = zealFrequency / 2; - } - } - } else if (hasZealMode(ZealMode::Compact)) { - gc(GC_SHRINK, JS::gcreason::DEBUG_GC); - } else { - gc(GC_NORMAL, JS::gcreason::DEBUG_GC); - } - -#endif -} - -void GCRuntime::setFullCompartmentChecks(bool enabled) { MOZ_ASSERT(!rt->isHeapMajorCollecting()); fullCompartmentChecks = enabled; } -#ifdef JS_GC_ZEAL -bool -GCRuntime::selectForMarking(JSObject* object) -{ - MOZ_ASSERT(!rt->isHeapMajorCollecting()); - return selectedForMarking.append(object); -} - -void -GCRuntime::clearSelectedForMarking() -{ - selectedForMarking.clearAndFree(); -} - -void -GCRuntime::setDeterministic(bool enabled) -{ - MOZ_ASSERT(!rt->isHeapMajorCollecting()); - deterministicOnly = enabled; -} -#endif - #ifdef DEBUG /* Should only be called manually under gdb */ @@ -7337,7 +6682,7 @@ JS::IsIncrementalGCEnabled(JSContext* cx) JS_PUBLIC_API(bool) JS::IsIncrementalGCInProgress(JSContext* cx) { - return cx->gc.isIncrementalGCInProgress() && !cx->gc.isVerifyPreBarriersEnabled(); + return cx->gc.isIncrementalGCInProgress(); } JS_PUBLIC_API(bool) |