diff --git a/components/style/gecko/generated/bindings.rs b/components/style/gecko/generated/bindings.rs index 3e8276c8885..eacccb5dafc 100644 --- a/components/style/gecko/generated/bindings.rs +++ b/components/style/gecko/generated/bindings.rs @@ -1597,4 +1597,8 @@ extern "C" { pub fn Gecko_GetElementsWithId ( aDocument : * const nsIDocument , aId : * mut nsAtom , ) -> * const nsTArray < * mut Element > ; } extern "C" { pub fn Gecko_GetBoolPrefValue ( pref_name : * const :: std :: os :: raw :: c_char , ) -> bool ; +} extern "C" { + pub fn Gecko_IsInServoTraversal ( ) -> bool ; +} extern "C" { + pub fn Gecko_IsMainThread ( ) -> bool ; } \ No newline at end of file diff --git a/ports/geckolib/glue.rs b/ports/geckolib/glue.rs index 31ec4bfa6f7..8ccbcc84e71 100644 --- a/ports/geckolib/glue.rs +++ b/ports/geckolib/glue.rs @@ -216,6 +216,16 @@ unsafe fn dummy_url_data() -> &'static RefPtr { RefPtr::from_ptr_ref(&DUMMY_URL_DATA) } +#[allow(dead_code)] +fn is_main_thread() -> bool { + unsafe { bindings::Gecko_IsMainThread() } +} + +#[allow(dead_code)] +fn is_in_servo_traversal() -> bool { + unsafe { bindings::Gecko_IsInServoTraversal() } +} + fn create_shared_context<'a>( global_style_data: &GlobalStyleData, guard: &'a SharedRwLockReadGuard, @@ -1014,8 +1024,13 @@ pub extern "C" fn Servo_Element_GetPseudoComputedValues(element: RawGeckoElement #[no_mangle] pub extern "C" fn Servo_Element_IsDisplayNone(element: RawGeckoElementBorrowed) -> bool { let element = GeckoElement(element); - let data = element.borrow_data().expect("Invoking Servo_Element_IsDisplayNone on unstyled element"); - data.styles.is_display_none() + let data = element.get_data().expect("Invoking Servo_Element_IsDisplayNone on unstyled element"); + + // This function is hot, so we bypass the AtomicRefCell. It would be nice to also assert that + // we're not in the servo traversal, but this function is called at various intermediate + // checkpoints when managing the traversal on the Gecko side. + debug_assert!(is_main_thread()); + unsafe { &*data.as_ptr() }.styles.is_display_none() } #[no_mangle] @@ -1335,6 +1350,7 @@ fn read_locked_arc(raw: & as HasFFI>::FFIType, func: F) -> R unsafe fn read_locked_arc_unchecked(raw: & as HasFFI>::FFIType, func: F) -> R where Locked: HasArcFFI, F: FnOnce(&T) -> R { + debug_assert!(is_main_thread() && !is_in_servo_traversal()); read_locked_arc(raw, func) }