mirror of
https://repo.dactyloidae.xyz/Dactyloidae/UXP.git
synced 2026-09-04 14:58:37 +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
|
|
@ -231,21 +231,6 @@ GC(JSContext *cx,
|
|||
return true;
|
||||
}
|
||||
|
||||
#ifdef JS_GC_ZEAL
|
||||
static bool
|
||||
GCZeal(JSContext *cx, unsigned argc, JS::Value *vp)
|
||||
{
|
||||
CallArgs args = CallArgsFromVp(argc, vp);
|
||||
|
||||
uint32_t zeal;
|
||||
if (!ToUint32(cx, args.get(0), &zeal))
|
||||
return false;
|
||||
|
||||
JS_SetGCZeal(cx, uint8_t(zeal), JS_DEFAULT_ZEAL_FREQ);
|
||||
return true;
|
||||
}
|
||||
#endif
|
||||
|
||||
const JSFunctionSpec gGlobalFunctions[] =
|
||||
{
|
||||
JS_FS("print", Print, 0,0),
|
||||
|
|
@ -255,9 +240,6 @@ const JSFunctionSpec gGlobalFunctions[] =
|
|||
JS_FS("dumpXPC", DumpXPC, 1,0),
|
||||
JS_FS("dump", Dump, 1,0),
|
||||
JS_FS("gc", GC, 0,0),
|
||||
#ifdef JS_GC_ZEAL
|
||||
JS_FS("gczeal", GCZeal, 1,0),
|
||||
#endif
|
||||
JS_FS_END
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -51,10 +51,6 @@ class CompileRuntime
|
|||
// &runtime()->activation_
|
||||
const void* addressOfActivation();
|
||||
|
||||
#ifdef JS_GC_ZEAL
|
||||
const void* addressOfGCZealModeBits();
|
||||
#endif
|
||||
|
||||
const void* addressOfInterruptUint32();
|
||||
|
||||
// We have to bake JSContext* into JIT code, but this pointer shouldn't be
|
||||
|
|
|
|||
|
|
@ -627,11 +627,7 @@ PostWriteElementBarrier(JSRuntime* rt, JSObject* obj, int32_t index)
|
|||
if (obj->is<NativeObject>() &&
|
||||
!obj->as<NativeObject>().isInWholeCellBuffer() &&
|
||||
uint32_t(index) < obj->as<NativeObject>().getDenseInitializedLength() &&
|
||||
(obj->as<NativeObject>().getDenseInitializedLength() > MAX_WHOLE_CELL_BUFFER_SIZE
|
||||
#ifdef JS_GC_ZEAL
|
||||
|| rt->hasZealMode(gc::ZealMode::ElementsBarrier)
|
||||
#endif
|
||||
))
|
||||
(obj->as<NativeObject>().getDenseInitializedLength() > MAX_WHOLE_CELL_BUFFER_SIZE))
|
||||
{
|
||||
rt->gc.storeBuffer.putSlot(&obj->as<NativeObject>(), HeapSlot::Element, index, 1);
|
||||
return;
|
||||
|
|
|
|||
|
|
@ -38,10 +38,6 @@
|
|||
/* Define to 1 if SpiderMonkey should include ctypes support. */
|
||||
#undef JS_HAS_CTYPES
|
||||
|
||||
/* Define to 1 if SpiderMonkey should support the ability to perform
|
||||
entirely too much GC. */
|
||||
#undef JS_GC_ZEAL
|
||||
|
||||
/* Define to 1 if SpiderMonkey should use small chunks. */
|
||||
#undef JS_GC_SMALL_CHUNK_SIZE
|
||||
|
||||
|
|
|
|||
|
|
@ -94,36 +94,6 @@ BEGIN_TEST(testGCFinalizeCallback)
|
|||
CHECK(checkFinalizeStatus());
|
||||
CHECK(checkFinalizeIsZoneGC(true));
|
||||
|
||||
#ifdef JS_GC_ZEAL
|
||||
|
||||
/* Full GC with reset due to new zone, becoming zone GC. */
|
||||
|
||||
FinalizeCalls = 0;
|
||||
JS_SetGCZeal(cx, 9, 1000000);
|
||||
JS::PrepareForFullGC(cx);
|
||||
js::SliceBudget budget(js::WorkBudget(1));
|
||||
cx->gc.startDebugGC(GC_NORMAL, budget);
|
||||
CHECK(cx->gc.state() == js::gc::State::Mark);
|
||||
CHECK(cx->gc.isFullGc());
|
||||
|
||||
JS::RootedObject global4(cx, createTestGlobal());
|
||||
budget = js::SliceBudget(js::WorkBudget(1));
|
||||
cx->gc.debugGCSlice(budget);
|
||||
while (cx->gc.isIncrementalGCInProgress())
|
||||
cx->gc.debugGCSlice(budget);
|
||||
CHECK(!cx->gc.isIncrementalGCInProgress());
|
||||
CHECK(!cx->gc.isFullGc());
|
||||
CHECK(checkMultipleGroups());
|
||||
CHECK(checkFinalizeStatus());
|
||||
|
||||
for (unsigned i = 0; i < FinalizeCalls - 1; ++i)
|
||||
CHECK(!IsZoneGCBuffer[i]);
|
||||
CHECK(IsZoneGCBuffer[FinalizeCalls - 1]);
|
||||
|
||||
JS_SetGCZeal(cx, 0, 0);
|
||||
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Make some use of the globals here to ensure the compiler doesn't optimize
|
||||
* them away in release builds, causing the zones to be collected and
|
||||
|
|
|
|||
|
|
@ -40,10 +40,6 @@ JSFunction* CreateGCThing(JSContext* cx)
|
|||
|
||||
BEGIN_TEST(testGCHeapPostBarriers)
|
||||
{
|
||||
#ifdef JS_GC_ZEAL
|
||||
AutoLeaveZeal nozeal(cx);
|
||||
#endif /* JS_GC_ZEAL */
|
||||
|
||||
/* Sanity check - objects start in the nursery and then become tenured. */
|
||||
JS_GC(cx);
|
||||
JS::RootedObject obj(cx, CreateGCThing<JSObject>(cx));
|
||||
|
|
|
|||
|
|
@ -101,10 +101,6 @@ class CCWTestTracer : public JS::CallbackTracer {
|
|||
|
||||
BEGIN_TEST(testTracingIncomingCCWs)
|
||||
{
|
||||
#ifdef JS_GC_ZEAL
|
||||
// Disable zeal modes because this test needs to control exactly when the GC happens.
|
||||
JS_SetGCZeal(cx, 0, 100);
|
||||
#endif
|
||||
JS_GC(cx);
|
||||
|
||||
JS::RootedObject global1(cx, JS::CurrentGlobalOrNull(cx));
|
||||
|
|
@ -146,10 +142,6 @@ countWrappers(JSCompartment* comp)
|
|||
|
||||
BEGIN_TEST(testDeadNurseryCCW)
|
||||
{
|
||||
#ifdef JS_GC_ZEAL
|
||||
// Disable zeal modes because this test needs to control exactly when the GC happens.
|
||||
JS_SetGCZeal(cx, 0, 100);
|
||||
#endif
|
||||
JS_GC(cx);
|
||||
|
||||
JS::RootedObject global1(cx, JS::CurrentGlobalOrNull(cx));
|
||||
|
|
@ -177,10 +169,6 @@ END_TEST(testDeadNurseryCCW)
|
|||
|
||||
BEGIN_TEST(testLiveNurseryCCW)
|
||||
{
|
||||
#ifdef JS_GC_ZEAL
|
||||
// Disable zeal modes because this test needs to control exactly when the GC happens.
|
||||
JS_SetGCZeal(cx, 0, 100);
|
||||
#endif
|
||||
JS_GC(cx);
|
||||
|
||||
JS::RootedObject global1(cx, JS::CurrentGlobalOrNull(cx));
|
||||
|
|
@ -208,10 +196,6 @@ END_TEST(testLiveNurseryCCW)
|
|||
|
||||
BEGIN_TEST(testLiveNurseryWrapperCCW)
|
||||
{
|
||||
#ifdef JS_GC_ZEAL
|
||||
// Disable zeal modes because this test needs to control exactly when the GC happens.
|
||||
JS_SetGCZeal(cx, 0, 100);
|
||||
#endif
|
||||
JS_GC(cx);
|
||||
|
||||
JS::RootedObject global1(cx, JS::CurrentGlobalOrNull(cx));
|
||||
|
|
@ -244,10 +228,6 @@ END_TEST(testLiveNurseryWrapperCCW)
|
|||
|
||||
BEGIN_TEST(testLiveNurseryWrappeeCCW)
|
||||
{
|
||||
#ifdef JS_GC_ZEAL
|
||||
// Disable zeal modes because this test needs to control exactly when the GC happens.
|
||||
JS_SetGCZeal(cx, 0, 100);
|
||||
#endif
|
||||
JS_GC(cx);
|
||||
|
||||
JS::RootedObject global1(cx, JS::CurrentGlobalOrNull(cx));
|
||||
|
|
@ -280,11 +260,6 @@ BEGIN_TEST(testIncrementalRoots)
|
|||
{
|
||||
JSRuntime* rt = cx->runtime();
|
||||
|
||||
#ifdef JS_GC_ZEAL
|
||||
// Disable zeal modes because this test needs to control exactly when the GC happens.
|
||||
JS_SetGCZeal(cx, 0, 100);
|
||||
#endif
|
||||
|
||||
// Construct a big object graph to mark. In JS, the resulting object graph
|
||||
// is equivalent to:
|
||||
//
|
||||
|
|
|
|||
|
|
@ -23,10 +23,6 @@ MinimizeHeap(JSContext* cx)
|
|||
|
||||
BEGIN_TEST(testGCUID)
|
||||
{
|
||||
#ifdef JS_GC_ZEAL
|
||||
AutoLeaveZeal nozeal(cx);
|
||||
#endif /* JS_GC_ZEAL */
|
||||
|
||||
uint64_t uid = 0;
|
||||
uint64_t tmp = 0;
|
||||
|
||||
|
|
|
|||
|
|
@ -418,39 +418,4 @@ class TestJSPrincipals : public JSPrincipals
|
|||
}
|
||||
};
|
||||
|
||||
#ifdef JS_GC_ZEAL
|
||||
/*
|
||||
* Temporarily disable the GC zeal setting. This is only useful in tests that
|
||||
* need very explicit GC behavior and should not be used elsewhere.
|
||||
*/
|
||||
class AutoLeaveZeal
|
||||
{
|
||||
JSContext* cx_;
|
||||
uint32_t zealBits_;
|
||||
uint32_t frequency_;
|
||||
|
||||
public:
|
||||
explicit AutoLeaveZeal(JSContext* cx) : cx_(cx) {
|
||||
uint32_t dummy;
|
||||
JS_GetGCZealBits(cx_, &zealBits_, &frequency_, &dummy);
|
||||
JS_SetGCZeal(cx_, 0, 0);
|
||||
JS::PrepareForFullGC(cx_);
|
||||
JS::GCForReason(cx_, GC_SHRINK, JS::gcreason::DEBUG_GC);
|
||||
}
|
||||
~AutoLeaveZeal() {
|
||||
for (size_t i = 0; i < sizeof(zealBits_) * 8; i++) {
|
||||
if (zealBits_ & (1 << i))
|
||||
JS_SetGCZeal(cx_, i, frequency_);
|
||||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
uint32_t zealBitsAfter, frequencyAfter, dummy;
|
||||
JS_GetGCZealBits(cx_, &zealBitsAfter, &frequencyAfter, &dummy);
|
||||
MOZ_ASSERT(zealBitsAfter == zealBits_);
|
||||
MOZ_ASSERT(frequencyAfter == frequency_);
|
||||
#endif
|
||||
}
|
||||
};
|
||||
#endif /* JS_GC_ZEAL */
|
||||
|
||||
#endif /* jsapi_tests_tests_h */
|
||||
|
|
|
|||
|
|
@ -6263,26 +6263,6 @@ JS_AbortIfWrongThread(JSContext* cx)
|
|||
MOZ_CRASH();
|
||||
}
|
||||
|
||||
#ifdef JS_GC_ZEAL
|
||||
JS_PUBLIC_API(void)
|
||||
JS_GetGCZealBits(JSContext* cx, uint32_t* zealBits, uint32_t* frequency, uint32_t* nextScheduled)
|
||||
{
|
||||
cx->runtime()->gc.getZealBits(zealBits, frequency, nextScheduled);
|
||||
}
|
||||
|
||||
JS_PUBLIC_API(void)
|
||||
JS_SetGCZeal(JSContext* cx, uint8_t zeal, uint32_t frequency)
|
||||
{
|
||||
cx->gc.setZeal(zeal, frequency);
|
||||
}
|
||||
|
||||
JS_PUBLIC_API(void)
|
||||
JS_ScheduleGC(JSContext* cx, uint32_t count)
|
||||
{
|
||||
cx->runtime()->gc.setNextScheduled(count);
|
||||
}
|
||||
#endif
|
||||
|
||||
JS_PUBLIC_API(void)
|
||||
JS_SetParallelParsingEnabled(JSContext* cx, bool enabled)
|
||||
{
|
||||
|
|
|
|||
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 */
|
||||
|
|
|
|||
|
|
@ -1264,19 +1264,6 @@ enum VerifierType {
|
|||
PreBarrierVerifier
|
||||
};
|
||||
|
||||
#ifdef JS_GC_ZEAL
|
||||
|
||||
extern const char* ZealModeHelpText;
|
||||
|
||||
/* Check that write barriers have been used correctly. See jsgc.cpp. */
|
||||
void
|
||||
VerifyBarriers(JSRuntime* rt, VerifierType type);
|
||||
|
||||
void
|
||||
MaybeVerifyBarriers(JSContext* cx, bool always = false);
|
||||
|
||||
#else
|
||||
|
||||
static inline void
|
||||
VerifyBarriers(JSRuntime* rt, VerifierType type)
|
||||
{
|
||||
|
|
@ -1287,8 +1274,6 @@ MaybeVerifyBarriers(JSContext* cx, bool always = false)
|
|||
{
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Instances of this class set the |JSRuntime::suppressGC| flag for the duration
|
||||
* that they are live. Use of this class is highly discouraged. Please carefully
|
||||
|
|
|
|||
|
|
@ -22,7 +22,7 @@
|
|||
#include "js/TraceKind.h"
|
||||
#include "js/TypeDecls.h"
|
||||
|
||||
#if defined(JS_GC_ZEAL) || defined(DEBUG)
|
||||
#if defined(DEBUG)
|
||||
# define JSGC_HASH_TABLE_CHECKS
|
||||
#endif
|
||||
|
||||
|
|
|
|||
|
|
@ -368,7 +368,7 @@ Poison(void* ptr, uint8_t value, size_t num)
|
|||
#endif
|
||||
|
||||
/* Enable poisoning in crash-diagnostics and zeal builds. */
|
||||
#if defined(JS_CRASH_DIAGNOSTICS) || defined(JS_GC_ZEAL)
|
||||
#if defined(JS_CRASH_DIAGNOSTICS)
|
||||
# define JS_POISON(p, val, size) Poison(p, val, size)
|
||||
#else
|
||||
# define JS_POISON(p, val, size) ((void) 0)
|
||||
|
|
|
|||
|
|
@ -1805,17 +1805,6 @@ if test -n "$MOZ_DEBUG"; then
|
|||
AC_DEFINE(JS_DEBUG)
|
||||
fi
|
||||
|
||||
dnl ========================================================
|
||||
dnl Zealous JavaScript GC
|
||||
dnl ========================================================
|
||||
MOZ_ARG_ENABLE_BOOL(gczeal,
|
||||
[ --enable-gczeal Enable zealous GCing],
|
||||
JS_GC_ZEAL=1,
|
||||
JS_GC_ZEAL= )
|
||||
if test -n "$JS_GC_ZEAL" -o -n "$MOZ_DEBUG"; then
|
||||
AC_DEFINE(JS_GC_ZEAL)
|
||||
fi
|
||||
|
||||
dnl ========================================================
|
||||
dnl Enable breakpoint for artificial OOMs
|
||||
dnl ========================================================
|
||||
|
|
|
|||
|
|
@ -323,10 +323,6 @@ static bool enableNativeRegExp = false;
|
|||
static bool enableUnboxedArrays = false;
|
||||
static bool enableSharedMemory = SHARED_MEMORY_DEFAULT;
|
||||
static bool enableWasmAlwaysBaseline = false;
|
||||
#ifdef JS_GC_ZEAL
|
||||
static uint32_t gZealBits = 0;
|
||||
static uint32_t gZealFrequency = 0;
|
||||
#endif
|
||||
static bool printTiming = false;
|
||||
static const char* jsCacheDir = nullptr;
|
||||
static const char* jsCacheAsmJSPath = nullptr;
|
||||
|
|
@ -7517,16 +7513,6 @@ SetContextOptions(JSContext* cx, const OptionParser& op)
|
|||
dumpEntrainedVariables = op.getBoolOption("dump-entrained-variables");
|
||||
#endif
|
||||
|
||||
#ifdef JS_GC_ZEAL
|
||||
const char* zealStr = op.getStringOption("gc-zeal");
|
||||
if (zealStr) {
|
||||
if (!cx->gc.parseAndSetZeal(zealStr))
|
||||
return false;
|
||||
uint32_t nextScheduled;
|
||||
cx->gc.getZealBits(&gZealBits, &gZealFrequency, &nextScheduled);
|
||||
}
|
||||
#endif
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
@ -7544,16 +7530,6 @@ SetWorkerContextOptions(JSContext* cx)
|
|||
cx->setOffthreadIonCompilationEnabled(offthreadCompilation);
|
||||
cx->profilingScripts = enableCodeCoverage || enableDisassemblyDumps;
|
||||
|
||||
#ifdef JS_GC_ZEAL
|
||||
if (gZealBits && gZealFrequency) {
|
||||
#define ZEAL_MODE(_, value) \
|
||||
if (gZealBits & (1 << value)) \
|
||||
cx->gc.setZeal(value, gZealFrequency);
|
||||
JS_FOR_EACH_ZEAL_MODE(ZEAL_MODE)
|
||||
#undef ZEAL_MODE
|
||||
}
|
||||
#endif
|
||||
|
||||
JS_SetNativeStackQuota(cx, gMaxStackSize);
|
||||
}
|
||||
|
||||
|
|
@ -7838,9 +7814,6 @@ main(int argc, char** argv, char** envp)
|
|||
"NUMBER of instructions.", -1)
|
||||
#endif
|
||||
|| !op.addIntOption('\0', "nursery-size", "SIZE-MB", "Set the maximum nursery size in MB", 16)
|
||||
#ifdef JS_GC_ZEAL
|
||||
|| !op.addStringOption('z', "gc-zeal", "LEVEL(;LEVEL)*[,N]", gc::ZealModeHelpText)
|
||||
#endif
|
||||
|| !op.addStringOption('\0', "module-load-path", "DIR", "Set directory to load modules from")
|
||||
)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -930,9 +930,6 @@ class DebugEnvironments
|
|||
void mark(JSTracer* trc);
|
||||
void sweep(JSRuntime* rt);
|
||||
void finish();
|
||||
#ifdef JS_GC_ZEAL
|
||||
void checkHashTablesAfterMovingGC(JSRuntime* rt);
|
||||
#endif
|
||||
|
||||
// If a live frame has a synthesized entry in missingEnvs, make sure it's not
|
||||
// collected.
|
||||
|
|
|
|||
|
|
@ -3007,9 +3007,6 @@ GENERATE_JSCONTEXTOPTION_GETTER_SETTER(Ion, ion, setIon)
|
|||
NS_IMETHODIMP
|
||||
nsXPCComponents_Utils::SetGCZeal(int32_t aValue, JSContext* cx)
|
||||
{
|
||||
#ifdef JS_GC_ZEAL
|
||||
JS_SetGCZeal(cx, uint8_t(aValue), JS_DEFAULT_ZEAL_FREQ);
|
||||
#endif
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1473,16 +1473,6 @@ ReloadPrefsCallback(const char* pref, void* data)
|
|||
sExtraWarningsForSystemJS = Preferences::GetBool(JS_OPTIONS_DOT_STR "strict.debug");
|
||||
#endif
|
||||
|
||||
#ifdef JS_GC_ZEAL
|
||||
int32_t zeal = Preferences::GetInt(JS_OPTIONS_DOT_STR "gczeal", -1);
|
||||
int32_t zeal_frequency =
|
||||
Preferences::GetInt(JS_OPTIONS_DOT_STR "gczeal.frequency",
|
||||
JS_DEFAULT_ZEAL_FREQ);
|
||||
if (zeal >= 0) {
|
||||
JS_SetGCZeal(cx, (uint8_t)zeal, zeal_frequency);
|
||||
}
|
||||
#endif // JS_GC_ZEAL
|
||||
|
||||
JS::ContextOptionsRef(cx).setBaseline(useBaseline)
|
||||
.setIon(useIon)
|
||||
.setAsmJS(useAsmJS)
|
||||
|
|
|
|||
|
|
@ -440,21 +440,6 @@ GC(JSContext* cx, unsigned argc, Value* vp)
|
|||
return true;
|
||||
}
|
||||
|
||||
#ifdef JS_GC_ZEAL
|
||||
static bool
|
||||
GCZeal(JSContext* cx, unsigned argc, Value* vp)
|
||||
{
|
||||
CallArgs args = CallArgsFromVp(argc, vp);
|
||||
uint32_t zeal;
|
||||
if (!ToUint32(cx, args.get(0), &zeal))
|
||||
return false;
|
||||
|
||||
JS_SetGCZeal(cx, uint8_t(zeal), JS_DEFAULT_ZEAL_FREQ);
|
||||
args.rval().setUndefined();
|
||||
return true;
|
||||
}
|
||||
#endif
|
||||
|
||||
static bool
|
||||
SendCommand(JSContext* cx, unsigned argc, Value* vp)
|
||||
{
|
||||
|
|
@ -652,9 +637,6 @@ static const JSFunctionSpec glob_functions[] = {
|
|||
JS_FS("dumpXPC", DumpXPC, 1,0),
|
||||
JS_FS("dump", Dump, 1,0),
|
||||
JS_FS("gc", GC, 0,0),
|
||||
#ifdef JS_GC_ZEAL
|
||||
JS_FS("gczeal", GCZeal, 1,0),
|
||||
#endif
|
||||
JS_FS("options", Options, 0,0),
|
||||
JS_FS("sendCommand", SendCommand, 1,0),
|
||||
JS_FS("atob", xpc::Atob, 1,0),
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue