style: Inline a bunch of trivial stuff we're paying function calls for in Geckolib. r?xidorn
draft
style: Inline a bunch of trivial stuff we're paying function calls for in Geckolib. r?xidorn
MozReview-Commit-ID: L7kJ0b7jYJR
--- 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)
}
}