GC the RuleTree when the Stylist is dropped. r=emilio
draft
GC the RuleTree when the Stylist is dropped. r=emilio
We only consider doing a GC currently if the root node has a zero refcount.
But that only happens if it has no children -- even weak children keep a
strong reference to their parent. So at the very least, we should do a
GC specifically when the RuleTree is going away. (We probably want to add
some other GC opportunities too at some point, otherwise it's easy to
never GC a RuleTree.)
MozReview-Commit-ID: Kb62knhEHL1
--- a/servo/components/style/selector_matching.rs
+++ b/servo/components/style/selector_matching.rs
@@ -619,16 +619,28 @@ impl Stylist {
current_state: ElementState)
-> RestyleHint
where E: ElementExt + Clone
{
self.state_deps.compute_hint(element, snapshot, current_state)
}
}
+impl Drop for Stylist {
+ fn drop(&mut self) {
+ // This is the last chance to GC the rule tree. If we have dropped all
+ // strong rule node references before the Stylist is dropped, then this
+ // will cause the rule tree to be destroyed correctly. If we haven't
+ // dropped all strong rule node references before now, then we will
+ // leak them, since there will be no way to call gc() on the rule tree
+ // after this point.
+ unsafe { self.rule_tree.gc(); }
+ }
+}
+
/// Map that contains the CSS rules for a specific PseudoElement
/// (or lack of PseudoElement).
#[cfg_attr(feature = "servo", derive(HeapSizeOf))]
struct PerPseudoElementSelectorMap {
/// Rules from user agent stylesheets
user_agent: SelectorMap,
/// Rules from author stylesheets