Bug 1382329 - Part 4: Hold mMonitor while accessing scripts in the write thread. r=erahm, a=jcristau FIREFOX_55_0b13_BUILD1 FIREFOX_55_0b13_RELEASE
authorKris Maglione <maglione.k@gmail.com>
Wed, 19 Jul 2017 14:16:56 -0700
changeset 617206 271221d4286a7641c21f8a13df2987d655f9d3dc
parent 617205 6a2562c3bc90bd6b16f0130294025de86f57fe8c
child 617207 26a85c7ea09f1e65221474e5f35d2fc24235a45d
child 617215 c9dc254f31dacb4c3a5f73c6946436612d2e8d92
child 617771 1113ca66a5261c920cf14567c66746140befab3e
child 617993 821b57122996aec1cc0e53fc8d96012cefba756d
child 618000 d1f3d05eedb92103f406d6ca846303f38996000f
child 618001 75839dee1d25f66b25b8570ad219c3d6221f11a0
child 618041 41b0e827b1c8b189cfd237b232b7da6dfdfbe7c8
child 619885 52b2aac1366175503ed2316be358687decd4445b
push id70980
push userrhelmer@mozilla.com
push dateFri, 28 Jul 2017 05:26:29 +0000
reviewerserahm, jcristau
bugs1382329
milestone55.0
Bug 1382329 - Part 4: Hold mMonitor while accessing scripts in the write thread. r=erahm, a=jcristau MozReview-Commit-ID: 66se8G27sqQ
js/xpconnect/loader/ScriptPreloader.cpp
--- a/js/xpconnect/loader/ScriptPreloader.cpp
+++ b/js/xpconnect/loader/ScriptPreloader.cpp
@@ -267,20 +267,20 @@ ScriptPreloader::Cleanup()
     }
 
     // Wait for any pending parses to finish before clearing the mScripts
     // hashtable, since the parse tasks depend on memory allocated by those
     // scripts.
     {
         MonitorAutoLock mal(mMonitor);
         FinishPendingParses(mal);
+
+        mScripts.Clear();
     }
 
-    mScripts.Clear();
-
     AutoSafeJSAPI jsapi;
     JS_RemoveExtraGCRootsTracer(jsapi.cx(), TraceOp, this);
 
     UnregisterWeakMemoryReporter(this);
 }
 
 void
 ScriptPreloader::InvalidateCache()
@@ -629,16 +629,21 @@ ScriptPreloader::WriteCache()
     if (exists) {
         NS_TRY(cacheFile->Remove(false));
     }
 
     {
         AutoFDClose fd;
         NS_TRY(cacheFile->OpenNSPRFileDesc(PR_WRONLY | PR_CREATE_FILE, 0644, &fd.rwget()));
 
+        // We also need to hold mMonitor while we're touching scripts in
+        // mScripts, or they may be freed before we're done with them.
+        mMonitor.AssertNotCurrentThreadOwns();
+        MonitorAutoLock mal(mMonitor);
+
         nsTArray<CachedScript*> scripts;
         for (auto& script : IterHash(mScripts, Match<ScriptStatus::Saved>())) {
             scripts.AppendElement(script);
         }
 
         // Sort scripts by load time, with async loaded scripts before sync scripts.
         // Since async scripts are always loaded immediately at startup, it helps to
         // have them stored contiguously.