style: Inline a bunch of trivial stuff we're paying function calls for in Geckolib. r?xidorn draft
authorEmilio Cobos Álvarez <emilio@crisal.io>
Mon, 21 Aug 2017 09:41:06 +0200
changeset 649744 f9dacd31a4b115736efff857e15ef6c9bd32ae19
parent 649738 ed8fa1ba93f8ad0d981635a5055d4885e3d0b1eb
child 727175 005e83b1f7428a7574a6a087a82024acf1d2bf05
push id75135
push userbmo:emilio+bugs@crisal.io
push dateMon, 21 Aug 2017 08:22:21 +0000
reviewersxidorn
milestone57.0a1
style: Inline a bunch of trivial stuff we're paying function calls for in Geckolib. r?xidorn MozReview-Commit-ID: L7kJ0b7jYJR
servo/components/style/data.rs
servo/components/style/gecko/restyle_damage.rs
servo/components/style/gecko/wrapper.rs
servo/components/style/traversal.rs
servo/components/style/traversal_flags.rs
--- a/servo/components/style/data.rs
+++ b/servo/components/style/data.rs
@@ -67,27 +67,29 @@ impl RestyleData {
             damage: RestyleDamage::empty(),
         }
     }
 
     /// Clear all the restyle state associated with this element.
     ///
     /// FIXME(bholley): The only caller of this should probably just assert that
     /// the hint is empty and call clear_flags_and_damage().
+    #[inline]
     fn clear_restyle_state(&mut self) {
         self.clear_restyle_flags_and_damage();
         self.hint = RestyleHint::empty();
     }
 
     /// Clear restyle flags and damage.
     ///
     /// Note that we don't touch the TRAVERSED_WITHOUT_STYLING bit, which gets
     /// set to the correct value on each traversal. There's no reason anyone
     /// needs to clear it, and clearing it accidentally mid-traversal could
     /// cause incorrect style sharing behavior.
+    #[inline]
     fn clear_restyle_flags_and_damage(&mut self) {
         self.damage = RestyleDamage::empty();
         self.flags = self.flags & TRAVERSED_WITHOUT_STYLING;
     }
 
     /// Returns whether this element or any ancestor is going to be
     /// reconstructed.
     pub fn reconstructed_self_or_ancestor(&self) -> bool {
@@ -119,32 +121,34 @@ impl RestyleData {
     /// Mark this element as restyled, which is useful to know whether we need
     /// to do a post-traversal.
     pub fn set_restyled(&mut self) {
         self.flags.insert(WAS_RESTYLED);
         self.flags.remove(TRAVERSED_WITHOUT_STYLING);
     }
 
     /// Returns true if this element was restyled.
+    #[inline]
     pub fn is_restyle(&self) -> bool {
         self.flags.contains(WAS_RESTYLED)
     }
 
     /// Mark that we traversed this element without computing any style for it.
     pub fn set_traversed_without_styling(&mut self) {
         self.flags.insert(TRAVERSED_WITHOUT_STYLING);
     }
 
     /// Returns whether the element was traversed without computing any style for
     /// it.
     pub fn traversed_without_styling(&self) -> bool {
         self.flags.contains(TRAVERSED_WITHOUT_STYLING)
     }
 
     /// Returns whether this element has been part of a restyle.
+    #[inline]
     pub fn contains_restyle_data(&self) -> bool {
         self.is_restyle() || !self.hint.is_empty() || !self.damage.is_empty()
     }
 }
 
 /// A lazily-allocated list of styles for eagerly-cascaded pseudo-elements.
 ///
 /// We use an Arc so that sharing these styles via the style sharing cache does
@@ -348,16 +352,17 @@ impl ElementData {
             );
             invalidator.invalidate();
             unsafe { element.set_handled_snapshot() }
             debug_assert!(element.handled_snapshot());
         }
     }
 
     /// Returns true if this element has styles.
+    #[inline]
     pub fn has_styles(&self) -> bool {
         self.styles.primary.is_some()
     }
 
     /// Returns the kind of restyling that we're going to need to do on this
     /// element, based of the stored restyle hint.
     pub fn restyle_kind(
         &self,
@@ -424,21 +429,23 @@ impl ElementData {
         debug_assert!(self.has_styles());
         let (important_rules, _custom) =
             self.styles.primary().rules().get_properties_overriding_animations(&guards);
         let (other_important_rules, _custom) = rules.get_properties_overriding_animations(&guards);
         important_rules != other_important_rules
     }
 
     /// Drops any restyle state from the element.
+    #[inline]
     pub fn clear_restyle_state(&mut self) {
         self.restyle.clear_restyle_state();
     }
 
     /// Drops restyle flags and damage from the element.
+    #[inline]
     pub fn clear_restyle_flags_and_damage(&mut self) {
         self.restyle.clear_restyle_flags_and_damage();
     }
 
     /// Measures memory usage.
     #[cfg(feature = "gecko")]
     pub fn malloc_size_of_children_excluding_cvs(&self, state: &mut SizeOfState) -> usize {
         let n = self.styles.malloc_size_of_children_excluding_cvs(state);
--- a/servo/components/style/gecko/restyle_damage.rs
+++ b/servo/components/style/gecko/restyle_damage.rs
@@ -13,31 +13,35 @@ use std::ops::{BitAnd, BitOr, BitOrAssig
 
 /// The representation of Gecko's restyle damage is just a wrapper over
 /// `nsChangeHint`.
 #[derive(Clone, Copy, Debug, PartialEq)]
 pub struct GeckoRestyleDamage(nsChangeHint);
 
 impl GeckoRestyleDamage {
     /// Trivially construct a new `GeckoRestyleDamage`.
+    #[inline]
     pub fn new(raw: nsChangeHint) -> Self {
         GeckoRestyleDamage(raw)
     }
 
     /// Get the inner change hint for this damage.
+    #[inline]
     pub fn as_change_hint(&self) -> nsChangeHint {
         self.0
     }
 
     /// Get an empty change hint, that is (`nsChangeHint(0)`).
+    #[inline]
     pub fn empty() -> Self {
         GeckoRestyleDamage(nsChangeHint(0))
     }
 
     /// Returns whether this restyle damage represents the empty damage.
+    #[inline]
     pub fn is_empty(&self) -> bool {
         self.0 == nsChangeHint(0)
     }
 
     /// Computes the `StyleDifference` (including the appropriate change hint)
     /// given an old style (in the form of a `nsStyleContext`, and a new style
     /// (in the form of `ComputedValues`).
     ///
--- a/servo/components/style/gecko/wrapper.rs
+++ b/servo/components/style/gecko/wrapper.rs
@@ -289,16 +289,17 @@ impl<'ln> TNode for GeckoNode<'ln> {
         let ptr: usize = self.0 as *const _ as usize;
         OpaqueNode(ptr)
     }
 
     fn debug_id(self) -> usize {
         unimplemented!()
     }
 
+    #[inline]
     fn as_element(&self) -> Option<GeckoElement<'ln>> {
         if self.is_element() {
             unsafe { Some(GeckoElement(&*(self.0 as *const _ as *const RawGeckoElement))) }
         } else {
             None
         }
     }
 
@@ -1014,43 +1015,47 @@ impl<'le> TElement for GeckoElement<'le>
     fn each_class<F>(&self, callback: F)
         where F: FnMut(&Atom)
     {
         snapshot_helpers::each_class(self.0,
                                      callback,
                                      Gecko_ClassOrClassList)
     }
 
+    #[inline]
     fn has_snapshot(&self) -> bool {
         self.flags() & (ELEMENT_HAS_SNAPSHOT as u32) != 0
     }
 
+    #[inline]
     fn handled_snapshot(&self) -> bool {
         self.flags() & (ELEMENT_HANDLED_SNAPSHOT as u32) != 0
     }
 
     unsafe fn set_handled_snapshot(&self) {
         debug_assert!(self.get_data().is_some());
         self.set_flags(ELEMENT_HANDLED_SNAPSHOT as u32)
     }
 
+    #[inline]
     fn has_dirty_descendants(&self) -> bool {
         self.flags() & (ELEMENT_HAS_DIRTY_DESCENDANTS_FOR_SERVO as u32) != 0
     }
 
     unsafe fn set_dirty_descendants(&self) {
         debug_assert!(self.get_data().is_some());
         debug!("Setting dirty descendants: {:?}", self);
         self.set_flags(ELEMENT_HAS_DIRTY_DESCENDANTS_FOR_SERVO as u32)
     }
 
     unsafe fn unset_dirty_descendants(&self) {
         self.unset_flags(ELEMENT_HAS_DIRTY_DESCENDANTS_FOR_SERVO as u32)
     }
 
+    #[inline]
     fn has_animation_only_dirty_descendants(&self) -> bool {
         self.flags() & (ELEMENT_HAS_ANIMATION_ONLY_DIRTY_DESCENDANTS_FOR_SERVO as u32) != 0
     }
 
     unsafe fn set_animation_only_dirty_descendants(&self) {
         self.set_flags(ELEMENT_HAS_ANIMATION_ONLY_DIRTY_DESCENDANTS_FOR_SERVO as u32)
     }
 
@@ -1059,21 +1064,23 @@ impl<'le> TElement for GeckoElement<'le>
     }
 
     unsafe fn clear_descendants_bits(&self) {
         self.unset_flags(ELEMENT_HAS_DIRTY_DESCENDANTS_FOR_SERVO as u32 |
                          ELEMENT_HAS_ANIMATION_ONLY_DIRTY_DESCENDANTS_FOR_SERVO as u32 |
                          NODE_DESCENDANTS_NEED_FRAMES as u32)
     }
 
+    #[inline]
     fn is_visited_link(&self) -> bool {
         use element_state::IN_VISITED_STATE;
         self.get_state().intersects(IN_VISITED_STATE)
     }
 
+    #[inline]
     fn is_native_anonymous(&self) -> bool {
         use gecko_bindings::structs::NODE_IS_NATIVE_ANONYMOUS;
         self.flags() & (NODE_IS_NATIVE_ANONYMOUS as u32) != 0
     }
 
     fn implemented_pseudo_element(&self) -> Option<PseudoElement> {
         if !self.is_native_anonymous() {
             return None;
@@ -1091,16 +1098,17 @@ impl<'le> TElement for GeckoElement<'le>
     fn store_children_to_process(&self, _: isize) {
         // This is only used for bottom-up traversal, and is thus a no-op for Gecko.
     }
 
     fn did_process_child(&self) -> isize {
         panic!("Atomic child count not implemented in Gecko");
     }
 
+    #[inline(always)]
     fn get_data(&self) -> Option<&AtomicRefCell<ElementData>> {
         unsafe { self.0.mServoData.get().as_ref() }
     }
 
     unsafe fn ensure_data(&self) -> AtomicRefMut<ElementData> {
         if self.get_data().is_none() {
             debug!("Creating ElementData for {:?}", self);
             let ptr = Box::into_raw(Box::new(AtomicRefCell::new(ElementData::default())));
@@ -1122,16 +1130,17 @@ impl<'le> TElement for GeckoElement<'le>
 
             // Perform a mutable borrow of the data in debug builds. This
             // serves as an assertion that there are no outstanding borrows
             // when we destroy the data.
             debug_assert!({ let _ = data.borrow_mut(); true });
         }
     }
 
+    #[inline]
     fn skip_root_and_item_based_display_fixup(&self) -> bool {
         // We don't want to fix up display values of native anonymous content.
         // Additionally, we want to skip root-based display fixup for document
         // level native anonymous content subtree roots, since they're not
         // really roots from the style fixup perspective.  Checking that we
         // are NAC handles both cases.
         self.is_native_anonymous()
     }
--- a/servo/components/style/traversal.rs
+++ b/servo/components/style/traversal.rs
@@ -52,23 +52,25 @@ impl TraversalDriver {
     /// Returns whether this represents a parallel traversal or not.
     #[inline]
     pub fn is_parallel(&self) -> bool {
         matches!(*self, TraversalDriver::Parallel)
     }
 }
 
 #[cfg(feature = "servo")]
+#[inline]
 fn is_servo_nonincremental_layout() -> bool {
     use servo_config::opts;
 
     opts::get().nonincremental_layout
 }
 
 #[cfg(not(feature = "servo"))]
+#[inline]
 fn is_servo_nonincremental_layout() -> bool {
     false
 }
 
 /// A DOM Traversal trait, that is used to generically implement styling for
 /// Gecko and Servo.
 pub trait DomTraversal<E: TElement> : Sync {
     /// Process `node` on the way down, before its children have been processed.
--- a/servo/components/style/traversal_flags.rs
+++ b/servo/components/style/traversal_flags.rs
@@ -72,12 +72,13 @@ pub fn assert_traversal_flags_match() {
             ClearAnimationOnlyDirtyDescendants,
         ServoTraversalFlags_ParallelTraversal => ParallelTraversal,
         ServoTraversalFlags_FlushThrottledAnimations => FlushThrottledAnimations,
     }
 }
 
 impl TraversalFlags {
     /// Returns true if the traversal is for animation-only restyles.
+    #[inline]
     pub fn for_animation_only(&self) -> bool {
         self.contains(AnimationOnly)
     }
 }