diff --git a/components/style/shared_lock.rs b/components/style/shared_lock.rs index d536673e3b2..5d10a6f07fb 100644 --- a/components/style/shared_lock.rs +++ b/components/style/shared_lock.rs @@ -176,6 +176,13 @@ impl Locked { } } + /// Access the data for reading without verifying the lock. Use with caution. + #[cfg(feature = "gecko")] + pub unsafe fn read_unchecked<'a>(&'a self) -> &'a T { + let ptr = self.data.get(); + &*ptr + } + /// Access the data for writing. pub fn write_with<'a>(&'a self, guard: &'a mut SharedRwLockWriteGuard) -> &'a mut T { assert!(self.same_lock_as(&guard.0), diff --git a/ports/geckolib/glue.rs b/ports/geckolib/glue.rs index ee7960a111e..3241e32bee1 100644 --- a/ports/geckolib/glue.rs +++ b/ports/geckolib/glue.rs @@ -1124,6 +1124,20 @@ fn read_locked_arc(raw: & as HasFFI>::FFIType, func: F) -> R func(Locked::::as_arc(&raw).read_with(&guard)) } +#[cfg(debug_assertions)] +unsafe fn read_locked_arc_unchecked(raw: & as HasFFI>::FFIType, func: F) -> R + where Locked: HasArcFFI, F: FnOnce(&T) -> R +{ + read_locked_arc(raw, func) +} + +#[cfg(not(debug_assertions))] +unsafe fn read_locked_arc_unchecked(raw: & as HasFFI>::FFIType, func: F) -> R + where Locked: HasArcFFI, F: FnOnce(&T) -> R +{ + func(Locked::::as_arc(&raw).read_unchecked()) +} + fn write_locked_arc(raw: & as HasFFI>::FFIType, func: F) -> R where Locked: HasArcFFI, F: FnOnce(&mut T) -> R { @@ -2263,9 +2277,14 @@ macro_rules! get_property_id_from_property { fn get_property_value(declarations: RawServoDeclarationBlockBorrowed, property_id: PropertyId, value: *mut nsAString) { - read_locked_arc(declarations, |decls: &PropertyDeclarationBlock| { - decls.property_value_to_css(&property_id, unsafe { value.as_mut().unwrap() }).unwrap(); - }) + // This callsite is hot enough that the lock acquisition shows up in profiles. + // Using an unchecked read here improves our performance by ~10% on the + // microbenchmark in bug 1355599. + unsafe { + read_locked_arc_unchecked(declarations, |decls: &PropertyDeclarationBlock| { + decls.property_value_to_css(&property_id, value.as_mut().unwrap()).unwrap(); + }) + } } #[no_mangle]