mirror of
https://repo.dactyloidae.xyz/Dactyloidae/UXP.git
synced 2026-09-03 22:38:41 +09:00
Remove remaining conditional GCZeal code.
Creates stubs: jsgc.h/cpp VerifyBarriers() stub MaybeVerifyBarriers() stub GCRuntime::computeNonIncrementalMarkingForValidation() stub GCRuntime::validateIncrementalMarking() stub GCRuntime::finishMarkingValidation() stub GCRuntime::pushZealSelectedObjects() stub bool useZeal? GCRuntime::runDebugGC() stub XPConnect: nsXPCComponents_Utils::SetGCZeal() stub (always NS_OK)
This commit is contained in:
parent
97a0673483
commit
b5de790f2a
20 changed files with 4 additions and 832 deletions
595
js/src/jsgc.cpp
595
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;
|
||||
|
|
@ -2635,7 +2473,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 +2886,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 +2908,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 +3241,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,290 +3886,19 @@ 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
|
||||
|
|
@ -5785,11 +5332,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
|
||||
|
|
@ -5818,16 +5360,6 @@ 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();
|
||||
|
|
@ -6202,11 +5734,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 +5745,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 +5810,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;
|
||||
}
|
||||
|
||||
|
|
@ -6360,13 +5865,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()
|
||||
|
|
@ -6460,17 +5958,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 +6053,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())
|
||||
|
|
@ -6756,59 +6238,6 @@ 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
|
||||
|
|
@ -6818,28 +6247,6 @@ GCRuntime::setFullCompartmentChecks(bool enabled)
|
|||
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 */
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue