From d2c78db981a508fab67f01ecb1a4eb90061c2e94 Mon Sep 17 00:00:00 2001 From: Narfinger Date: Mon, 8 Sep 2025 18:06:03 +0200 Subject: [PATCH] Moves to FxHashMap for Allocator, BHM, Canvas, Media, Servo, WebGL and WebGPU (#39202) This moves more of HashMap/FnvHashMap to FxHashmap. Again we only changed instances that do not look security related and have small keys. Additionally, allocator used the fnv feature which did not seem to be used. Testing: Unit Tests and WPT should cover this and functionality change is highly unlikely. Signed-off-by: Narfinger --- Cargo.lock | 10 +++++++--- components/allocator/Cargo.toml | 4 ++-- components/allocator/tracking.rs | 6 +++--- components/background_hang_monitor/Cargo.toml | 1 + .../background_hang_monitor.rs | 7 ++++--- components/canvas/Cargo.toml | 1 + components/canvas/canvas_paint_thread.rs | 6 +++--- components/media/Cargo.toml | 2 +- components/media/media_thread.rs | 4 ++-- components/servo/Cargo.toml | 1 + components/servo/javascript_evaluator.rs | 5 ++--- components/servo/lib.rs | 4 ++-- components/webgl/Cargo.toml | 2 +- components/webgl/webgl_mode/inprocess.rs | 7 +++---- components/webgl/webgl_thread.rs | 10 +++++----- components/webgl/webxr.rs | 4 ++-- components/webgpu/Cargo.toml | 1 + components/webgpu/swapchain.rs | 6 +++--- components/webgpu/wgpu_thread.rs | 18 +++++++++--------- 19 files changed, 53 insertions(+), 46 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index d44f91d96d2..342221ded37 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -738,6 +738,7 @@ dependencies = [ "mach2", "nix 0.30.1", "rustc-demangle", + "rustc-hash 2.1.1", "serde_json", ] @@ -1171,6 +1172,7 @@ dependencies = [ "pixels", "pollster", "range", + "rustc-hash 2.1.1", "servo-tracing", "servo_arc", "servo_config", @@ -5044,6 +5046,7 @@ dependencies = [ "profile", "profile_traits", "rayon", + "rustc-hash 2.1.1", "rustls", "script", "script_traits", @@ -5248,9 +5251,9 @@ version = "0.0.1" dependencies = [ "compositing_traits", "euclid", - "fnv", "ipc-channel", "log", + "rustc-hash 2.1.1", "serde", "servo-media", "servo_config", @@ -7863,8 +7866,8 @@ name = "servo_allocator" version = "0.0.1" dependencies = [ "backtrace", - "fnv", "libc", + "rustc-hash 2.1.1", "tikv-jemalloc-sys", "tikv-jemallocator", "windows-sys 0.61.0", @@ -9834,13 +9837,13 @@ dependencies = [ "compositing_traits", "crossbeam-channel", "euclid", - "fnv", "glow", "half", "ipc-channel", "itertools 0.14.0", "log", "pixels", + "rustc-hash 2.1.1", "surfman", "webrender", "webrender_api", @@ -9859,6 +9862,7 @@ dependencies = [ "ipc-channel", "log", "pixels", + "rustc-hash 2.1.1", "serde", "servo_config", "webgpu_traits", diff --git a/components/allocator/Cargo.toml b/components/allocator/Cargo.toml index b88d98914aa..904e07eb054 100644 --- a/components/allocator/Cargo.toml +++ b/components/allocator/Cargo.toml @@ -11,12 +11,12 @@ rust-version.workspace = true path = "lib.rs" [features] -allocation-tracking = ["backtrace", "fnv"] +allocation-tracking = ["backtrace", "dep:rustc-hash"] use-system-allocator = ["libc"] [dependencies] backtrace = { workspace = true, optional = true } -fnv = { workspace = true, optional = true } +rustc-hash = { workspace = true, optional = true } [target.'cfg(not(any(windows, target_env = "ohos")))'.dependencies] libc = { workspace = true, optional = true } diff --git a/components/allocator/tracking.rs b/components/allocator/tracking.rs index f5c98467327..43f231c2562 100644 --- a/components/allocator/tracking.rs +++ b/components/allocator/tracking.rs @@ -12,7 +12,7 @@ use std::collections::hash_map::Entry; use std::os::raw::c_void; use std::sync::Mutex; -use fnv::{FnvBuildHasher, FnvHashMap}; +use rustc_hash::{FxBuildHasher, FxHashMap}; /// The maximum number of allocations that we'll keep track of. Once the limit /// is reached, we'll evict the first allocation that is smaller than the new addition. @@ -54,8 +54,8 @@ impl AllocSite { unsafe impl Send for AllocSite {} /// A map of pointers to allocation callsite metadata. -static ALLOCATION_SITES: Mutex> = - const { Mutex::new(FnvHashMap::with_hasher(FnvBuildHasher::new())) }; +static ALLOCATION_SITES: Mutex> = + const { Mutex::new(FxHashMap::default()) }; #[derive(Default)] pub struct AccountingAlloc { diff --git a/components/background_hang_monitor/Cargo.toml b/components/background_hang_monitor/Cargo.toml index cb3632b9e1a..5e7162711d3 100644 --- a/components/background_hang_monitor/Cargo.toml +++ b/components/background_hang_monitor/Cargo.toml @@ -17,6 +17,7 @@ doctest = false background_hang_monitor_api = { workspace = true } backtrace = { workspace = true } base = { workspace = true } +rustc-hash = { workspace = true } crossbeam-channel = { workspace = true } ipc-channel = { workspace = true } libc = { workspace = true } diff --git a/components/background_hang_monitor/background_hang_monitor.rs b/components/background_hang_monitor/background_hang_monitor.rs index 8e0d7797710..6958545caf5 100644 --- a/components/background_hang_monitor/background_hang_monitor.rs +++ b/components/background_hang_monitor/background_hang_monitor.rs @@ -2,7 +2,7 @@ * 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/. */ -use std::collections::{HashMap, VecDeque}; +use std::collections::VecDeque; use std::thread::{self, Builder, JoinHandle}; use std::time::{Duration, Instant}; @@ -14,6 +14,7 @@ use background_hang_monitor_api::{ use crossbeam_channel::{Receiver, Sender, after, never, select, unbounded}; use ipc_channel::ipc::{IpcReceiver, IpcSender}; use ipc_channel::router::ROUTER; +use rustc_hash::FxHashMap; use crate::sampler::{NativeStack, Sampler}; @@ -208,8 +209,8 @@ struct MonitoredComponent { struct Sample(MonitoredComponentId, Instant, NativeStack); struct BackgroundHangMonitorWorker { - component_names: HashMap, - monitored_components: HashMap, + component_names: FxHashMap, + monitored_components: FxHashMap, constellation_chan: IpcSender, port: Receiver<(MonitoredComponentId, MonitoredComponentMsg)>, control_port: Receiver, diff --git a/components/canvas/Cargo.toml b/components/canvas/Cargo.toml index 61ff86098b5..2f53ff64f7e 100644 --- a/components/canvas/Cargo.toml +++ b/components/canvas/Cargo.toml @@ -28,6 +28,7 @@ euclid = { workspace = true } fonts = { path = "../fonts" } ipc-channel = { workspace = true } kurbo = { workspace = true } +rustc-hash = { workspace = true } log = { workspace = true } net_traits = { workspace = true } peniko = { workspace = true, optional = true } diff --git a/components/canvas/canvas_paint_thread.rs b/components/canvas/canvas_paint_thread.rs index ee480fb90a9..517ddf01351 100644 --- a/components/canvas/canvas_paint_thread.rs +++ b/components/canvas/canvas_paint_thread.rs @@ -3,7 +3,6 @@ * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ use std::borrow::ToOwned; -use std::collections::HashMap; use std::{f32, thread}; use base::Epoch; @@ -16,12 +15,13 @@ use ipc_channel::ipc::{self, IpcSender}; use ipc_channel::router::ROUTER; use log::warn; use pixels::Snapshot; +use rustc_hash::FxHashMap; use webrender_api::ImageKey; use crate::canvas_data::*; pub struct CanvasPaintThread { - canvases: HashMap, + canvases: FxHashMap, next_canvas_id: CanvasId, compositor_api: CrossProcessCompositorApi, } @@ -29,7 +29,7 @@ pub struct CanvasPaintThread { impl CanvasPaintThread { fn new(compositor_api: CrossProcessCompositorApi) -> CanvasPaintThread { CanvasPaintThread { - canvases: HashMap::new(), + canvases: FxHashMap::default(), next_canvas_id: CanvasId(0), compositor_api: compositor_api.clone(), } diff --git a/components/media/Cargo.toml b/components/media/Cargo.toml index cf51080ec7a..c80f39cddbe 100644 --- a/components/media/Cargo.toml +++ b/components/media/Cargo.toml @@ -14,7 +14,7 @@ path = "lib.rs" [dependencies] compositing_traits = { workspace = true } euclid = { workspace = true } -fnv = { workspace = true } +rustc-hash = { workspace = true } ipc-channel = { workspace = true } log = { workspace = true } serde = { workspace = true } diff --git a/components/media/media_thread.rs b/components/media/media_thread.rs index 44551fd488d..11c7f27fe6e 100644 --- a/components/media/media_thread.rs +++ b/components/media/media_thread.rs @@ -6,9 +6,9 @@ use std::sync::{Arc, Mutex}; use std::thread; use compositing_traits::{WebrenderExternalImageRegistry, WebrenderImageHandlerType}; -use fnv::FnvHashMap; use ipc_channel::ipc::{IpcSender, channel}; use log::{trace, warn}; +use rustc_hash::FxHashMap; use webrender_api::ExternalImageId; /// GL player threading API entry point that lives in the @@ -19,7 +19,7 @@ use crate::{GLPlayerMsg, GLPlayerMsgForward}; /// a set of video players with GL render. pub struct GLPlayerThread { /// Map of live players. - players: FnvHashMap>, + players: FxHashMap>, /// List of registered webrender external images. /// We use it to get an unique ID for new players. external_images: Arc>, diff --git a/components/servo/Cargo.toml b/components/servo/Cargo.toml index 6308dd8b3a0..af1daa1a560 100644 --- a/components/servo/Cargo.toml +++ b/components/servo/Cargo.toml @@ -67,6 +67,7 @@ vello_cpu = ["constellation/vello_cpu"] [dependencies] background_hang_monitor = { path = "../background_hang_monitor" } base = { workspace = true } +rustc-hash = { workspace = true } bincode = { workspace = true } bluetooth = { path = "../bluetooth", optional = true } bluetooth_traits = { workspace = true, optional = true } diff --git a/components/servo/javascript_evaluator.rs b/components/servo/javascript_evaluator.rs index 41cb5539b05..3bd4029c646 100644 --- a/components/servo/javascript_evaluator.rs +++ b/components/servo/javascript_evaluator.rs @@ -2,11 +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/. */ -use std::collections::HashMap; - use base::id::WebViewId; use constellation_traits::EmbedderToConstellationMessage; use embedder_traits::{JSValue, JavaScriptEvaluationError, JavaScriptEvaluationId}; +use rustc_hash::FxHashMap; use crate::ConstellationProxy; @@ -17,7 +16,7 @@ struct PendingEvaluation { pub(crate) struct JavaScriptEvaluator { current_id: JavaScriptEvaluationId, constellation_proxy: ConstellationProxy, - pending_evaluations: HashMap, + pending_evaluations: FxHashMap, } impl JavaScriptEvaluator { diff --git a/components/servo/lib.rs b/components/servo/lib.rs index aaa59bf2d8e..b8e97af4504 100644 --- a/components/servo/lib.rs +++ b/components/servo/lib.rs @@ -27,7 +27,6 @@ mod webview_delegate; use std::cell::{Cell, RefCell}; use std::cmp::max; -use std::collections::HashMap; use std::path::PathBuf; use std::rc::{Rc, Weak}; use std::sync::{Arc, Mutex}; @@ -96,6 +95,7 @@ use net_traits::{exit_fetch_thread, start_fetch_thread}; use profile::{mem as profile_mem, time as profile_time}; use profile_traits::mem::MemoryReportResult; use profile_traits::{mem, time}; +use rustc_hash::FxHashMap; use script::{JSEngineSetup, ServiceWorkerManager}; use servo_config::opts::Opts; pub use servo_config::prefs::PrefValue; @@ -209,7 +209,7 @@ pub struct Servo { /// as `Weak` references so that the embedding application can control their lifetime. /// When accessed, `Servo` will be reponsible for cleaning up the invalid `Weak` /// references. - webviews: RefCell>>>, + webviews: RefCell>>>, servo_errors: ServoErrorChannel, /// For single-process Servo instances, this field controls the initialization /// and deinitialization of the JS Engine. Multiprocess Servo instances have their diff --git a/components/webgl/Cargo.toml b/components/webgl/Cargo.toml index de0eefd57b7..a973813225a 100644 --- a/components/webgl/Cargo.toml +++ b/components/webgl/Cargo.toml @@ -19,11 +19,11 @@ webxr = ["dep:webxr", "dep:webxr-api"] base = { workspace = true } bitflags = { workspace = true } byteorder = { workspace = true } +rustc-hash = { workspace = true } canvas_traits = { workspace = true } compositing_traits = { workspace = true } crossbeam-channel = { workspace = true } euclid = { workspace = true } -fnv = { workspace = true } glow = { workspace = true } half = "2" ipc-channel = { workspace = true } diff --git a/components/webgl/webgl_mode/inprocess.rs b/components/webgl/webgl_mode/inprocess.rs index 6ed47737821..4b9b479e2ec 100644 --- a/components/webgl/webgl_mode/inprocess.rs +++ b/components/webgl/webgl_mode/inprocess.rs @@ -2,7 +2,6 @@ * 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/. */ -use std::default::Default; use std::rc::Rc; use std::sync::{Arc, Mutex}; @@ -13,8 +12,8 @@ use compositing_traits::{ WebrenderExternalImageRegistry, }; use euclid::default::Size2D; -use fnv::FnvHashMap; use log::debug; +use rustc_hash::FxHashMap; use surfman::chains::{SwapChainAPI, SwapChains, SwapChainsAPI}; use surfman::{Device, SurfaceTexture}; use webrender::RenderApiSender; @@ -87,7 +86,7 @@ impl WebGLComm { struct WebGLExternalImages { rendering_context: Rc, swap_chains: SwapChains, - locked_front_buffers: FnvHashMap, + locked_front_buffers: FxHashMap, } impl WebGLExternalImages { @@ -98,7 +97,7 @@ impl WebGLExternalImages { Self { rendering_context, swap_chains, - locked_front_buffers: FnvHashMap::default(), + locked_front_buffers: FxHashMap::default(), } } diff --git a/components/webgl/webgl_thread.rs b/components/webgl/webgl_thread.rs index f71884b4abc..d459a225388 100644 --- a/components/webgl/webgl_thread.rs +++ b/components/webgl/webgl_thread.rs @@ -29,7 +29,6 @@ use compositing_traits::{ WebrenderImageHandlerType, }; use euclid::default::Size2D; -use fnv::FnvHashMap; use glow::{ self as gl, ActiveTransformFeedback, Context as Gl, HasContext, NativeTransformFeedback, NativeUniformLocation, NativeVertexArray, PixelUnpackData, ShaderPrecisionFormat, @@ -40,6 +39,7 @@ use ipc_channel::ipc::IpcSharedMemory; use itertools::Itertools; use log::{debug, error, trace, warn}; use pixels::{self, PixelFormat, SnapshotAlphaMode, unmultiply_inplace}; +use rustc_hash::FxHashMap; use surfman::chains::{PreserveBuffer, SwapChains, SwapChainsAPI}; use surfman::{ self, Adapter, Connection, Context, ContextAttributeFlags, ContextAttributes, Device, @@ -210,9 +210,9 @@ pub(crate) struct WebGLThread { compositor_api: CrossProcessCompositorApi, webrender_api: RenderApi, /// Map of live WebGLContexts. - contexts: FnvHashMap, + contexts: FxHashMap, /// Cached information for WebGLContexts. - cached_context_info: FnvHashMap, + cached_context_info: FxHashMap, /// Current bound context. bound_context_id: Option, /// List of registered webrender external images. @@ -863,7 +863,7 @@ impl WebGLThread { pub(crate) fn make_current_if_needed<'a>( device: &Device, context_id: WebGLContextId, - contexts: &'a FnvHashMap, + contexts: &'a FxHashMap, bound_id: &mut Option, ) -> Option<&'a GLContextData> { let data = contexts.get(&context_id); @@ -882,7 +882,7 @@ impl WebGLThread { pub(crate) fn make_current_if_needed_mut<'a>( device: &Device, context_id: WebGLContextId, - contexts: &'a mut FnvHashMap, + contexts: &'a mut FxHashMap, bound_id: &mut Option, ) -> Option<&'a mut GLContextData> { let data = contexts.get_mut(&context_id); diff --git a/components/webgl/webxr.rs b/components/webgl/webxr.rs index d43303e7393..7d71a5f2495 100644 --- a/components/webgl/webxr.rs +++ b/components/webgl/webxr.rs @@ -8,7 +8,7 @@ use std::num::NonZeroU32; use canvas_traits::webgl::{ WebGLContextId, WebGLMsg, WebGLSender, WebXRCommand, WebXRLayerManagerId, webgl_channel, }; -use fnv::FnvHashMap; +use rustc_hash::FxHashMap; use surfman::{Context, Device}; use webxr::SurfmanGL as WebXRSurfman; use webxr_api::{ @@ -310,7 +310,7 @@ impl Drop for WebXRBridgeManager { } pub(crate) struct WebXRBridgeContexts<'a> { - pub(crate) contexts: &'a mut FnvHashMap, + pub(crate) contexts: &'a mut FxHashMap, pub(crate) bound_context_id: &'a mut Option, } diff --git a/components/webgpu/Cargo.toml b/components/webgpu/Cargo.toml index a2119f4c83c..4c5539478a7 100644 --- a/components/webgpu/Cargo.toml +++ b/components/webgpu/Cargo.toml @@ -15,6 +15,7 @@ path = "lib.rs" arrayvec = { workspace = true, features = ["serde"] } base = { workspace = true } compositing_traits = { workspace = true } +rustc-hash = { workspace = true } euclid = { workspace = true } ipc-channel = { workspace = true } log = { workspace = true } diff --git a/components/webgpu/swapchain.rs b/components/webgpu/swapchain.rs index f19c9bc4670..139134f1a59 100644 --- a/components/webgpu/swapchain.rs +++ b/components/webgpu/swapchain.rs @@ -2,7 +2,6 @@ * 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/. */ -use std::collections::HashMap; use std::ptr::NonNull; use std::slice; use std::sync::{Arc, Mutex}; @@ -17,6 +16,7 @@ use euclid::default::Size2D; use ipc_channel::ipc::IpcSender; use log::{error, warn}; use pixels::{IpcSnapshot, Snapshot, SnapshotAlphaMode, SnapshotPixelFormat}; +use rustc_hash::FxHashMap; use serde::{Deserialize, Serialize}; use webgpu_traits::{ ContextConfiguration, Error, PRESENTATION_BUFFER_COUNT, WebGPUContextId, WebGPUMsg, @@ -35,7 +35,7 @@ use crate::wgt; const DEFAULT_IMAGE_FORMAT: ImageFormat = ImageFormat::RGBA8; -pub type WGPUImageMap = Arc>>; +pub type WGPUImageMap = Arc>>; /// Presentation id encodes current configuration and current image /// so that async presentation does not update context with older data @@ -80,7 +80,7 @@ impl Drop for GPUPresentationBuffer { #[derive(Default)] pub struct WGPUExternalImages { pub images: WGPUImageMap, - pub locked_ids: HashMap>, + pub locked_ids: FxHashMap>, } impl WebrenderExternalImageApi for WGPUExternalImages { diff --git a/components/webgpu/wgpu_thread.rs b/components/webgpu/wgpu_thread.rs index d86f259c658..d549f739fb0 100644 --- a/components/webgpu/wgpu_thread.rs +++ b/components/webgpu/wgpu_thread.rs @@ -5,7 +5,6 @@ //! Data and main loop of WebGPU thread. use std::borrow::Cow; -use std::collections::HashMap; use std::slice; use std::sync::{Arc, Mutex}; @@ -15,6 +14,7 @@ use compositing_traits::{ }; use ipc_channel::ipc::{IpcReceiver, IpcSender, IpcSharedMemory}; use log::{info, warn}; +use rustc_hash::FxHashMap; use servo_config::pref; use webgpu_traits::{ Adapter, ComputePassId, DeviceLostReason, Error, ErrorScope, Mapping, Pipeline, PopError, @@ -98,21 +98,21 @@ pub(crate) struct WGPU { sender: IpcSender, pub(crate) script_sender: IpcSender, pub(crate) global: Arc, - devices: Arc>>, + devices: Arc>>, // TODO: Remove this (https://github.com/gfx-rs/wgpu/issues/867) /// This stores first error on command encoder, /// because wgpu does not invalidate command encoder object /// (this is also reused for invalidation of command buffers) - error_command_encoders: HashMap, + error_command_encoders: FxHashMap, pub(crate) compositor_api: CrossProcessCompositorApi, pub(crate) external_images: Arc>, pub(crate) wgpu_image_map: WGPUImageMap, /// Provides access to poller thread pub(crate) poller: Poller, /// Store compute passes - compute_passes: HashMap>, + compute_passes: FxHashMap>, /// Store render passes - render_passes: HashMap>, + render_passes: FxHashMap>, } impl WGPU { @@ -147,13 +147,13 @@ impl WGPU { sender, script_sender, global, - devices: Arc::new(Mutex::new(HashMap::new())), - error_command_encoders: HashMap::new(), + devices: Arc::new(Mutex::new(FxHashMap::default())), + error_command_encoders: FxHashMap::default(), compositor_api, external_images, wgpu_image_map, - compute_passes: HashMap::new(), - render_passes: HashMap::new(), + compute_passes: FxHashMap::default(), + render_passes: FxHashMap::default(), } }