Bug 1300210 - Initialize nsCCUncollectableMarker::sGeneration to 1. r=smaug
The immediate reason we need to change this is that
bug 1299911
proposes adding a verifier to check that there are no black-gray edges
in the JS heap, and sGeneration being 0 causes that to fail, due to
mozilla::dom::TraceBlackJS(). If something is a black root, I believe
the verifier requires that it be marked black. This makes sense,
because a black root is something that is definitely alive, and if the
object is marked gray, the CC might free it, as far as the GC knows.
This fails because when the browser starts, it GCs and marks the stuff
at the bottom of TraceBlackJS grey. Then it runs the CC, which flips
sGeneration to 1. Now, the verifier runs (before the GC runs!), and it
sees that the stuff in TraceBlackJS claims to be black, but is grey,
causing a verification failure.
In this particular case the code is actually safe. The purpose of the
black-gray invariant is to ensure that the CC does not incorrectly
unlink any gray C++ objects that are reachable from black JS
roots. The JS objects in TraceBlackJS should all be reachable directly
from a C++ object, and the CC knows that those C++ objects are alive
(because of refcounting). Therefore, the CC will not unlink any
objects that are reachable from black JS roots.
MozReview-Commit-ID: 8PrRkjqWBL
--- a/dom/base/nsCCUncollectableMarker.cpp
+++ b/dom/base/nsCCUncollectableMarker.cpp
@@ -35,17 +35,21 @@
#include "nsObserverService.h"
#include "nsFocusManager.h"
#include "nsIInterfaceRequestorUtils.h"
using namespace mozilla;
using namespace mozilla::dom;
static bool sInited = 0;
-uint32_t nsCCUncollectableMarker::sGeneration = 0;
+// The initial value of sGeneration should not be the same as the
+// value it is given at xpcom-shutdown, because this will make any GCs
+// before we first CC benignly violate the black-gray invariant, due
+// to dom::TraceBlackJS().
+uint32_t nsCCUncollectableMarker::sGeneration = 1;
#ifdef MOZ_XUL
#include "nsXULPrototypeCache.h"
#endif
NS_IMPL_ISUPPORTS(nsCCUncollectableMarker, nsIObserver)
/* static */
nsresult