Bug 736563 - mark global objects held by live windows black during GC. r=smaug
authorAndrew McCreight <amccreight@mozilla.com>
Tue, 27 Mar 2012 12:22:10 -0700
changeset 93753 bb496ca24eefd6679b0258a00ab01a85cac0aef3
parent 93752 b25f7ea3446005bd980b071f4597bbb4b6953bb4
child 93754 43b9f25a14b08e295151e3a4e7fd7334bba1d1dc
push id886
push userlsblakk@mozilla.com
push dateMon, 04 Jun 2012 19:57:52 +0000
treeherdermozilla-beta@bbd8d5efd6d1 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerssmaug
bugs736563
milestone14.0a1
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 736563 - mark global objects held by live windows black during GC. r=smaug
content/base/src/nsCCUncollectableMarker.cpp
content/base/src/nsCCUncollectableMarker.h
js/xpconnect/src/XPCJSRuntime.cpp
--- a/content/base/src/nsCCUncollectableMarker.cpp
+++ b/content/base/src/nsCCUncollectableMarker.cpp
@@ -373,8 +373,34 @@ nsCCUncollectableMarker::Observe(nsISupp
   if (xulCache) {
     xulCache->MarkInCCGeneration(sGeneration);
   }
 #endif
 
   return NS_OK;
 }
 
+static PLDHashOperator
+TraceActiveWindowGlobal(const PRUint64& aId, nsGlobalWindow*& aWindow, void* aClosure)
+{
+  if (aWindow->GetDocShell() && aWindow->IsOuterWindow()) {
+    if (JSObject* global = aWindow->FastGetGlobalJSObject()) {
+      JSTracer* trc = static_cast<JSTracer *>(aClosure);
+      JS_CALL_OBJECT_TRACER(trc, global, "active window global");
+    }
+  }
+  return PL_DHASH_NEXT;
+}
+
+void
+mozilla::dom::TraceBlackJS(JSTracer* aTrc)
+{
+  if (!nsCCUncollectableMarker::sGeneration) {
+    return;
+  }
+
+  // Mark globals of active windows black.
+  nsGlobalWindow::WindowByIdTable* windowsById =
+    nsGlobalWindow::GetWindowsTable();
+  if (windowsById) {
+    windowsById->Enumerate(TraceActiveWindowGlobal, aTrc);
+  }
+}
--- a/content/base/src/nsCCUncollectableMarker.h
+++ b/content/base/src/nsCCUncollectableMarker.h
@@ -33,16 +33,18 @@
  * the provisions above, a recipient may use your version of this file under
  * the terms of any one of the MPL, the GPL or the LGPL.
  *
  * ***** END LICENSE BLOCK ***** */
 
 #include "nsIObserver.h"
 #include "nsCycleCollectionParticipant.h"
 
+struct JSTracer;
+
 class nsCCUncollectableMarker : public nsIObserver
 {
   NS_DECL_ISUPPORTS
   NS_DECL_NSIOBSERVER
 
   /**
    * Inits a global nsCCUncollectableMarker. Should only be called once.
    */
@@ -51,20 +53,26 @@ class nsCCUncollectableMarker : public n
   /**
    * Checks if we're collecting during a given generation
    */
   static bool InGeneration(PRUint32 aGeneration)
   {
     return aGeneration && aGeneration == sGeneration;
   }
 
-  static bool InGeneration(nsCycleCollectionTraversalCallback &cb,
+  static bool InGeneration(nsCycleCollectionTraversalCallback& aCb,
                            PRUint32 aGeneration)
   {
-    return InGeneration(aGeneration) && !cb.WantAllTraces();
+    return InGeneration(aGeneration) && !aCb.WantAllTraces();
   }
 
   static PRUint32 sGeneration;
 
 private:
   nsCCUncollectableMarker() {}
 
 };
+
+namespace mozilla {
+namespace dom {
+void TraceBlackJS(JSTracer* aTrc);
+}
+}
--- a/js/xpconnect/src/XPCJSRuntime.cpp
+++ b/js/xpconnect/src/XPCJSRuntime.cpp
@@ -342,16 +342,19 @@ void XPCJSRuntime::TraceBlackJS(JSTracer
         XPCAutoLock lock(self->mMapLock);
 
         // XPCJSObjectHolders don't participate in cycle collection, so always
         // trace them here.
         XPCRootSetElem *e;
         for (e = self->mObjectHolderRoots; e; e = e->GetNextRoot())
             static_cast<XPCJSObjectHolder*>(e)->TraceJS(trc);
     }
+
+    dom::TraceBlackJS(trc);
+
 }
 
 // static
 void XPCJSRuntime::TraceGrayJS(JSTracer* trc, void* data)
 {
     XPCJSRuntime* self = (XPCJSRuntime*)data;
 
     // Mark these roots as gray so the CC can walk them later.