Bug 553671 part 5 - Extract GCUntilDone() from js_GC(). r=gal.

--HG--
extra : rebase_source : 1356bdf760348479248284dd90eb8535895af8f9
This commit is contained in:
Jason Orendorff 2010-04-08 08:01:21 -05:00
parent 08bfa47c56
commit d1526f1df5

View File

@ -2837,7 +2837,7 @@ void dumpGCTimer(GCTimer *gcT, uint64 firstEnter, bool lastGC)
/*
* Common cache invalidation and so forth that must be done before GC. Even if
* js_GC calls GC several times, this work only needs to be done once.
* GCUntilDone calls GC several times, this work only needs to be done once.
*/
static void
PreGCCleanup(JSContext *cx, JSGCInvocationKind gckind)
@ -3117,6 +3117,45 @@ GC(JSContext *cx, JSGCInvocationKind gckind GCTIMER_PARAM)
#endif /* JS_DUMP_LOOP_STATS */
}
/*
* GC, repeatedly if necessary, until we think we have not created any new
* garbage and no other threads are demanding more GC.
*/
static void
GCUntilDone(JSContext *cx, JSGCInvocationKind gckind GCTIMER_PARAM)
{
JSRuntime *rt = cx->runtime;
JS_UNLOCK_GC(rt);
#ifdef JS_TRACER
if (!JS_ON_TRACE(cx))
#endif
{
VOUCH_HAVE_STACK();
PreGCCleanup(cx, gckind);
TIMESTAMP(gcTimer.startMark);
restart:
GC(cx, gckind GCTIMER_ARG);
}
JS_LOCK_GC(rt);
/*
* We want to restart GC if js_GC was called recursively or if any of the
* finalizers called js_RemoveRoot or js_UnlockGCThingRT.
*/
if (!JS_ON_TRACE(cx) && (rt->gcLevel > 1 || rt->gcPoke)) {
VOUCH_HAVE_STACK();
rt->gcLevel = 1;
rt->gcPoke = JS_FALSE;
JS_UNLOCK_GC(rt);
goto restart;
}
}
/*
* Call the GC callback, if any, to signal that GC is starting. Return false if
* the callback vetoes GC.
@ -3400,37 +3439,9 @@ js_GC(JSContext *cx, JSGCInvocationKind gckind)
goto restart_at_beginning;
}
JS_UNLOCK_GC(rt);
#ifdef JS_TRACER
if (!JS_ON_TRACE(cx))
#endif
{
VOUCH_HAVE_STACK();
PreGCCleanup(cx, gckind);
TIMESTAMP(gcTimer.startMark);
restart:
GC(cx, gckind GCTIMER_ARG);
}
JS_LOCK_GC(rt);
/*
* We want to restart GC if js_GC was called recursively or if any of the
* finalizers called js_RemoveRoot or js_UnlockGCThingRT.
*/
if (!JS_ON_TRACE(cx) && (rt->gcLevel > 1 || rt->gcPoke)) {
VOUCH_HAVE_STACK();
rt->gcLevel = 1;
rt->gcPoke = JS_FALSE;
JS_UNLOCK_GC(rt);
goto restart;
}
GCUntilDone(cx, gckind GCTIMER_ARG);
rt->setGCLastBytes(rt->gcBytes);
done_running:
rt->gcLevel = 0;
rt->gcRunning = rt->gcRegenShapes = false;