Bug 1459688: Properly traverse the stylesheet list of the shadow root. r=smaug
authorEmilio Cobos Álvarez <emilio@crisal.io>
Mon, 07 May 2018 19:11:13 +0200
changeset 417133 3b491d808696692d2f48fb7ff333e579a8312583
parent 417132 139dd5338407becb5bdef2429f41fa758e4b931d
child 417134 6419ce7979bdb0de0b4b7bf194976b703912cb4b
push id33961
push userrgurzau@mozilla.com
push dateMon, 07 May 2018 22:08:28 +0000
treeherdermozilla-central@59005ba3cd3e [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerssmaug
bugs1459688
milestone61.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 1459688: Properly traverse the stylesheet list of the shadow root. r=smaug This is sound because the unlink implementation of the stylesheet drops the preserved wrapper, and there are no strong references back to any node from the stylesheet or any of the non-unlinked members. This almost is the same setup that works for document sheets. We need to account for a double reference in case the sheet is applicable because Servo keeps another reference to it in that case, instead of in the StyleSet / PresShell. Added the testcase as a crashtest, in the hopes that if it regresses leak reporting on automation will catch it. MozReview-Commit-ID: Kcc5oaOvP9A
dom/base/ShadowRoot.cpp
dom/base/crashtests/1459688.html
dom/base/crashtests/crashtests.list
--- a/dom/base/ShadowRoot.cpp
+++ b/dom/base/ShadowRoot.cpp
@@ -18,18 +18,25 @@
 #include "mozilla/StyleSheet.h"
 #include "mozilla/StyleSheetInlines.h"
 
 using namespace mozilla;
 using namespace mozilla::dom;
 
 NS_IMPL_CYCLE_COLLECTION_CLASS(ShadowRoot)
 
-NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(ShadowRoot,
-                                                  DocumentFragment)
+NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(ShadowRoot, DocumentFragment)
+  NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mStyleSheets)
+  for (StyleSheet* sheet : tmp->mStyleSheets) {
+    // mServoStyles keeps another reference to it if applicable.
+    if (sheet->IsApplicable()) {
+      NS_CYCLE_COLLECTION_NOTE_EDGE_NAME(cb, "mServoStyles->sheets[i]");
+      cb.NoteXPCOMChild(sheet);
+    }
+  }
   NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mDOMStyleSheets)
   for (auto iter = tmp->mIdentifierMap.ConstIter(); !iter.Done();
        iter.Next()) {
     iter.Get()->Traverse(&cb);
   }
 NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
 
 NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(ShadowRoot)
new file mode 100644
--- /dev/null
+++ b/dom/base/crashtests/1459688.html
@@ -0,0 +1,6 @@
+<!doctype html>
+<div id="host"></div>
+<script>
+  host.attachShadow({ mode: "open" }).innerHTML = `<style></style>`;
+  host.shadowRoot.styleSheets[0].foobie = host.shadowRoot;
+</script>
--- a/dom/base/crashtests/crashtests.list
+++ b/dom/base/crashtests/crashtests.list
@@ -238,8 +238,9 @@ load 1411473.html
 pref(dom.webcomponents.shadowdom.enabled,false) load 1422931.html
 pref(dom.webcomponents.shadowdom.enabled,true) load 1419799.html
 skip-if(!browserIsRemote) pref(dom.webcomponents.customelements.enabled,true) pref(dom.disable_open_during_load,false) load 1419902.html # skip on non e10s loads, Bug 1419902
 pref(dom.webcomponents.shadowdom.enabled,true) load 1422883.html
 pref(dom.webcomponents.shadowdom.enabled,true) load 1428053.html
 load 1449601.html
 load 1445670.html
 load 1458016.html
+pref(dom.webcomponents.shadowdom.enabled,true) load 1459688.html