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; @@ -265,9 +266,29 @@ impl<'ln> GeckoNode<'ln> { GeckoNode(&content._base) } + #[inline] + fn flags_atomic(&self) -> &AtomicU32 { + use std::cell::Cell; + let flags: &Cell = &(self.0)._base._base_1.mFlags; + + #[allow(dead_code)] + fn static_assert() { + let _: [u8; std::mem::size_of::>()] = [0u8; std::mem::size_of::()]; + let _: [u8; std::mem::align_of::>()] = [0u8; std::mem::align_of::()]; + } + + // 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, &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, 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.