diff options
author | Emilio Cobos Álvarez <emilio@crisal.io> | 2023-06-07 00:03:23 +0200 |
---|---|---|
committer | Oriol Brufau <obrufau@igalia.com> | 2023-06-09 11:18:08 +0200 |
commit | 01fb804320b948e19424c2b2fc84c83f6099dc72 (patch) | |
tree | 957e494447c240956cc9051ac42dde1d8b90d29f | |
parent | ece2a747090694166625db2428a1e0a82db9b2d5 (diff) | |
download | servo-01fb804320b948e19424c2b2fc84c83f6099dc72.tar.gz servo-01fb804320b948e19424c2b2fc84c83f6099dc72.zip |
style: Use atomic ops to read / write node flags from stylo
The flags stylo cares about reading and writing potentially at the same
time are disjoint, so there's no need for any strong memory ordering.
Differential Revision: https://phabricator.services.mozilla.com/D141829
-rw-r--r-- | components/style/gecko/wrapper.rs | 31 |
1 files changed, 24 insertions, 7 deletions
diff --git a/components/style/gecko/wrapper.rs b/components/style/gecko/wrapper.rs index d89cac962ee..875700fdf42 100644 --- a/components/style/gecko/wrapper.rs +++ b/components/style/gecko/wrapper.rs @@ -76,6 +76,7 @@ use selectors::matching::{ElementSelectorFlags, MatchingContext}; use selectors::sink::Push; use selectors::{Element, OpaqueElement}; use servo_arc::{Arc, ArcBorrow, RawOffsetArc}; +use std::sync::atomic::{AtomicU32, Ordering}; use std::fmt; use std::hash::{Hash, Hasher}; use std::mem; @@ -266,8 +267,28 @@ impl<'ln> GeckoNode<'ln> { } #[inline] + fn flags_atomic(&self) -> &AtomicU32 { + use std::cell::Cell; + let flags: &Cell<u32> = &(self.0)._base._base_1.mFlags; + + #[allow(dead_code)] + fn static_assert() { + let _: [u8; std::mem::size_of::<Cell<u32>>()] = [0u8; std::mem::size_of::<AtomicU32>()]; + let _: [u8; std::mem::align_of::<Cell<u32>>()] = [0u8; std::mem::align_of::<AtomicU32>()]; + } + + // Rust doesn't provide standalone atomic functions like GCC/clang do + // (via the atomic intrinsics) or via std::atomic_ref, but it guarantees + // that the memory representation of u32 and AtomicU32 matches: + // https://doc.rust-lang.org/std/sync/atomic/struct.AtomicU32.html + unsafe { + std::mem::transmute::<&Cell<u32>, &AtomicU32>(flags) + } + } + + #[inline] fn flags(&self) -> u32 { - (self.0)._base._base_1.mFlags + self.flags_atomic().load(Ordering::Relaxed) } #[inline] @@ -648,18 +669,14 @@ impl<'le> GeckoElement<'le> { self.as_node().flags() } - // FIXME: We can implement this without OOL calls, but we can't easily given - // GeckoNode is a raw reference. - // - // We can use a Cell<T>, but that's a bit of a pain. #[inline] fn set_flags(&self, flags: u32) { - unsafe { Gecko_SetNodeFlags(self.as_node().0, flags) } + self.as_node().flags_atomic().fetch_or(flags, Ordering::Relaxed); } #[inline] unsafe fn unset_flags(&self, flags: u32) { - Gecko_UnsetNodeFlags(self.as_node().0, flags) + self.as_node().flags_atomic().fetch_and(!flags, Ordering::Relaxed); } /// Returns true if this element has descendants for lazy frame construction. |