From af2f4da5907fe6a2a982158fe965a0b6c9dfa8ba Mon Sep 17 00:00:00 2001 From: "brendan%mozilla.org" Date: Tue, 16 May 2000 02:44:27 +0000 Subject: [PATCH] Fix GC request debiting to cope with multiple JSContexts on the same thread (39321, r=shaver). git-svn-id: svn://10.0.0.236/trunk@69949 18797224-902f-48f8-a5cc-f745e15eee43 --- mozilla/js/src/jsgc.c | 45 ++++++++++++++++++++++++++++++++++++------- 1 file changed, 38 insertions(+), 7 deletions(-) diff --git a/mozilla/js/src/jsgc.c b/mozilla/js/src/jsgc.c index 6e8b44c2373..06c20a480c5 100644 --- a/mozilla/js/src/jsgc.c +++ b/mozilla/js/src/jsgc.c @@ -787,6 +787,7 @@ js_GC(JSContext *cx) JSBool a_all_clear, f_all_clear; #ifdef JS_THREADSAFE jsword currentThread; + uint32 requestDebit; #endif rt = cx->runtime; @@ -826,10 +827,40 @@ js_GC(JSContext *cx) return; } - /* If we're in a request, indicate, temporarily, that we're inactive. */ - if (cx->requestDepth) { - rt->requestCount--; - JS_NOTIFY_REQUEST_DONE(rt); + /* + * If we're in one or more requests (possibly on more than one context) + * running on the current thread, indicate, temporarily, that all these + * requests are inactive. NB: if cx->thread is 0, then cx is not using + * the request model, and does not contribute to rt->requestCount. + */ + requestDebit = 0; + if (cx->thread) { + /* + * Check all contexts for any with the same thread-id. XXX should we + * keep a sub-list of contexts having the same id? + */ + iter = NULL; + while ((acx = js_ContextIterator(rt, &iter)) != NULL) { + if (acx->thread == cx->thread && acx->requestDepth) + requestDebit++; + } + } else { + /* + * We assert, but check anyway, in case someone is misusing the API. + * Avoiding the loop over all of rt's contexts is a win in the event + * that the GC runs only on request-less contexts with 0 thread-ids, + * in a special thread such as the UI/DOM/Layout "mozilla" or "main" + * thread in Mozilla-the-browser. + */ + JS_ASSERT(cx->requestDepth == 0); + if (cx->requestDepth) + requestDebit = 1; + } + if (requestDebit) { + JS_ASSERT(requestDebit >= rt->requestCount); + rt->requestCount -= requestDebit; + if (rt->requestCount == 0) + JS_NOTIFY_REQUEST_DONE(rt); } /* If another thread is already in GC, don't attempt GC; wait instead. */ @@ -1085,9 +1116,9 @@ out: rt->gcLastBytes = rt->gcBytes; #ifdef JS_THREADSAFE - /* If we were invoked during a request, undo the temporary decrement. */ - if (cx->requestDepth) - rt->requestCount++; + /* If we were invoked during a request, pay back the temporary debit. */ + if (requestDebit) + rt->requestCount += requestDebit; rt->gcThread = 0; JS_NOTIFY_GC_DONE(rt); JS_UNLOCK_GC(rt);