bug 586161 - making sure that all compartments are purged. r=anygregor
authorIgor Bukanov <igor@mir2.org>
Mon, 27 Sep 2010 14:29:01 +0200
changeset 54730 95f5f23e16aff9371c6599ce73852515073ce3e7
parent 54729 d680172d578f60dc2c6bcb5113002e7577cb9051
child 54731 e005076ad7984354bbfe104970456d8fe119de93
push id16011
push userrsayre@mozilla.com
push dateWed, 29 Sep 2010 06:01:57 +0000
treeherdermozilla-central@d7e659b4f80c [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersanygregor
bugs586161
milestone2.0b7pre
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
bug 586161 - making sure that all compartments are purged. r=anygregor
js/src/jscntxt.cpp
js/src/jscompartment.cpp
js/src/jsgc.cpp
js/src/methodjit/MethodJIT.cpp
js/src/methodjit/MethodJIT.h
js/src/methodjit/MonoIC.cpp
js/src/methodjit/MonoIC.h
--- a/js/src/jscntxt.cpp
+++ b/js/src/jscntxt.cpp
@@ -2195,18 +2195,16 @@ FreeOldArenas(JSRuntime *rt, JSArenaPool
             JS_FreeArenaPool(pool);
     }
 }
 
 void
 JSContext::purge()
 {
     FreeOldArenas(runtime, &regExpPool);
-    /* FIXME: bug 586161 */
-    compartment->purge(this);
 }
 
 void
 JSContext::updateJITEnabled()
 {
 #ifdef JS_TRACER
     traceJitEnabled = ((options & JSOPTION_JIT) &&
                        (debugHooks == &js_NullDebugHooks ||
--- a/js/src/jscompartment.cpp
+++ b/js/src/jscompartment.cpp
@@ -295,21 +295,31 @@ void
 JSCompartment::sweep(JSContext *cx)
 {
     chunk = NULL;
     /* Remove dead wrappers from the table. */
     for (WrapperMap::Enum e(crossCompartmentWrappers); !e.empty(); e.popFront()) {
         if (IsAboutToBeFinalized(e.front().value.toGCThing()))
             e.removeFront();
     }
+
+#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->jit)
+            mjit::ic::SweepCallICs(script);
+    }
+#endif
 }
 
 void
 JSCompartment::purge(JSContext *cx)
 {
+    freeLists.purge();
+
 #ifdef JS_METHODJIT
     for (JSScript *script = (JSScript *)scripts.next;
          &script->links != &scripts;
          script = (JSScript *)script->links.next) {
         if (script->jit) {
 # if defined JS_POLYIC
             mjit::ic::PurgePICs(cx, script);
 # endif
--- a/js/src/jsgc.cpp
+++ b/js/src/jsgc.cpp
@@ -2241,17 +2241,17 @@ PreGCCleanup(JSContext *cx, JSGCInvocati
         || rt->gcZeal >= 1
 #endif
         ) {
         rt->gcRegenShapes = true;
         rt->shapeGen = Shape::LAST_RESERVED_SHAPE;
         rt->protoHazardShape = 0;
     }
     for (JSCompartment **c = rt->compartments.begin(); c != rt->compartments.end(); ++c)
-        (*c)->freeLists.purge();
+        (*c)->purge(cx);
 
     js_PurgeThreads(cx);
     {
         JSContext *iter = NULL;
         while (JSContext *acx = js_ContextIterator(rt, JS_TRUE, &iter))
             acx->purge();
     }
 }
@@ -2332,21 +2332,16 @@ MarkAndSweep(JSContext *cx, JSGCInvocati
     rt->liveObjectPropsPreSweep = rt->liveObjectProps;
 #endif
 
 #ifdef JS_TRACER
     for (ThreadDataIter i(rt); !i.empty(); i.popFront())
         i.threadData()->traceMonitor.sweep();
 #endif
 
-#ifdef JS_METHODJIT
-    /* Fix-up call ICs guarding against unreachable objects. */
-    mjit::SweepCallICs(cx);
-#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/methodjit/MethodJIT.cpp
+++ b/js/src/methodjit/MethodJIT.cpp
@@ -865,33 +865,16 @@ mjit::ReleaseScriptCode(JSContext *cx, J
 
         // The recompiler may call ReleaseScriptCode, in which case it
         // will get called again when the script is destroyed, so we
         // must protect against calling ReleaseScriptCode twice.
         script->jit = NULL;
     }
 }
 
-void
-mjit::SweepCallICs(JSContext *cx)
-{
-#ifdef JS_MONOIC
-    JSRuntime *rt = cx->runtime;
-    for (size_t i = 0; i < rt->compartments.length(); i++) {
-        JSCompartment *compartment = rt->compartments[i];
-        for (JSScript *script = (JSScript *)compartment->scripts.next;
-             &script->links != &compartment->scripts;
-             script = (JSScript *)script->links.next) {
-            if (script->jit)
-                ic::SweepCallICs(cx, script);
-        }
-    }
-#endif
-}
-
 #ifdef JS_METHODJIT_PROFILE_STUBS
 void JS_FASTCALL
 mjit::ProfileStubCall(VMFrame &f)
 {
     JSOp op = JSOp(*f.regs.pc);
     StubCallsForOp[op]++;
 }
 #endif
--- a/js/src/methodjit/MethodJIT.h
+++ b/js/src/methodjit/MethodJIT.h
@@ -199,19 +199,16 @@ void JS_FASTCALL
 ProfileStubCall(VMFrame &f);
 
 CompileStatus JS_NEVER_INLINE
 TryCompile(JSContext *cx, JSScript *script, JSFunction *fun, JSObject *scopeChain);
 
 void
 ReleaseScriptCode(JSContext *cx, JSScript *script);
 
-void
-SweepCallICs(JSContext *cx);
-
 static inline CompileStatus
 CanMethodJIT(JSContext *cx, JSScript *script, JSFunction *fun, JSObject *scopeChain)
 {
     if (!cx->methodJitEnabled || script->ncode == JS_UNJITTABLE_METHOD)
         return Compile_Abort;
     if (script->ncode == NULL)
         return TryCompile(cx, script, fun, scopeChain);
     return Compile_Okay;
--- a/js/src/methodjit/MonoIC.cpp
+++ b/js/src/methodjit/MonoIC.cpp
@@ -727,17 +727,17 @@ ic::PurgeMICs(JSContext *cx, JSScript *s
           default:
             JS_NOT_REACHED("Unknown MIC type during purge");
             break;
         }
     }
 }
 
 void
-ic::SweepCallICs(JSContext *cx, JSScript *script)
+ic::SweepCallICs(JSScript *script)
 {
     for (uint32 i = 0; i < script->jit->nCallICs; i++) {
         ic::CallICInfo &ic = script->callICs[i];
 
         /*
          * If the object is unreachable, we're guaranteed not to be currently
          * executing a stub generated by a guard on that object. This lets us
          * precisely GC call ICs while keeping the identity guard safe.
--- a/js/src/methodjit/MonoIC.h
+++ b/js/src/methodjit/MonoIC.h
@@ -188,16 +188,16 @@ struct CallICInfo {
 };
 
 void * JS_FASTCALL New(VMFrame &f, uint32 index);
 void * JS_FASTCALL Call(VMFrame &f, uint32 index);
 void JS_FASTCALL NativeNew(VMFrame &f, uint32 index);
 void JS_FASTCALL NativeCall(VMFrame &f, uint32 index);
 
 void PurgeMICs(JSContext *cx, JSScript *script);
-void SweepCallICs(JSContext *cx, JSScript *script);
+void SweepCallICs(JSScript *script);
 
 } /* namespace ic */
 } /* namespace mjit */
 } /* namespace js */
 
 #endif /* jsjaeger_mono_ic_h__ */