Bug 1358056. Fix stylesheet handling of associated documents in various edge cases. r=heycam
authorBoris Zbarsky <bzbarsky@mit.edu>
Mon, 24 Apr 2017 15:44:19 -0400
changeset 354687 38740b783dda69f1888c1d8f5770b544e1b31dbe
parent 354686 69a988036095290ca01dc47b8e59ef08043f5e14
child 354688 b55e0e4fec2d59f104944777ac6a5e124faa205e
push id31709
push userihsiao@mozilla.com
push dateTue, 25 Apr 2017 03:21:59 +0000
treeherdermozilla-central@85932a5027c0 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersheycam
bugs1358056
milestone55.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 1358056. Fix stylesheet handling of associated documents in various edge cases. r=heycam
layout/style/CSSStyleSheet.cpp
layout/style/StyleSheet.cpp
--- a/layout/style/CSSStyleSheet.cpp
+++ b/layout/style/CSSStyleSheet.cpp
@@ -1026,17 +1026,17 @@ CSSStyleSheet::ReparseSheet(const nsAStr
     }
   }
 
   // nuke child sheets list and current namespace map
   for (StyleSheet* child = GetFirstChild(); child; ) {
     NS_ASSERTION(child->mParent == this, "Child sheet is not parented to this!");
     StyleSheet* next = child->mNext;
     child->mParent = nullptr;
-    child->mDocument = nullptr;
+    child->SetAssociatedDocument(nullptr, NotOwnedByDocument);
     child->mNext = nullptr;
     child = next;
   }
   SheetInfo().mFirstChild = nullptr;
   Inner()->mNameSpaceMap = nullptr;
 
   uint32_t lineNumber = 1;
   if (mOwningNode) {
--- a/layout/style/StyleSheet.cpp
+++ b/layout/style/StyleSheet.cpp
@@ -80,17 +80,22 @@ StyleSheet::UnlinkInner()
   // don't want to do any addrefing in the process, just to make sure
   // we don't confuse the cycle collector (though on the face of it,
   // addref/release pairs during unlink should probably be ok).
   RefPtr<StyleSheet> child;
   child.swap(SheetInfo().mFirstChild);
   while (child) {
     MOZ_ASSERT(child->mParent == this, "We have a unique inner!");
     child->mParent = nullptr;
-    child->mDocument = nullptr;
+    // We (and child) might still think we're owned by a document, because
+    // unlink order is non-deterministic, so the document's unlink, which would
+    // tell us it does't own us anymore, may not have happened yet.  But if
+    // we're being unlinked, clearly we're not owned by a document anymore
+    // conceptually!
+    child->SetAssociatedDocument(nullptr, NotOwnedByDocument);
 
     RefPtr<StyleSheet> next;
     // Null out child->mNext, but don't let it die yet
     next.swap(child->mNext);
     // Switch to looking at the old value of child->mNext next iteration
     child.swap(next);
     // "next" is now our previous value of child; it'll get released
     // as we loop around.
@@ -499,16 +504,19 @@ StyleSheet::UnparentChildren()
 {
   // XXXbz this is a little bogus; see the XXX comment where we
   // declare mFirstChild in StyleSheetInfo.
   for (StyleSheet* child = GetFirstChild();
        child;
        child = child->mNext) {
     if (child->mParent == this) {
       child->mParent = nullptr;
+      MOZ_ASSERT(child->mDocumentAssociationMode == NotOwnedByDocument,
+                 "How did we get to the destructor, exactly, if we're owned "
+                 "by a document?");
       child->mDocument = nullptr;
     }
   }
 }
 
 void
 StyleSheet::SubjectSubsumesInnerPrincipal(nsIPrincipal& aSubjectPrincipal,
                                           ErrorResult& aRv)
@@ -609,17 +617,17 @@ StyleSheet::AppendStyleSheet(StyleSheet*
   while (*tail) {
     tail = &(*tail)->mNext;
   }
   *tail = aSheet;
 
   // This is not reference counted. Our parent tells us when
   // it's going away.
   aSheet->mParent = this;
-  aSheet->mDocument = mDocument;
+  aSheet->SetAssociatedDocument(mDocument, mDocumentAssociationMode);
   DidDirty();
 }
 
 size_t
 StyleSheet::SizeOfIncludingThis(MallocSizeOf aMallocSizeOf) const
 {
   size_t n = 0;
   const StyleSheet* s = this;