diff --git a/js/public/GCAPI.h b/js/public/GCAPI.h index 55e766093776..29b24f05569d 100644 --- a/js/public/GCAPI.h +++ b/js/public/GCAPI.h @@ -307,37 +307,22 @@ WasIncrementalGC(JSRuntime *rt); /* * Generational GC: * - * Note: Generational GC is not yet enabled by default. The following functions - * are non-functional unless SpiderMonkey was configured with + * Note: Generational GC is not yet enabled by default. The following class + * is non-functional unless SpiderMonkey was configured with * --enable-gcgenerational. */ -/* - * Generational GC is enabled by default. Use this method to disable it. - */ -extern JS_FRIEND_API(void) -DisableGenerationalGC(JSRuntime *rt); - -/* - * Generational GC may be re-enabled at runtime. - */ -extern JS_FRIEND_API(void) -EnableGenerationalGC(JSRuntime *rt); - /* Ensure that generational GC is disabled within some scope. */ class JS_FRIEND_API(AutoDisableGenerationalGC) { JSRuntime *runtime; +#ifdef JS_GC_ZEAL + bool restartVerifier; +#endif public: - AutoDisableGenerationalGC(JSRuntime *rt) - : runtime(rt) - { - DisableGenerationalGC(rt); - } - ~AutoDisableGenerationalGC() { - EnableGenerationalGC(runtime); - } + AutoDisableGenerationalGC(JSRuntime *rt); + ~AutoDisableGenerationalGC(); }; /* diff --git a/js/src/gc/GCInternals.h b/js/src/gc/GCInternals.h index 2445f45f3f4a..2fcb99808309 100644 --- a/js/src/gc/GCInternals.h +++ b/js/src/gc/GCInternals.h @@ -126,7 +126,7 @@ class AutoStopVerifyingBarriers public: AutoStopVerifyingBarriers(JSRuntime *rt, bool isShutdown - MOZ_GUARD_OBJECT_NOTIFIER_PARAM) + MOZ_GUARD_OBJECT_NOTIFIER_PARAM) : runtime(rt) { restartPreVerifier = !isShutdown && rt->gcVerifyPreData; diff --git a/js/src/gc/RootMarking.cpp b/js/src/gc/RootMarking.cpp index 3f8bb47dadd9..f0fb83a4fd89 100644 --- a/js/src/gc/RootMarking.cpp +++ b/js/src/gc/RootMarking.cpp @@ -263,6 +263,7 @@ MarkWordConservatively(JSTracer *trc, uintptr_t w) MarkIfGCThingWord(trc, w); } +#ifndef JSGC_USE_EXACT_ROOTING MOZ_ASAN_BLACKLIST static void MarkRangeConservatively(JSTracer *trc, const uintptr_t *begin, const uintptr_t *end) @@ -272,7 +273,6 @@ MarkRangeConservatively(JSTracer *trc, const uintptr_t *begin, const uintptr_t * MarkWordConservatively(trc, *i); } -#ifndef JSGC_USE_EXACT_ROOTING static void MarkRangeConservativelyAndSkipIon(JSTracer *trc, JSRuntime *rt, const uintptr_t *begin, const uintptr_t *end) { @@ -343,8 +343,6 @@ MarkConservativeStackRoots(JSTracer *trc, bool useSavedRoots) ArrayEnd(cgcd->registerSnapshot.words)); } -#endif /* JSGC_USE_EXACT_ROOTING */ - void js::MarkStackRangeConservatively(JSTracer *trc, Value *beginv, Value *endv) { @@ -363,6 +361,8 @@ js::MarkStackRangeConservatively(JSTracer *trc, Value *beginv, Value *endv) #endif } +#endif /* JSGC_USE_EXACT_ROOTING */ + MOZ_NEVER_INLINE void ConservativeGCData::recordStackTop() { diff --git a/js/src/gc/Verifier.cpp b/js/src/gc/Verifier.cpp index 0d035a5b2e0e..36a43edd5db8 100644 --- a/js/src/gc/Verifier.cpp +++ b/js/src/gc/Verifier.cpp @@ -368,6 +368,8 @@ typedef HashMap, SystemAllocPolicy> */ struct VerifyPreTracer : JSTracer { + JS::AutoDisableGenerationalGC noggc; + /* The gcNumber when the verification began. */ uint64_t number; @@ -381,13 +383,10 @@ struct VerifyPreTracer : JSTracer char *term; NodeMap nodemap; - VerifyPreTracer(JSRuntime *rt) : root(nullptr) { - JS::DisableGenerationalGC(rt); - } + VerifyPreTracer(JSRuntime *rt) : noggc(rt), root(nullptr) {} ~VerifyPreTracer() { js_free(root); - JS::EnableGenerationalGC(runtime); } }; diff --git a/js/src/jsfriendapi.cpp b/js/src/jsfriendapi.cpp index 51e29b156d13..39090d284145 100644 --- a/js/src/jsfriendapi.cpp +++ b/js/src/jsfriendapi.cpp @@ -930,11 +930,18 @@ JS::DisableIncrementalGC(JSRuntime *rt) rt->gcIncrementalEnabled = false; } -extern JS_FRIEND_API(void) -JS::DisableGenerationalGC(JSRuntime *rt) +JS::AutoDisableGenerationalGC::AutoDisableGenerationalGC(JSRuntime *rt) + : runtime(rt) +#ifdef JS_GC_ZEAL + , restartVerifier(rt->gcVerifyPostData) +#endif { #ifdef JSGC_GENERATIONAL if (IsGenerationalGCEnabled(rt)) { +#ifdef JS_GC_ZEAL + if (restartVerifier) + gc::EndVerifyPostBarriers(rt); +#endif MinorGC(rt, JS::gcreason::API); rt->gcNursery.disable(); rt->gcStoreBuffer.disable(); @@ -943,15 +950,18 @@ JS::DisableGenerationalGC(JSRuntime *rt) ++rt->gcGenerationalDisabled; } -extern JS_FRIEND_API(void) -JS::EnableGenerationalGC(JSRuntime *rt) +JS::AutoDisableGenerationalGC::~AutoDisableGenerationalGC() { - JS_ASSERT(rt->gcGenerationalDisabled > 0); - --rt->gcGenerationalDisabled; + JS_ASSERT(runtime->gcGenerationalDisabled > 0); + --runtime->gcGenerationalDisabled; #ifdef JSGC_GENERATIONAL - if (IsGenerationalGCEnabled(rt)) { - rt->gcNursery.enable(); - rt->gcStoreBuffer.enable(); + if (runtime->gcGenerationalDisabled == 0) { + runtime->gcNursery.enable(); + runtime->gcStoreBuffer.enable(); +#ifdef JS_GC_ZEAL + if (restartVerifier) + gc::StartVerifyPostBarriers(runtime); +#endif } #endif } diff --git a/js/src/shell/js.cpp b/js/src/shell/js.cpp index 85f45be52166..17f0fc29f00b 100644 --- a/js/src/shell/js.cpp +++ b/js/src/shell/js.cpp @@ -6203,8 +6203,9 @@ main(int argc, char **argv, char **envp) JS_SetGCParameter(rt, JSGC_MAX_BYTES, 0xffffffff); #ifdef JSGC_GENERATIONAL + Maybe noggc; if (op.getBoolOption("no-ggc")) - JS::DisableGenerationalGC(rt); + noggc.construct(rt); #endif size_t availMem = op.getIntOption("available-memory"); diff --git a/js/src/shell/jsheaptools.cpp b/js/src/shell/jsheaptools.cpp index 35737b56ff24..45b7eddd3ebf 100644 --- a/js/src/shell/jsheaptools.cpp +++ b/js/src/shell/jsheaptools.cpp @@ -155,15 +155,11 @@ class HeapReverser : public JSTracer, public JS::CustomAutoRooter /* Construct a HeapReverser for |context|'s heap. */ HeapReverser(JSContext *cx) : JS::CustomAutoRooter(cx), + noggc(JS_GetRuntime(cx)), runtime(JS_GetRuntime(cx)), parent(nullptr) { JS_TracerInit(this, runtime, traverseEdgeWithThis); - JS::DisableGenerationalGC(runtime); - } - - ~HeapReverser() { - JS::EnableGenerationalGC(runtime); } bool init() { return map.init(); } @@ -172,6 +168,8 @@ class HeapReverser : public JSTracer, public JS::CustomAutoRooter bool reverseHeap(); private: + JS::AutoDisableGenerationalGC noggc; + /* A runtime pointer for use by the destructor. */ JSRuntime *runtime;