tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

commit bbeecfb159fb6174ffa7a912ba114c41af5fd762
parent 70a4e7824b0453fc89c09638173c525bf4956644
Author: Nico Burns <nico@nicoburns.com>
Date:   Mon, 15 Dec 2025 19:03:58 +0000

Bug 2005254: Stylo: Use std::sync::LazyLock instead of lazy_static crate (r=firefox-style-system-reviewers,dshin)

Differential Revision: https://phabricator.services.mozilla.com/D275846

Diffstat:
MCargo.lock | 1-
Mservo/components/style/Cargo.toml | 2--
Mservo/components/style/author_styles.rs | 6+++---
Mservo/components/style/build.rs | 12+++++-------
Mservo/components/style/build_gecko.rs | 58+++++++++++++++++++++++++++++++---------------------------
Mservo/components/style/custom_properties_map.rs | 19+++++++++----------
Mservo/components/style/gecko/url.rs | 13+++++--------
Mservo/components/style/gecko/wrapper.rs | 61+++++++++++++++++++++++++++++++------------------------------
Mservo/components/style/global_style_data.rs | 123++++++++++++++++++++++++++++++++++++++-----------------------------------------
Mservo/components/style/lib.rs | 2--
Mservo/components/style/properties/gecko.mako.rs | 22++++++++++------------
Mservo/components/style/stylist.rs | 42++++++++++++++++++------------------------
Mservo/components/style/values/computed/font.rs | 16+++++++---------
Mservo/ports/geckolib/glue.rs | 3++-
14 files changed, 180 insertions(+), 200 deletions(-)

