mirror of
https://github.com/mozilla/gecko-dev.git
synced 2025-04-02 12:32:55 +00:00
Bug 988486 - Move verifier functions into GCRuntime r=terrence
This commit is contained in:
parent
ff878c9058
commit
f17bd34eff
@ -13,6 +13,12 @@
|
|||||||
#include "js/RootingAPI.h"
|
#include "js/RootingAPI.h"
|
||||||
#include "js/Value.h"
|
#include "js/Value.h"
|
||||||
|
|
||||||
|
namespace js {
|
||||||
|
namespace gc {
|
||||||
|
class GCRuntime;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
typedef enum JSGCMode {
|
typedef enum JSGCMode {
|
||||||
/* Perform only global GCs. */
|
/* Perform only global GCs. */
|
||||||
JSGC_MODE_GLOBAL = 0,
|
JSGC_MODE_GLOBAL = 0,
|
||||||
@ -329,7 +335,7 @@ WasIncrementalGC(JSRuntime *rt);
|
|||||||
/* Ensure that generational GC is disabled within some scope. */
|
/* Ensure that generational GC is disabled within some scope. */
|
||||||
class JS_FRIEND_API(AutoDisableGenerationalGC)
|
class JS_FRIEND_API(AutoDisableGenerationalGC)
|
||||||
{
|
{
|
||||||
JSRuntime *runtime;
|
js::gc::GCRuntime *gc;
|
||||||
#if defined(JSGC_GENERATIONAL) && defined(JS_GC_ZEAL)
|
#if defined(JSGC_GENERATIONAL) && defined(JS_GC_ZEAL)
|
||||||
bool restartVerifier;
|
bool restartVerifier;
|
||||||
#endif
|
#endif
|
||||||
|
@ -91,24 +91,10 @@ IncrementalSafety
|
|||||||
IsIncrementalGCSafe(JSRuntime *rt);
|
IsIncrementalGCSafe(JSRuntime *rt);
|
||||||
|
|
||||||
#ifdef JS_GC_ZEAL
|
#ifdef JS_GC_ZEAL
|
||||||
void
|
|
||||||
StartVerifyPreBarriers(JSRuntime *rt);
|
|
||||||
|
|
||||||
void
|
|
||||||
EndVerifyPreBarriers(JSRuntime *rt);
|
|
||||||
|
|
||||||
void
|
|
||||||
StartVerifyPostBarriers(JSRuntime *rt);
|
|
||||||
|
|
||||||
void
|
|
||||||
EndVerifyPostBarriers(JSRuntime *rt);
|
|
||||||
|
|
||||||
void
|
|
||||||
FinishVerifier(JSRuntime *rt);
|
|
||||||
|
|
||||||
class AutoStopVerifyingBarriers
|
class AutoStopVerifyingBarriers
|
||||||
{
|
{
|
||||||
JSRuntime *runtime;
|
GCRuntime *gc;
|
||||||
bool restartPreVerifier;
|
bool restartPreVerifier;
|
||||||
bool restartPostVerifier;
|
bool restartPostVerifier;
|
||||||
MOZ_DECL_USE_GUARD_OBJECT_NOTIFIER
|
MOZ_DECL_USE_GUARD_OBJECT_NOTIFIER
|
||||||
@ -116,22 +102,19 @@ class AutoStopVerifyingBarriers
|
|||||||
public:
|
public:
|
||||||
AutoStopVerifyingBarriers(JSRuntime *rt, bool isShutdown
|
AutoStopVerifyingBarriers(JSRuntime *rt, bool isShutdown
|
||||||
MOZ_GUARD_OBJECT_NOTIFIER_PARAM)
|
MOZ_GUARD_OBJECT_NOTIFIER_PARAM)
|
||||||
: runtime(rt)
|
: gc(&rt->gc)
|
||||||
{
|
{
|
||||||
restartPreVerifier = !isShutdown && rt->gc.verifyPreData;
|
restartPreVerifier = gc->endVerifyPreBarriers() && !isShutdown;
|
||||||
restartPostVerifier = !isShutdown && rt->gc.verifyPostData && JS::IsGenerationalGCEnabled(rt);
|
restartPostVerifier = gc->endVerifyPostBarriers() && !isShutdown &&
|
||||||
if (rt->gc.verifyPreData)
|
JS::IsGenerationalGCEnabled(rt);
|
||||||
EndVerifyPreBarriers(rt);
|
|
||||||
if (rt->gc.verifyPostData)
|
|
||||||
EndVerifyPostBarriers(rt);
|
|
||||||
MOZ_GUARD_OBJECT_NOTIFIER_INIT;
|
MOZ_GUARD_OBJECT_NOTIFIER_INIT;
|
||||||
}
|
}
|
||||||
|
|
||||||
~AutoStopVerifyingBarriers() {
|
~AutoStopVerifyingBarriers() {
|
||||||
if (restartPreVerifier)
|
if (restartPreVerifier)
|
||||||
StartVerifyPreBarriers(runtime);
|
gc->startVerifyPreBarriers();
|
||||||
if (restartPostVerifier)
|
if (restartPostVerifier)
|
||||||
StartVerifyPostBarriers(runtime);
|
gc->startVerifyPostBarriers();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
#else
|
#else
|
||||||
|
@ -131,6 +131,13 @@ class GCRuntime
|
|||||||
|
|
||||||
void markRuntime(JSTracer *trc, bool useSavedRoots = false);
|
void markRuntime(JSTracer *trc, bool useSavedRoots = false);
|
||||||
|
|
||||||
|
#ifdef JS_GC_ZEAL
|
||||||
|
void verifyPreBarriers();
|
||||||
|
void verifyPostBarriers();
|
||||||
|
void maybeVerifyPreBarriers(bool always);
|
||||||
|
void maybeVerifyPostBarriers(bool always);
|
||||||
|
#endif
|
||||||
|
|
||||||
public:
|
public:
|
||||||
// Internal public interface
|
// Internal public interface
|
||||||
void recordNativeStackTop();
|
void recordNativeStackTop();
|
||||||
@ -179,6 +186,18 @@ class GCRuntime
|
|||||||
|
|
||||||
void setAlwaysPreserveCode() { alwaysPreserveCode = true; }
|
void setAlwaysPreserveCode() { alwaysPreserveCode = true; }
|
||||||
|
|
||||||
|
bool isGenerationalGCEnabled() { return generationalDisabled == 0; }
|
||||||
|
void disableGenerationalGC();
|
||||||
|
void enableGenerationalGC();
|
||||||
|
|
||||||
|
#ifdef JS_GC_ZEAL
|
||||||
|
void startVerifyPreBarriers();
|
||||||
|
bool endVerifyPreBarriers();
|
||||||
|
void startVerifyPostBarriers();
|
||||||
|
bool endVerifyPostBarriers();
|
||||||
|
void finishVerifier();
|
||||||
|
#endif
|
||||||
|
|
||||||
private:
|
private:
|
||||||
// For ArenaLists::allocateFromArenaInline()
|
// For ArenaLists::allocateFromArenaInline()
|
||||||
friend class ArenaLists;
|
friend class ArenaLists;
|
||||||
|
@ -169,9 +169,9 @@ NextNode(VerifyNode *node)
|
|||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
gc::StartVerifyPreBarriers(JSRuntime *rt)
|
gc::GCRuntime::startVerifyPreBarriers()
|
||||||
{
|
{
|
||||||
if (rt->gc.verifyPreData || rt->gc.incrementalState != NO_INCREMENTAL)
|
if (verifyPreData || incrementalState != NO_INCREMENTAL)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -180,7 +180,7 @@ gc::StartVerifyPreBarriers(JSRuntime *rt)
|
|||||||
* starting the pre barrier verifier if the post barrier verifier is already
|
* starting the pre barrier verifier if the post barrier verifier is already
|
||||||
* running.
|
* running.
|
||||||
*/
|
*/
|
||||||
if (rt->gc.verifyPostData)
|
if (verifyPostData)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
MinorGC(rt, JS::gcreason::EVICT_NURSERY);
|
MinorGC(rt, JS::gcreason::EVICT_NURSERY);
|
||||||
@ -190,10 +190,10 @@ gc::StartVerifyPreBarriers(JSRuntime *rt)
|
|||||||
if (!IsIncrementalGCSafe(rt))
|
if (!IsIncrementalGCSafe(rt))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
for (GCChunkSet::Range r(rt->gc.chunkSet.all()); !r.empty(); r.popFront())
|
for (GCChunkSet::Range r(chunkSet.all()); !r.empty(); r.popFront())
|
||||||
r.front()->bitmap.clear();
|
r.front()->bitmap.clear();
|
||||||
|
|
||||||
rt->gc.number++;
|
number++;
|
||||||
|
|
||||||
VerifyPreTracer *trc = js_new<VerifyPreTracer>(rt, JSTraceCallback(nullptr));
|
VerifyPreTracer *trc = js_new<VerifyPreTracer>(rt, JSTraceCallback(nullptr));
|
||||||
if (!trc)
|
if (!trc)
|
||||||
@ -219,10 +219,10 @@ gc::StartVerifyPreBarriers(JSRuntime *rt)
|
|||||||
trc->curnode = MakeNode(trc, nullptr, JSGCTraceKind(0));
|
trc->curnode = MakeNode(trc, nullptr, JSGCTraceKind(0));
|
||||||
|
|
||||||
/* We want MarkRuntime to save the roots to gcSavedRoots. */
|
/* We want MarkRuntime to save the roots to gcSavedRoots. */
|
||||||
rt->gc.incrementalState = MARK_ROOTS;
|
incrementalState = MARK_ROOTS;
|
||||||
|
|
||||||
/* Make all the roots be edges emanating from the root node. */
|
/* Make all the roots be edges emanating from the root node. */
|
||||||
rt->gc.markRuntime(trc);
|
markRuntime(trc);
|
||||||
|
|
||||||
VerifyNode *node;
|
VerifyNode *node;
|
||||||
node = trc->curnode;
|
node = trc->curnode;
|
||||||
@ -245,9 +245,9 @@ gc::StartVerifyPreBarriers(JSRuntime *rt)
|
|||||||
node = NextNode(node);
|
node = NextNode(node);
|
||||||
}
|
}
|
||||||
|
|
||||||
rt->gc.verifyPreData = trc;
|
verifyPreData = trc;
|
||||||
rt->gc.incrementalState = MARK;
|
incrementalState = MARK;
|
||||||
rt->gc.marker.start();
|
marker.start();
|
||||||
|
|
||||||
rt->setNeedsBarrier(true);
|
rt->setNeedsBarrier(true);
|
||||||
for (ZonesIter zone(rt, WithAtoms); !zone.done(); zone.next()) {
|
for (ZonesIter zone(rt, WithAtoms); !zone.done(); zone.next()) {
|
||||||
@ -259,9 +259,9 @@ gc::StartVerifyPreBarriers(JSRuntime *rt)
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
oom:
|
oom:
|
||||||
rt->gc.incrementalState = NO_INCREMENTAL;
|
incrementalState = NO_INCREMENTAL;
|
||||||
js_delete(trc);
|
js_delete(trc);
|
||||||
rt->gc.verifyPreData = nullptr;
|
verifyPreData = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool
|
static bool
|
||||||
@ -316,18 +316,18 @@ AssertMarkedOrAllocated(const EdgeValue &edge)
|
|||||||
MOZ_CRASH();
|
MOZ_CRASH();
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
bool
|
||||||
gc::EndVerifyPreBarriers(JSRuntime *rt)
|
gc::GCRuntime::endVerifyPreBarriers()
|
||||||
{
|
{
|
||||||
|
VerifyPreTracer *trc = (VerifyPreTracer *)verifyPreData;
|
||||||
|
|
||||||
|
if (!trc)
|
||||||
|
return false;
|
||||||
|
|
||||||
JS_ASSERT(!JS::IsGenerationalGCEnabled(rt));
|
JS_ASSERT(!JS::IsGenerationalGCEnabled(rt));
|
||||||
|
|
||||||
AutoPrepareForTracing prep(rt, SkipAtoms);
|
AutoPrepareForTracing prep(rt, SkipAtoms);
|
||||||
|
|
||||||
VerifyPreTracer *trc = (VerifyPreTracer *)rt->gc.verifyPreData;
|
|
||||||
|
|
||||||
if (!trc)
|
|
||||||
return;
|
|
||||||
|
|
||||||
bool compartmentCreated = false;
|
bool compartmentCreated = false;
|
||||||
|
|
||||||
/* We need to disable barriers before tracing, which may invoke barriers. */
|
/* We need to disable barriers before tracing, which may invoke barriers. */
|
||||||
@ -344,11 +344,11 @@ gc::EndVerifyPreBarriers(JSRuntime *rt)
|
|||||||
* We need to bump gcNumber so that the methodjit knows that jitcode has
|
* We need to bump gcNumber so that the methodjit knows that jitcode has
|
||||||
* been discarded.
|
* been discarded.
|
||||||
*/
|
*/
|
||||||
JS_ASSERT(trc->number == rt->gc.number);
|
JS_ASSERT(trc->number == number);
|
||||||
rt->gc.number++;
|
number++;
|
||||||
|
|
||||||
rt->gc.verifyPreData = nullptr;
|
verifyPreData = nullptr;
|
||||||
rt->gc.incrementalState = NO_INCREMENTAL;
|
incrementalState = NO_INCREMENTAL;
|
||||||
|
|
||||||
if (!compartmentCreated && IsIncrementalGCSafe(rt)) {
|
if (!compartmentCreated && IsIncrementalGCSafe(rt)) {
|
||||||
trc->setTraceCallback(CheckEdge);
|
trc->setTraceCallback(CheckEdge);
|
||||||
@ -368,10 +368,11 @@ gc::EndVerifyPreBarriers(JSRuntime *rt)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
rt->gc.marker.reset();
|
marker.reset();
|
||||||
rt->gc.marker.stop();
|
marker.stop();
|
||||||
|
|
||||||
js_delete(trc);
|
js_delete(trc);
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*** Post-Barrier Verifyier ***/
|
/*** Post-Barrier Verifyier ***/
|
||||||
@ -399,24 +400,24 @@ struct VerifyPostTracer : JSTracer
|
|||||||
* important edges were inserted into the storebuffer.
|
* important edges were inserted into the storebuffer.
|
||||||
*/
|
*/
|
||||||
void
|
void
|
||||||
gc::StartVerifyPostBarriers(JSRuntime *rt)
|
gc::GCRuntime::startVerifyPostBarriers()
|
||||||
{
|
{
|
||||||
#ifdef JSGC_GENERATIONAL
|
#ifdef JSGC_GENERATIONAL
|
||||||
if (rt->gc.verifyPostData ||
|
if (verifyPostData ||
|
||||||
rt->gc.incrementalState != NO_INCREMENTAL)
|
incrementalState != NO_INCREMENTAL)
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
MinorGC(rt, JS::gcreason::EVICT_NURSERY);
|
MinorGC(rt, JS::gcreason::EVICT_NURSERY);
|
||||||
|
|
||||||
rt->gc.number++;
|
number++;
|
||||||
|
|
||||||
VerifyPostTracer *trc = js_new<VerifyPostTracer>(rt, JSTraceCallback(nullptr));
|
VerifyPostTracer *trc = js_new<VerifyPostTracer>(rt, JSTraceCallback(nullptr));
|
||||||
if (!trc)
|
if (!trc)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
rt->gc.verifyPostData = trc;
|
verifyPostData = trc;
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -485,21 +486,23 @@ PostVerifierVisitEdge(JSTracer *jstrc, void **thingp, JSGCTraceKind kind)
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
void
|
bool
|
||||||
js::gc::EndVerifyPostBarriers(JSRuntime *rt)
|
js::gc::GCRuntime::endVerifyPostBarriers()
|
||||||
{
|
{
|
||||||
#ifdef JSGC_GENERATIONAL
|
#ifdef JSGC_GENERATIONAL
|
||||||
|
VerifyPostTracer *trc = (VerifyPostTracer *)verifyPostData;
|
||||||
|
if (!trc)
|
||||||
|
return false;
|
||||||
|
|
||||||
VerifyPostTracer::EdgeSet edges;
|
VerifyPostTracer::EdgeSet edges;
|
||||||
AutoPrepareForTracing prep(rt, SkipAtoms);
|
AutoPrepareForTracing prep(rt, SkipAtoms);
|
||||||
|
|
||||||
VerifyPostTracer *trc = (VerifyPostTracer *)rt->gc.verifyPostData;
|
|
||||||
|
|
||||||
/* Visit every entry in the store buffer and put the edges in a hash set. */
|
/* Visit every entry in the store buffer and put the edges in a hash set. */
|
||||||
trc->setTraceCallback(PostVerifierCollectStoreBufferEdges);
|
trc->setTraceCallback(PostVerifierCollectStoreBufferEdges);
|
||||||
if (!edges.init())
|
if (!edges.init())
|
||||||
goto oom;
|
goto oom;
|
||||||
trc->edges = &edges;
|
trc->edges = &edges;
|
||||||
rt->gc.storeBuffer.markAll(trc);
|
storeBuffer.markAll(trc);
|
||||||
|
|
||||||
/* Walk the heap to find any edges not the the |edges| set. */
|
/* Walk the heap to find any edges not the the |edges| set. */
|
||||||
trc->setTraceCallback(PostVerifierVisitEdge);
|
trc->setTraceCallback(PostVerifierVisitEdge);
|
||||||
@ -514,96 +517,100 @@ js::gc::EndVerifyPostBarriers(JSRuntime *rt)
|
|||||||
|
|
||||||
oom:
|
oom:
|
||||||
js_delete(trc);
|
js_delete(trc);
|
||||||
rt->gc.verifyPostData = nullptr;
|
verifyPostData = nullptr;
|
||||||
|
return true;
|
||||||
|
#else
|
||||||
|
return false;
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
/*** Barrier Verifier Scheduling ***/
|
/*** Barrier Verifier Scheduling ***/
|
||||||
|
|
||||||
static void
|
void
|
||||||
VerifyPreBarriers(JSRuntime *rt)
|
gc::GCRuntime::verifyPreBarriers()
|
||||||
{
|
{
|
||||||
if (rt->gc.verifyPreData)
|
if (verifyPreData)
|
||||||
EndVerifyPreBarriers(rt);
|
endVerifyPreBarriers();
|
||||||
else
|
else
|
||||||
StartVerifyPreBarriers(rt);
|
startVerifyPreBarriers();
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
void
|
||||||
VerifyPostBarriers(JSRuntime *rt)
|
gc::GCRuntime::verifyPostBarriers()
|
||||||
{
|
{
|
||||||
if (rt->gc.verifyPostData)
|
if (verifyPostData)
|
||||||
EndVerifyPostBarriers(rt);
|
endVerifyPostBarriers();
|
||||||
else
|
else
|
||||||
StartVerifyPostBarriers(rt);
|
startVerifyPostBarriers();
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
gc::VerifyBarriers(JSRuntime *rt, VerifierType type)
|
gc::VerifyBarriers(JSRuntime *rt, VerifierType type)
|
||||||
{
|
{
|
||||||
if (type == PreBarrierVerifier)
|
if (type == PreBarrierVerifier)
|
||||||
VerifyPreBarriers(rt);
|
rt->gc.verifyPreBarriers();
|
||||||
else
|
else
|
||||||
VerifyPostBarriers(rt);
|
rt->gc.verifyPostBarriers();
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
void
|
||||||
MaybeVerifyPreBarriers(JSRuntime *rt, bool always)
|
gc::GCRuntime::maybeVerifyPreBarriers(bool always)
|
||||||
{
|
{
|
||||||
if (rt->gcZeal() != ZealVerifierPreValue)
|
if (zealMode != ZealVerifierPreValue)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (rt->mainThread.suppressGC)
|
if (rt->mainThread.suppressGC)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (VerifyPreTracer *trc = (VerifyPreTracer *)rt->gc.verifyPreData) {
|
if (VerifyPreTracer *trc = (VerifyPreTracer *)verifyPreData) {
|
||||||
if (++trc->count < rt->gc.zealFrequency && !always)
|
if (++trc->count < zealFrequency && !always)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
EndVerifyPreBarriers(rt);
|
endVerifyPreBarriers();
|
||||||
}
|
}
|
||||||
|
|
||||||
StartVerifyPreBarriers(rt);
|
startVerifyPreBarriers();
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
void
|
||||||
MaybeVerifyPostBarriers(JSRuntime *rt, bool always)
|
gc::GCRuntime::maybeVerifyPostBarriers(bool always)
|
||||||
{
|
{
|
||||||
#ifdef JSGC_GENERATIONAL
|
#ifdef JSGC_GENERATIONAL
|
||||||
if (rt->gcZeal() != ZealVerifierPostValue)
|
if (zealMode != ZealVerifierPostValue)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (rt->mainThread.suppressGC || !rt->gc.storeBuffer.isEnabled())
|
if (rt->mainThread.suppressGC || !storeBuffer.isEnabled())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (VerifyPostTracer *trc = (VerifyPostTracer *)rt->gc.verifyPostData) {
|
if (VerifyPostTracer *trc = (VerifyPostTracer *)verifyPostData) {
|
||||||
if (++trc->count < rt->gc.zealFrequency && !always)
|
if (++trc->count < zealFrequency && !always)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
EndVerifyPostBarriers(rt);
|
endVerifyPostBarriers();
|
||||||
}
|
}
|
||||||
StartVerifyPostBarriers(rt);
|
startVerifyPostBarriers();
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
js::gc::MaybeVerifyBarriers(JSContext *cx, bool always)
|
js::gc::MaybeVerifyBarriers(JSContext *cx, bool always)
|
||||||
{
|
{
|
||||||
MaybeVerifyPreBarriers(cx->runtime(), always);
|
GCRuntime *gc = &cx->runtime()->gc;
|
||||||
MaybeVerifyPostBarriers(cx->runtime(), always);
|
gc->maybeVerifyPreBarriers(always);
|
||||||
|
gc->maybeVerifyPostBarriers(always);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
js::gc::FinishVerifier(JSRuntime *rt)
|
js::gc::GCRuntime::finishVerifier()
|
||||||
{
|
{
|
||||||
if (VerifyPreTracer *trc = (VerifyPreTracer *)rt->gc.verifyPreData) {
|
if (VerifyPreTracer *trc = (VerifyPreTracer *)verifyPreData) {
|
||||||
js_delete(trc);
|
js_delete(trc);
|
||||||
rt->gc.verifyPreData = nullptr;
|
verifyPreData = nullptr;
|
||||||
}
|
}
|
||||||
#ifdef JSGC_GENERATIONAL
|
#ifdef JSGC_GENERATIONAL
|
||||||
if (VerifyPostTracer *trc = (VerifyPostTracer *)rt->gc.verifyPostData) {
|
if (VerifyPostTracer *trc = (VerifyPostTracer *)verifyPostData) {
|
||||||
js_delete(trc);
|
js_delete(trc);
|
||||||
rt->gc.verifyPostData = nullptr;
|
verifyPostData = nullptr;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
@ -928,37 +928,24 @@ JS::DisableIncrementalGC(JSRuntime *rt)
|
|||||||
}
|
}
|
||||||
|
|
||||||
JS::AutoDisableGenerationalGC::AutoDisableGenerationalGC(JSRuntime *rt)
|
JS::AutoDisableGenerationalGC::AutoDisableGenerationalGC(JSRuntime *rt)
|
||||||
: runtime(rt)
|
: gc(&rt->gc)
|
||||||
#if defined(JSGC_GENERATIONAL) && defined(JS_GC_ZEAL)
|
#if defined(JSGC_GENERATIONAL) && defined(JS_GC_ZEAL)
|
||||||
, restartVerifier(rt->gc.verifyPostData)
|
, restartVerifier(false)
|
||||||
#endif
|
#endif
|
||||||
{
|
{
|
||||||
#ifdef JSGC_GENERATIONAL
|
#if defined(JSGC_GENERATIONAL) && defined(JS_GC_ZEAL)
|
||||||
if (IsGenerationalGCEnabled(rt)) {
|
restartVerifier = gc->endVerifyPostBarriers();
|
||||||
#ifdef JS_GC_ZEAL
|
|
||||||
if (restartVerifier)
|
|
||||||
gc::EndVerifyPostBarriers(rt);
|
|
||||||
#endif
|
#endif
|
||||||
MinorGC(rt, JS::gcreason::API);
|
gc->disableGenerationalGC();
|
||||||
rt->gc.nursery.disable();
|
|
||||||
rt->gc.storeBuffer.disable();
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
++rt->gc.generationalDisabled;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
JS::AutoDisableGenerationalGC::~AutoDisableGenerationalGC()
|
JS::AutoDisableGenerationalGC::~AutoDisableGenerationalGC()
|
||||||
{
|
{
|
||||||
JS_ASSERT(runtime->gc.generationalDisabled > 0);
|
gc->enableGenerationalGC();
|
||||||
--runtime->gc.generationalDisabled;
|
#if defined(JSGC_GENERATIONAL) && defined(JS_GC_ZEAL)
|
||||||
#ifdef JSGC_GENERATIONAL
|
if (restartVerifier) {
|
||||||
if (runtime->gc.generationalDisabled == 0) {
|
JS_ASSERT(gc->isGenerationalGCEnabled());
|
||||||
runtime->gc.nursery.enable();
|
gc->startVerifyPostBarriers();
|
||||||
runtime->gc.storeBuffer.enable();
|
|
||||||
#ifdef JS_GC_ZEAL
|
|
||||||
if (restartVerifier)
|
|
||||||
gc::StartVerifyPostBarriers(runtime);
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
@ -966,7 +953,7 @@ JS::AutoDisableGenerationalGC::~AutoDisableGenerationalGC()
|
|||||||
extern JS_FRIEND_API(bool)
|
extern JS_FRIEND_API(bool)
|
||||||
JS::IsGenerationalGCEnabled(JSRuntime *rt)
|
JS::IsGenerationalGCEnabled(JSRuntime *rt)
|
||||||
{
|
{
|
||||||
return rt->gc.generationalDisabled == 0;
|
return rt->gc.isGenerationalGCEnabled();
|
||||||
}
|
}
|
||||||
|
|
||||||
JS_FRIEND_API(bool)
|
JS_FRIEND_API(bool)
|
||||||
|
@ -1244,7 +1244,7 @@ GCRuntime::finish()
|
|||||||
|
|
||||||
#ifdef JS_GC_ZEAL
|
#ifdef JS_GC_ZEAL
|
||||||
/* Free memory associated with GC verification. */
|
/* Free memory associated with GC verification. */
|
||||||
FinishVerifier(rt);
|
finishVerifier();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* Delete all remaining zones. */
|
/* Delete all remaining zones. */
|
||||||
@ -5007,6 +5007,32 @@ GCRuntime::minorGC(JSContext *cx, JS::gcreason::Reason reason)
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
GCRuntime::disableGenerationalGC()
|
||||||
|
{
|
||||||
|
#ifdef JSGC_GENERATIONAL
|
||||||
|
if (isGenerationalGCEnabled()) {
|
||||||
|
minorGC(JS::gcreason::API);
|
||||||
|
nursery.disable();
|
||||||
|
storeBuffer.disable();
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
++rt->gc.generationalDisabled;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
GCRuntime::enableGenerationalGC()
|
||||||
|
{
|
||||||
|
JS_ASSERT(generationalDisabled > 0);
|
||||||
|
--generationalDisabled;
|
||||||
|
#ifdef JSGC_GENERATIONAL
|
||||||
|
if (generationalDisabled == 0) {
|
||||||
|
nursery.enable();
|
||||||
|
storeBuffer.enable();
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
js::gc::GCIfNeeded(JSContext *cx)
|
js::gc::GCIfNeeded(JSContext *cx)
|
||||||
{
|
{
|
||||||
|
@ -311,7 +311,7 @@ class ZoneCellIterUnderGC : public ZoneCellIterImpl
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
/* In debug builds, assert that no allocation occurs while it is live. */
|
/* In debug builds, assert that no allocation occurs. */
|
||||||
class AutoAssertNoAlloc
|
class AutoAssertNoAlloc
|
||||||
{
|
{
|
||||||
#ifdef JS_DEBUG
|
#ifdef JS_DEBUG
|
||||||
@ -335,6 +335,7 @@ class AutoAssertNoAlloc
|
|||||||
public:
|
public:
|
||||||
AutoAssertNoAlloc() {}
|
AutoAssertNoAlloc() {}
|
||||||
AutoAssertNoAlloc(JSRuntime *) {}
|
AutoAssertNoAlloc(JSRuntime *) {}
|
||||||
|
void disallowAlloc(JSRuntime *rt) {}
|
||||||
#endif
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user