diff options
author | Emilio Cobos Álvarez <emilio@crisal.io> | 2018-08-21 12:31:11 +0200 |
---|---|---|
committer | Emilio Cobos Álvarez <emilio@crisal.io> | 2018-09-03 12:31:48 +0200 |
commit | 86b4b7036962247e4c6e270390e9765062e5ef99 (patch) | |
tree | ed94bfb3f358d068a7ff4ad2c4413f5a91233b96 | |
parent | 4f04988c1373b9e14e407d8682407165aad03b98 (diff) | |
download | servo-86b4b7036962247e4c6e270390e9765062e5ef99.tar.gz servo-86b4b7036962247e4c6e270390e9765062e5ef99.zip |
style: Make the counters non-atomic counters and merge afterwards.
This was consistently faster in the benchmark (even when counters were disabled,
which was slightly suspicious, but...).
Anyway, it's not really much code, most of it is FFI copy-pasta.
Differential Revision: https://phabricator.services.mozilla.com/D3874
-rw-r--r-- | components/style/gecko/arc_types.rs | 5 | ||||
-rw-r--r-- | components/style/gecko_bindings/sugar/ownership.rs | 9 | ||||
-rw-r--r-- | components/style/use_counters/mod.rs | 42 |
3 files changed, 45 insertions, 11 deletions
diff --git a/components/style/gecko/arc_types.rs b/components/style/gecko/arc_types.rs index 271915f4fa8..7351cbfeac4 100644 --- a/components/style/gecko/arc_types.rs +++ b/components/style/gecko/arc_types.rs @@ -21,7 +21,6 @@ use gecko_bindings::bindings::RawServoRuleNode; use gecko_bindings::bindings::RawServoRuleNodeStrong; use gecko_bindings::bindings::RawServoSupportsRule; use gecko_bindings::bindings::ServoCssRules; -use gecko_bindings::bindings::StyleUseCounters; use gecko_bindings::structs::RawServoAnimationValue; use gecko_bindings::structs::RawServoDeclarationBlock; use gecko_bindings::structs::RawServoFontFaceRule; @@ -40,7 +39,6 @@ use stylesheets::{CounterStyleRule, CssRules, FontFaceRule, FontFeatureValuesRul use stylesheets::{DocumentRule, ImportRule, KeyframesRule, MediaRule, NamespaceRule, PageRule}; use stylesheets::{StyleRule, StylesheetContents, SupportsRule}; use stylesheets::keyframes_rule::Keyframe; -use use_counters::UseCounters; macro_rules! impl_arc_ffi { ($servo_type:ty => $gecko_type:ty[$addref:ident, $release:ident]) => { @@ -61,9 +59,6 @@ macro_rules! impl_arc_ffi { }; } -impl_arc_ffi!(UseCounters => StyleUseCounters - [Servo_UseCounters_AddRef, Servo_UseCounters_Release]); - impl_arc_ffi!(Locked<CssRules> => ServoCssRules [Servo_CssRules_AddRef, Servo_CssRules_Release]); diff --git a/components/style/gecko_bindings/sugar/ownership.rs b/components/style/gecko_bindings/sugar/ownership.rs index 2bc85f53ff7..91c7a504eb1 100644 --- a/components/style/gecko_bindings/sugar/ownership.rs +++ b/components/style/gecko_bindings/sugar/ownership.rs @@ -305,6 +305,15 @@ pub struct OwnedOrNull<GeckoType> { } impl<GeckoType> OwnedOrNull<GeckoType> { + /// Returns a null pointer. + #[inline] + pub fn null() -> Self { + Self { + ptr: ptr::null_mut(), + _marker: PhantomData, + } + } + /// Returns whether this pointer is null. #[inline] pub fn is_null(&self) -> bool { diff --git a/components/style/use_counters/mod.rs b/components/style/use_counters/mod.rs index 03fdc045365..92bc6adb01a 100644 --- a/components/style/use_counters/mod.rs +++ b/components/style/use_counters/mod.rs @@ -4,10 +4,10 @@ //! Various stuff for CSS property use counters. +#[cfg(feature = "gecko")] +use gecko_bindings::sugar::ownership::{HasBoxFFI, HasFFI, HasSimpleFFI}; use properties::{NonCustomPropertyId, NON_CUSTOM_PROPERTY_ID_COUNT}; -// FIXME(emilio): We need AtomicU32 on stable ASAP... -use std::sync::atomic::AtomicUsize; -use std::sync::atomic::Ordering; +use std::cell::Cell; #[cfg(target_pointer_width = "64")] const BITS_PER_ENTRY: usize = 64; @@ -18,7 +18,7 @@ const BITS_PER_ENTRY: usize = 32; /// One bit per each non-custom CSS property. #[derive(Default)] pub struct NonCustomPropertyUseCounters { - storage: [AtomicUsize; (NON_CUSTOM_PROPERTY_ID_COUNT - 1 + BITS_PER_ENTRY) / BITS_PER_ENTRY], + storage: [Cell<usize>; (NON_CUSTOM_PROPERTY_ID_COUNT - 1 + BITS_PER_ENTRY) / BITS_PER_ENTRY], } impl NonCustomPropertyUseCounters { @@ -36,7 +36,8 @@ impl NonCustomPropertyUseCounters { #[inline] pub fn record(&self, id: NonCustomPropertyId) { let (bucket, pattern) = Self::bucket_and_pattern(id); - self.storage[bucket].fetch_or(pattern, Ordering::Relaxed); + let bucket = &self.storage[bucket]; + bucket.set(bucket.get() | pattern) } /// Returns whether a given non-custom property ID has been recorded @@ -44,7 +45,15 @@ impl NonCustomPropertyUseCounters { #[inline] pub fn recorded(&self, id: NonCustomPropertyId) -> bool { let (bucket, pattern) = Self::bucket_and_pattern(id); - self.storage[bucket].load(Ordering::Relaxed) & pattern != 0 + self.storage[bucket].get() & pattern != 0 + } + + /// Merge `other` into `self`. + #[inline] + fn merge(&self, other: &Self) { + for (bucket, other_bucket) in self.storage.iter().zip(other.storage.iter()) { + bucket.set(bucket.get() | other_bucket.get()) + } } } @@ -55,3 +64,24 @@ pub struct UseCounters { /// document's stylesheets. pub non_custom_properties: NonCustomPropertyUseCounters, } + +impl UseCounters { + /// Merge the use counters. + /// + /// Used for parallel parsing, where we parse off-main-thread. + #[inline] + pub fn merge(&self, other: &Self) { + self.non_custom_properties.merge(&other.non_custom_properties) + } +} + +#[cfg(feature = "gecko")] +unsafe impl HasFFI for UseCounters { + type FFIType = ::gecko_bindings::structs::StyleUseCounters; +} + +#[cfg(feature = "gecko")] +unsafe impl HasSimpleFFI for UseCounters {} + +#[cfg(feature = "gecko")] +unsafe impl HasBoxFFI for UseCounters {} |