From fee752ae24256502a03d02b33360dc2ff34cda61 Mon Sep 17 00:00:00 2001 From: Andreas Gal Date: Thu, 13 Aug 2009 08:35:35 -0700 Subject: [PATCH] Cleaning code cache flush handling (510136, r=jorendorff). --- js/src/jscntxt.h | 8 ++------ js/src/jstracer.cpp | 42 ++++++++++++++++++++++++++++-------------- 2 files changed, 30 insertions(+), 20 deletions(-) diff --git a/js/src/jscntxt.h b/js/src/jscntxt.h index 2d4dbf31062..62938029c56 100644 --- a/js/src/jscntxt.h +++ b/js/src/jscntxt.h @@ -133,7 +133,6 @@ struct JSTraceMonitor { * last-ditch GC and suppress calls to JS_ReportOutOfMemory. * * !tracecx && !recorder: not on trace - * !tracecx && !recorder && prohibitFlush: deep-bailed * !tracecx && recorder && !recorder->deepAborted: recording * !tracecx && recorder && recorder->deepAborted: deep aborted * tracecx && !recorder: executing a trace @@ -164,17 +163,14 @@ struct JSTraceMonitor { * If nonzero, do not flush the JIT cache after a deep bail. That would * free JITted code pages that we will later return to. Instead, set the * needFlush flag so that it can be flushed later. - * - * NB: needFlush and useReservedObjects are packed together. */ - uintN prohibitFlush; - JSPackedBool needFlush; + JSBool needFlush; /* * reservedObjects is a linked list (via fslots[0]) of preallocated JSObjects. * The JIT uses this to ensure that leaving a trace tree can't fail. */ - JSPackedBool useReservedObjects; + JSBool useReservedObjects; JSObject *reservedObjects; /* Parts for the regular expression compiler. This is logically diff --git a/js/src/jstracer.cpp b/js/src/jstracer.cpp index f46bf7e0f1f..7db2fcb24ec 100644 --- a/js/src/jstracer.cpp +++ b/js/src/jstracer.cpp @@ -3352,6 +3352,32 @@ TraceRecorder::guard(bool expected, LIns* cond, ExitType exitType) guard(expected, cond, snapshot(exitType)); } +/* + * Determine whether any context associated with the same thread as cx is + * executing native code. + */ +static inline bool +ProhibitFlush(JSContext* cx) +{ + if (cx->interpState) // early out if the given is in native code + return true; + + JSCList *cl; + +#ifdef JS_THREADSAFE + JSThread* thread = cx->thread; + for (cl = thread->contextList.next; cl != &thread->contextList; cl = cl->next) + if (CX_FROM_THREAD_LINKS(cl)->interpState) + return true; +#else + JSRuntime* rt = cx->runtime; + for (cl = rt->contextList.next; cl != &rt->contextList; cl = cl->next) + if (js_ContextFromLinkField(cl)->interpState) + return true; +#endif + return false; +} + static JS_REQUIRES_STACK void FlushJITCache(JSContext* cx) { @@ -3369,7 +3395,7 @@ FlushJITCache(JSContext* cx) } Fragmento* fragmento = tm->fragmento; if (fragmento) { - if (tm->prohibitFlush) { + if (ProhibitFlush(cx)) { debug_only_print0(LC_TMTracer, "Deferring fragmento flush due to deep bail.\n"); tm->needFlush = JS_TRUE; return; @@ -5395,10 +5421,6 @@ ExecuteTree(JSContext* cx, Fragment* f, uintN& inlineCallCount, if (!js_ReserveObjects(cx, MAX_CALL_STACK_ENTRIES)) return NULL; -#ifdef DEBUG - uintN savedProhibitFlush = JS_TRACE_MONITOR(cx).prohibitFlush; -#endif - /* Set up the interpreter state block, which is followed by the native global frame. */ InterpState* state = (InterpState*)alloca(sizeof(InterpState) + (globalFrameSize+1)*sizeof(double)); state->cx = cx; @@ -5487,7 +5509,6 @@ ExecuteTree(JSContext* cx, Fragment* f, uintN& inlineCallCount, JS_ASSERT(lr->exitType != LOOP_EXIT || !lr->calldepth); tm->tracecx = NULL; LeaveTree(*state, lr); - JS_ASSERT(JS_TRACE_MONITOR(cx).prohibitFlush == savedProhibitFlush); return state->innermost; } @@ -5623,9 +5644,6 @@ LeaveTree(InterpState& state, VMSideExit* lr) + innermost->sp_adj / sizeof(jsdouble) - i); } } - JSTraceMonitor* tm = &JS_TRACE_MONITOR(cx); - if (tm->prohibitFlush && --tm->prohibitFlush == 0 && tm->needFlush) - FlushJITCache(cx); return; } @@ -6699,10 +6717,7 @@ js_OverfullFragmento(JSTraceMonitor* tm, Fragmento *fragmento) jsuint maxsz = tm->maxCodeCacheBytes; VMAllocator *allocator = tm->allocator; CodeAlloc *codeAlloc = tm->codeAlloc; - if (fragmento == tm->fragmento) { - if (tm->prohibitFlush) - return false; - } else { + if (fragmento == tm->reFragmento) { /* * At the time of making the code cache size configurable, we were using * 16 MB for the main code cache and 1 MB for the regular expression code @@ -6732,7 +6747,6 @@ js_DeepBail(JSContext *cx) JS_ASSERT(tracecx->bailExit); tm->tracecx = NULL; - tm->prohibitFlush++; debug_only_print0(LC_TMTracer, "Deep bail.\n"); LeaveTree(*tracecx->interpState, tracecx->bailExit); tracecx->bailExit = NULL;