diff --git a/Cargo.lock b/Cargo.lock @@ -6691,7 +6691,6 @@ dependencies = [ "indexmap", "itertools", "itoa", - "lazy_static", "log", "malloc_size_of", "malloc_size_of_derive", diff --git a/servo/components/style/Cargo.toml b/servo/components/style/Cargo.toml @@ -66,7 +66,6 @@ icu_segmenter = { version = "2.0", default-features = false, features = ["auto", indexmap = {version = "2", features = ["std"]} itertools = "0.14" itoa = "1.0" -lazy_static = "1" log = "0.4" malloc_size_of = { path = "../malloc_size_of" } malloc_size_of_derive = { path = "../../../xpcom/rust/malloc_size_of_derive" } @@ -102,7 +101,6 @@ gecko-profiler = { path = "../../../tools/profiler/rust-api" } url = { version = "2.5", optional = true, features = ["serde"] } [build-dependencies] -lazy_static = "1" log = { version = "0.4", features = ["std"] } bindgen = {version = "0.69", optional = true, default-features = false} regex = {version = "1.0", optional = true, default-features = false, features = ["perf", "std"]} diff --git a/servo/components/style/author_styles.rs b/servo/components/style/author_styles.rs @@ -13,6 +13,7 @@ use crate::stylesheets::StylesheetInDocument; use crate::stylist::CascadeData; use crate::stylist::Stylist; use servo_arc::Arc; +use std::sync::LazyLock; /// A set of author stylesheets and their computed representation, such as the /// ones used for ShadowRoot. @@ -31,9 +32,8 @@ where pub use self::GenericAuthorStyles as AuthorStyles; -lazy_static! { - static ref EMPTY_CASCADE_DATA: Arc<CascadeData> = Arc::new_leaked(CascadeData::new()); -} +static EMPTY_CASCADE_DATA: LazyLock<Arc<CascadeData>> = + LazyLock::new(|| Arc::new_leaked(CascadeData::new())); impl<S> GenericAuthorStyles<S> where diff --git a/servo/components/style/build.rs b/servo/components/style/build.rs @@ -2,12 +2,10 @@ * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ -#[macro_use] -extern crate lazy_static; - use std::env; use std::path::Path; use std::process::{exit, Command}; +use std::sync::LazyLock; use walkdir::WalkDir; #[cfg(feature = "gecko")] @@ -18,8 +16,8 @@ mod build_gecko { pub fn generate() {} } -lazy_static! { - pub static ref PYTHON: String = env::var("PYTHON3").ok().unwrap_or_else(|| { +pub static PYTHON: LazyLock<String> = LazyLock::new(|| { + env::var("PYTHON3").ok().unwrap_or_else(|| { let candidates = if cfg!(windows) { ["python3.exe"] } else { @@ -39,8 +37,8 @@ lazy_static! { "Can't find python (tried {})! Try fixing PATH or setting the PYTHON3 env var", candidates.join(", ") ) - }); -} + }) +}); fn generate_properties(engine: &str) { for entry in WalkDir::new("properties") { diff --git a/servo/components/style/build_gecko.rs b/servo/components/style/build_gecko.rs @@ -13,14 +13,14 @@ use std::io::{Read, Write}; use std::path::{Path, PathBuf}; use std::process::{exit, Command}; use std::slice; +use std::sync::LazyLock; use std::sync::Mutex; use std::time::SystemTime; use toml; use toml::value::Table; -lazy_static! { - static ref OUTDIR_PATH: PathBuf = PathBuf::from(env::var_os("OUT_DIR").unwrap()).join("gecko"); -} +static OUTDIR_PATH: LazyLock<PathBuf> = + LazyLock::new(|| PathBuf::from(env::var_os("OUT_DIR").unwrap()).join("gecko")); const STRUCTS_FILE: &'static str = "structs.rs"; @@ -39,32 +39,36 @@ fn read_config(path: &PathBuf) -> Table { } } -lazy_static! { - static ref CONFIG: Table = { - // Load Gecko's binding generator config from the source tree. - let path = mozbuild::TOPSRCDIR.join("layout/style/ServoBindings.toml"); - read_config(&path) - }; - static ref BINDGEN_FLAGS: Vec<String> = { - mozbuild::config::BINDGEN_SYSTEM_FLAGS - .iter() - .chain(&mozbuild::config::NSPR_CFLAGS) - .chain(&mozbuild::config::MOZ_PIXMAN_CFLAGS) - .chain(&mozbuild::config::MOZ_ICU_CFLAGS) - .map(|s| s.to_string()) - .collect() - }; - static ref INCLUDE_RE: Regex = Regex::new(r#"#include\s*"(.+?)""#).unwrap(); - static ref DISTDIR_PATH: PathBuf = mozbuild::TOPOBJDIR.join("dist"); - static ref SEARCH_PATHS: Vec<PathBuf> = vec![ +static CONFIG: LazyLock<Table> = LazyLock::new(|| { + // Load Gecko's binding generator config from the source tree. + let path = mozbuild::TOPSRCDIR.join("layout/style/ServoBindings.toml"); + read_config(&path) +}); +static BINDGEN_FLAGS: LazyLock<Vec<String>> = LazyLock::new(|| { + mozbuild::config::BINDGEN_SYSTEM_FLAGS + .iter() + .chain(&mozbuild::config::NSPR_CFLAGS) + .chain(&mozbuild::config::MOZ_PIXMAN_CFLAGS) + .chain(&mozbuild::config::MOZ_ICU_CFLAGS) + .map(|s| s.to_string()) + .collect() +}); +static INCLUDE_RE: LazyLock<Regex> = LazyLock::new(|| Regex::new(r#"#include\s*"(.+?)""#).unwrap()); +static DISTDIR_PATH: LazyLock<PathBuf> = LazyLock::new(|| mozbuild::TOPOBJDIR.join("dist")); +static SEARCH_PATHS: LazyLock<Vec<PathBuf>> = LazyLock::new(|| { + vec![ DISTDIR_PATH.join("include"), DISTDIR_PATH.join("include/nspr"), - ]; - static ref ADDED_PATHS: Mutex<HashSet<PathBuf>> = Mutex::new(HashSet::new()); - static ref LAST_MODIFIED: Mutex<SystemTime> = - Mutex::new(get_modified_time(&env::current_exe().unwrap()) - .expect("Failed to get modified time of executable")); -} + ] +}); +static ADDED_PATHS: LazyLock<Mutex<HashSet<PathBuf>>> = + LazyLock::new(|| Mutex::new(HashSet::new())); +static LAST_MODIFIED: LazyLock<Mutex<SystemTime>> = LazyLock::new(|| { + Mutex::new( + get_modified_time(&env::current_exe().unwrap()) + .expect("Failed to get modified time of executable"), + ) +}); fn get_modified_time(file: &Path) -> Option<SystemTime> { file.metadata().and_then(|m| m.modified()).ok() diff --git a/servo/components/style/custom_properties_map.rs b/servo/components/style/custom_properties_map.rs @@ -10,6 +10,7 @@ use crate::selector_map::PrecomputedHasher; use indexmap::IndexMap; use servo_arc::Arc; use std::hash::BuildHasherDefault; +use std::sync::LazyLock; /// A map for a set of custom properties, which implements copy-on-write behavior on insertion with /// cheap copying. @@ -26,16 +27,14 @@ impl Default for CustomPropertiesMap { type OwnMap = IndexMap<Name, Option<ComputedRegisteredValue>, BuildHasherDefault<PrecomputedHasher>>; -lazy_static! { - static ref EMPTY: Arc<Inner> = { - Arc::new_leaked(Inner { - own_properties: Default::default(), - parent: None, - len: 0, - ancestor_count: 0, - }) - }; -} +static EMPTY: LazyLock<Arc<Inner>> = LazyLock::new(|| { + Arc::new_leaked(Inner { + own_properties: Default::default(), + parent: None, + len: 0, + ancestor_count: 0, + }) +}); #[derive(Debug, Clone)] struct Inner { diff --git a/servo/components/style/gecko/url.rs b/servo/components/style/gecko/url.rs @@ -17,7 +17,7 @@ use servo_arc::Arc; use std::collections::HashMap; use std::fmt::{self, Write}; use std::mem::ManuallyDrop; -use std::sync::RwLock; +use std::sync::{LazyLock, RwLock}; use style_traits::{CssWriter, ParseError, ToCss}; use to_shmem::{SharedMemoryBuilder, ToShmem}; @@ -382,10 +382,7 @@ impl ToCss for ComputedUrl { } } -lazy_static! { - /// A table mapping CssUrlData objects to their lazily created LoadData - /// objects. - static ref LOAD_DATA_TABLE: RwLock<HashMap<LoadDataKey, Box<LoadData>>> = { - Default::default() - }; -} +/// A table mapping CssUrlData objects to their lazily created LoadData +/// objects. +static LOAD_DATA_TABLE: LazyLock<RwLock<HashMap<LoadDataKey, Box<LoadData>>>> = + LazyLock::new(|| Default::default()); diff --git a/servo/components/style/gecko/wrapper.rs b/servo/components/style/gecko/wrapper.rs @@ -1674,34 +1674,36 @@ impl<'le> TElement for GeckoElement<'le> { use crate::properties::longhands::color::SpecifiedValue as SpecifiedColor; use crate::stylesheets::layer_rule::LayerOrder; use crate::values::specified::{color::Color, font::XTextScale}; - lazy_static! { - static ref TABLE_COLOR_RULE: ApplicableDeclarationBlock = { - let global_style_data = &*GLOBAL_STYLE_DATA; - let pdb = PropertyDeclarationBlock::with_one( - PropertyDeclaration::Color(SpecifiedColor(Color::InheritFromBodyQuirk.into())), - Importance::Normal, - ); - let arc = Arc::new_leaked(global_style_data.shared_lock.wrap(pdb)); - ApplicableDeclarationBlock::from_declarations( - arc, - ServoCascadeLevel::PresHints, - LayerOrder::root(), - ) - }; - static ref MATHML_LANG_RULE: ApplicableDeclarationBlock = { - let global_style_data = &*GLOBAL_STYLE_DATA; - let pdb = PropertyDeclarationBlock::with_one( - PropertyDeclaration::XLang(SpecifiedLang(atom!("x-math"))), - Importance::Normal, - ); - let arc = Arc::new_leaked(global_style_data.shared_lock.wrap(pdb)); - ApplicableDeclarationBlock::from_declarations( - arc, - ServoCascadeLevel::PresHints, - LayerOrder::root(), - ) - }; - static ref SVG_TEXT_DISABLE_SCALE_RULE: ApplicableDeclarationBlock = { + use std::sync::LazyLock; + + static TABLE_COLOR_RULE: LazyLock<ApplicableDeclarationBlock> = LazyLock::new(|| { + let global_style_data = &*GLOBAL_STYLE_DATA; + let pdb = PropertyDeclarationBlock::with_one( + PropertyDeclaration::Color(SpecifiedColor(Color::InheritFromBodyQuirk.into())), + Importance::Normal, + ); + let arc = Arc::new_leaked(global_style_data.shared_lock.wrap(pdb)); + ApplicableDeclarationBlock::from_declarations( + arc, + ServoCascadeLevel::PresHints, + LayerOrder::root(), + ) + }); + static MATHML_LANG_RULE: LazyLock<ApplicableDeclarationBlock> = LazyLock::new(|| { + let global_style_data = &*GLOBAL_STYLE_DATA; + let pdb = PropertyDeclarationBlock::with_one( + PropertyDeclaration::XLang(SpecifiedLang(atom!("x-math"))), + Importance::Normal, + ); + let arc = Arc::new_leaked(global_style_data.shared_lock.wrap(pdb)); + ApplicableDeclarationBlock::from_declarations( + arc, + ServoCascadeLevel::PresHints, + LayerOrder::root(), + ) + }); + static SVG_TEXT_DISABLE_SCALE_RULE: LazyLock<ApplicableDeclarationBlock> = + LazyLock::new(|| { let global_style_data = &*GLOBAL_STYLE_DATA; let pdb = PropertyDeclarationBlock::with_one( PropertyDeclaration::XTextScale(XTextScale::None), @@ -1713,8 +1715,7 @@ impl<'le> TElement for GeckoElement<'le> { ServoCascadeLevel::PresHints, LayerOrder::root(), ) - }; - }; + }); let ns = self.namespace_id(); // <th> elements get a default MozCenterOrInherit which may get overridden diff --git a/servo/components/style/global_style_data.rs b/servo/components/style/global_style_data.rs @@ -15,7 +15,7 @@ use parking_lot::{Mutex, RwLock, RwLockReadGuard}; use std::os::unix::thread::{JoinHandleExt, RawPthread}; #[cfg(windows)] use std::os::windows::{io::AsRawHandle, prelude::RawHandle}; -use std::{io, thread}; +use std::{io, sync::LazyLock, thread}; use thin_vec::ThinVec; /// Platform-specific handle to a thread. @@ -65,17 +65,14 @@ fn thread_name(index: usize) -> String { format!("StyleThread#{}", index) } -lazy_static! { - /// JoinHandles for spawned style threads. These will be joined during - /// StyleThreadPool::shutdown() after exiting the thread pool. - /// - /// This would be quite inefficient if rayon destroyed and re-created - /// threads regularly during threadpool operation in response to demand, - /// however rayon actually never destroys its threads until the entire - /// thread pool is shut-down, so the size of this list is bounded. - static ref STYLE_THREAD_JOIN_HANDLES: Mutex<Vec<thread::JoinHandle<()>>> = - Mutex::new(Vec::new()); -} +/// JoinHandles for spawned style threads. These will be joined during +/// StyleThreadPool::shutdown() after exiting the thread pool. +/// +/// This would be quite inefficient if rayon destroyed and re-created +/// threads regularly during threadpool operation in response to demand, +/// however rayon actually never destroys its threads until the entire +/// thread pool is shut-down, so the size of this list is bounded. +static STYLE_THREAD_JOIN_HANDLES: Mutex<Vec<thread::JoinHandle<()>>> = Mutex::new(Vec::new()); fn thread_spawn(options: rayon::ThreadBuilder) -> io::Result<()> { let mut b = thread::Builder::new(); @@ -139,7 +136,7 @@ impl StyleThreadPool { pub fn get_thread_handles(handles: &mut ThinVec<PlatformThreadHandle>) { // Force the lazy initialization of STYLE_THREAD_POOL so that the threads get spawned and // their join handles are added to STYLE_THREAD_JOIN_HANDLES. - lazy_static::initialize(&STYLE_THREAD_POOL); + LazyLock::force(&STYLE_THREAD_POOL); for join_handle in STYLE_THREAD_JOIN_HANDLES.lock().iter() { #[cfg(unix)] @@ -171,59 +168,57 @@ fn stylo_threads_pref() -> i32 { /// there on many-core machines (see bug 1431285 comment 14). pub(crate) const STYLO_MAX_THREADS: usize = 6; -lazy_static! { - /// Global thread pool - pub static ref STYLE_THREAD_POOL: StyleThreadPool = { - use std::cmp; - // We always set this pref on startup, before layout or script have had a chance of - // accessing (and thus creating) the thread-pool. - let threads_pref: i32 = stylo_threads_pref(); - let num_threads = if threads_pref >= 0 { - threads_pref as usize +/// Global thread pool +pub static STYLE_THREAD_POOL: LazyLock<StyleThreadPool> = LazyLock::new(|| { + use std::cmp; + // We always set this pref on startup, before layout or script have had a chance of + // accessing (and thus creating) the thread-pool. + let threads_pref: i32 = stylo_threads_pref(); + let num_threads = if threads_pref >= 0 { + threads_pref as usize + } else { + // Gecko may wish to override the default number of threads, for example on + // systems with heterogeneous CPUs. + #[cfg(feature = "gecko")] + let num_threads = unsafe { bindings::Gecko_GetNumStyleThreads() }; + #[cfg(not(feature = "gecko"))] + let num_threads = -1; + + if num_threads >= 0 { + num_threads as usize } else { - // Gecko may wish to override the default number of threads, for example on - // systems with heterogeneous CPUs. - #[cfg(feature = "gecko")] - let num_threads = unsafe { bindings::Gecko_GetNumStyleThreads() }; - #[cfg(not(feature = "gecko"))] - let num_threads = -1; - - if num_threads >= 0 { - num_threads as usize - } else { - // The default heuristic is num_virtual_cores * .75. This gives us three threads on a - // hyper-threaded dual core, and six threads on a hyper-threaded quad core. - cmp::max(num_cpus::get() * 3 / 4, 1) - } - }; - - let num_threads = cmp::min(num_threads, STYLO_MAX_THREADS); - // Since the main-thread is also part of the pool, having one thread or less doesn't make - // sense. - let (pool, num_threads) = if num_threads <= 1 { - (None, None) - } else { - let workers = rayon::ThreadPoolBuilder::new() - .spawn_handler(thread_spawn) - .use_current_thread() - .num_threads(num_threads) - .thread_name(thread_name) - .start_handler(thread_startup) - .exit_handler(thread_shutdown) - .stack_size(STYLE_THREAD_STACK_SIZE_KB * 1024) - .build(); - (workers.ok(), Some(num_threads)) - }; - - StyleThreadPool { - num_threads, - style_thread_pool: RwLock::new(pool), + // The default heuristic is num_virtual_cores * .75. This gives us three threads on a + // hyper-threaded dual core, and six threads on a hyper-threaded quad core. + cmp::max(num_cpus::get() * 3 / 4, 1) } }; - /// Global style data - pub static ref GLOBAL_STYLE_DATA: GlobalStyleData = GlobalStyleData { - shared_lock: SharedRwLock::new_leaked(), - options: StyleSystemOptions::default(), + let num_threads = cmp::min(num_threads, STYLO_MAX_THREADS); + // Since the main-thread is also part of the pool, having one thread or less doesn't make + // sense. + let (pool, num_threads) = if num_threads <= 1 { + (None, None) + } else { + let workers = rayon::ThreadPoolBuilder::new() + .spawn_handler(thread_spawn) + .use_current_thread() + .num_threads(num_threads) + .thread_name(thread_name) + .start_handler(thread_startup) + .exit_handler(thread_shutdown) + .stack_size(STYLE_THREAD_STACK_SIZE_KB * 1024) + .build(); + (workers.ok(), Some(num_threads)) }; -} + + StyleThreadPool { + num_threads, + style_thread_pool: RwLock::new(pool), + } +}); + +/// Global style data +pub static GLOBAL_STYLE_DATA: LazyLock<GlobalStyleData> = LazyLock::new(|| GlobalStyleData { + shared_lock: SharedRwLock::new_leaked(), + options: StyleSystemOptions::default(), +}); diff --git a/servo/components/style/lib.rs b/servo/components/style/lib.rs @@ -36,8 +36,6 @@ extern crate gecko_profiler; #[macro_use] pub mod gecko_string_cache; #[macro_use] -extern crate lazy_static; -#[macro_use] extern crate log; #[allow(unused_extern_crates)] #[macro_use] diff --git a/servo/components/style/properties/gecko.mako.rs b/servo/components/style/properties/gecko.mako.rs @@ -444,18 +444,16 @@ impl ${style_struct.gecko_struct_name} { UniqueArc::assume_init(result).shareable() } % else: - lazy_static! { - static ref DEFAULT: Arc<${style_struct.gecko_struct_name}> = unsafe { - let mut result = UniqueArc::<${style_struct.gecko_struct_name}>::new_uninit(); - Gecko_Construct_Default_${style_struct.gecko_ffi_name}( - result.as_mut_ptr() as *mut _, - std::ptr::null(), - ); - let arc = UniqueArc::assume_init(result).shareable(); - arc.mark_as_intentionally_leaked(); - arc - }; - }; + static DEFAULT: std::sync::LazyLock<Arc<${style_struct.gecko_struct_name}>> = std::sync::LazyLock::new(|| unsafe { + let mut result = UniqueArc::<${style_struct.gecko_struct_name}>::new_uninit(); + Gecko_Construct_Default_${style_struct.gecko_ffi_name}( + result.as_mut_ptr() as *mut _, + std::ptr::null(), + ); + let arc = UniqueArc::assume_init(result).shareable(); + arc.mark_as_intentionally_leaked(); + arc + }); DEFAULT.clone() % endif } diff --git a/servo/components/style/stylist.rs b/servo/components/style/stylist.rs @@ -85,7 +85,7 @@ use servo_arc::{Arc, ArcBorrow, ThinArc}; use smallvec::SmallVec; use std::cmp::Ordering; use std::hash::{Hash, Hasher}; -use std::sync::Mutex; +use std::sync::{LazyLock, Mutex}; use std::{mem, ops}; /// The type of the stylesheets that the stylist contains. @@ -277,11 +277,9 @@ pub fn add_size_of_ua_cache(ops: &mut MallocSizeOfOps, sizes: &mut ServoStyleSet .add_size_of(ops, sizes); } -lazy_static! { - /// A cache of computed user-agent data, to be shared across documents. - static ref UA_CASCADE_DATA_CACHE: Mutex<UserAgentCascadeDataCache> = - Mutex::new(UserAgentCascadeDataCache::new()); -} +/// A cache of computed user-agent data, to be shared across documents. +static UA_CASCADE_DATA_CACHE: LazyLock<Mutex<UserAgentCascadeDataCache>> = + LazyLock::new(|| Mutex::new(UserAgentCascadeDataCache::new())); impl CascadeDataCacheEntry for UserAgentCascadeData { fn rebuild<S>( @@ -343,14 +341,12 @@ struct UserAgentCascadeData { precomputed_pseudo_element_decls: PrecomputedPseudoElementDeclarations, } -lazy_static! { - /// The empty UA cascade data for un-filled stylists. - static ref EMPTY_UA_CASCADE_DATA: Arc<UserAgentCascadeData> = { - let arc = Arc::new(UserAgentCascadeData::default()); - arc.mark_as_intentionally_leaked(); - arc - }; -} +/// The empty UA cascade data for un-filled stylists. +static EMPTY_UA_CASCADE_DATA: LazyLock<Arc<UserAgentCascadeData>> = LazyLock::new(|| { + let arc = Arc::new(UserAgentCascadeData::default()); + arc.mark_as_intentionally_leaked(); + arc +}); /// All the computed information for all the stylesheets that apply to the /// document. @@ -3182,16 +3178,14 @@ pub struct CascadeData { num_declarations: usize, } -lazy_static! { - static ref IMPLICIT_SCOPE: SelectorList<SelectorImpl> = { - // Implicit scope, as per https://github.com/w3c/csswg-drafts/issues/10196 - // Also, `&` is `:where(:scope)`, as per https://github.com/w3c/csswg-drafts/issues/9740 - // ``:where(:scope)` effectively behaves the same as the implicit scope. - let list = SelectorList::implicit_scope(); - list.mark_as_intentionally_leaked(); - list - }; -} +static IMPLICIT_SCOPE: LazyLock<SelectorList<SelectorImpl>> = LazyLock::new(|| { + // Implicit scope, as per https://github.com/w3c/csswg-drafts/issues/10196 + // Also, `&` is `:where(:scope)`, as per https://github.com/w3c/csswg-drafts/issues/9740 + // ``:where(:scope)` effectively behaves the same as the implicit scope. + let list = SelectorList::implicit_scope(); + list.mark_as_intentionally_leaked(); + list +}); fn scope_start_matches_shadow_host(start: &SelectorList<SelectorImpl>) -> bool { // TODO(emilio): Should we carry a MatchesFeaturelessHost rather than a bool around? diff --git a/servo/components/style/values/computed/font.rs b/servo/components/style/values/computed/font.rs @@ -362,15 +362,13 @@ pub struct FontFamily { macro_rules! static_font_family { ($ident:ident, $family:expr) => { - lazy_static! { - static ref $ident: FontFamily = FontFamily { - families: FontFamilyList { - list: crate::ArcSlice::from_iter_leaked(std::iter::once($family)), - }, - is_system_font: false, - is_initial: false, - }; - } + static $ident: std::sync::LazyLock<FontFamily> = std::sync::LazyLock::new(|| FontFamily { + families: FontFamilyList { + list: crate::ArcSlice::from_iter_leaked(std::iter::once($family)), + }, + is_system_font: false, + is_initial: false, + }); }; } diff --git a/servo/ports/geckolib/glue.rs b/servo/ports/geckolib/glue.rs @@ -25,6 +25,7 @@ use std::fmt::Write; use std::iter; use std::os::raw::c_void; use std::ptr; +use std::sync::LazyLock; use style::color::mix::ColorInterpolationMethod; use style::color::{AbsoluteColor, ColorComponents, ColorSpace}; use style::computed_value_flags::ComputedValueFlags; @@ -226,7 +227,7 @@ pub unsafe extern "C" fn Servo_Initialize( thread_state::initialize(thread_state::ThreadState::LAYOUT); debug_assert!(is_main_thread()); - lazy_static::initialize(&STYLE_THREAD_POOL); + LazyLock::force(&STYLE_THREAD_POOL); // Perform some debug-only runtime assertions. origin_flags::assert_flags_match();