Bug 584860 - TraceMonitor cleanups (r=igor,a=blocker)
authorBill McCloskey <wmccloskey@mozilla.com>
Wed, 29 Dec 2010 17:55:24 -0800
changeset 59734 f66eefcf11ff7f0849bf1912a807314ee549f714
parent 59733 c9682df3daf8f31c3f0d1f8fb4a525d8af9de30b
child 59735 15479f7be9d81edf78e72fe43eab0cf30a64a6b2
push id1
push usershaver@mozilla.com
push dateTue, 04 Jan 2011 17:58:04 +0000
reviewersigor, blocker
bugs584860
milestone2.0b9pre
Bug 584860 - TraceMonitor cleanups (r=igor,a=blocker)
js/src/jscntxt.h
js/src/jscompartment.cpp
js/src/jscompartment.h
js/src/jsfun.cpp
js/src/jsgc.cpp
js/src/jsscript.cpp
js/src/jsscript.h
--- a/js/src/jscntxt.h
+++ b/js/src/jscntxt.h
@@ -959,17 +959,17 @@ struct JSThreadData {
     /* Property cache for faster call/get/set invocation. */
     js::PropertyCache   propertyCache;
 
 #ifdef JS_TRACER
     /* Counts the number of iterations run by a trace. */
     unsigned            iterationCounter;
 
     /* Maximum size of the tracer's code cache before we start flushing. */
-    uint32                  maxCodeCacheBytes;
+    uint32              maxCodeCacheBytes;
 #endif
 
     /* State used by dtoa.c. */
     DtoaState           *dtoaState;
 
     /*
      * A single-entry cache for some base-10 double-to-string conversions.
      * This helps date-format-xparb.js.  It also avoids skewing the results
--- a/js/src/jscompartment.cpp
+++ b/js/src/jscompartment.cpp
@@ -359,16 +359,20 @@ JSCompartment::sweep(JSContext *cx)
                      !IsAboutToBeFinalized(e.front().value.toGCThing()),
                      e.front().key.isString());
         if (IsAboutToBeFinalized(e.front().key.toGCThing()) ||
             IsAboutToBeFinalized(e.front().value.toGCThing())) {
             e.removeFront();
         }
     }
 
+#ifdef JS_TRACER
+    traceMonitor.sweep();
+#endif
+
 #if defined JS_METHODJIT && defined JS_MONOIC
     for (JSCList *cursor = scripts.next; cursor != &scripts; cursor = cursor->next) {
         JSScript *script = reinterpret_cast<JSScript *>(cursor);
         if (script->hasJITCode())
             mjit::ic::SweepCallICs(script);
     }
 #endif
 }
--- a/js/src/jscompartment.h
+++ b/js/src/jscompartment.h
@@ -70,23 +70,23 @@ typedef HashMap<jsbytecode*,
 
 class Oracle;
 
 typedef HashSet<JSScript *,
                 DefaultHasher<JSScript *>,
                 SystemAllocPolicy> TracedScriptSet;
 
 /*
- * Trace monitor. Every JSThread (if JS_THREADSAFE) or JSRuntime (if not
- * JS_THREADSAFE) has an associated trace monitor that keeps track of loop
- * frequencies for all JavaScript code loaded into that runtime.
+ * Trace monitor. Every JSCompartment has an associated trace monitor
+ * that keeps track of loop frequencies for all JavaScript code loaded
+ * into that runtime.
  */
 struct TraceMonitor {
     /*
-     * The context currently executing JIT-compiled code on this thread, or
+     * The context currently executing JIT-compiled code in this compartment, or
      * NULL if none. Among other things, this can in certain cases prevent
      * last-ditch GC and suppress calls to JS_ReportOutOfMemory.
      *
      * !tracecx && !recorder: not on trace
      * !tracecx && recorder: recording
      * tracecx && !recorder: executing a trace
      * tracecx && recorder: executing inner loop, recording outer loop
      */
--- a/js/src/jsfun.cpp
+++ b/js/src/jsfun.cpp
@@ -2055,17 +2055,17 @@ fun_finalize(JSContext *cx, JSObject *ob
         return;
     }
 
     /*
      * Null-check of u.i.script is required since the parser sets interpreted
      * very early.
      */
     if (FUN_INTERPRETED(fun) && fun->u.i.script)
-        js_DestroyScriptFromGC(cx, fun->u.i.script, obj->compartment());
+        js_DestroyScriptFromGC(cx, fun->u.i.script);
 }
 
 int
 JSFunction::sharpSlotBase(JSContext *cx)
 {
 #if JS_HAS_SHARP_VARS
     JSAtom *name = js_Atomize(cx, "#array", 6, 0);
     if (name) {
--- a/js/src/jsgc.cpp
+++ b/js/src/jsgc.cpp
@@ -1736,17 +1736,17 @@ js_DestroyScriptsToGC(JSContext *cx, JSC
 {
     JSScript **listp, *script;
 
     for (size_t i = 0; i != JS_ARRAY_LENGTH(comp->scriptsToGC); ++i) {
         listp = &comp->scriptsToGC[i];
         while ((script = *listp) != NULL) {
             *listp = script->u.nextToGC;
             script->u.nextToGC = NULL;
-            js_DestroyScriptFromGC(cx, script, comp);
+            js_DestroyScriptFromGC(cx, script);
         }
     }
 }
 
 /*
  * This function is called from js_FinishAtomState to force the finalization
  * of the permanently interned strings when cx is not available.
  */
@@ -2172,22 +2172,16 @@ MarkAndSweep(JSContext *cx, JSGCInvocati
     /* Finalize watch points associated with unreachable objects. */
     js_SweepWatchPoints(cx);
 
 #ifdef DEBUG
     /* Save the pre-sweep count of scope-mapped properties. */
     rt->liveObjectPropsPreSweep = rt->liveObjectProps;
 #endif
 
-#ifdef JS_TRACER
-    for (JSCompartment **comp = rt->compartments.begin(); comp != rt->compartments.end(); comp++) {
-        (*comp)->traceMonitor.sweep();
-    }
-#endif
-
     /*
      * We finalize iterators before other objects so the iterator can use the
      * object which properties it enumerates over to finalize the enumeration
      * state. We finalize objects before other GC things to ensure that
      * object's finalizer can access them even if they will be freed.
      */
 
     for (JSCompartment **comp = rt->compartments.begin(); comp != rt->compartments.end(); comp++) {
--- a/js/src/jsscript.cpp
+++ b/js/src/jsscript.cpp
@@ -417,17 +417,17 @@ js_XDRScript(JSXDRState *xdr, JSScript *
 
 #endif /* JS_HAS_XDR */
 
 static void
 script_finalize(JSContext *cx, JSObject *obj)
 {
     JSScript *script = (JSScript *) obj->getPrivate();
     if (script)
-        js_DestroyScriptFromGC(cx, script, obj->compartment());
+        js_DestroyScriptFromGC(cx, script);
 }
 
 static void
 script_trace(JSTracer *trc, JSObject *obj)
 {
     JSScript *script = (JSScript *) obj->getPrivate();
     if (script)
         js_TraceScript(trc, script);
@@ -1213,17 +1213,17 @@ js_CallDestroyScriptHook(JSContext *cx, 
     JSDestroyScriptHook hook;
 
     hook = cx->debugHooks->destroyScriptHook;
     if (hook)
         hook(cx, script, cx->debugHooks->destroyScriptHookData);
 }
 
 static void
-DestroyScript(JSContext *cx, JSScript *script, JSCompartment *comp)
+DestroyScript(JSContext *cx, JSScript *script)
 {
 #ifdef DEBUG
     if (script->isEmpty())
         JS_RUNTIME_UNMETER(cx->runtime, liveEmptyScripts);
     else
         JS_RUNTIME_UNMETER(cx->runtime, liveScripts);
 #endif
 
@@ -1272,39 +1272,39 @@ DestroyScript(JSContext *cx, JSScript *s
 
 #ifdef CHECK_SCRIPT_OWNER
             JS_ASSERT(script->owner == cx->thread);
 #endif
         }
     }
 
 #ifdef JS_TRACER
-    PurgeScriptFragments(&comp->traceMonitor, script);
+    PurgeScriptFragments(&script->compartment->traceMonitor, script);
 #endif
 
 #if defined(JS_METHODJIT)
     mjit::ReleaseScriptCode(cx, script);
 #endif
     JS_REMOVE_LINK(&script->links);
 
     cx->free(script);
 }
 
 void
 js_DestroyScript(JSContext *cx, JSScript *script)
 {
     JS_ASSERT(!cx->runtime->gcRunning);
-    DestroyScript(cx, script, cx->compartment);
+    DestroyScript(cx, script);
 }
 
 void
-js_DestroyScriptFromGC(JSContext *cx, JSScript *script, JSCompartment *comp)
+js_DestroyScriptFromGC(JSContext *cx, JSScript *script)
 {
     JS_ASSERT(cx->runtime->gcRunning);
-    DestroyScript(cx, script, comp);
+    DestroyScript(cx, script);
 }
 
 void
 js_TraceScript(JSTracer *trc, JSScript *script)
 {
     JSAtomMap *map = &script->atomMap;
     MarkAtomRange(trc, map->length, map->vector, "atomMap");
 
--- a/js/src/jsscript.h
+++ b/js/src/jsscript.h
@@ -497,17 +497,17 @@ js_CallDestroyScriptHook(JSContext *cx, 
 extern void
 js_DestroyScript(JSContext *cx, JSScript *script);
 
 /*
  * If data is not null, it indicates that the script could been accessed only
  * from that thread.
  */
 extern void
-js_DestroyScriptFromGC(JSContext *cx, JSScript *script, JSCompartment *comp);
+js_DestroyScriptFromGC(JSContext *cx, JSScript *script);
 
 extern void
 js_TraceScript(JSTracer *trc, JSScript *script);
 
 extern JSBool
 js_NewScriptObject(JSContext *cx, JSScript *script);
 
 /*