From 84465e776856cb9af9b31007d1231b4940109e4e Mon Sep 17 00:00:00 2001 From: Narfinger Date: Wed, 10 Sep 2025 15:34:54 +0200 Subject: [PATCH] Removed FnvHash and transformed the rest to FxHashmap (#39233) This should be the final PR for the Hash Function series that is trivial. Of note: I decided to transform `HashMapTracedValues` to use FxBuildHasher. This is likely not going to improve performance as Atom's already have a unique u32 that is used as the Hash but it safes a few bytes for the RandomState that is normally in the HashMap. Signed-off-by: Narfinger Testing: Hash function changes should not change functionality, we slightly decrease the size and unit tests still work. Signed-off-by: Narfinger --- Cargo.lock | 18 ++++----- Cargo.toml | 1 - components/compositing/Cargo.toml | 2 +- components/compositing/compositor.rs | 8 ++-- components/compositing/touch.rs | 15 ++++---- components/compositing/webview_manager.rs | 4 +- components/compositing/webview_renderer.rs | 9 ++--- components/constellation/Cargo.toml | 2 +- components/constellation/broadcastchannel.rs | 4 +- components/constellation/browsingcontext.rs | 14 +++---- components/constellation/constellation.rs | 37 +++++++++--------- .../constellation/constellation_webview.rs | 8 ++-- components/constellation/webview_manager.rs | 8 ++-- components/devtools/Cargo.toml | 1 + components/devtools/id.rs | 9 ++--- components/devtools/lib.rs | 17 +++++---- components/fonts/Cargo.toml | 2 +- components/fonts/font_context.rs | 9 ++--- components/layout/Cargo.toml | 1 - components/layout/context.rs | 5 +-- components/layout/display_list/hit_test.rs | 7 ++-- components/layout/layout_impl.rs | 14 +++---- components/net/filemanager_thread.rs | 8 ++-- components/net/image_cache.rs | 12 +++--- components/script/Cargo.toml | 1 - components/script/dom/bindings/refcounted.rs | 14 +++---- .../script/dom/customelementregistry.rs | 12 ++++-- components/script/dom/document.rs | 38 +++++++++++-------- components/script/dom/documentfragment.rs | 9 +++-- components/script/dom/documentorshadowroot.rs | 5 ++- components/script/dom/eventtarget.rs | 5 +-- components/script/dom/globalscope.rs | 3 +- components/script/dom/html/htmlformelement.rs | 7 +++- .../script/dom/servoparser/async_html.rs | 7 ++-- .../script/dom/stylepropertymapreadonly.rs | 3 +- .../script/dom/webgl/extensions/extensions.rs | 24 ++++++------ components/script/dom/webgl/webglprogram.rs | 6 +-- components/script/dom/webxr/xrsession.rs | 6 ++- components/script/iframe_collection.rs | 4 +- components/script/script_thread.rs | 3 +- components/shared/compositing/Cargo.toml | 2 +- components/shared/compositing/display_list.rs | 6 +-- components/shared/constellation/Cargo.toml | 1 - .../constellation/from_script_message.rs | 4 +- components/shared/constellation/lib.rs | 8 ++-- components/shared/embedder/Cargo.toml | 1 + components/shared/embedder/webdriver.rs | 3 +- components/shared/layout/Cargo.toml | 1 - components/shared/layout/lib.rs | 5 +-- components/shared/net/Cargo.toml | 1 + components/shared/net/lib.rs | 6 +-- components/shared/script/Cargo.toml | 2 +- components/shared/script/lib.rs | 4 +- components/webdriver_server/Cargo.toml | 1 + components/webdriver_server/actions.rs | 6 +-- 55 files changed, 211 insertions(+), 202 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index f546df77532..7c94e99d3f8 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1480,13 +1480,13 @@ dependencies = [ "dpi", "embedder_traits", "euclid", - "fnv", "gleam", "ipc-channel", "libc", "log", "pixels", "profile_traits", + "rustc-hash 2.1.1", "servo-tracing", "servo_allocator", "servo_config", @@ -1513,7 +1513,6 @@ dependencies = [ "dpi", "embedder_traits", "euclid", - "fnv", "gleam", "glow", "image", @@ -1522,6 +1521,7 @@ dependencies = [ "malloc_size_of_derive", "profile_traits", "raw-window-handle", + "rustc-hash 2.1.1", "serde", "servo_geometry", "servo_malloc_size_of", @@ -1577,7 +1577,6 @@ dependencies = [ "devtools_traits", "embedder_traits", "euclid", - "fnv", "fonts", "gaol", "ipc-channel", @@ -1590,6 +1589,7 @@ dependencies = [ "parking_lot", "profile", "profile_traits", + "rustc-hash 2.1.1", "script_traits", "serde", "servo-tracing", @@ -1616,7 +1616,6 @@ dependencies = [ "devtools_traits", "embedder_traits", "euclid", - "fnv", "fonts_traits", "http 1.3.1", "hyper_serde", @@ -2043,6 +2042,7 @@ dependencies = [ "log", "net", "net_traits", + "rustc-hash 2.1.1", "serde", "serde_json", "servo_config", @@ -2376,6 +2376,7 @@ dependencies = [ "malloc_size_of_derive", "num-derive", "pixels", + "rustc-hash 2.1.1", "serde", "servo_geometry", "servo_malloc_size_of", @@ -2753,7 +2754,6 @@ dependencies = [ "core-text", "dwrote", "euclid", - "fnv", "fonts_traits", "fontsan", "freetype-sys", @@ -2770,6 +2770,7 @@ dependencies = [ "profile_traits", "range", "read-fonts", + "rustc-hash 2.1.1", "serde", "servo-tracing", "servo_allocator", @@ -4836,7 +4837,6 @@ dependencies = [ "data-url", "embedder_traits", "euclid", - "fnv", "fonts", "fonts_traits", "fxhash", @@ -4892,7 +4892,6 @@ dependencies = [ "constellation_traits", "embedder_traits", "euclid", - "fnv", "fonts", "fonts_traits", "html5ever", @@ -5599,6 +5598,7 @@ dependencies = [ "percent-encoding", "pixels", "profile_traits", + "rustc-hash 2.1.1", "rustls-pki-types", "serde", "servo_arc", @@ -7319,7 +7319,6 @@ dependencies = [ "embedder_traits", "encoding_rs", "euclid", - "fnv", "fonts", "fonts_traits", "fxhash", @@ -7462,7 +7461,6 @@ dependencies = [ "devtools_traits", "embedder_traits", "euclid", - "fnv", "ipc-channel", "keyboard-types", "log", @@ -7471,6 +7469,7 @@ dependencies = [ "net_traits", "pixels", "profile_traits", + "rustc-hash 2.1.1", "serde", "servo_config", "servo_malloc_size_of", @@ -9792,6 +9791,7 @@ dependencies = [ "keyboard-types", "log", "pixels", + "rustc-hash 2.1.1", "serde", "serde_json", "servo_config", diff --git a/Cargo.toml b/Cargo.toml index bcd6234f44b..750a7fc84f0 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -60,7 +60,6 @@ embedder_traits = { path = "components/shared/embedder" } encoding_rs = "0.8" env_logger = "0.11" euclid = "0.22" -fnv = "1.0" fonts_traits = { path = "components/shared/fonts" } freetype-sys = "0.20" fxhash = "0.2" diff --git a/components/compositing/Cargo.toml b/components/compositing/Cargo.toml index de35ce24e1f..c65a5ab5284 100644 --- a/components/compositing/Cargo.toml +++ b/components/compositing/Cargo.toml @@ -28,9 +28,9 @@ compositing_traits = { workspace = true } constellation_traits = { workspace = true } crossbeam-channel = { workspace = true } dpi = { workspace = true } +rustc-hash = { workspace = true } embedder_traits = { workspace = true } euclid = { workspace = true } -fnv = { workspace = true } gleam = { workspace = true } ipc-channel = { workspace = true } libc = { workspace = true } diff --git a/components/compositing/compositor.rs b/components/compositing/compositor.rs index e4349b40b0d..bf7d67ec803 100644 --- a/components/compositing/compositor.rs +++ b/components/compositing/compositor.rs @@ -3,8 +3,8 @@ * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ use std::cell::{Cell, Ref, RefCell}; +use std::collections::HashMap; use std::collections::hash_map::Entry; -use std::collections::{HashMap, HashSet}; use std::env; use std::fs::create_dir_all; use std::iter::once; @@ -28,7 +28,6 @@ use crossbeam_channel::Sender; use dpi::PhysicalSize; use embedder_traits::{CompositorHitTestResult, InputEvent, ShutdownState, ViewportDetails}; use euclid::{Point2D, Rect, Scale, Size2D, Transform3D}; -use fnv::FnvHashMap; use ipc_channel::ipc::{self, IpcSharedMemory}; use log::{debug, info, trace, warn}; use pixels::{CorsStatus, ImageFrame, ImageMetadata, PixelFormat, RasterImage}; @@ -37,6 +36,7 @@ use profile_traits::mem::{ }; use profile_traits::time::{self as profile_time, ProfilerCategory}; use profile_traits::{path, time_profile}; +use rustc_hash::{FxHashMap, FxHashSet}; use servo_config::{opts, pref}; use servo_geometry::DeviceIndependentPixel; use style_traits::CSSPixel; @@ -1184,7 +1184,7 @@ impl IOCompositor { // complete (i.e. has *all* layers painted to the requested epoch). // This gets sent to the constellation for comparison with the current // frame tree. - let mut pipeline_epochs = FnvHashMap::default(); + let mut pipeline_epochs = FxHashMap::default(); for id in self .webview_renderers .iter() @@ -1702,7 +1702,7 @@ struct FrameDelayer { pending_frame: bool, /// A list of pipelines that should be notified when we are no longer waiting for /// canvas images. - waiting_pipelines: HashSet, + waiting_pipelines: FxHashSet, } impl FrameDelayer { diff --git a/components/compositing/touch.rs b/components/compositing/touch.rs index 357ca48d70e..40b4727a8e0 100644 --- a/components/compositing/touch.rs +++ b/components/compositing/touch.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 embedder_traits::{TouchId, TouchSequenceId}; use euclid::{Point2D, Scale, Vector2D}; use log::{debug, error, warn}; +use rustc_hash::FxHashMap; use webrender_api::units::{DeviceIntPoint, DevicePixel, DevicePoint, LayoutVector2D}; use self::TouchSequenceState::*; @@ -26,7 +25,7 @@ const FLING_MAX_SCREEN_PX: f32 = 4000.0; pub struct TouchHandler { pub current_sequence_id: TouchSequenceId, // todo: VecDeque + modulo arithmetic would be more efficient. - touch_sequence_map: HashMap, + touch_sequence_map: FxHashMap, } /// Whether the default move action is allowed or not. @@ -203,12 +202,14 @@ impl TouchHandler { prevent_move: TouchMoveAllowed::Pending, pending_touch_move_action: None, }; + // We insert a simulated initial touch sequence, which is already finished, + // so that we always have one element in the map, which simplifies creating + // a new touch sequence on touch_down. + let mut touch_sequence_map = FxHashMap::default(); + touch_sequence_map.insert(TouchSequenceId::new(), finished_info); TouchHandler { current_sequence_id: TouchSequenceId::new(), - // We insert a simulated initial touch sequence, which is already finished, - // so that we always have one element in the map, which simplifies creating - // a new touch sequence on touch_down. - touch_sequence_map: HashMap::from([(TouchSequenceId::new(), finished_info)]), + touch_sequence_map, } } diff --git a/components/compositing/webview_manager.rs b/components/compositing/webview_manager.rs index fc03e0aad1c..6ee72ae9e4a 100644 --- a/components/compositing/webview_manager.rs +++ b/components/compositing/webview_manager.rs @@ -2,10 +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 std::collections::hash_map::{Entry, Values, ValuesMut}; use base::id::WebViewId; +use rustc_hash::FxHashMap; use crate::webview_renderer::{UnknownWebView, WebViewRenderer}; @@ -13,7 +13,7 @@ use crate::webview_renderer::{UnknownWebView, WebViewRenderer}; pub struct WebViewManager { /// Our top-level browsing contexts. In the WebRender scene, their pipelines are the children of /// a single root pipeline that also applies any pinch zoom transformation. - webviews: HashMap, + webviews: FxHashMap, /// The order to paint them in, topmost last. pub(crate) painting_order: Vec, diff --git a/components/compositing/webview_renderer.rs b/components/compositing/webview_renderer.rs index ac4d80cb69a..59007d69147 100644 --- a/components/compositing/webview_renderer.rs +++ b/components/compositing/webview_renderer.rs @@ -3,7 +3,6 @@ * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ use std::cell::RefCell; -use std::collections::HashMap; use std::collections::hash_map::{Entry, Keys}; use std::rc::Rc; @@ -20,9 +19,9 @@ use embedder_traits::{ TouchEvent, TouchEventResult, TouchEventType, TouchId, ViewportDetails, }; use euclid::{Point2D, Scale, Vector2D}; -use fnv::FnvHashSet; use log::{debug, warn}; use malloc_size_of::MallocSizeOf; +use rustc_hash::{FxHashMap, FxHashSet}; use servo_geometry::DeviceIndependentPixel; use style_traits::{CSSPixel, PinchZoomFactor}; use webrender_api::units::{DeviceIntPoint, DevicePixel, DevicePoint, DeviceRect, LayoutVector2D}; @@ -80,7 +79,7 @@ pub(crate) struct WebViewRenderer { /// The rectangle of the [`WebView`] in device pixels, which is the viewport. pub rect: DeviceRect, /// Tracks details about each active pipeline that the compositor knows about. - pub pipelines: HashMap, + pub pipelines: FxHashMap, /// Data that is shared by all WebView renderers. pub(crate) global: Rc>, /// Pending scroll/zoom events. @@ -228,7 +227,7 @@ impl WebViewRenderer { // state for some unattached pipelines in order to preserve scroll position when // navigating backward and forward. fn collect_pipelines( - pipelines: &mut FnvHashSet, + pipelines: &mut FxHashSet, frame_tree: &SendableFrameTree, ) { pipelines.insert(frame_tree.pipeline.id); @@ -237,7 +236,7 @@ impl WebViewRenderer { } } - let mut attached_pipelines: FnvHashSet = FnvHashSet::default(); + let mut attached_pipelines: FxHashSet = FxHashSet::default(); collect_pipelines(&mut attached_pipelines, frame_tree); self.pipelines diff --git a/components/constellation/Cargo.toml b/components/constellation/Cargo.toml index 28a64d8bbc9..ea6f8c2bdfb 100644 --- a/components/constellation/Cargo.toml +++ b/components/constellation/Cargo.toml @@ -38,9 +38,9 @@ devtools_traits = { workspace = true } embedder_traits = { workspace = true } euclid = { workspace = true } fonts = { path = "../fonts" } -fnv = { workspace = true } ipc-channel = { workspace = true } keyboard-types = { workspace = true } +rustc-hash = { workspace = true } layout_api = { workspace = true } log = { workspace = true } media = { path = "../media" } diff --git a/components/constellation/broadcastchannel.rs b/components/constellation/broadcastchannel.rs index d76536c4749..c1af08972fc 100644 --- a/components/constellation/broadcastchannel.rs +++ b/components/constellation/broadcastchannel.rs @@ -6,15 +6,15 @@ use std::collections::HashMap; use base::id::BroadcastChannelRouterId; use constellation_traits::BroadcastChannelMsg; -use fnv::FnvHashMap; use ipc_channel::ipc::IpcSender; use log::warn; +use rustc_hash::FxHashMap; use servo_url::ImmutableOrigin; #[derive(Default)] pub(crate) struct BroadcastChannels { /// A map of broadcast routers to their IPC sender. - routers: FnvHashMap>, + routers: FxHashMap>, /// A map of origin to a map of channel name to a list of relevant routers. channels: HashMap>>, diff --git a/components/constellation/browsingcontext.rs b/components/constellation/browsingcontext.rs index 9a99fe21ab9..802c03e06a3 100644 --- a/components/constellation/browsingcontext.rs +++ b/components/constellation/browsingcontext.rs @@ -4,8 +4,8 @@ use base::id::{BrowsingContextGroupId, BrowsingContextId, PipelineId, WebViewId}; use embedder_traits::ViewportDetails; -use fnv::{FnvHashMap, FnvHashSet}; use log::warn; +use rustc_hash::{FxHashMap, FxHashSet}; use crate::pipeline::Pipeline; @@ -70,7 +70,7 @@ pub struct BrowsingContext { /// All the pipelines that have been presented or will be presented in /// this browsing context. - pub pipelines: FnvHashSet, + pub pipelines: FxHashSet, } impl BrowsingContext { @@ -88,7 +88,7 @@ impl BrowsingContext { inherited_secure_context: Option, throttled: bool, ) -> BrowsingContext { - let mut pipelines = FnvHashSet::default(); + let mut pipelines = FxHashSet::default(); pipelines.insert(pipeline_id); BrowsingContext { bc_group_id, @@ -122,12 +122,12 @@ pub struct FullyActiveBrowsingContextsIterator<'a> { pub stack: Vec, /// The set of all browsing contexts. - pub browsing_contexts: &'a FnvHashMap, + pub browsing_contexts: &'a FxHashMap, /// The set of all pipelines. We use this to find the active /// children of a frame, which are the iframes in the currently /// active document. - pub pipelines: &'a FnvHashMap, + pub pipelines: &'a FxHashMap, } impl<'a> Iterator for FullyActiveBrowsingContextsIterator<'a> { @@ -169,12 +169,12 @@ pub struct AllBrowsingContextsIterator<'a> { pub stack: Vec, /// The set of all browsing contexts. - pub browsing_contexts: &'a FnvHashMap, + pub browsing_contexts: &'a FxHashMap, /// The set of all pipelines. We use this to find the /// children of a browsing context, which are the iframes in all documents /// in the session history. - pub pipelines: &'a FnvHashMap, + pub pipelines: &'a FxHashMap, } impl<'a> Iterator for AllBrowsingContextsIterator<'a> { diff --git a/components/constellation/constellation.rs b/components/constellation/constellation.rs index 0d533516885..7fcbe5600ec 100644 --- a/components/constellation/constellation.rs +++ b/components/constellation/constellation.rs @@ -139,7 +139,6 @@ use embedder_traits::{ }; use euclid::Size2D; use euclid::default::Size2D as UntypedSize2D; -use fnv::{FnvHashMap, FnvHashSet}; use fonts::SystemFontServiceProxy; use ipc_channel::Error as IpcError; use ipc_channel::ipc::{self, IpcReceiver, IpcSender}; @@ -157,6 +156,7 @@ use net_traits::{ }; use profile_traits::mem::ProfilerMsg; use profile_traits::{mem, time}; +use rustc_hash::{FxHashMap, FxHashSet}; use script_traits::{ ConstellationInputEvent, DiscardBrowsingContext, DocumentActivity, ProgressiveWebMetricType, ScriptThreadMessage, UpdatePipelineIdReason, @@ -190,7 +190,7 @@ use crate::session_history::{ }; use crate::webview_manager::WebViewManager; -type PendingApprovalNavigations = HashMap; +type PendingApprovalNavigations = FxHashMap; #[derive(Debug)] /// The state used by MessagePortInfo to represent the various states the port can be in. @@ -241,7 +241,7 @@ struct WebrenderWGPU { #[derive(Clone, Default)] struct BrowsingContextGroup { /// A browsing context group holds a set of top-level browsing contexts. - top_level_browsing_context_set: FnvHashSet, + top_level_browsing_context_set: FxHashSet, /// The set of all event loops in this BrowsingContextGroup. /// We store the event loops in a map @@ -385,25 +385,25 @@ pub struct Constellation { webrender_wgpu: WebrenderWGPU, /// A map of message-port Id to info. - message_ports: FnvHashMap, + message_ports: FxHashMap, /// A map of router-id to ipc-sender, to route messages to ports. - message_port_routers: FnvHashMap>, + message_port_routers: FxHashMap>, /// Bookkeeping for BroadcastChannel functionnality. broadcast_channels: BroadcastChannels, /// The set of all the pipelines in the browser. (See the `pipeline` module /// for more details.) - pipelines: FnvHashMap, + pipelines: FxHashMap, /// The set of all the browsing contexts in the browser. - browsing_contexts: FnvHashMap, + browsing_contexts: FxHashMap, /// A user agent holds a a set of browsing context groups. /// /// - browsing_context_group_set: FnvHashMap, + browsing_context_group_set: FxHashMap, /// The Id counter for BrowsingContextGroup. browsing_context_group_next_id: u32, @@ -426,7 +426,7 @@ pub struct Constellation { webdriver_input_command_reponse_sender: Option>, /// Document states for loaded pipelines (used only when writing screenshots). - document_states: FnvHashMap, + document_states: FxHashMap, /// Are we shutting down? shutting_down: bool, @@ -482,7 +482,7 @@ pub struct Constellation { async_runtime: Box, /// When in single-process mode, join handles for script-threads. - script_join_handles: FnvHashMap>, + script_join_handles: FxHashMap>, /// A list of URLs that can access privileged internal APIs. privileged_urls: Vec, @@ -2120,7 +2120,7 @@ where fn handle_message_port_transfer_failed( &mut self, - ports: FnvHashMap, + ports: FxHashMap, ) { for (port_id, mut transfer_info) in ports.into_iter() { let entry = match self.message_ports.remove(&port_id) { @@ -2202,7 +2202,7 @@ where router_id: MessagePortRouterId, ports: Vec, ) { - let mut response = FnvHashMap::default(); + let mut response = FxHashMap::default(); for port_id in ports.into_iter() { let entry = match self.message_ports.remove(&port_id) { None => { @@ -3785,11 +3785,10 @@ where webview_id: WebViewId, direction: TraversalDirection, ) { - let mut browsing_context_changes = - FnvHashMap::::default(); + let mut browsing_context_changes = FxHashMap::::default(); let mut pipeline_changes = - FnvHashMap::, ServoUrl)>::default(); - let mut url_to_load = FnvHashMap::::default(); + FxHashMap::, ServoUrl)>::default(); + let mut url_to_load = FxHashMap::::default(); { let session_history = self.get_joint_session_history(webview_id); match direction { @@ -4792,7 +4791,7 @@ where }; let mut pipelines_to_close = vec![]; - let mut states_to_close = FnvHashMap::default(); + let mut states_to_close = FxHashMap::default(); let diffs_to_close = self .get_joint_session_history(change.webview_id) @@ -5049,7 +5048,7 @@ where #[servo_tracing::instrument(skip_all)] fn handle_is_ready_to_save_image( &mut self, - pipeline_states: FnvHashMap, + pipeline_states: FxHashMap, ) -> ReadyToSave { // Note that this function can panic, due to ipc-channel creation // failure. Avoiding this panic would require a mechanism for dealing @@ -5593,7 +5592,7 @@ where fn handle_set_scroll_states( &self, pipeline_id: PipelineId, - scroll_states: FnvHashMap, + scroll_states: FxHashMap, ) { let Some(pipeline) = self.pipelines.get(&pipeline_id) else { warn!("Discarding scroll offset update for unknown pipeline"); diff --git a/components/constellation/constellation_webview.rs b/components/constellation/constellation_webview.rs index 3aa0b15678c..dccae037ea2 100644 --- a/components/constellation/constellation_webview.rs +++ b/components/constellation/constellation_webview.rs @@ -5,8 +5,8 @@ use base::id::{BrowsingContextId, PipelineId}; use embedder_traits::{InputEvent, MouseLeftViewportEvent, Theme}; use euclid::Point2D; -use fnv::FnvHashMap; use log::warn; +use rustc_hash::FxHashMap; use script_traits::{ConstellationInputEvent, ScriptThreadMessage}; use style_traits::CSSPixel; @@ -63,7 +63,7 @@ impl ConstellationWebView { fn target_pipeline_id_for_input_event( &self, event: &ConstellationInputEvent, - browsing_contexts: &FnvHashMap, + browsing_contexts: &FxHashMap, ) -> Option { if let Some(hit_test_result) = &event.hit_test_result { return Some(hit_test_result.pipeline_id); @@ -84,8 +84,8 @@ impl ConstellationWebView { pub(crate) fn forward_input_event( &mut self, event: ConstellationInputEvent, - pipelines: &FnvHashMap, - browsing_contexts: &FnvHashMap, + pipelines: &FxHashMap, + browsing_contexts: &FxHashMap, ) { let Some(pipeline_id) = self.target_pipeline_id_for_input_event(&event, browsing_contexts) else { diff --git a/components/constellation/webview_manager.rs b/components/constellation/webview_manager.rs index df9a9cd9afb..7a309dcbe76 100644 --- a/components/constellation/webview_manager.rs +++ b/components/constellation/webview_manager.rs @@ -2,16 +2,14 @@ * 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 fnv::FnvHashMap; +use rustc_hash::FxHashMap; #[derive(Debug)] pub struct WebViewManager { /// Our top-level browsing contexts. In the WebRender scene, their pipelines are the children of /// a single root pipeline that also applies any pinch zoom transformation. - webviews: FnvHashMap, + webviews: FxHashMap, /// The order in which they were focused, latest last. focus_order: Vec, @@ -23,7 +21,7 @@ pub struct WebViewManager { impl Default for WebViewManager { fn default() -> Self { Self { - webviews: HashMap::default(), + webviews: FxHashMap::default(), focus_order: Vec::default(), is_focused: false, } diff --git a/components/devtools/Cargo.toml b/components/devtools/Cargo.toml index 0b150d9f715..27047e053f7 100644 --- a/components/devtools/Cargo.toml +++ b/components/devtools/Cargo.toml @@ -15,6 +15,7 @@ path = "lib.rs" base = { workspace = true } base64 = { workspace = true } chrono = { workspace = true } +rustc-hash = { workspace = true } crossbeam-channel = { workspace = true } devtools_traits = { workspace = true } embedder_traits = { workspace = true } diff --git a/components/devtools/id.rs b/components/devtools/id.rs index 40408d91f95..f6b6a4646ec 100644 --- a/components/devtools/id.rs +++ b/components/devtools/id.rs @@ -2,15 +2,14 @@ * 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::{BrowsingContextId, PipelineId, WebViewId}; +use rustc_hash::FxHashMap; #[derive(Debug, Default)] pub(crate) struct IdMap { - pub(crate) browser_ids: HashMap, - pub(crate) browsing_context_ids: HashMap, - pub(crate) outer_window_ids: HashMap, + pub(crate) browser_ids: FxHashMap, + pub(crate) browsing_context_ids: FxHashMap, + pub(crate) outer_window_ids: FxHashMap, } impl IdMap { diff --git a/components/devtools/lib.rs b/components/devtools/lib.rs index 2373b2f48ec..c697060ec71 100644 --- a/components/devtools/lib.rs +++ b/components/devtools/lib.rs @@ -30,6 +30,7 @@ use embedder_traits::{AllowOrDeny, EmbedderMsg, EmbedderProxy}; use ipc_channel::ipc::IpcSender; use log::{trace, warn}; use resource::{ResourceArrayType, ResourceAvailable}; +use rustc_hash::FxHashMap; use serde::Serialize; use servo_rand::RngCore; @@ -116,12 +117,12 @@ pub(crate) struct StreamId(u32); struct DevtoolsInstance { actors: Arc>, id_map: Arc>, - browsing_contexts: HashMap, + browsing_contexts: FxHashMap, receiver: Receiver, - pipelines: HashMap, - actor_workers: HashMap, + pipelines: FxHashMap, + actor_workers: FxHashMap, actor_requests: HashMap, - connections: HashMap, + connections: FxHashMap, next_resource_id: u64, } @@ -179,12 +180,12 @@ impl DevtoolsInstance { let instance = Self { actors, id_map: Arc::new(Mutex::new(IdMap::default())), - browsing_contexts: HashMap::new(), - pipelines: HashMap::new(), + browsing_contexts: FxHashMap::default(), + pipelines: FxHashMap::default(), receiver, actor_requests: HashMap::new(), - actor_workers: HashMap::new(), - connections: HashMap::new(), + actor_workers: FxHashMap::default(), + connections: FxHashMap::default(), next_resource_id: 1, }; diff --git a/components/fonts/Cargo.toml b/components/fonts/Cargo.toml index 08bbdca3880..55f08d158de 100644 --- a/components/fonts/Cargo.toml +++ b/components/fonts/Cargo.toml @@ -22,7 +22,6 @@ base = { workspace = true } bitflags = { workspace = true } compositing_traits = { workspace = true } euclid = { workspace = true } -fnv = { workspace = true } fonts_traits = { workspace = true } fontsan = { git = "https://github.com/servo/fontsan" } # FIXME (#34517): macOS only needs this when building libservo without `--features media-gstreamer` @@ -46,6 +45,7 @@ servo_config = { path = "../config" } servo_url = { path = "../url" } skrifa = { workspace = true } smallvec = { workspace = true } +rustc-hash = { workspace = true } stylo = { workspace = true } stylo_atoms = { workspace = true } tracing = { workspace = true, optional = true } diff --git a/components/fonts/font_context.rs b/components/fonts/font_context.rs index 9b124cde24f..38f189ab136 100644 --- a/components/fonts/font_context.rs +++ b/components/fonts/font_context.rs @@ -4,7 +4,7 @@ use std::collections::{HashMap, HashSet}; use std::default::Default; -use std::hash::{BuildHasherDefault, Hash, Hasher}; +use std::hash::{Hash, Hasher}; use std::ops::Deref; use std::sync::Arc; use std::sync::atomic::{AtomicBool, Ordering}; @@ -12,7 +12,6 @@ use std::sync::atomic::{AtomicBool, Ordering}; use app_units::Au; use base::id::WebViewId; use compositing_traits::CrossProcessCompositorApi; -use fnv::FnvHasher; use fonts_traits::{ CSSFontFaceDescriptors, FontDescriptor, FontIdentifier, FontTemplate, FontTemplateRef, FontTemplateRefMethods, StylesheetWebFontLoadFinishedCallback, @@ -22,6 +21,7 @@ use malloc_size_of_derive::MallocSizeOf; use net_traits::request::{Destination, Referrer, RequestBuilder}; use net_traits::{CoreResourceThread, FetchResponseMsg, ResourceThreads, fetch_async}; use parking_lot::{Mutex, RwLock}; +use rustc_hash::FxHashSet; use servo_arc::Arc as ServoArc; use servo_config::pref; use servo_url::ServoUrl; @@ -78,8 +78,7 @@ pub struct FontContext { /// A caching map between the specification of a font in CSS style and /// resolved [`FontGroup`] which contains information about all fonts that /// can be selected with that style. - resolved_font_groups: - RwLock>>, + resolved_font_groups: RwLock>, web_fonts: CrossThreadFontStore, @@ -612,7 +611,7 @@ impl FontContextWebFontMethods for Arc { self.have_removed_web_fonts.store(false, Ordering::Relaxed); - let mut removed_keys: HashSet = HashSet::new(); + let mut removed_keys: FxHashSet = FxHashSet::default(); webrender_font_keys.retain(|identifier, font_key| { if unused_identifiers.contains(identifier) { removed_keys.insert(*font_key); diff --git a/components/layout/Cargo.toml b/components/layout/Cargo.toml index 4ca3062e430..6046c7cdc25 100644 --- a/components/layout/Cargo.toml +++ b/components/layout/Cargo.toml @@ -26,7 +26,6 @@ cssparser = { workspace = true } data-url = { workspace = true } embedder_traits = { workspace = true } euclid = { workspace = true } -fnv = { workspace = true } fonts = { path = "../fonts" } fonts_traits = { workspace = true } fxhash = { workspace = true } diff --git a/components/layout/context.rs b/components/layout/context.rs index 3e594ed331b..2267597c487 100644 --- a/components/layout/context.rs +++ b/components/layout/context.rs @@ -2,11 +2,11 @@ * 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::sync::Arc; use embedder_traits::UntrustedNodeAddress; use euclid::Size2D; -use fnv::FnvHashMap; use fonts::FontContext; use layout_api::wrapper_traits::ThreadSafeLayoutNode; use layout_api::{ @@ -102,8 +102,7 @@ pub(crate) struct ImageResolver { // A cache that maps image resources used in CSS (e.g as the `url()` value // for `background-image` or `content` property) to the final resolved image data. - pub resolved_images_cache: - Arc>>, + pub resolved_images_cache: Arc>>, /// The current animation timeline value used to properly initialize animating images. pub animation_timeline_value: f64, diff --git a/components/layout/display_list/hit_test.rs b/components/layout/display_list/hit_test.rs index 55368d8b7bd..f0e9fdbb309 100644 --- a/components/layout/display_list/hit_test.rs +++ b/components/layout/display_list/hit_test.rs @@ -2,14 +2,13 @@ * 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 app_units::Au; use base::id::ScrollTreeNodeId; use embedder_traits::Cursor; use euclid::{Box2D, Vector2D}; use kurbo::{Ellipse, Shape}; use layout_api::{ElementsFromPointFlags, ElementsFromPointResult}; +use rustc_hash::FxHashMap; use servo_geometry::FastLayoutTransform; use style::computed_values::backface_visibility::T as BackfaceVisibility; use style::computed_values::pointer_events::T as PointerEvents; @@ -40,7 +39,7 @@ pub(crate) struct HitTest<'a> { /// The resulting [`HitTestResultItems`] for this hit test. results: Vec, /// A cache of hit test results for shared clip nodes. - clip_hit_test_results: HashMap, + clip_hit_test_results: FxHashMap, } impl<'a> HitTest<'a> { @@ -55,7 +54,7 @@ impl<'a> HitTest<'a> { projected_point_to_test: None, stacking_context_tree, results: Vec::new(), - clip_hit_test_results: HashMap::new(), + clip_hit_test_results: FxHashMap::default(), }; stacking_context_tree .root_stacking_context diff --git a/components/layout/layout_impl.rs b/components/layout/layout_impl.rs index 7a4ddf63f23..b9f8ffd0015 100644 --- a/components/layout/layout_impl.rs +++ b/components/layout/layout_impl.rs @@ -5,6 +5,7 @@ #![allow(unsafe_code)] use std::cell::{Cell, RefCell}; +use std::collections::HashMap; use std::fmt::Debug; use std::process; use std::rc::Rc; @@ -21,10 +22,8 @@ use cssparser::ParserInput; use embedder_traits::{Theme, ViewportDetails}; use euclid::default::{Point2D as UntypedPoint2D, Rect as UntypedRect}; use euclid::{Point2D, Scale, Size2D}; -use fnv::FnvHashMap; use fonts::{FontContext, FontContextWebFontMethods}; use fonts_traits::StylesheetWebFontLoadFinishedCallback; -use fxhash::FxHashMap; use layout_api::wrapper_traits::LayoutNode; use layout_api::{ BoxAreaType, IFrameSizes, Layout, LayoutConfig, LayoutDamage, LayoutFactory, @@ -41,6 +40,7 @@ use profile_traits::time::{ self as profile_time, TimerMetadata, TimerMetadataFrameType, TimerMetadataReflowType, }; use profile_traits::{path, time_profile}; +use rustc_hash::FxHashMap; use script::layout_dom::{ServoLayoutDocument, ServoLayoutElement, ServoLayoutNode}; use script_traits::{DrawAPaintImageResult, PaintWorkletError, Painter, ScriptThreadMessage}; use servo_arc::Arc as ServoArc; @@ -181,7 +181,7 @@ pub struct LayoutThread { // A cache that maps image resources specified in CSS (e.g as the `url()` value // for `background-image` or `content` properties) to either the final resolved // image data, or an error if the image cache failed to load/decode the image. - resolved_images_cache: Arc>>, + resolved_images_cache: Arc>>, /// The executors for paint worklets. registered_painters: RegisteredPaintersImpl, @@ -514,7 +514,7 @@ impl Layout for LayoutThread { fn set_scroll_offsets_from_renderer( &mut self, - scroll_states: &FnvHashMap, + scroll_states: &FxHashMap, ) { let mut stacking_context_tree = self.stacking_context_tree.borrow_mut(); let Some(stacking_context_tree) = stacking_context_tree.as_mut() else { @@ -1422,7 +1422,7 @@ struct RegisteredPainterImpl { painter: Box, name: Atom, // FIXME: Should be a PrecomputedHashMap. - properties: FxHashMap, + properties: fxhash::FxHashMap, } impl SpeculativePainter for RegisteredPainterImpl { @@ -1437,7 +1437,7 @@ impl SpeculativePainter for RegisteredPainterImpl { } impl RegisteredSpeculativePainter for RegisteredPainterImpl { - fn properties(&self) -> &FxHashMap { + fn properties(&self) -> &fxhash::FxHashMap { &self.properties } fn name(&self) -> Atom { @@ -1458,7 +1458,7 @@ impl Painter for RegisteredPainterImpl { } } -struct RegisteredPaintersImpl(FnvHashMap); +struct RegisteredPaintersImpl(HashMap); impl RegisteredSpeculativePainters for RegisteredPaintersImpl { fn get(&self, name: &Atom) -> Option<&dyn RegisteredSpeculativePainter> { diff --git a/components/net/filemanager_thread.rs b/components/net/filemanager_thread.rs index d5c77714176..e4045db2adc 100644 --- a/components/net/filemanager_thread.rs +++ b/components/net/filemanager_thread.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, HashSet}; use std::fs::File; use std::io::{BufRead, BufReader, Read, Seek, SeekFrom}; use std::ops::Index; @@ -25,6 +24,7 @@ use net_traits::filemanager_thread::{ }; use net_traits::http_percent_encode; use net_traits::response::{Response, ResponseBody}; +use rustc_hash::{FxHashMap, FxHashSet}; use servo_arc::Arc as ServoArc; use servo_config::pref; use tokio::sync::mpsc::UnboundedSender as TokioSender; @@ -54,7 +54,7 @@ struct FileStoreEntry { is_valid_url: AtomicBool, /// UUIDs of fetch instances that acquired an interest in this file, /// when the url was still valid. - outstanding_tokens: HashSet, + outstanding_tokens: FxHashSet, } #[derive(Clone)] @@ -433,13 +433,13 @@ enum BlobBounds { /// from FileID to FileStoreEntry which might have different backend implementation. /// Access to the content is encapsulated as methods of this struct. struct FileManagerStore { - entries: RwLock>, + entries: RwLock>, } impl FileManagerStore { fn new() -> Self { FileManagerStore { - entries: RwLock::new(HashMap::new()), + entries: RwLock::new(FxHashMap::default()), } } diff --git a/components/net/image_cache.rs b/components/net/image_cache.rs index 1409b424e54..9874d25b210 100644 --- a/components/net/image_cache.rs +++ b/components/net/image_cache.rs @@ -487,12 +487,12 @@ struct ImageCacheStore { /// Vector (e.g. SVG) images that have been sucessfully loaded and parsed /// but are yet to be rasterized. Since the same SVG data can be used for /// rasterizing at different sizes, we use this hasmap to share the data. - vector_images: HashMap, + vector_images: FxHashMap, /// Vector images for which rasterization at a particular size has started /// or completed. If completed, the `result` member of `RasterizationTask` /// contains the rasterized image. - rasterized_vector_images: HashMap<(PendingImageId, DeviceIntSize), RasterizationTask>, + rasterized_vector_images: FxHashMap<(PendingImageId, DeviceIntSize), RasterizationTask>, /// The placeholder image used when an image fails to load #[conditional_malloc_size_of] @@ -722,8 +722,8 @@ impl ImageCache for ImageCacheImpl { store: Arc::new(Mutex::new(ImageCacheStore { pending_loads: AllPendingLoads::new(), completed_loads: HashMap::new(), - vector_images: HashMap::new(), - rasterized_vector_images: HashMap::new(), + vector_images: FxHashMap::default(), + rasterized_vector_images: FxHashMap::default(), placeholder_image: get_placeholder_image(&compositor_api, &rippy_data), placeholder_url: ServoUrl::parse("chrome://resources/rippy.png").unwrap(), compositor_api: compositor_api.clone(), @@ -1083,8 +1083,8 @@ impl ImageCache for ImageCacheImpl { placeholder_image, placeholder_url, compositor_api, - vector_images: HashMap::new(), - rasterized_vector_images: HashMap::new(), + vector_images: FxHashMap::default(), + rasterized_vector_images: FxHashMap::default(), key_cache: KeyCache::new(), pipeline_id, })), diff --git a/components/script/Cargo.toml b/components/script/Cargo.toml index 4fb6a8590d8..01a21e44e6d 100644 --- a/components/script/Cargo.toml +++ b/components/script/Cargo.toml @@ -65,7 +65,6 @@ domobject_derive = { path = "../domobject_derive" } embedder_traits = { workspace = true } encoding_rs = { workspace = true } euclid = { workspace = true } -fnv = { workspace = true } fonts = { path = "../fonts" } fonts_traits = { workspace = true } fxhash = { workspace = true } diff --git a/components/script/dom/bindings/refcounted.rs b/components/script/dom/bindings/refcounted.rs index 052b8dbccc1..1bfe37c67aa 100644 --- a/components/script/dom/bindings/refcounted.rs +++ b/components/script/dom/bindings/refcounted.rs @@ -29,8 +29,8 @@ use std::marker::PhantomData; use std::rc::Rc; use std::sync::{Arc, Weak}; -use fnv::FnvHashMap; use js::jsapi::JSTracer; +use rustc_hash::FxHashMap; use script_bindings::script_runtime::CanGc; use crate::dom::bindings::conversions::ToJSValConvertible; @@ -47,14 +47,14 @@ mod dummy { use std::cell::RefCell; use std::rc::Rc; - use fnv::{FnvBuildHasher, FnvHashMap}; + use rustc_hash::FxHashMap; use super::LiveDOMReferences; thread_local!(pub(crate) static LIVE_REFERENCES: Rc> = Rc::new(RefCell::new( LiveDOMReferences { - reflectable_table: RefCell::new(FnvHashMap::with_hasher(FnvBuildHasher::new())), - promise_table: RefCell::new(FnvHashMap::with_hasher(FnvBuildHasher::new())), + reflectable_table: RefCell::new(FxHashMap::default()), + promise_table: RefCell::new(FxHashMap::default()), } ))); } @@ -232,8 +232,8 @@ impl Clone for Trusted { #[cfg_attr(crown, allow(crown::unrooted_must_root))] pub(crate) struct LiveDOMReferences { // keyed on pointer to Rust DOM object - reflectable_table: RefCell>>, - promise_table: RefCell>>>, + reflectable_table: RefCell>>, + promise_table: RefCell>>>, } impl LiveDOMReferences { @@ -283,7 +283,7 @@ impl LiveDOMReferences { } /// Remove null entries from the live references table -fn remove_nulls(table: &mut FnvHashMap>) { +fn remove_nulls(table: &mut FxHashMap>) { let to_remove: Vec = table .iter() .filter(|&(_, value)| Weak::upgrade(value).is_none()) diff --git a/components/script/dom/customelementregistry.rs b/components/script/dom/customelementregistry.rs index 016d1f81810..29636553e4e 100644 --- a/components/script/dom/customelementregistry.rs +++ b/components/script/dom/customelementregistry.rs @@ -15,6 +15,7 @@ use js::jsapi::{HandleValueArray, Heap, IsCallable, IsConstructor, JSAutoRealm, use js::jsval::{BooleanValue, JSVal, NullValue, ObjectValue, UndefinedValue}; use js::rust::wrappers::{Construct1, JS_GetProperty, SameValue}; use js::rust::{HandleObject, MutableHandleValue}; +use rustc_hash::FxBuildHasher; use script_bindings::conversions::{SafeFromJSValConvertible, SafeToJSValConvertible}; use super::bindings::trace::HashMapTracedValues; @@ -68,12 +69,15 @@ pub(crate) struct CustomElementRegistry { window: Dom, #[ignore_malloc_size_of = "Rc"] - when_defined: DomRefCell>>, + /// It is safe to use FxBuildHasher here as `LocalName` is an `Atom` in the string_cache. + /// These get a u32 hashed instead of a string. + when_defined: DomRefCell, FxBuildHasher>>, element_definition_is_running: Cell, #[ignore_malloc_size_of = "Rc"] - definitions: DomRefCell>>, + definitions: + DomRefCell, FxBuildHasher>>, } impl CustomElementRegistry { @@ -81,9 +85,9 @@ impl CustomElementRegistry { CustomElementRegistry { reflector_: Reflector::new(), window: Dom::from_ref(window), - when_defined: DomRefCell::new(HashMapTracedValues::new()), + when_defined: DomRefCell::new(HashMapTracedValues::new_fx()), element_definition_is_running: Cell::new(false), - definitions: DomRefCell::new(HashMapTracedValues::new()), + definitions: DomRefCell::new(HashMapTracedValues::new_fx()), } } diff --git a/components/script/dom/document.rs b/components/script/dom/document.rs index 0db9949b727..7a323c791af 100644 --- a/components/script/dom/document.rs +++ b/components/script/dom/document.rs @@ -30,7 +30,6 @@ use embedder_traits::{AllowOrDeny, AnimationState, EmbedderMsg, FocusSequenceNum use encoding_rs::{Encoding, UTF_8}; use euclid::Point2D; use euclid::default::{Rect, Size2D}; -use fnv::FnvHashMap; use html5ever::{LocalName, Namespace, QualName, local_name, ns}; use hyper_serde::Serde; use js::rust::{HandleObject, HandleValue, MutableHandleValue}; @@ -47,7 +46,7 @@ use percent_encoding::percent_decode; use profile_traits::ipc as profile_ipc; use profile_traits::time::TimerMetadataFrameType; use regex::bytes::Regex; -use rustc_hash::FxBuildHasher; +use rustc_hash::{FxBuildHasher, FxHashMap}; use script_bindings::codegen::GenericBindings::ElementBinding::ElementMethods; use script_bindings::interfaces::DocumentHelpers; use script_bindings::script_runtime::JSContext; @@ -304,11 +303,12 @@ pub(crate) struct Document { quirks_mode: Cell, /// A helper used to process and store data related to input event handling. event_handler: DocumentEventHandler, - /// Caches for the getElement methods - id_map: DomRefCell>>>, - name_map: DomRefCell>>>, - tag_map: DomRefCell>>, - tagns_map: DomRefCell>>, + /// Caches for the getElement methods. It is safe to use FxHash for these maps + /// as Atoms are `string_cache` items that will have the hash computed from a u32. + id_map: DomRefCell>, FxBuildHasher>>, + name_map: DomRefCell>, FxBuildHasher>>, + tag_map: DomRefCell, FxBuildHasher>>, + tagns_map: DomRefCell, FxBuildHasher>>, classes_map: DomRefCell, Dom>>, images: MutNullableDom, embeds: MutNullableDom, @@ -375,7 +375,7 @@ pub(crate) struct Document { appropriate_template_contents_owner_document: MutNullableDom, /// Information on elements needing restyle to ship over to layout when the /// time comes. - pending_restyles: DomRefCell, NoTrace>>, + pending_restyles: DomRefCell, NoTrace>>, /// A collection of reasons that the [`Document`] needs to be restyled at the next /// opportunity for a reflow. If this is empty, then the [`Document`] does not need to /// be restyled. @@ -436,7 +436,9 @@ pub(crate) struct Document { /// whenever any element with the same ID as the form attribute /// is inserted or removed from the document. /// See - form_id_listener_map: DomRefCell>>>, + /// It is safe to use FxBuildHasher here as Atoms are in the string_cache + form_id_listener_map: + DomRefCell>, FxBuildHasher>>, #[no_trace] interactive_time: DomRefCell, #[no_trace] @@ -2796,11 +2798,15 @@ impl Document { fonts.fulfill_ready_promise_if_needed(can_gc) } - pub(crate) fn id_map(&self) -> Ref<'_, HashMapTracedValues>>> { + pub(crate) fn id_map( + &self, + ) -> Ref<'_, HashMapTracedValues>, FxBuildHasher>> { self.id_map.borrow() } - pub(crate) fn name_map(&self) -> Ref<'_, HashMapTracedValues>>> { + pub(crate) fn name_map( + &self, + ) -> Ref<'_, HashMapTracedValues>, FxBuildHasher>> { self.name_map.borrow() } @@ -3332,14 +3338,14 @@ impl Document { // https://dom.spec.whatwg.org/#concept-document-quirks quirks_mode: Cell::new(QuirksMode::NoQuirks), event_handler: DocumentEventHandler::new(window), - id_map: DomRefCell::new(HashMapTracedValues::new()), - name_map: DomRefCell::new(HashMapTracedValues::new()), + id_map: DomRefCell::new(HashMapTracedValues::new_fx()), + name_map: DomRefCell::new(HashMapTracedValues::new_fx()), // https://dom.spec.whatwg.org/#concept-document-encoding encoding: Cell::new(encoding), is_html_document: is_html_document == IsHTMLDocument::HTMLDocument, activity: Cell::new(activity), - tag_map: DomRefCell::new(HashMapTracedValues::new()), - tagns_map: DomRefCell::new(HashMapTracedValues::new()), + tag_map: DomRefCell::new(HashMapTracedValues::new_fx()), + tagns_map: DomRefCell::new(HashMapTracedValues::new_fx()), classes_map: DomRefCell::new(HashMapTracedValues::new()), images: Default::default(), embeds: Default::default(), @@ -3383,7 +3389,7 @@ impl Document { current_parser: Default::default(), base_element: Default::default(), appropriate_template_contents_owner_document: Default::default(), - pending_restyles: DomRefCell::new(FnvHashMap::default()), + pending_restyles: DomRefCell::new(FxHashMap::default()), needs_restyle: Cell::new(RestyleReason::DOMChanged), dom_interactive: Cell::new(Default::default()), dom_content_loaded_event_start: Cell::new(Default::default()), diff --git a/components/script/dom/documentfragment.rs b/components/script/dom/documentfragment.rs index b2b89e3c793..9f7ecf156a4 100644 --- a/components/script/dom/documentfragment.rs +++ b/components/script/dom/documentfragment.rs @@ -4,6 +4,7 @@ use dom_struct::dom_struct; use js::rust::HandleObject; +use rustc_hash::FxBuildHasher; use stylo_atoms::Atom; use super::bindings::trace::HashMapTracedValues; @@ -29,7 +30,7 @@ use crate::script_runtime::CanGc; pub(crate) struct DocumentFragment { node: Node, /// Caches for the getElement methods - id_map: DomRefCell>>>, + id_map: DomRefCell>, FxBuildHasher>>, } impl DocumentFragment { @@ -37,7 +38,7 @@ impl DocumentFragment { pub(crate) fn new_inherited(document: &Document) -> DocumentFragment { DocumentFragment { node: Node::new_inherited(document), - id_map: DomRefCell::new(HashMapTracedValues::new()), + id_map: DomRefCell::new(HashMapTracedValues::new_fx()), } } @@ -58,7 +59,9 @@ impl DocumentFragment { ) } - pub(crate) fn id_map(&self) -> &DomRefCell>>> { + pub(crate) fn id_map( + &self, + ) -> &DomRefCell>, FxBuildHasher>> { &self.id_map } } diff --git a/components/script/dom/documentorshadowroot.rs b/components/script/dom/documentorshadowroot.rs index 7678c4d217c..cd0e5c38db7 100644 --- a/components/script/dom/documentorshadowroot.rs +++ b/components/script/dom/documentorshadowroot.rs @@ -9,6 +9,7 @@ use std::fmt; use embedder_traits::UntrustedNodeAddress; use js::rust::HandleValue; use layout_api::ElementsFromPointFlags; +use rustc_hash::FxBuildHasher; use script_bindings::error::{Error, ErrorResult}; use script_bindings::script_runtime::JSContext; use servo_arc::Arc; @@ -307,7 +308,7 @@ impl DocumentOrShadowRoot { /// Remove any existing association between the provided id/name and any elements in this document. pub(crate) fn unregister_named_element( &self, - id_map: &DomRefCell>>>, + id_map: &DomRefCell>, FxBuildHasher>>, to_unregister: &Element, id: &Atom, ) { @@ -335,7 +336,7 @@ impl DocumentOrShadowRoot { /// Associate an element present in this document with the provided id/name. pub(crate) fn register_named_element( &self, - id_map: &DomRefCell>>>, + id_map: &DomRefCell>, FxBuildHasher>>, element: &Element, id: &Atom, root: DomRoot, diff --git a/components/script/dom/eventtarget.rs b/components/script/dom/eventtarget.rs index 1ffc1e59707..9ef7b45722a 100644 --- a/components/script/dom/eventtarget.rs +++ b/components/script/dom/eventtarget.rs @@ -6,19 +6,18 @@ use std::cell::RefCell; use std::collections::hash_map::Entry::{Occupied, Vacant}; use std::default::Default; use std::ffi::CString; -use std::hash::BuildHasherDefault; use std::mem; use std::ops::{Deref, DerefMut}; use std::rc::Rc; use deny_public_fields::DenyPublicFields; use dom_struct::dom_struct; -use fnv::FnvHasher; use js::jsapi::JS::CompileFunction; use js::jsapi::{JS_GetFunctionObject, SupportUnscopables}; use js::jsval::JSVal; use js::rust::{CompileOptionsWrapper, HandleObject, transform_u16_to_source_text}; use libc::c_char; +use rustc_hash::FxBuildHasher; use servo_url::ServoUrl; use style::str::HTML_SPACE_CHARACTERS; use stylo_atoms::Atom; @@ -512,7 +511,7 @@ impl EventListeners { #[dom_struct] pub struct EventTarget { reflector_: Reflector, - handlers: DomRefCell>>, + handlers: DomRefCell>, } impl EventTarget { diff --git a/components/script/dom/globalscope.rs b/components/script/dom/globalscope.rs index 26a67867873..e97506836df 100644 --- a/components/script/dom/globalscope.rs +++ b/components/script/dom/globalscope.rs @@ -27,7 +27,6 @@ use crossbeam_channel::Sender; use devtools_traits::{PageError, ScriptToDevtoolsControlMsg}; use dom_struct::dom_struct; use embedder_traits::{EmbedderMsg, JavaScriptEvaluationError, ScriptToEmbedderChan}; -use fnv::FnvHashMap; use fonts::FontContext; use ipc_channel::ipc::{self, IpcSender}; use ipc_channel::router::ROUTER; @@ -567,7 +566,7 @@ impl MessageListener { }; let mut succeeded = vec![]; - let mut failed = FnvHashMap::default(); + let mut failed = FxHashMap::default(); for (id, info) in ports.into_iter() { if global.is_managing_port(&id) { diff --git a/components/script/dom/html/htmlformelement.rs b/components/script/dom/html/htmlformelement.rs index d6ad7e46aa1..ac6876392d5 100644 --- a/components/script/dom/html/htmlformelement.rs +++ b/components/script/dom/html/htmlformelement.rs @@ -16,6 +16,7 @@ use js::rust::HandleObject; use mime::{self, Mime}; use net_traits::http_percent_encode; use net_traits::request::Referrer; +use rustc_hash::FxBuildHasher; use servo_rand::random; use style::attr::AttrValue; use style::str::split_html_space_chars; @@ -93,8 +94,10 @@ pub(crate) struct HTMLFormElement { elements: DomOnceCell, controls: DomRefCell>>, + /// It is safe to use FxBuildHasher here as `Atom` is in the string_cache. #[allow(clippy::type_complexity)] - past_names_map: DomRefCell, NoTrace)>>, + past_names_map: + DomRefCell, NoTrace), FxBuildHasher>>, /// The current generation of past names, i.e., the number of name changes to the name. current_name_generation: Cell, @@ -126,7 +129,7 @@ impl HTMLFormElement { constructing_entry_list: Cell::new(false), elements: Default::default(), controls: DomRefCell::new(Vec::new()), - past_names_map: DomRefCell::new(HashMapTracedValues::new()), + past_names_map: DomRefCell::new(HashMapTracedValues::new_fx()), current_name_generation: Cell::new(0), firing_submission_events: Cell::new(false), rel_list: Default::default(), diff --git a/components/script/dom/servoparser/async_html.rs b/components/script/dom/servoparser/async_html.rs index 4a83ac95eef..86b33ab5368 100644 --- a/components/script/dom/servoparser/async_html.rs +++ b/components/script/dom/servoparser/async_html.rs @@ -6,7 +6,6 @@ use std::borrow::Cow; use std::cell::{Cell, Ref, RefCell, RefMut}; -use std::collections::HashMap; use std::collections::vec_deque::VecDeque; use std::rc::Rc; use std::thread; @@ -226,8 +225,8 @@ pub(crate) struct Tokenizer { #[ignore_malloc_size_of = "Defined in std"] #[no_trace] html_tokenizer_sender: Sender, - #[ignore_malloc_size_of = "Defined in std"] - nodes: RefCell>>, + //#[ignore_malloc_size_of = "Defined in std"] + nodes: RefCell>>, #[no_trace] url: ServoUrl, parsing_algorithm: ParsingAlgorithm, @@ -256,7 +255,7 @@ impl Tokenizer { document: Dom::from_ref(document), receiver: tokenizer_receiver, html_tokenizer_sender: to_html_tokenizer_sender, - nodes: RefCell::new(HashMap::new()), + nodes: RefCell::new(FxHashMap::default()), url, parsing_algorithm: algorithm, custom_element_reaction_stack, diff --git a/components/script/dom/stylepropertymapreadonly.rs b/components/script/dom/stylepropertymapreadonly.rs index e9baaf3aebc..fa2a8175df5 100644 --- a/components/script/dom/stylepropertymapreadonly.rs +++ b/components/script/dom/stylepropertymapreadonly.rs @@ -6,6 +6,7 @@ use std::cmp::Ordering; use std::iter::Iterator; use dom_struct::dom_struct; +use rustc_hash::FxBuildHasher; use style::custom_properties; use stylo_atoms::Atom; @@ -21,7 +22,7 @@ use crate::script_runtime::CanGc; #[dom_struct] pub(crate) struct StylePropertyMapReadOnly { reflector: Reflector, - entries: HashMapTracedValues>, + entries: HashMapTracedValues, FxBuildHasher>, } impl StylePropertyMapReadOnly { diff --git a/components/script/dom/webgl/extensions/extensions.rs b/components/script/dom/webgl/extensions/extensions.rs index ab93f3b8582..9fdf46586cb 100644 --- a/components/script/dom/webgl/extensions/extensions.rs +++ b/components/script/dom/webgl/extensions/extensions.rs @@ -7,9 +7,9 @@ use std::iter::FromIterator; use std::ptr::NonNull; use canvas_traits::webgl::{GlType, TexFormat, WebGLSLVersion, WebGLVersion}; -use fnv::{FnvHashMap, FnvHashSet}; use js::jsapi::JSObject; use malloc_size_of::MallocSizeOf; +use rustc_hash::{FxHashMap, FxHashSet}; type GLenum = u32; use super::wrapper::{TypedWebGLExtensionWrapper, WebGLExtensionWrapper}; @@ -81,25 +81,25 @@ const DEFAULT_DISABLED_GET_VERTEX_ATTRIB_NAMES_WEBGL1: [GLenum; 1] = /// WebGL features that are enabled/disabled by WebGL Extensions. #[derive(JSTraceable, MallocSizeOf)] struct WebGLExtensionFeatures { - gl_extensions: FnvHashSet, - disabled_tex_types: FnvHashSet, - not_filterable_tex_types: FnvHashSet, + gl_extensions: FxHashSet, + disabled_tex_types: FxHashSet, + not_filterable_tex_types: FxHashSet, #[no_trace] - effective_tex_internal_formats: FnvHashMap, + effective_tex_internal_formats: FxHashMap, /// WebGL Hint() targets enabled by extensions. - hint_targets: FnvHashSet, + hint_targets: FxHashSet, /// WebGL GetParameter() names enabled by extensions. - disabled_get_parameter_names: FnvHashSet, + disabled_get_parameter_names: FxHashSet, /// WebGL GetTexParameter() names enabled by extensions. - disabled_get_tex_parameter_names: FnvHashSet, + disabled_get_tex_parameter_names: FxHashSet, /// WebGL GetAttribVertex() names enabled by extensions. - disabled_get_vertex_attrib_names: FnvHashSet, + disabled_get_vertex_attrib_names: FxHashSet, /// WebGL OES_element_index_uint extension. element_index_uint_enabled: bool, /// WebGL EXT_blend_minmax extension. blend_minmax_enabled: bool, /// WebGL supported texture compression formats enabled by extensions. - tex_compression_formats: FnvHashMap, + tex_compression_formats: FxHashMap, } impl WebGLExtensionFeatures { @@ -199,7 +199,7 @@ impl WebGLExtensions { if self.extensions.borrow().is_empty() { let gl_str = cb(); self.features.borrow_mut().gl_extensions = - FnvHashSet::from_iter(gl_str.split(&[',', ' '][..]).map(|s| s.into())); + FxHashSet::from_iter(gl_str.split(&[',', ' '][..]).map(|s| s.into())); self.register_all_extensions(); } } @@ -382,7 +382,7 @@ impl WebGLExtensions { } pub(crate) fn add_tex_compression_formats(&self, formats: &[TexCompression]) { - let formats: FnvHashMap = formats + let formats: FxHashMap = formats .iter() .map(|&compression| (compression.format.as_gl_constant(), compression)) .collect(); diff --git a/components/script/dom/webgl/webglprogram.rs b/components/script/dom/webgl/webglprogram.rs index 875be1dc4d0..29750c521bd 100644 --- a/components/script/dom/webgl/webglprogram.rs +++ b/components/script/dom/webgl/webglprogram.rs @@ -4,13 +4,13 @@ // https://www.khronos.org/registry/webgl/specs/latest/1.0/webgl.idl use std::cell::Cell; +use std::collections::HashSet; use canvas_traits::webgl::{ ActiveAttribInfo, ActiveUniformBlockInfo, ActiveUniformInfo, WebGLCommand, WebGLError, WebGLProgramId, WebGLResult, webgl_channel, }; use dom_struct::dom_struct; -use fnv::FnvHashSet; use crate::canvas_context::CanvasContext; use crate::dom::bindings::cell::{DomRefCell, Ref}; @@ -180,8 +180,8 @@ impl WebGLProgram { let link_info = receiver.recv().unwrap(); { - let mut used_locs = FnvHashSet::default(); - let mut used_names = FnvHashSet::default(); + let mut used_locs = HashSet::new(); + let mut used_names = HashSet::new(); for active_attrib in &*link_info.active_attribs { let Some(location) = active_attrib.location else { continue; diff --git a/components/script/dom/webxr/xrsession.rs b/components/script/dom/webxr/xrsession.rs index 752150de775..555029b2016 100644 --- a/components/script/dom/webxr/xrsession.rs +++ b/components/script/dom/webxr/xrsession.rs @@ -17,6 +17,7 @@ use js::jsapi::JSObject; use js::rust::MutableHandleValue; use js::typedarray::Float32Array; use profile_traits::ipc; +use rustc_hash::FxBuildHasher; use stylo_atoms::Atom; use webxr_api::{ self, ApiSpace, ContextId as WebXRContextId, Display, EntityTypes, EnvironmentBlendMode, @@ -103,7 +104,8 @@ pub(crate) struct XRSession { #[no_trace] next_hit_test_id: Cell, #[ignore_malloc_size_of = "defined in webxr"] - pending_hit_test_promises: DomRefCell>>, + pending_hit_test_promises: + DomRefCell, FxBuildHasher>>, /// Opaque framebuffers need to know the session is "outside of a requestAnimationFrame" /// outside_raf: Cell, @@ -142,7 +144,7 @@ impl XRSession { end_promises: DomRefCell::new(vec![]), ended: Cell::new(false), next_hit_test_id: Cell::new(HitTestId(0)), - pending_hit_test_promises: DomRefCell::new(HashMapTracedValues::new()), + pending_hit_test_promises: DomRefCell::new(HashMapTracedValues::new_fx()), outside_raf: Cell::new(true), input_frames: DomRefCell::new(HashMap::new()), framerate: Cell::new(0.0), diff --git a/components/script/iframe_collection.rs b/components/script/iframe_collection.rs index 8aca5f5e91b..a59622bce56 100644 --- a/components/script/iframe_collection.rs +++ b/components/script/iframe_collection.rs @@ -7,8 +7,8 @@ use std::default::Default; use base::id::BrowsingContextId; use constellation_traits::{IFrameSizeMsg, ScriptToConstellationMessage, WindowSizeType}; use embedder_traits::ViewportDetails; -use fnv::FnvHashMap; use layout_api::IFrameSizes; +use rustc_hash::FxHashMap; use crate::dom::bindings::inheritance::Castable; use crate::dom::bindings::root::{Dom, DomRoot}; @@ -56,7 +56,7 @@ impl IFrameCollection { // Preserve any old sizes, but only for `