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
This commit is contained in:
Emilio Cobos Álvarez 2023-06-07 00:03:23 +02:00 committed by Oriol Brufau
parent ece2a74709
commit 01fb804320

View file

@ -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<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.