stylo: Make Servo_TraverseSubtree and Servo_AssertTreeIsClean output more useful info. r?bholley draft
authorEmilio Cobos Álvarez <emilio@crisal.io>
Fri, 25 Aug 2017 16:38:38 +0200
changeset 653081 832296cf0d86166965cb83e944b263fb461d1392
parent 653080 e61f1b240cac4cdd0dc0c872f84f878479758c57
child 653082 c84a33f918ff9f17a555c8bf98ea85a16d08bdf2
push id76234
push userbmo:emilio+bugs@crisal.io
push dateFri, 25 Aug 2017 14:52:07 +0000
reviewersbholley
milestone57.0a1
stylo: Make Servo_TraverseSubtree and Servo_AssertTreeIsClean output more useful info. r?bholley MozReview-Commit-ID: FqBMdAouFGh
servo/components/style/dom.rs
servo/ports/geckolib/glue.rs
--- a/servo/components/style/dom.rs
+++ b/servo/components/style/dom.rs
@@ -201,28 +201,35 @@ impl<N: TNode> Debug for ShowSubtreeData
     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
         writeln!(f, "DOM Subtree:")?;
         fmt_subtree(f, &|f, n| fmt_with_data_and_primary_values(f, n), self.0, 1)
     }
 }
 
 fn fmt_with_data<N: TNode>(f: &mut fmt::Formatter, n: N) -> fmt::Result {
     if let Some(el) = n.as_element() {
-        write!(f, "{:?} dd={} data={:?}", el, el.has_dirty_descendants(), el.borrow_data())
+        write!(
+            f, "{:?} dd={} aodd={} data={:?}",
+            el,
+            el.has_dirty_descendants(),
+            el.has_animation_only_dirty_descendants(),
+            el.borrow_data(),
+       )
     } else {
         write!(f, "{:?}", n)
     }
 }
 
 fn fmt_with_data_and_primary_values<N: TNode>(f: &mut fmt::Formatter, n: N) -> fmt::Result {
     if let Some(el) = n.as_element() {
         let dd = el.has_dirty_descendants();
+        let aodd = el.has_animation_only_dirty_descendants();
         let data = el.borrow_data();
         let values = data.as_ref().and_then(|d| d.styles.get_primary());
-        write!(f, "{:?} dd={} data={:?} values={:?}", el, dd, &data, values)
+        write!(f, "{:?} dd={} aodd={} data={:?} values={:?}", el, dd, aodd, &data, values)
     } else {
         write!(f, "{:?}", n)
     }
 }
 
 fn fmt_subtree<F, N: TNode>(f: &mut fmt::Formatter, stringify: &F, n: N, indent: u32)
                             -> fmt::Result
     where F: Fn(&mut fmt::Formatter, N) -> fmt::Result
--- a/servo/ports/geckolib/glue.rs
+++ b/servo/ports/geckolib/glue.rs
@@ -255,27 +255,29 @@ fn traverse_subtree(element: GeckoElemen
     }
 }
 
 /// Traverses the subtree rooted at `root` for restyling.
 ///
 /// Returns whether a Gecko post-traversal (to perform lazy frame construction,
 /// or consume any RestyleData, or drop any ElementData) is required.
 #[no_mangle]
-pub extern "C" fn Servo_TraverseSubtree(root: RawGeckoElementBorrowed,
-                                        raw_data: RawServoStyleSetBorrowed,
-                                        snapshots: *const ServoElementSnapshotTable,
-                                        raw_flags: ServoTraversalFlags)
-                                        -> bool {
+pub extern "C" fn Servo_TraverseSubtree(
+    root: RawGeckoElementBorrowed,
+    raw_data: RawServoStyleSetBorrowed,
+    snapshots: *const ServoElementSnapshotTable,
+    raw_flags: ServoTraversalFlags
+) -> bool {
     let traversal_flags = TraversalFlags::from_bits_truncate(raw_flags);
     debug_assert!(!snapshots.is_null());
 
     let element = GeckoElement(root);
 
     debug!("Servo_TraverseSubtree (flags={:?})", traversal_flags);
+    debug!("{:?}", ShowSubtreeData(element.as_node()));
     // It makes no sense to do an animation restyle when we're styling
     // newly-inserted content.
     if !traversal_flags.contains(traversal_flags::UnstyledOnly) {
         let needs_animation_only_restyle =
             element.has_animation_only_dirty_descendants() ||
             element.has_animation_restyle_hints();
 
         if needs_animation_only_restyle {
@@ -3306,16 +3308,18 @@ pub extern "C" fn Servo_AnimationValue_C
 
 #[no_mangle]
 pub extern "C" fn Servo_AssertTreeIsClean(root: RawGeckoElementBorrowed) {
     if !cfg!(feature = "gecko_debug") {
         panic!("Calling Servo_AssertTreeIsClean in release build");
     }
 
     let root = GeckoElement(root);
+    debug!("{:?}", ShowSubtreeData(root.as_node()));
+
     fn assert_subtree_is_clean<'le>(el: GeckoElement<'le>) {
         debug_assert!(!el.has_dirty_descendants() && !el.has_animation_only_dirty_descendants(),
                       "{:?} has still dirty bit {:?} or animation-only dirty bit {:?}",
                       el, el.has_dirty_descendants(), el.has_animation_only_dirty_descendants());
         for child in el.as_node().traversal_children() {
             if let Some(child) = child.as_element() {
                 assert_subtree_is_clean(child);
             }