Bug 1300210 - Initialize nsCCUncollectableMarker::sGeneration to 1. r=smaug draft
authorAndrew McCreight <continuation@gmail.com>
Fri, 02 Sep 2016 15:51:05 -0700
changeset 409513 71e90eb8bd370c4b7d5ed7632af4793652d17345
parent 409512 0c1942f069ac2fd8c5d716d7fdc64f78c640ec50
child 530348 ac69183859e853d671ee03890aa7f6430d5e76eb
push id28478
push userbmo:continuation@gmail.com
push dateFri, 02 Sep 2016 23:03:45 +0000
reviewerssmaug
bugs1300210, 1299911
milestone51.0a1
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
dom/base/nsCCUncollectableMarker.cpp
--- 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