Bug 975947 - Fix generational GC's interaction with the barrier verifier; r=sfink

This commit is contained in:
Terrence Cole 2014-02-24 15:08:05 -08:00
Родитель 01365b86a7
Коммит d09ef4dcaf
7 изменённых файлов: 38 добавлений и 45 удалений

Просмотреть файл

@ -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();
};
/*

Просмотреть файл

@ -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;

Просмотреть файл

@ -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()
{

Просмотреть файл

@ -368,6 +368,8 @@ typedef HashMap<void *, VerifyNode *, DefaultHasher<void *>, 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);
}
};

Просмотреть файл

@ -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
}

Просмотреть файл

@ -6203,8 +6203,9 @@ main(int argc, char **argv, char **envp)
JS_SetGCParameter(rt, JSGC_MAX_BYTES, 0xffffffff);
#ifdef JSGC_GENERATIONAL
Maybe<JS::AutoDisableGenerationalGC> noggc;
if (op.getBoolOption("no-ggc"))
JS::DisableGenerationalGC(rt);
noggc.construct(rt);
#endif
size_t availMem = op.getIntOption("available-memory");

Просмотреть файл

@ -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;