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<Atom,..>` 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 <Narfinger@users.noreply.github.com>

Testing: Hash function changes should not change functionality, we
slightly decrease the size and unit tests still work.

Signed-off-by: Narfinger <Narfinger@users.noreply.github.com>
This commit is contained in:
Narfinger 2025-09-10 15:34:54 +02:00 committed by GitHub
parent 726b456120
commit 84465e7768
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
55 changed files with 211 additions and 202 deletions

18
Cargo.lock generated
View file

@ -1480,13 +1480,13 @@ dependencies = [
"dpi", "dpi",
"embedder_traits", "embedder_traits",
"euclid", "euclid",
"fnv",
"gleam", "gleam",
"ipc-channel", "ipc-channel",
"libc", "libc",
"log", "log",
"pixels", "pixels",
"profile_traits", "profile_traits",
"rustc-hash 2.1.1",
"servo-tracing", "servo-tracing",
"servo_allocator", "servo_allocator",
"servo_config", "servo_config",
@ -1513,7 +1513,6 @@ dependencies = [
"dpi", "dpi",
"embedder_traits", "embedder_traits",
"euclid", "euclid",
"fnv",
"gleam", "gleam",
"glow", "glow",
"image", "image",
@ -1522,6 +1521,7 @@ dependencies = [
"malloc_size_of_derive", "malloc_size_of_derive",
"profile_traits", "profile_traits",
"raw-window-handle", "raw-window-handle",
"rustc-hash 2.1.1",
"serde", "serde",
"servo_geometry", "servo_geometry",
"servo_malloc_size_of", "servo_malloc_size_of",
@ -1577,7 +1577,6 @@ dependencies = [
"devtools_traits", "devtools_traits",
"embedder_traits", "embedder_traits",
"euclid", "euclid",
"fnv",
"fonts", "fonts",
"gaol", "gaol",
"ipc-channel", "ipc-channel",
@ -1590,6 +1589,7 @@ dependencies = [
"parking_lot", "parking_lot",
"profile", "profile",
"profile_traits", "profile_traits",
"rustc-hash 2.1.1",
"script_traits", "script_traits",
"serde", "serde",
"servo-tracing", "servo-tracing",
@ -1616,7 +1616,6 @@ dependencies = [
"devtools_traits", "devtools_traits",
"embedder_traits", "embedder_traits",
"euclid", "euclid",
"fnv",
"fonts_traits", "fonts_traits",
"http 1.3.1", "http 1.3.1",
"hyper_serde", "hyper_serde",
@ -2043,6 +2042,7 @@ dependencies = [
"log", "log",
"net", "net",
"net_traits", "net_traits",
"rustc-hash 2.1.1",
"serde", "serde",
"serde_json", "serde_json",
"servo_config", "servo_config",
@ -2376,6 +2376,7 @@ dependencies = [
"malloc_size_of_derive", "malloc_size_of_derive",
"num-derive", "num-derive",
"pixels", "pixels",
"rustc-hash 2.1.1",
"serde", "serde",
"servo_geometry", "servo_geometry",
"servo_malloc_size_of", "servo_malloc_size_of",
@ -2753,7 +2754,6 @@ dependencies = [
"core-text", "core-text",
"dwrote", "dwrote",
"euclid", "euclid",
"fnv",
"fonts_traits", "fonts_traits",
"fontsan", "fontsan",
"freetype-sys", "freetype-sys",
@ -2770,6 +2770,7 @@ dependencies = [
"profile_traits", "profile_traits",
"range", "range",
"read-fonts", "read-fonts",
"rustc-hash 2.1.1",
"serde", "serde",
"servo-tracing", "servo-tracing",
"servo_allocator", "servo_allocator",
@ -4836,7 +4837,6 @@ dependencies = [
"data-url", "data-url",
"embedder_traits", "embedder_traits",
"euclid", "euclid",
"fnv",
"fonts", "fonts",
"fonts_traits", "fonts_traits",
"fxhash", "fxhash",
@ -4892,7 +4892,6 @@ dependencies = [
"constellation_traits", "constellation_traits",
"embedder_traits", "embedder_traits",
"euclid", "euclid",
"fnv",
"fonts", "fonts",
"fonts_traits", "fonts_traits",
"html5ever", "html5ever",
@ -5599,6 +5598,7 @@ dependencies = [
"percent-encoding", "percent-encoding",
"pixels", "pixels",
"profile_traits", "profile_traits",
"rustc-hash 2.1.1",
"rustls-pki-types", "rustls-pki-types",
"serde", "serde",
"servo_arc", "servo_arc",
@ -7319,7 +7319,6 @@ dependencies = [
"embedder_traits", "embedder_traits",
"encoding_rs", "encoding_rs",
"euclid", "euclid",
"fnv",
"fonts", "fonts",
"fonts_traits", "fonts_traits",
"fxhash", "fxhash",
@ -7462,7 +7461,6 @@ dependencies = [
"devtools_traits", "devtools_traits",
"embedder_traits", "embedder_traits",
"euclid", "euclid",
"fnv",
"ipc-channel", "ipc-channel",
"keyboard-types", "keyboard-types",
"log", "log",
@ -7471,6 +7469,7 @@ dependencies = [
"net_traits", "net_traits",
"pixels", "pixels",
"profile_traits", "profile_traits",
"rustc-hash 2.1.1",
"serde", "serde",
"servo_config", "servo_config",
"servo_malloc_size_of", "servo_malloc_size_of",
@ -9792,6 +9791,7 @@ dependencies = [
"keyboard-types", "keyboard-types",
"log", "log",
"pixels", "pixels",
"rustc-hash 2.1.1",
"serde", "serde",
"serde_json", "serde_json",
"servo_config", "servo_config",

View file

@ -60,7 +60,6 @@ embedder_traits = { path = "components/shared/embedder" }
encoding_rs = "0.8" encoding_rs = "0.8"
env_logger = "0.11" env_logger = "0.11"
euclid = "0.22" euclid = "0.22"
fnv = "1.0"
fonts_traits = { path = "components/shared/fonts" } fonts_traits = { path = "components/shared/fonts" }
freetype-sys = "0.20" freetype-sys = "0.20"
fxhash = "0.2" fxhash = "0.2"

View file

@ -28,9 +28,9 @@ compositing_traits = { workspace = true }
constellation_traits = { workspace = true } constellation_traits = { workspace = true }
crossbeam-channel = { workspace = true } crossbeam-channel = { workspace = true }
dpi = { workspace = true } dpi = { workspace = true }
rustc-hash = { workspace = true }
embedder_traits = { workspace = true } embedder_traits = { workspace = true }
euclid = { workspace = true } euclid = { workspace = true }
fnv = { workspace = true }
gleam = { workspace = true } gleam = { workspace = true }
ipc-channel = { workspace = true } ipc-channel = { workspace = true }
libc = { workspace = true } libc = { workspace = true }

View file

@ -3,8 +3,8 @@
* file, You can obtain one at https://mozilla.org/MPL/2.0/. */ * file, You can obtain one at https://mozilla.org/MPL/2.0/. */
use std::cell::{Cell, Ref, RefCell}; use std::cell::{Cell, Ref, RefCell};
use std::collections::HashMap;
use std::collections::hash_map::Entry; use std::collections::hash_map::Entry;
use std::collections::{HashMap, HashSet};
use std::env; use std::env;
use std::fs::create_dir_all; use std::fs::create_dir_all;
use std::iter::once; use std::iter::once;
@ -28,7 +28,6 @@ use crossbeam_channel::Sender;
use dpi::PhysicalSize; use dpi::PhysicalSize;
use embedder_traits::{CompositorHitTestResult, InputEvent, ShutdownState, ViewportDetails}; use embedder_traits::{CompositorHitTestResult, InputEvent, ShutdownState, ViewportDetails};
use euclid::{Point2D, Rect, Scale, Size2D, Transform3D}; use euclid::{Point2D, Rect, Scale, Size2D, Transform3D};
use fnv::FnvHashMap;
use ipc_channel::ipc::{self, IpcSharedMemory}; use ipc_channel::ipc::{self, IpcSharedMemory};
use log::{debug, info, trace, warn}; use log::{debug, info, trace, warn};
use pixels::{CorsStatus, ImageFrame, ImageMetadata, PixelFormat, RasterImage}; 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::time::{self as profile_time, ProfilerCategory};
use profile_traits::{path, time_profile}; use profile_traits::{path, time_profile};
use rustc_hash::{FxHashMap, FxHashSet};
use servo_config::{opts, pref}; use servo_config::{opts, pref};
use servo_geometry::DeviceIndependentPixel; use servo_geometry::DeviceIndependentPixel;
use style_traits::CSSPixel; use style_traits::CSSPixel;
@ -1184,7 +1184,7 @@ impl IOCompositor {
// complete (i.e. has *all* layers painted to the requested epoch). // complete (i.e. has *all* layers painted to the requested epoch).
// This gets sent to the constellation for comparison with the current // This gets sent to the constellation for comparison with the current
// frame tree. // frame tree.
let mut pipeline_epochs = FnvHashMap::default(); let mut pipeline_epochs = FxHashMap::default();
for id in self for id in self
.webview_renderers .webview_renderers
.iter() .iter()
@ -1702,7 +1702,7 @@ struct FrameDelayer {
pending_frame: bool, pending_frame: bool,
/// A list of pipelines that should be notified when we are no longer waiting for /// A list of pipelines that should be notified when we are no longer waiting for
/// canvas images. /// canvas images.
waiting_pipelines: HashSet<PipelineId>, waiting_pipelines: FxHashSet<PipelineId>,
} }
impl FrameDelayer { impl FrameDelayer {

View file

@ -2,11 +2,10 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this * 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/. */ * file, You can obtain one at https://mozilla.org/MPL/2.0/. */
use std::collections::HashMap;
use embedder_traits::{TouchId, TouchSequenceId}; use embedder_traits::{TouchId, TouchSequenceId};
use euclid::{Point2D, Scale, Vector2D}; use euclid::{Point2D, Scale, Vector2D};
use log::{debug, error, warn}; use log::{debug, error, warn};
use rustc_hash::FxHashMap;
use webrender_api::units::{DeviceIntPoint, DevicePixel, DevicePoint, LayoutVector2D}; use webrender_api::units::{DeviceIntPoint, DevicePixel, DevicePoint, LayoutVector2D};
use self::TouchSequenceState::*; use self::TouchSequenceState::*;
@ -26,7 +25,7 @@ const FLING_MAX_SCREEN_PX: f32 = 4000.0;
pub struct TouchHandler { pub struct TouchHandler {
pub current_sequence_id: TouchSequenceId, pub current_sequence_id: TouchSequenceId,
// todo: VecDeque + modulo arithmetic would be more efficient. // todo: VecDeque + modulo arithmetic would be more efficient.
touch_sequence_map: HashMap<TouchSequenceId, TouchSequenceInfo>, touch_sequence_map: FxHashMap<TouchSequenceId, TouchSequenceInfo>,
} }
/// Whether the default move action is allowed or not. /// Whether the default move action is allowed or not.
@ -203,12 +202,14 @@ impl TouchHandler {
prevent_move: TouchMoveAllowed::Pending, prevent_move: TouchMoveAllowed::Pending,
pending_touch_move_action: None, 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 { TouchHandler {
current_sequence_id: TouchSequenceId::new(), current_sequence_id: TouchSequenceId::new(),
// We insert a simulated initial touch sequence, which is already finished, touch_sequence_map,
// 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)]),
} }
} }

View file

@ -2,10 +2,10 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this * 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/. */ * 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 std::collections::hash_map::{Entry, Values, ValuesMut};
use base::id::WebViewId; use base::id::WebViewId;
use rustc_hash::FxHashMap;
use crate::webview_renderer::{UnknownWebView, WebViewRenderer}; use crate::webview_renderer::{UnknownWebView, WebViewRenderer};
@ -13,7 +13,7 @@ use crate::webview_renderer::{UnknownWebView, WebViewRenderer};
pub struct WebViewManager<WebView> { pub struct WebViewManager<WebView> {
/// Our top-level browsing contexts. In the WebRender scene, their pipelines are the children of /// 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. /// a single root pipeline that also applies any pinch zoom transformation.
webviews: HashMap<WebViewId, WebView>, webviews: FxHashMap<WebViewId, WebView>,
/// The order to paint them in, topmost last. /// The order to paint them in, topmost last.
pub(crate) painting_order: Vec<WebViewId>, pub(crate) painting_order: Vec<WebViewId>,

View file

@ -3,7 +3,6 @@
* file, You can obtain one at https://mozilla.org/MPL/2.0/. */ * file, You can obtain one at https://mozilla.org/MPL/2.0/. */
use std::cell::RefCell; use std::cell::RefCell;
use std::collections::HashMap;
use std::collections::hash_map::{Entry, Keys}; use std::collections::hash_map::{Entry, Keys};
use std::rc::Rc; use std::rc::Rc;
@ -20,9 +19,9 @@ use embedder_traits::{
TouchEvent, TouchEventResult, TouchEventType, TouchId, ViewportDetails, TouchEvent, TouchEventResult, TouchEventType, TouchId, ViewportDetails,
}; };
use euclid::{Point2D, Scale, Vector2D}; use euclid::{Point2D, Scale, Vector2D};
use fnv::FnvHashSet;
use log::{debug, warn}; use log::{debug, warn};
use malloc_size_of::MallocSizeOf; use malloc_size_of::MallocSizeOf;
use rustc_hash::{FxHashMap, FxHashSet};
use servo_geometry::DeviceIndependentPixel; use servo_geometry::DeviceIndependentPixel;
use style_traits::{CSSPixel, PinchZoomFactor}; use style_traits::{CSSPixel, PinchZoomFactor};
use webrender_api::units::{DeviceIntPoint, DevicePixel, DevicePoint, DeviceRect, LayoutVector2D}; 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. /// The rectangle of the [`WebView`] in device pixels, which is the viewport.
pub rect: DeviceRect, pub rect: DeviceRect,
/// Tracks details about each active pipeline that the compositor knows about. /// Tracks details about each active pipeline that the compositor knows about.
pub pipelines: HashMap<PipelineId, PipelineDetails>, pub pipelines: FxHashMap<PipelineId, PipelineDetails>,
/// Data that is shared by all WebView renderers. /// Data that is shared by all WebView renderers.
pub(crate) global: Rc<RefCell<ServoRenderer>>, pub(crate) global: Rc<RefCell<ServoRenderer>>,
/// Pending scroll/zoom events. /// Pending scroll/zoom events.
@ -228,7 +227,7 @@ impl WebViewRenderer {
// state for some unattached pipelines in order to preserve scroll position when // state for some unattached pipelines in order to preserve scroll position when
// navigating backward and forward. // navigating backward and forward.
fn collect_pipelines( fn collect_pipelines(
pipelines: &mut FnvHashSet<PipelineId>, pipelines: &mut FxHashSet<PipelineId>,
frame_tree: &SendableFrameTree, frame_tree: &SendableFrameTree,
) { ) {
pipelines.insert(frame_tree.pipeline.id); pipelines.insert(frame_tree.pipeline.id);
@ -237,7 +236,7 @@ impl WebViewRenderer {
} }
} }
let mut attached_pipelines: FnvHashSet<PipelineId> = FnvHashSet::default(); let mut attached_pipelines: FxHashSet<PipelineId> = FxHashSet::default();
collect_pipelines(&mut attached_pipelines, frame_tree); collect_pipelines(&mut attached_pipelines, frame_tree);
self.pipelines self.pipelines

View file

@ -38,9 +38,9 @@ devtools_traits = { workspace = true }
embedder_traits = { workspace = true } embedder_traits = { workspace = true }
euclid = { workspace = true } euclid = { workspace = true }
fonts = { path = "../fonts" } fonts = { path = "../fonts" }
fnv = { workspace = true }
ipc-channel = { workspace = true } ipc-channel = { workspace = true }
keyboard-types = { workspace = true } keyboard-types = { workspace = true }
rustc-hash = { workspace = true }
layout_api = { workspace = true } layout_api = { workspace = true }
log = { workspace = true } log = { workspace = true }
media = { path = "../media" } media = { path = "../media" }

View file

@ -6,15 +6,15 @@ use std::collections::HashMap;
use base::id::BroadcastChannelRouterId; use base::id::BroadcastChannelRouterId;
use constellation_traits::BroadcastChannelMsg; use constellation_traits::BroadcastChannelMsg;
use fnv::FnvHashMap;
use ipc_channel::ipc::IpcSender; use ipc_channel::ipc::IpcSender;
use log::warn; use log::warn;
use rustc_hash::FxHashMap;
use servo_url::ImmutableOrigin; use servo_url::ImmutableOrigin;
#[derive(Default)] #[derive(Default)]
pub(crate) struct BroadcastChannels { pub(crate) struct BroadcastChannels {
/// A map of broadcast routers to their IPC sender. /// A map of broadcast routers to their IPC sender.
routers: FnvHashMap<BroadcastChannelRouterId, IpcSender<BroadcastChannelMsg>>, routers: FxHashMap<BroadcastChannelRouterId, IpcSender<BroadcastChannelMsg>>,
/// A map of origin to a map of channel name to a list of relevant routers. /// A map of origin to a map of channel name to a list of relevant routers.
channels: HashMap<ImmutableOrigin, HashMap<String, Vec<BroadcastChannelRouterId>>>, channels: HashMap<ImmutableOrigin, HashMap<String, Vec<BroadcastChannelRouterId>>>,

View file

@ -4,8 +4,8 @@
use base::id::{BrowsingContextGroupId, BrowsingContextId, PipelineId, WebViewId}; use base::id::{BrowsingContextGroupId, BrowsingContextId, PipelineId, WebViewId};
use embedder_traits::ViewportDetails; use embedder_traits::ViewportDetails;
use fnv::{FnvHashMap, FnvHashSet};
use log::warn; use log::warn;
use rustc_hash::{FxHashMap, FxHashSet};
use crate::pipeline::Pipeline; use crate::pipeline::Pipeline;
@ -70,7 +70,7 @@ pub struct BrowsingContext {
/// All the pipelines that have been presented or will be presented in /// All the pipelines that have been presented or will be presented in
/// this browsing context. /// this browsing context.
pub pipelines: FnvHashSet<PipelineId>, pub pipelines: FxHashSet<PipelineId>,
} }
impl BrowsingContext { impl BrowsingContext {
@ -88,7 +88,7 @@ impl BrowsingContext {
inherited_secure_context: Option<bool>, inherited_secure_context: Option<bool>,
throttled: bool, throttled: bool,
) -> BrowsingContext { ) -> BrowsingContext {
let mut pipelines = FnvHashSet::default(); let mut pipelines = FxHashSet::default();
pipelines.insert(pipeline_id); pipelines.insert(pipeline_id);
BrowsingContext { BrowsingContext {
bc_group_id, bc_group_id,
@ -122,12 +122,12 @@ pub struct FullyActiveBrowsingContextsIterator<'a> {
pub stack: Vec<BrowsingContextId>, pub stack: Vec<BrowsingContextId>,
/// The set of all browsing contexts. /// The set of all browsing contexts.
pub browsing_contexts: &'a FnvHashMap<BrowsingContextId, BrowsingContext>, pub browsing_contexts: &'a FxHashMap<BrowsingContextId, BrowsingContext>,
/// The set of all pipelines. We use this to find the active /// The set of all pipelines. We use this to find the active
/// children of a frame, which are the iframes in the currently /// children of a frame, which are the iframes in the currently
/// active document. /// active document.
pub pipelines: &'a FnvHashMap<PipelineId, Pipeline>, pub pipelines: &'a FxHashMap<PipelineId, Pipeline>,
} }
impl<'a> Iterator for FullyActiveBrowsingContextsIterator<'a> { impl<'a> Iterator for FullyActiveBrowsingContextsIterator<'a> {
@ -169,12 +169,12 @@ pub struct AllBrowsingContextsIterator<'a> {
pub stack: Vec<BrowsingContextId>, pub stack: Vec<BrowsingContextId>,
/// The set of all browsing contexts. /// The set of all browsing contexts.
pub browsing_contexts: &'a FnvHashMap<BrowsingContextId, BrowsingContext>, pub browsing_contexts: &'a FxHashMap<BrowsingContextId, BrowsingContext>,
/// The set of all pipelines. We use this to find the /// The set of all pipelines. We use this to find the
/// children of a browsing context, which are the iframes in all documents /// children of a browsing context, which are the iframes in all documents
/// in the session history. /// in the session history.
pub pipelines: &'a FnvHashMap<PipelineId, Pipeline>, pub pipelines: &'a FxHashMap<PipelineId, Pipeline>,
} }
impl<'a> Iterator for AllBrowsingContextsIterator<'a> { impl<'a> Iterator for AllBrowsingContextsIterator<'a> {

View file

@ -139,7 +139,6 @@ use embedder_traits::{
}; };
use euclid::Size2D; use euclid::Size2D;
use euclid::default::Size2D as UntypedSize2D; use euclid::default::Size2D as UntypedSize2D;
use fnv::{FnvHashMap, FnvHashSet};
use fonts::SystemFontServiceProxy; use fonts::SystemFontServiceProxy;
use ipc_channel::Error as IpcError; use ipc_channel::Error as IpcError;
use ipc_channel::ipc::{self, IpcReceiver, IpcSender}; use ipc_channel::ipc::{self, IpcReceiver, IpcSender};
@ -157,6 +156,7 @@ use net_traits::{
}; };
use profile_traits::mem::ProfilerMsg; use profile_traits::mem::ProfilerMsg;
use profile_traits::{mem, time}; use profile_traits::{mem, time};
use rustc_hash::{FxHashMap, FxHashSet};
use script_traits::{ use script_traits::{
ConstellationInputEvent, DiscardBrowsingContext, DocumentActivity, ProgressiveWebMetricType, ConstellationInputEvent, DiscardBrowsingContext, DocumentActivity, ProgressiveWebMetricType,
ScriptThreadMessage, UpdatePipelineIdReason, ScriptThreadMessage, UpdatePipelineIdReason,
@ -190,7 +190,7 @@ use crate::session_history::{
}; };
use crate::webview_manager::WebViewManager; use crate::webview_manager::WebViewManager;
type PendingApprovalNavigations = HashMap<PipelineId, (LoadData, NavigationHistoryBehavior)>; type PendingApprovalNavigations = FxHashMap<PipelineId, (LoadData, NavigationHistoryBehavior)>;
#[derive(Debug)] #[derive(Debug)]
/// The state used by MessagePortInfo to represent the various states the port can be in. /// The state used by MessagePortInfo to represent the various states the port can be in.
@ -241,7 +241,7 @@ struct WebrenderWGPU {
#[derive(Clone, Default)] #[derive(Clone, Default)]
struct BrowsingContextGroup { struct BrowsingContextGroup {
/// A browsing context group holds a set of top-level browsing contexts. /// A browsing context group holds a set of top-level browsing contexts.
top_level_browsing_context_set: FnvHashSet<WebViewId>, top_level_browsing_context_set: FxHashSet<WebViewId>,
/// The set of all event loops in this BrowsingContextGroup. /// The set of all event loops in this BrowsingContextGroup.
/// We store the event loops in a map /// We store the event loops in a map
@ -385,25 +385,25 @@ pub struct Constellation<STF, SWF> {
webrender_wgpu: WebrenderWGPU, webrender_wgpu: WebrenderWGPU,
/// A map of message-port Id to info. /// A map of message-port Id to info.
message_ports: FnvHashMap<MessagePortId, MessagePortInfo>, message_ports: FxHashMap<MessagePortId, MessagePortInfo>,
/// A map of router-id to ipc-sender, to route messages to ports. /// A map of router-id to ipc-sender, to route messages to ports.
message_port_routers: FnvHashMap<MessagePortRouterId, IpcSender<MessagePortMsg>>, message_port_routers: FxHashMap<MessagePortRouterId, IpcSender<MessagePortMsg>>,
/// Bookkeeping for BroadcastChannel functionnality. /// Bookkeeping for BroadcastChannel functionnality.
broadcast_channels: BroadcastChannels, broadcast_channels: BroadcastChannels,
/// The set of all the pipelines in the browser. (See the `pipeline` module /// The set of all the pipelines in the browser. (See the `pipeline` module
/// for more details.) /// for more details.)
pipelines: FnvHashMap<PipelineId, Pipeline>, pipelines: FxHashMap<PipelineId, Pipeline>,
/// The set of all the browsing contexts in the browser. /// The set of all the browsing contexts in the browser.
browsing_contexts: FnvHashMap<BrowsingContextId, BrowsingContext>, browsing_contexts: FxHashMap<BrowsingContextId, BrowsingContext>,
/// A user agent holds a a set of browsing context groups. /// A user agent holds a a set of browsing context groups.
/// ///
/// <https://html.spec.whatwg.org/multipage/#browsing-context-group-set> /// <https://html.spec.whatwg.org/multipage/#browsing-context-group-set>
browsing_context_group_set: FnvHashMap<BrowsingContextGroupId, BrowsingContextGroup>, browsing_context_group_set: FxHashMap<BrowsingContextGroupId, BrowsingContextGroup>,
/// The Id counter for BrowsingContextGroup. /// The Id counter for BrowsingContextGroup.
browsing_context_group_next_id: u32, browsing_context_group_next_id: u32,
@ -426,7 +426,7 @@ pub struct Constellation<STF, SWF> {
webdriver_input_command_reponse_sender: Option<IpcSender<WebDriverCommandResponse>>, webdriver_input_command_reponse_sender: Option<IpcSender<WebDriverCommandResponse>>,
/// Document states for loaded pipelines (used only when writing screenshots). /// Document states for loaded pipelines (used only when writing screenshots).
document_states: FnvHashMap<PipelineId, DocumentState>, document_states: FxHashMap<PipelineId, DocumentState>,
/// Are we shutting down? /// Are we shutting down?
shutting_down: bool, shutting_down: bool,
@ -482,7 +482,7 @@ pub struct Constellation<STF, SWF> {
async_runtime: Box<dyn AsyncRuntime>, async_runtime: Box<dyn AsyncRuntime>,
/// When in single-process mode, join handles for script-threads. /// When in single-process mode, join handles for script-threads.
script_join_handles: FnvHashMap<WebViewId, JoinHandle<()>>, script_join_handles: FxHashMap<WebViewId, JoinHandle<()>>,
/// A list of URLs that can access privileged internal APIs. /// A list of URLs that can access privileged internal APIs.
privileged_urls: Vec<ServoUrl>, privileged_urls: Vec<ServoUrl>,
@ -2120,7 +2120,7 @@ where
fn handle_message_port_transfer_failed( fn handle_message_port_transfer_failed(
&mut self, &mut self,
ports: FnvHashMap<MessagePortId, PortTransferInfo>, ports: FxHashMap<MessagePortId, PortTransferInfo>,
) { ) {
for (port_id, mut transfer_info) in ports.into_iter() { for (port_id, mut transfer_info) in ports.into_iter() {
let entry = match self.message_ports.remove(&port_id) { let entry = match self.message_ports.remove(&port_id) {
@ -2202,7 +2202,7 @@ where
router_id: MessagePortRouterId, router_id: MessagePortRouterId,
ports: Vec<MessagePortId>, ports: Vec<MessagePortId>,
) { ) {
let mut response = FnvHashMap::default(); let mut response = FxHashMap::default();
for port_id in ports.into_iter() { for port_id in ports.into_iter() {
let entry = match self.message_ports.remove(&port_id) { let entry = match self.message_ports.remove(&port_id) {
None => { None => {
@ -3785,11 +3785,10 @@ where
webview_id: WebViewId, webview_id: WebViewId,
direction: TraversalDirection, direction: TraversalDirection,
) { ) {
let mut browsing_context_changes = let mut browsing_context_changes = FxHashMap::<BrowsingContextId, NeedsToReload>::default();
FnvHashMap::<BrowsingContextId, NeedsToReload>::default();
let mut pipeline_changes = let mut pipeline_changes =
FnvHashMap::<PipelineId, (Option<HistoryStateId>, ServoUrl)>::default(); FxHashMap::<PipelineId, (Option<HistoryStateId>, ServoUrl)>::default();
let mut url_to_load = FnvHashMap::<PipelineId, ServoUrl>::default(); let mut url_to_load = FxHashMap::<PipelineId, ServoUrl>::default();
{ {
let session_history = self.get_joint_session_history(webview_id); let session_history = self.get_joint_session_history(webview_id);
match direction { match direction {
@ -4792,7 +4791,7 @@ where
}; };
let mut pipelines_to_close = vec![]; 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 let diffs_to_close = self
.get_joint_session_history(change.webview_id) .get_joint_session_history(change.webview_id)
@ -5049,7 +5048,7 @@ where
#[servo_tracing::instrument(skip_all)] #[servo_tracing::instrument(skip_all)]
fn handle_is_ready_to_save_image( fn handle_is_ready_to_save_image(
&mut self, &mut self,
pipeline_states: FnvHashMap<PipelineId, Epoch>, pipeline_states: FxHashMap<PipelineId, Epoch>,
) -> ReadyToSave { ) -> ReadyToSave {
// Note that this function can panic, due to ipc-channel creation // Note that this function can panic, due to ipc-channel creation
// failure. Avoiding this panic would require a mechanism for dealing // failure. Avoiding this panic would require a mechanism for dealing
@ -5593,7 +5592,7 @@ where
fn handle_set_scroll_states( fn handle_set_scroll_states(
&self, &self,
pipeline_id: PipelineId, pipeline_id: PipelineId,
scroll_states: FnvHashMap<ExternalScrollId, LayoutVector2D>, scroll_states: FxHashMap<ExternalScrollId, LayoutVector2D>,
) { ) {
let Some(pipeline) = self.pipelines.get(&pipeline_id) else { let Some(pipeline) = self.pipelines.get(&pipeline_id) else {
warn!("Discarding scroll offset update for unknown pipeline"); warn!("Discarding scroll offset update for unknown pipeline");

View file

@ -5,8 +5,8 @@
use base::id::{BrowsingContextId, PipelineId}; use base::id::{BrowsingContextId, PipelineId};
use embedder_traits::{InputEvent, MouseLeftViewportEvent, Theme}; use embedder_traits::{InputEvent, MouseLeftViewportEvent, Theme};
use euclid::Point2D; use euclid::Point2D;
use fnv::FnvHashMap;
use log::warn; use log::warn;
use rustc_hash::FxHashMap;
use script_traits::{ConstellationInputEvent, ScriptThreadMessage}; use script_traits::{ConstellationInputEvent, ScriptThreadMessage};
use style_traits::CSSPixel; use style_traits::CSSPixel;
@ -63,7 +63,7 @@ impl ConstellationWebView {
fn target_pipeline_id_for_input_event( fn target_pipeline_id_for_input_event(
&self, &self,
event: &ConstellationInputEvent, event: &ConstellationInputEvent,
browsing_contexts: &FnvHashMap<BrowsingContextId, BrowsingContext>, browsing_contexts: &FxHashMap<BrowsingContextId, BrowsingContext>,
) -> Option<PipelineId> { ) -> Option<PipelineId> {
if let Some(hit_test_result) = &event.hit_test_result { if let Some(hit_test_result) = &event.hit_test_result {
return Some(hit_test_result.pipeline_id); return Some(hit_test_result.pipeline_id);
@ -84,8 +84,8 @@ impl ConstellationWebView {
pub(crate) fn forward_input_event( pub(crate) fn forward_input_event(
&mut self, &mut self,
event: ConstellationInputEvent, event: ConstellationInputEvent,
pipelines: &FnvHashMap<PipelineId, Pipeline>, pipelines: &FxHashMap<PipelineId, Pipeline>,
browsing_contexts: &FnvHashMap<BrowsingContextId, BrowsingContext>, browsing_contexts: &FxHashMap<BrowsingContextId, BrowsingContext>,
) { ) {
let Some(pipeline_id) = self.target_pipeline_id_for_input_event(&event, browsing_contexts) let Some(pipeline_id) = self.target_pipeline_id_for_input_event(&event, browsing_contexts)
else { else {

View file

@ -2,16 +2,14 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this * 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/. */ * file, You can obtain one at https://mozilla.org/MPL/2.0/. */
use std::collections::HashMap;
use base::id::WebViewId; use base::id::WebViewId;
use fnv::FnvHashMap; use rustc_hash::FxHashMap;
#[derive(Debug)] #[derive(Debug)]
pub struct WebViewManager<WebView> { pub struct WebViewManager<WebView> {
/// Our top-level browsing contexts. In the WebRender scene, their pipelines are the children of /// 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. /// a single root pipeline that also applies any pinch zoom transformation.
webviews: FnvHashMap<WebViewId, WebView>, webviews: FxHashMap<WebViewId, WebView>,
/// The order in which they were focused, latest last. /// The order in which they were focused, latest last.
focus_order: Vec<WebViewId>, focus_order: Vec<WebViewId>,
@ -23,7 +21,7 @@ pub struct WebViewManager<WebView> {
impl<WebView> Default for WebViewManager<WebView> { impl<WebView> Default for WebViewManager<WebView> {
fn default() -> Self { fn default() -> Self {
Self { Self {
webviews: HashMap::default(), webviews: FxHashMap::default(),
focus_order: Vec::default(), focus_order: Vec::default(),
is_focused: false, is_focused: false,
} }

View file

@ -15,6 +15,7 @@ path = "lib.rs"
base = { workspace = true } base = { workspace = true }
base64 = { workspace = true } base64 = { workspace = true }
chrono = { workspace = true } chrono = { workspace = true }
rustc-hash = { workspace = true }
crossbeam-channel = { workspace = true } crossbeam-channel = { workspace = true }
devtools_traits = { workspace = true } devtools_traits = { workspace = true }
embedder_traits = { workspace = true } embedder_traits = { workspace = true }

View file

@ -2,15 +2,14 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this * 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/. */ * file, You can obtain one at https://mozilla.org/MPL/2.0/. */
use std::collections::HashMap;
use base::id::{BrowsingContextId, PipelineId, WebViewId}; use base::id::{BrowsingContextId, PipelineId, WebViewId};
use rustc_hash::FxHashMap;
#[derive(Debug, Default)] #[derive(Debug, Default)]
pub(crate) struct IdMap { pub(crate) struct IdMap {
pub(crate) browser_ids: HashMap<WebViewId, u32>, pub(crate) browser_ids: FxHashMap<WebViewId, u32>,
pub(crate) browsing_context_ids: HashMap<BrowsingContextId, u32>, pub(crate) browsing_context_ids: FxHashMap<BrowsingContextId, u32>,
pub(crate) outer_window_ids: HashMap<PipelineId, u32>, pub(crate) outer_window_ids: FxHashMap<PipelineId, u32>,
} }
impl IdMap { impl IdMap {

View file

@ -30,6 +30,7 @@ use embedder_traits::{AllowOrDeny, EmbedderMsg, EmbedderProxy};
use ipc_channel::ipc::IpcSender; use ipc_channel::ipc::IpcSender;
use log::{trace, warn}; use log::{trace, warn};
use resource::{ResourceArrayType, ResourceAvailable}; use resource::{ResourceArrayType, ResourceAvailable};
use rustc_hash::FxHashMap;
use serde::Serialize; use serde::Serialize;
use servo_rand::RngCore; use servo_rand::RngCore;
@ -116,12 +117,12 @@ pub(crate) struct StreamId(u32);
struct DevtoolsInstance { struct DevtoolsInstance {
actors: Arc<Mutex<ActorRegistry>>, actors: Arc<Mutex<ActorRegistry>>,
id_map: Arc<Mutex<IdMap>>, id_map: Arc<Mutex<IdMap>>,
browsing_contexts: HashMap<BrowsingContextId, String>, browsing_contexts: FxHashMap<BrowsingContextId, String>,
receiver: Receiver<DevtoolsControlMsg>, receiver: Receiver<DevtoolsControlMsg>,
pipelines: HashMap<PipelineId, BrowsingContextId>, pipelines: FxHashMap<PipelineId, BrowsingContextId>,
actor_workers: HashMap<WorkerId, String>, actor_workers: FxHashMap<WorkerId, String>,
actor_requests: HashMap<String, String>, actor_requests: HashMap<String, String>,
connections: HashMap<StreamId, TcpStream>, connections: FxHashMap<StreamId, TcpStream>,
next_resource_id: u64, next_resource_id: u64,
} }
@ -179,12 +180,12 @@ impl DevtoolsInstance {
let instance = Self { let instance = Self {
actors, actors,
id_map: Arc::new(Mutex::new(IdMap::default())), id_map: Arc::new(Mutex::new(IdMap::default())),
browsing_contexts: HashMap::new(), browsing_contexts: FxHashMap::default(),
pipelines: HashMap::new(), pipelines: FxHashMap::default(),
receiver, receiver,
actor_requests: HashMap::new(), actor_requests: HashMap::new(),
actor_workers: HashMap::new(), actor_workers: FxHashMap::default(),
connections: HashMap::new(), connections: FxHashMap::default(),
next_resource_id: 1, next_resource_id: 1,
}; };

View file

@ -22,7 +22,6 @@ base = { workspace = true }
bitflags = { workspace = true } bitflags = { workspace = true }
compositing_traits = { workspace = true } compositing_traits = { workspace = true }
euclid = { workspace = true } euclid = { workspace = true }
fnv = { workspace = true }
fonts_traits = { workspace = true } fonts_traits = { workspace = true }
fontsan = { git = "https://github.com/servo/fontsan" } fontsan = { git = "https://github.com/servo/fontsan" }
# FIXME (#34517): macOS only needs this when building libservo without `--features media-gstreamer` # 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" } servo_url = { path = "../url" }
skrifa = { workspace = true } skrifa = { workspace = true }
smallvec = { workspace = true } smallvec = { workspace = true }
rustc-hash = { workspace = true }
stylo = { workspace = true } stylo = { workspace = true }
stylo_atoms = { workspace = true } stylo_atoms = { workspace = true }
tracing = { workspace = true, optional = true } tracing = { workspace = true, optional = true }

View file

@ -4,7 +4,7 @@
use std::collections::{HashMap, HashSet}; use std::collections::{HashMap, HashSet};
use std::default::Default; use std::default::Default;
use std::hash::{BuildHasherDefault, Hash, Hasher}; use std::hash::{Hash, Hasher};
use std::ops::Deref; use std::ops::Deref;
use std::sync::Arc; use std::sync::Arc;
use std::sync::atomic::{AtomicBool, Ordering}; use std::sync::atomic::{AtomicBool, Ordering};
@ -12,7 +12,6 @@ use std::sync::atomic::{AtomicBool, Ordering};
use app_units::Au; use app_units::Au;
use base::id::WebViewId; use base::id::WebViewId;
use compositing_traits::CrossProcessCompositorApi; use compositing_traits::CrossProcessCompositorApi;
use fnv::FnvHasher;
use fonts_traits::{ use fonts_traits::{
CSSFontFaceDescriptors, FontDescriptor, FontIdentifier, FontTemplate, FontTemplateRef, CSSFontFaceDescriptors, FontDescriptor, FontIdentifier, FontTemplate, FontTemplateRef,
FontTemplateRefMethods, StylesheetWebFontLoadFinishedCallback, FontTemplateRefMethods, StylesheetWebFontLoadFinishedCallback,
@ -22,6 +21,7 @@ use malloc_size_of_derive::MallocSizeOf;
use net_traits::request::{Destination, Referrer, RequestBuilder}; use net_traits::request::{Destination, Referrer, RequestBuilder};
use net_traits::{CoreResourceThread, FetchResponseMsg, ResourceThreads, fetch_async}; use net_traits::{CoreResourceThread, FetchResponseMsg, ResourceThreads, fetch_async};
use parking_lot::{Mutex, RwLock}; use parking_lot::{Mutex, RwLock};
use rustc_hash::FxHashSet;
use servo_arc::Arc as ServoArc; use servo_arc::Arc as ServoArc;
use servo_config::pref; use servo_config::pref;
use servo_url::ServoUrl; use servo_url::ServoUrl;
@ -78,8 +78,7 @@ pub struct FontContext {
/// A caching map between the specification of a font in CSS style and /// A caching map between the specification of a font in CSS style and
/// resolved [`FontGroup`] which contains information about all fonts that /// resolved [`FontGroup`] which contains information about all fonts that
/// can be selected with that style. /// can be selected with that style.
resolved_font_groups: resolved_font_groups: RwLock<HashMap<FontGroupCacheKey, FontGroupRef>>,
RwLock<HashMap<FontGroupCacheKey, FontGroupRef, BuildHasherDefault<FnvHasher>>>,
web_fonts: CrossThreadFontStore, web_fonts: CrossThreadFontStore,
@ -612,7 +611,7 @@ impl FontContextWebFontMethods for Arc<FontContext> {
self.have_removed_web_fonts.store(false, Ordering::Relaxed); self.have_removed_web_fonts.store(false, Ordering::Relaxed);
let mut removed_keys: HashSet<FontKey> = HashSet::new(); let mut removed_keys: FxHashSet<FontKey> = FxHashSet::default();
webrender_font_keys.retain(|identifier, font_key| { webrender_font_keys.retain(|identifier, font_key| {
if unused_identifiers.contains(identifier) { if unused_identifiers.contains(identifier) {
removed_keys.insert(*font_key); removed_keys.insert(*font_key);

View file

@ -26,7 +26,6 @@ cssparser = { workspace = true }
data-url = { workspace = true } data-url = { workspace = true }
embedder_traits = { workspace = true } embedder_traits = { workspace = true }
euclid = { workspace = true } euclid = { workspace = true }
fnv = { workspace = true }
fonts = { path = "../fonts" } fonts = { path = "../fonts" }
fonts_traits = { workspace = true } fonts_traits = { workspace = true }
fxhash = { workspace = true } fxhash = { workspace = true }

View file

@ -2,11 +2,11 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this * 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/. */ * file, You can obtain one at https://mozilla.org/MPL/2.0/. */
use std::collections::HashMap;
use std::sync::Arc; use std::sync::Arc;
use embedder_traits::UntrustedNodeAddress; use embedder_traits::UntrustedNodeAddress;
use euclid::Size2D; use euclid::Size2D;
use fnv::FnvHashMap;
use fonts::FontContext; use fonts::FontContext;
use layout_api::wrapper_traits::ThreadSafeLayoutNode; use layout_api::wrapper_traits::ThreadSafeLayoutNode;
use layout_api::{ 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 // 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. // for `background-image` or `content` property) to the final resolved image data.
pub resolved_images_cache: pub resolved_images_cache: Arc<RwLock<HashMap<(ServoUrl, UsePlaceholder), CachedImageOrError>>>,
Arc<RwLock<FnvHashMap<(ServoUrl, UsePlaceholder), CachedImageOrError>>>,
/// The current animation timeline value used to properly initialize animating images. /// The current animation timeline value used to properly initialize animating images.
pub animation_timeline_value: f64, pub animation_timeline_value: f64,

View file

@ -2,14 +2,13 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this * 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/. */ * file, You can obtain one at https://mozilla.org/MPL/2.0/. */
use std::collections::HashMap;
use app_units::Au; use app_units::Au;
use base::id::ScrollTreeNodeId; use base::id::ScrollTreeNodeId;
use embedder_traits::Cursor; use embedder_traits::Cursor;
use euclid::{Box2D, Vector2D}; use euclid::{Box2D, Vector2D};
use kurbo::{Ellipse, Shape}; use kurbo::{Ellipse, Shape};
use layout_api::{ElementsFromPointFlags, ElementsFromPointResult}; use layout_api::{ElementsFromPointFlags, ElementsFromPointResult};
use rustc_hash::FxHashMap;
use servo_geometry::FastLayoutTransform; use servo_geometry::FastLayoutTransform;
use style::computed_values::backface_visibility::T as BackfaceVisibility; use style::computed_values::backface_visibility::T as BackfaceVisibility;
use style::computed_values::pointer_events::T as PointerEvents; 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. /// The resulting [`HitTestResultItems`] for this hit test.
results: Vec<ElementsFromPointResult>, results: Vec<ElementsFromPointResult>,
/// A cache of hit test results for shared clip nodes. /// A cache of hit test results for shared clip nodes.
clip_hit_test_results: HashMap<ClipId, bool>, clip_hit_test_results: FxHashMap<ClipId, bool>,
} }
impl<'a> HitTest<'a> { impl<'a> HitTest<'a> {
@ -55,7 +54,7 @@ impl<'a> HitTest<'a> {
projected_point_to_test: None, projected_point_to_test: None,
stacking_context_tree, stacking_context_tree,
results: Vec::new(), results: Vec::new(),
clip_hit_test_results: HashMap::new(), clip_hit_test_results: FxHashMap::default(),
}; };
stacking_context_tree stacking_context_tree
.root_stacking_context .root_stacking_context

View file

@ -5,6 +5,7 @@
#![allow(unsafe_code)] #![allow(unsafe_code)]
use std::cell::{Cell, RefCell}; use std::cell::{Cell, RefCell};
use std::collections::HashMap;
use std::fmt::Debug; use std::fmt::Debug;
use std::process; use std::process;
use std::rc::Rc; use std::rc::Rc;
@ -21,10 +22,8 @@ use cssparser::ParserInput;
use embedder_traits::{Theme, ViewportDetails}; use embedder_traits::{Theme, ViewportDetails};
use euclid::default::{Point2D as UntypedPoint2D, Rect as UntypedRect}; use euclid::default::{Point2D as UntypedPoint2D, Rect as UntypedRect};
use euclid::{Point2D, Scale, Size2D}; use euclid::{Point2D, Scale, Size2D};
use fnv::FnvHashMap;
use fonts::{FontContext, FontContextWebFontMethods}; use fonts::{FontContext, FontContextWebFontMethods};
use fonts_traits::StylesheetWebFontLoadFinishedCallback; use fonts_traits::StylesheetWebFontLoadFinishedCallback;
use fxhash::FxHashMap;
use layout_api::wrapper_traits::LayoutNode; use layout_api::wrapper_traits::LayoutNode;
use layout_api::{ use layout_api::{
BoxAreaType, IFrameSizes, Layout, LayoutConfig, LayoutDamage, LayoutFactory, BoxAreaType, IFrameSizes, Layout, LayoutConfig, LayoutDamage, LayoutFactory,
@ -41,6 +40,7 @@ use profile_traits::time::{
self as profile_time, TimerMetadata, TimerMetadataFrameType, TimerMetadataReflowType, self as profile_time, TimerMetadata, TimerMetadataFrameType, TimerMetadataReflowType,
}; };
use profile_traits::{path, time_profile}; use profile_traits::{path, time_profile};
use rustc_hash::FxHashMap;
use script::layout_dom::{ServoLayoutDocument, ServoLayoutElement, ServoLayoutNode}; use script::layout_dom::{ServoLayoutDocument, ServoLayoutElement, ServoLayoutNode};
use script_traits::{DrawAPaintImageResult, PaintWorkletError, Painter, ScriptThreadMessage}; use script_traits::{DrawAPaintImageResult, PaintWorkletError, Painter, ScriptThreadMessage};
use servo_arc::Arc as ServoArc; 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 // 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 // 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. // image data, or an error if the image cache failed to load/decode the image.
resolved_images_cache: Arc<RwLock<FnvHashMap<(ServoUrl, UsePlaceholder), CachedImageOrError>>>, resolved_images_cache: Arc<RwLock<HashMap<(ServoUrl, UsePlaceholder), CachedImageOrError>>>,
/// The executors for paint worklets. /// The executors for paint worklets.
registered_painters: RegisteredPaintersImpl, registered_painters: RegisteredPaintersImpl,
@ -514,7 +514,7 @@ impl Layout for LayoutThread {
fn set_scroll_offsets_from_renderer( fn set_scroll_offsets_from_renderer(
&mut self, &mut self,
scroll_states: &FnvHashMap<ExternalScrollId, LayoutVector2D>, scroll_states: &FxHashMap<ExternalScrollId, LayoutVector2D>,
) { ) {
let mut stacking_context_tree = self.stacking_context_tree.borrow_mut(); let mut stacking_context_tree = self.stacking_context_tree.borrow_mut();
let Some(stacking_context_tree) = stacking_context_tree.as_mut() else { let Some(stacking_context_tree) = stacking_context_tree.as_mut() else {
@ -1422,7 +1422,7 @@ struct RegisteredPainterImpl {
painter: Box<dyn Painter>, painter: Box<dyn Painter>,
name: Atom, name: Atom,
// FIXME: Should be a PrecomputedHashMap. // FIXME: Should be a PrecomputedHashMap.
properties: FxHashMap<Atom, PropertyId>, properties: fxhash::FxHashMap<Atom, PropertyId>,
} }
impl SpeculativePainter for RegisteredPainterImpl { impl SpeculativePainter for RegisteredPainterImpl {
@ -1437,7 +1437,7 @@ impl SpeculativePainter for RegisteredPainterImpl {
} }
impl RegisteredSpeculativePainter for RegisteredPainterImpl { impl RegisteredSpeculativePainter for RegisteredPainterImpl {
fn properties(&self) -> &FxHashMap<Atom, PropertyId> { fn properties(&self) -> &fxhash::FxHashMap<Atom, PropertyId> {
&self.properties &self.properties
} }
fn name(&self) -> Atom { fn name(&self) -> Atom {
@ -1458,7 +1458,7 @@ impl Painter for RegisteredPainterImpl {
} }
} }
struct RegisteredPaintersImpl(FnvHashMap<Atom, RegisteredPainterImpl>); struct RegisteredPaintersImpl(HashMap<Atom, RegisteredPainterImpl>);
impl RegisteredSpeculativePainters for RegisteredPaintersImpl { impl RegisteredSpeculativePainters for RegisteredPaintersImpl {
fn get(&self, name: &Atom) -> Option<&dyn RegisteredSpeculativePainter> { fn get(&self, name: &Atom) -> Option<&dyn RegisteredSpeculativePainter> {

View file

@ -2,7 +2,6 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this * 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/. */ * file, You can obtain one at https://mozilla.org/MPL/2.0/. */
use std::collections::{HashMap, HashSet};
use std::fs::File; use std::fs::File;
use std::io::{BufRead, BufReader, Read, Seek, SeekFrom}; use std::io::{BufRead, BufReader, Read, Seek, SeekFrom};
use std::ops::Index; use std::ops::Index;
@ -25,6 +24,7 @@ use net_traits::filemanager_thread::{
}; };
use net_traits::http_percent_encode; use net_traits::http_percent_encode;
use net_traits::response::{Response, ResponseBody}; use net_traits::response::{Response, ResponseBody};
use rustc_hash::{FxHashMap, FxHashSet};
use servo_arc::Arc as ServoArc; use servo_arc::Arc as ServoArc;
use servo_config::pref; use servo_config::pref;
use tokio::sync::mpsc::UnboundedSender as TokioSender; use tokio::sync::mpsc::UnboundedSender as TokioSender;
@ -54,7 +54,7 @@ struct FileStoreEntry {
is_valid_url: AtomicBool, is_valid_url: AtomicBool,
/// UUIDs of fetch instances that acquired an interest in this file, /// UUIDs of fetch instances that acquired an interest in this file,
/// when the url was still valid. /// when the url was still valid.
outstanding_tokens: HashSet<Uuid>, outstanding_tokens: FxHashSet<Uuid>,
} }
#[derive(Clone)] #[derive(Clone)]
@ -433,13 +433,13 @@ enum BlobBounds {
/// from FileID to FileStoreEntry which might have different backend implementation. /// from FileID to FileStoreEntry which might have different backend implementation.
/// Access to the content is encapsulated as methods of this struct. /// Access to the content is encapsulated as methods of this struct.
struct FileManagerStore { struct FileManagerStore {
entries: RwLock<HashMap<Uuid, FileStoreEntry>>, entries: RwLock<FxHashMap<Uuid, FileStoreEntry>>,
} }
impl FileManagerStore { impl FileManagerStore {
fn new() -> Self { fn new() -> Self {
FileManagerStore { FileManagerStore {
entries: RwLock::new(HashMap::new()), entries: RwLock::new(FxHashMap::default()),
} }
} }

View file

@ -487,12 +487,12 @@ struct ImageCacheStore {
/// Vector (e.g. SVG) images that have been sucessfully loaded and parsed /// 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 /// 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. /// rasterizing at different sizes, we use this hasmap to share the data.
vector_images: HashMap<PendingImageId, VectorImageData>, vector_images: FxHashMap<PendingImageId, VectorImageData>,
/// Vector images for which rasterization at a particular size has started /// Vector images for which rasterization at a particular size has started
/// or completed. If completed, the `result` member of `RasterizationTask` /// or completed. If completed, the `result` member of `RasterizationTask`
/// contains the rasterized image. /// 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 /// The placeholder image used when an image fails to load
#[conditional_malloc_size_of] #[conditional_malloc_size_of]
@ -722,8 +722,8 @@ impl ImageCache for ImageCacheImpl {
store: Arc::new(Mutex::new(ImageCacheStore { store: Arc::new(Mutex::new(ImageCacheStore {
pending_loads: AllPendingLoads::new(), pending_loads: AllPendingLoads::new(),
completed_loads: HashMap::new(), completed_loads: HashMap::new(),
vector_images: HashMap::new(), vector_images: FxHashMap::default(),
rasterized_vector_images: HashMap::new(), rasterized_vector_images: FxHashMap::default(),
placeholder_image: get_placeholder_image(&compositor_api, &rippy_data), placeholder_image: get_placeholder_image(&compositor_api, &rippy_data),
placeholder_url: ServoUrl::parse("chrome://resources/rippy.png").unwrap(), placeholder_url: ServoUrl::parse("chrome://resources/rippy.png").unwrap(),
compositor_api: compositor_api.clone(), compositor_api: compositor_api.clone(),
@ -1083,8 +1083,8 @@ impl ImageCache for ImageCacheImpl {
placeholder_image, placeholder_image,
placeholder_url, placeholder_url,
compositor_api, compositor_api,
vector_images: HashMap::new(), vector_images: FxHashMap::default(),
rasterized_vector_images: HashMap::new(), rasterized_vector_images: FxHashMap::default(),
key_cache: KeyCache::new(), key_cache: KeyCache::new(),
pipeline_id, pipeline_id,
})), })),

View file

@ -65,7 +65,6 @@ domobject_derive = { path = "../domobject_derive" }
embedder_traits = { workspace = true } embedder_traits = { workspace = true }
encoding_rs = { workspace = true } encoding_rs = { workspace = true }
euclid = { workspace = true } euclid = { workspace = true }
fnv = { workspace = true }
fonts = { path = "../fonts" } fonts = { path = "../fonts" }
fonts_traits = { workspace = true } fonts_traits = { workspace = true }
fxhash = { workspace = true } fxhash = { workspace = true }

View file

@ -29,8 +29,8 @@ use std::marker::PhantomData;
use std::rc::Rc; use std::rc::Rc;
use std::sync::{Arc, Weak}; use std::sync::{Arc, Weak};
use fnv::FnvHashMap;
use js::jsapi::JSTracer; use js::jsapi::JSTracer;
use rustc_hash::FxHashMap;
use script_bindings::script_runtime::CanGc; use script_bindings::script_runtime::CanGc;
use crate::dom::bindings::conversions::ToJSValConvertible; use crate::dom::bindings::conversions::ToJSValConvertible;
@ -47,14 +47,14 @@ mod dummy {
use std::cell::RefCell; use std::cell::RefCell;
use std::rc::Rc; use std::rc::Rc;
use fnv::{FnvBuildHasher, FnvHashMap}; use rustc_hash::FxHashMap;
use super::LiveDOMReferences; use super::LiveDOMReferences;
thread_local!(pub(crate) static LIVE_REFERENCES: Rc<RefCell<LiveDOMReferences>> = thread_local!(pub(crate) static LIVE_REFERENCES: Rc<RefCell<LiveDOMReferences>> =
Rc::new(RefCell::new( Rc::new(RefCell::new(
LiveDOMReferences { LiveDOMReferences {
reflectable_table: RefCell::new(FnvHashMap::with_hasher(FnvBuildHasher::new())), reflectable_table: RefCell::new(FxHashMap::default()),
promise_table: RefCell::new(FnvHashMap::with_hasher(FnvBuildHasher::new())), promise_table: RefCell::new(FxHashMap::default()),
} }
))); )));
} }
@ -232,8 +232,8 @@ impl<T: DomObject> Clone for Trusted<T> {
#[cfg_attr(crown, allow(crown::unrooted_must_root))] #[cfg_attr(crown, allow(crown::unrooted_must_root))]
pub(crate) struct LiveDOMReferences { pub(crate) struct LiveDOMReferences {
// keyed on pointer to Rust DOM object // keyed on pointer to Rust DOM object
reflectable_table: RefCell<FnvHashMap<*const libc::c_void, Weak<TrustedReference>>>, reflectable_table: RefCell<FxHashMap<*const libc::c_void, Weak<TrustedReference>>>,
promise_table: RefCell<FnvHashMap<*const Promise, Vec<Rc<Promise>>>>, promise_table: RefCell<FxHashMap<*const Promise, Vec<Rc<Promise>>>>,
} }
impl LiveDOMReferences { impl LiveDOMReferences {
@ -283,7 +283,7 @@ impl LiveDOMReferences {
} }
/// Remove null entries from the live references table /// Remove null entries from the live references table
fn remove_nulls<K: Eq + Hash + Clone, V>(table: &mut FnvHashMap<K, Weak<V>>) { fn remove_nulls<K: Eq + Hash + Clone, V>(table: &mut FxHashMap<K, Weak<V>>) {
let to_remove: Vec<K> = table let to_remove: Vec<K> = table
.iter() .iter()
.filter(|&(_, value)| Weak::upgrade(value).is_none()) .filter(|&(_, value)| Weak::upgrade(value).is_none())

View file

@ -15,6 +15,7 @@ use js::jsapi::{HandleValueArray, Heap, IsCallable, IsConstructor, JSAutoRealm,
use js::jsval::{BooleanValue, JSVal, NullValue, ObjectValue, UndefinedValue}; use js::jsval::{BooleanValue, JSVal, NullValue, ObjectValue, UndefinedValue};
use js::rust::wrappers::{Construct1, JS_GetProperty, SameValue}; use js::rust::wrappers::{Construct1, JS_GetProperty, SameValue};
use js::rust::{HandleObject, MutableHandleValue}; use js::rust::{HandleObject, MutableHandleValue};
use rustc_hash::FxBuildHasher;
use script_bindings::conversions::{SafeFromJSValConvertible, SafeToJSValConvertible}; use script_bindings::conversions::{SafeFromJSValConvertible, SafeToJSValConvertible};
use super::bindings::trace::HashMapTracedValues; use super::bindings::trace::HashMapTracedValues;
@ -68,12 +69,15 @@ pub(crate) struct CustomElementRegistry {
window: Dom<Window>, window: Dom<Window>,
#[ignore_malloc_size_of = "Rc"] #[ignore_malloc_size_of = "Rc"]
when_defined: DomRefCell<HashMapTracedValues<LocalName, Rc<Promise>>>, /// 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<HashMapTracedValues<LocalName, Rc<Promise>, FxBuildHasher>>,
element_definition_is_running: Cell<bool>, element_definition_is_running: Cell<bool>,
#[ignore_malloc_size_of = "Rc"] #[ignore_malloc_size_of = "Rc"]
definitions: DomRefCell<HashMapTracedValues<LocalName, Rc<CustomElementDefinition>>>, definitions:
DomRefCell<HashMapTracedValues<LocalName, Rc<CustomElementDefinition>, FxBuildHasher>>,
} }
impl CustomElementRegistry { impl CustomElementRegistry {
@ -81,9 +85,9 @@ impl CustomElementRegistry {
CustomElementRegistry { CustomElementRegistry {
reflector_: Reflector::new(), reflector_: Reflector::new(),
window: Dom::from_ref(window), 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), element_definition_is_running: Cell::new(false),
definitions: DomRefCell::new(HashMapTracedValues::new()), definitions: DomRefCell::new(HashMapTracedValues::new_fx()),
} }
} }

View file

@ -30,7 +30,6 @@ use embedder_traits::{AllowOrDeny, AnimationState, EmbedderMsg, FocusSequenceNum
use encoding_rs::{Encoding, UTF_8}; use encoding_rs::{Encoding, UTF_8};
use euclid::Point2D; use euclid::Point2D;
use euclid::default::{Rect, Size2D}; use euclid::default::{Rect, Size2D};
use fnv::FnvHashMap;
use html5ever::{LocalName, Namespace, QualName, local_name, ns}; use html5ever::{LocalName, Namespace, QualName, local_name, ns};
use hyper_serde::Serde; use hyper_serde::Serde;
use js::rust::{HandleObject, HandleValue, MutableHandleValue}; 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::ipc as profile_ipc;
use profile_traits::time::TimerMetadataFrameType; use profile_traits::time::TimerMetadataFrameType;
use regex::bytes::Regex; use regex::bytes::Regex;
use rustc_hash::FxBuildHasher; use rustc_hash::{FxBuildHasher, FxHashMap};
use script_bindings::codegen::GenericBindings::ElementBinding::ElementMethods; use script_bindings::codegen::GenericBindings::ElementBinding::ElementMethods;
use script_bindings::interfaces::DocumentHelpers; use script_bindings::interfaces::DocumentHelpers;
use script_bindings::script_runtime::JSContext; use script_bindings::script_runtime::JSContext;
@ -304,11 +303,12 @@ pub(crate) struct Document {
quirks_mode: Cell<QuirksMode>, quirks_mode: Cell<QuirksMode>,
/// A helper used to process and store data related to input event handling. /// A helper used to process and store data related to input event handling.
event_handler: DocumentEventHandler, event_handler: DocumentEventHandler,
/// Caches for the getElement methods /// Caches for the getElement methods. It is safe to use FxHash for these maps
id_map: DomRefCell<HashMapTracedValues<Atom, Vec<Dom<Element>>>>, /// as Atoms are `string_cache` items that will have the hash computed from a u32.
name_map: DomRefCell<HashMapTracedValues<Atom, Vec<Dom<Element>>>>, id_map: DomRefCell<HashMapTracedValues<Atom, Vec<Dom<Element>>, FxBuildHasher>>,
tag_map: DomRefCell<HashMapTracedValues<LocalName, Dom<HTMLCollection>>>, name_map: DomRefCell<HashMapTracedValues<Atom, Vec<Dom<Element>>, FxBuildHasher>>,
tagns_map: DomRefCell<HashMapTracedValues<QualName, Dom<HTMLCollection>>>, tag_map: DomRefCell<HashMapTracedValues<LocalName, Dom<HTMLCollection>, FxBuildHasher>>,
tagns_map: DomRefCell<HashMapTracedValues<QualName, Dom<HTMLCollection>, FxBuildHasher>>,
classes_map: DomRefCell<HashMapTracedValues<Vec<Atom>, Dom<HTMLCollection>>>, classes_map: DomRefCell<HashMapTracedValues<Vec<Atom>, Dom<HTMLCollection>>>,
images: MutNullableDom<HTMLCollection>, images: MutNullableDom<HTMLCollection>,
embeds: MutNullableDom<HTMLCollection>, embeds: MutNullableDom<HTMLCollection>,
@ -375,7 +375,7 @@ pub(crate) struct Document {
appropriate_template_contents_owner_document: MutNullableDom<Document>, appropriate_template_contents_owner_document: MutNullableDom<Document>,
/// Information on elements needing restyle to ship over to layout when the /// Information on elements needing restyle to ship over to layout when the
/// time comes. /// time comes.
pending_restyles: DomRefCell<FnvHashMap<Dom<Element>, NoTrace<PendingRestyle>>>, pending_restyles: DomRefCell<FxHashMap<Dom<Element>, NoTrace<PendingRestyle>>>,
/// A collection of reasons that the [`Document`] needs to be restyled at the next /// 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 /// opportunity for a reflow. If this is empty, then the [`Document`] does not need to
/// be restyled. /// be restyled.
@ -436,7 +436,9 @@ pub(crate) struct Document {
/// whenever any element with the same ID as the form attribute /// whenever any element with the same ID as the form attribute
/// is inserted or removed from the document. /// is inserted or removed from the document.
/// See <https://html.spec.whatwg.org/multipage/#form-owner> /// See <https://html.spec.whatwg.org/multipage/#form-owner>
form_id_listener_map: DomRefCell<HashMapTracedValues<Atom, HashSet<Dom<Element>>>>, /// It is safe to use FxBuildHasher here as Atoms are in the string_cache
form_id_listener_map:
DomRefCell<HashMapTracedValues<Atom, HashSet<Dom<Element>>, FxBuildHasher>>,
#[no_trace] #[no_trace]
interactive_time: DomRefCell<ProgressiveWebMetrics>, interactive_time: DomRefCell<ProgressiveWebMetrics>,
#[no_trace] #[no_trace]
@ -2796,11 +2798,15 @@ impl Document {
fonts.fulfill_ready_promise_if_needed(can_gc) fonts.fulfill_ready_promise_if_needed(can_gc)
} }
pub(crate) fn id_map(&self) -> Ref<'_, HashMapTracedValues<Atom, Vec<Dom<Element>>>> { pub(crate) fn id_map(
&self,
) -> Ref<'_, HashMapTracedValues<Atom, Vec<Dom<Element>>, FxBuildHasher>> {
self.id_map.borrow() self.id_map.borrow()
} }
pub(crate) fn name_map(&self) -> Ref<'_, HashMapTracedValues<Atom, Vec<Dom<Element>>>> { pub(crate) fn name_map(
&self,
) -> Ref<'_, HashMapTracedValues<Atom, Vec<Dom<Element>>, FxBuildHasher>> {
self.name_map.borrow() self.name_map.borrow()
} }
@ -3332,14 +3338,14 @@ impl Document {
// https://dom.spec.whatwg.org/#concept-document-quirks // https://dom.spec.whatwg.org/#concept-document-quirks
quirks_mode: Cell::new(QuirksMode::NoQuirks), quirks_mode: Cell::new(QuirksMode::NoQuirks),
event_handler: DocumentEventHandler::new(window), event_handler: DocumentEventHandler::new(window),
id_map: DomRefCell::new(HashMapTracedValues::new()), id_map: DomRefCell::new(HashMapTracedValues::new_fx()),
name_map: DomRefCell::new(HashMapTracedValues::new()), name_map: DomRefCell::new(HashMapTracedValues::new_fx()),
// https://dom.spec.whatwg.org/#concept-document-encoding // https://dom.spec.whatwg.org/#concept-document-encoding
encoding: Cell::new(encoding), encoding: Cell::new(encoding),
is_html_document: is_html_document == IsHTMLDocument::HTMLDocument, is_html_document: is_html_document == IsHTMLDocument::HTMLDocument,
activity: Cell::new(activity), activity: Cell::new(activity),
tag_map: DomRefCell::new(HashMapTracedValues::new()), tag_map: DomRefCell::new(HashMapTracedValues::new_fx()),
tagns_map: DomRefCell::new(HashMapTracedValues::new()), tagns_map: DomRefCell::new(HashMapTracedValues::new_fx()),
classes_map: DomRefCell::new(HashMapTracedValues::new()), classes_map: DomRefCell::new(HashMapTracedValues::new()),
images: Default::default(), images: Default::default(),
embeds: Default::default(), embeds: Default::default(),
@ -3383,7 +3389,7 @@ impl Document {
current_parser: Default::default(), current_parser: Default::default(),
base_element: Default::default(), base_element: Default::default(),
appropriate_template_contents_owner_document: 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), needs_restyle: Cell::new(RestyleReason::DOMChanged),
dom_interactive: Cell::new(Default::default()), dom_interactive: Cell::new(Default::default()),
dom_content_loaded_event_start: Cell::new(Default::default()), dom_content_loaded_event_start: Cell::new(Default::default()),

View file

@ -4,6 +4,7 @@
use dom_struct::dom_struct; use dom_struct::dom_struct;
use js::rust::HandleObject; use js::rust::HandleObject;
use rustc_hash::FxBuildHasher;
use stylo_atoms::Atom; use stylo_atoms::Atom;
use super::bindings::trace::HashMapTracedValues; use super::bindings::trace::HashMapTracedValues;
@ -29,7 +30,7 @@ use crate::script_runtime::CanGc;
pub(crate) struct DocumentFragment { pub(crate) struct DocumentFragment {
node: Node, node: Node,
/// Caches for the getElement methods /// Caches for the getElement methods
id_map: DomRefCell<HashMapTracedValues<Atom, Vec<Dom<Element>>>>, id_map: DomRefCell<HashMapTracedValues<Atom, Vec<Dom<Element>>, FxBuildHasher>>,
} }
impl DocumentFragment { impl DocumentFragment {
@ -37,7 +38,7 @@ impl DocumentFragment {
pub(crate) fn new_inherited(document: &Document) -> DocumentFragment { pub(crate) fn new_inherited(document: &Document) -> DocumentFragment {
DocumentFragment { DocumentFragment {
node: Node::new_inherited(document), 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<HashMapTracedValues<Atom, Vec<Dom<Element>>>> { pub(crate) fn id_map(
&self,
) -> &DomRefCell<HashMapTracedValues<Atom, Vec<Dom<Element>>, FxBuildHasher>> {
&self.id_map &self.id_map
} }
} }

View file

@ -9,6 +9,7 @@ use std::fmt;
use embedder_traits::UntrustedNodeAddress; use embedder_traits::UntrustedNodeAddress;
use js::rust::HandleValue; use js::rust::HandleValue;
use layout_api::ElementsFromPointFlags; use layout_api::ElementsFromPointFlags;
use rustc_hash::FxBuildHasher;
use script_bindings::error::{Error, ErrorResult}; use script_bindings::error::{Error, ErrorResult};
use script_bindings::script_runtime::JSContext; use script_bindings::script_runtime::JSContext;
use servo_arc::Arc; 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. /// Remove any existing association between the provided id/name and any elements in this document.
pub(crate) fn unregister_named_element( pub(crate) fn unregister_named_element(
&self, &self,
id_map: &DomRefCell<HashMapTracedValues<Atom, Vec<Dom<Element>>>>, id_map: &DomRefCell<HashMapTracedValues<Atom, Vec<Dom<Element>>, FxBuildHasher>>,
to_unregister: &Element, to_unregister: &Element,
id: &Atom, id: &Atom,
) { ) {
@ -335,7 +336,7 @@ impl DocumentOrShadowRoot {
/// Associate an element present in this document with the provided id/name. /// Associate an element present in this document with the provided id/name.
pub(crate) fn register_named_element( pub(crate) fn register_named_element(
&self, &self,
id_map: &DomRefCell<HashMapTracedValues<Atom, Vec<Dom<Element>>>>, id_map: &DomRefCell<HashMapTracedValues<Atom, Vec<Dom<Element>>, FxBuildHasher>>,
element: &Element, element: &Element,
id: &Atom, id: &Atom,
root: DomRoot<Node>, root: DomRoot<Node>,

View file

@ -6,19 +6,18 @@ use std::cell::RefCell;
use std::collections::hash_map::Entry::{Occupied, Vacant}; use std::collections::hash_map::Entry::{Occupied, Vacant};
use std::default::Default; use std::default::Default;
use std::ffi::CString; use std::ffi::CString;
use std::hash::BuildHasherDefault;
use std::mem; use std::mem;
use std::ops::{Deref, DerefMut}; use std::ops::{Deref, DerefMut};
use std::rc::Rc; use std::rc::Rc;
use deny_public_fields::DenyPublicFields; use deny_public_fields::DenyPublicFields;
use dom_struct::dom_struct; use dom_struct::dom_struct;
use fnv::FnvHasher;
use js::jsapi::JS::CompileFunction; use js::jsapi::JS::CompileFunction;
use js::jsapi::{JS_GetFunctionObject, SupportUnscopables}; use js::jsapi::{JS_GetFunctionObject, SupportUnscopables};
use js::jsval::JSVal; use js::jsval::JSVal;
use js::rust::{CompileOptionsWrapper, HandleObject, transform_u16_to_source_text}; use js::rust::{CompileOptionsWrapper, HandleObject, transform_u16_to_source_text};
use libc::c_char; use libc::c_char;
use rustc_hash::FxBuildHasher;
use servo_url::ServoUrl; use servo_url::ServoUrl;
use style::str::HTML_SPACE_CHARACTERS; use style::str::HTML_SPACE_CHARACTERS;
use stylo_atoms::Atom; use stylo_atoms::Atom;
@ -512,7 +511,7 @@ impl EventListeners {
#[dom_struct] #[dom_struct]
pub struct EventTarget { pub struct EventTarget {
reflector_: Reflector, reflector_: Reflector,
handlers: DomRefCell<HashMapTracedValues<Atom, EventListeners, BuildHasherDefault<FnvHasher>>>, handlers: DomRefCell<HashMapTracedValues<Atom, EventListeners, FxBuildHasher>>,
} }
impl EventTarget { impl EventTarget {

View file

@ -27,7 +27,6 @@ use crossbeam_channel::Sender;
use devtools_traits::{PageError, ScriptToDevtoolsControlMsg}; use devtools_traits::{PageError, ScriptToDevtoolsControlMsg};
use dom_struct::dom_struct; use dom_struct::dom_struct;
use embedder_traits::{EmbedderMsg, JavaScriptEvaluationError, ScriptToEmbedderChan}; use embedder_traits::{EmbedderMsg, JavaScriptEvaluationError, ScriptToEmbedderChan};
use fnv::FnvHashMap;
use fonts::FontContext; use fonts::FontContext;
use ipc_channel::ipc::{self, IpcSender}; use ipc_channel::ipc::{self, IpcSender};
use ipc_channel::router::ROUTER; use ipc_channel::router::ROUTER;
@ -567,7 +566,7 @@ impl MessageListener {
}; };
let mut succeeded = vec![]; let mut succeeded = vec![];
let mut failed = FnvHashMap::default(); let mut failed = FxHashMap::default();
for (id, info) in ports.into_iter() { for (id, info) in ports.into_iter() {
if global.is_managing_port(&id) { if global.is_managing_port(&id) {

View file

@ -16,6 +16,7 @@ use js::rust::HandleObject;
use mime::{self, Mime}; use mime::{self, Mime};
use net_traits::http_percent_encode; use net_traits::http_percent_encode;
use net_traits::request::Referrer; use net_traits::request::Referrer;
use rustc_hash::FxBuildHasher;
use servo_rand::random; use servo_rand::random;
use style::attr::AttrValue; use style::attr::AttrValue;
use style::str::split_html_space_chars; use style::str::split_html_space_chars;
@ -93,8 +94,10 @@ pub(crate) struct HTMLFormElement {
elements: DomOnceCell<HTMLFormControlsCollection>, elements: DomOnceCell<HTMLFormControlsCollection>,
controls: DomRefCell<Vec<Dom<Element>>>, controls: DomRefCell<Vec<Dom<Element>>>,
/// It is safe to use FxBuildHasher here as `Atom` is in the string_cache.
#[allow(clippy::type_complexity)] #[allow(clippy::type_complexity)]
past_names_map: DomRefCell<HashMapTracedValues<Atom, (Dom<Element>, NoTrace<usize>)>>, past_names_map:
DomRefCell<HashMapTracedValues<Atom, (Dom<Element>, NoTrace<usize>), FxBuildHasher>>,
/// The current generation of past names, i.e., the number of name changes to the name. /// The current generation of past names, i.e., the number of name changes to the name.
current_name_generation: Cell<usize>, current_name_generation: Cell<usize>,
@ -126,7 +129,7 @@ impl HTMLFormElement {
constructing_entry_list: Cell::new(false), constructing_entry_list: Cell::new(false),
elements: Default::default(), elements: Default::default(),
controls: DomRefCell::new(Vec::new()), 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), current_name_generation: Cell::new(0),
firing_submission_events: Cell::new(false), firing_submission_events: Cell::new(false),
rel_list: Default::default(), rel_list: Default::default(),

View file

@ -6,7 +6,6 @@
use std::borrow::Cow; use std::borrow::Cow;
use std::cell::{Cell, Ref, RefCell, RefMut}; use std::cell::{Cell, Ref, RefCell, RefMut};
use std::collections::HashMap;
use std::collections::vec_deque::VecDeque; use std::collections::vec_deque::VecDeque;
use std::rc::Rc; use std::rc::Rc;
use std::thread; use std::thread;
@ -226,8 +225,8 @@ pub(crate) struct Tokenizer {
#[ignore_malloc_size_of = "Defined in std"] #[ignore_malloc_size_of = "Defined in std"]
#[no_trace] #[no_trace]
html_tokenizer_sender: Sender<ToHtmlTokenizerMsg>, html_tokenizer_sender: Sender<ToHtmlTokenizerMsg>,
#[ignore_malloc_size_of = "Defined in std"] //#[ignore_malloc_size_of = "Defined in std"]
nodes: RefCell<HashMap<ParseNodeId, Dom<Node>>>, nodes: RefCell<FxHashMap<ParseNodeId, Dom<Node>>>,
#[no_trace] #[no_trace]
url: ServoUrl, url: ServoUrl,
parsing_algorithm: ParsingAlgorithm, parsing_algorithm: ParsingAlgorithm,
@ -256,7 +255,7 @@ impl Tokenizer {
document: Dom::from_ref(document), document: Dom::from_ref(document),
receiver: tokenizer_receiver, receiver: tokenizer_receiver,
html_tokenizer_sender: to_html_tokenizer_sender, html_tokenizer_sender: to_html_tokenizer_sender,
nodes: RefCell::new(HashMap::new()), nodes: RefCell::new(FxHashMap::default()),
url, url,
parsing_algorithm: algorithm, parsing_algorithm: algorithm,
custom_element_reaction_stack, custom_element_reaction_stack,

View file

@ -6,6 +6,7 @@ use std::cmp::Ordering;
use std::iter::Iterator; use std::iter::Iterator;
use dom_struct::dom_struct; use dom_struct::dom_struct;
use rustc_hash::FxBuildHasher;
use style::custom_properties; use style::custom_properties;
use stylo_atoms::Atom; use stylo_atoms::Atom;
@ -21,7 +22,7 @@ use crate::script_runtime::CanGc;
#[dom_struct] #[dom_struct]
pub(crate) struct StylePropertyMapReadOnly { pub(crate) struct StylePropertyMapReadOnly {
reflector: Reflector, reflector: Reflector,
entries: HashMapTracedValues<Atom, Dom<CSSStyleValue>>, entries: HashMapTracedValues<Atom, Dom<CSSStyleValue>, FxBuildHasher>,
} }
impl StylePropertyMapReadOnly { impl StylePropertyMapReadOnly {

View file

@ -7,9 +7,9 @@ use std::iter::FromIterator;
use std::ptr::NonNull; use std::ptr::NonNull;
use canvas_traits::webgl::{GlType, TexFormat, WebGLSLVersion, WebGLVersion}; use canvas_traits::webgl::{GlType, TexFormat, WebGLSLVersion, WebGLVersion};
use fnv::{FnvHashMap, FnvHashSet};
use js::jsapi::JSObject; use js::jsapi::JSObject;
use malloc_size_of::MallocSizeOf; use malloc_size_of::MallocSizeOf;
use rustc_hash::{FxHashMap, FxHashSet};
type GLenum = u32; type GLenum = u32;
use super::wrapper::{TypedWebGLExtensionWrapper, WebGLExtensionWrapper}; 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. /// WebGL features that are enabled/disabled by WebGL Extensions.
#[derive(JSTraceable, MallocSizeOf)] #[derive(JSTraceable, MallocSizeOf)]
struct WebGLExtensionFeatures { struct WebGLExtensionFeatures {
gl_extensions: FnvHashSet<String>, gl_extensions: FxHashSet<String>,
disabled_tex_types: FnvHashSet<GLenum>, disabled_tex_types: FxHashSet<GLenum>,
not_filterable_tex_types: FnvHashSet<GLenum>, not_filterable_tex_types: FxHashSet<GLenum>,
#[no_trace] #[no_trace]
effective_tex_internal_formats: FnvHashMap<TexFormatType, TexFormat>, effective_tex_internal_formats: FxHashMap<TexFormatType, TexFormat>,
/// WebGL Hint() targets enabled by extensions. /// WebGL Hint() targets enabled by extensions.
hint_targets: FnvHashSet<GLenum>, hint_targets: FxHashSet<GLenum>,
/// WebGL GetParameter() names enabled by extensions. /// WebGL GetParameter() names enabled by extensions.
disabled_get_parameter_names: FnvHashSet<GLenum>, disabled_get_parameter_names: FxHashSet<GLenum>,
/// WebGL GetTexParameter() names enabled by extensions. /// WebGL GetTexParameter() names enabled by extensions.
disabled_get_tex_parameter_names: FnvHashSet<GLenum>, disabled_get_tex_parameter_names: FxHashSet<GLenum>,
/// WebGL GetAttribVertex() names enabled by extensions. /// WebGL GetAttribVertex() names enabled by extensions.
disabled_get_vertex_attrib_names: FnvHashSet<GLenum>, disabled_get_vertex_attrib_names: FxHashSet<GLenum>,
/// WebGL OES_element_index_uint extension. /// WebGL OES_element_index_uint extension.
element_index_uint_enabled: bool, element_index_uint_enabled: bool,
/// WebGL EXT_blend_minmax extension. /// WebGL EXT_blend_minmax extension.
blend_minmax_enabled: bool, blend_minmax_enabled: bool,
/// WebGL supported texture compression formats enabled by extensions. /// WebGL supported texture compression formats enabled by extensions.
tex_compression_formats: FnvHashMap<GLenum, TexCompression>, tex_compression_formats: FxHashMap<GLenum, TexCompression>,
} }
impl WebGLExtensionFeatures { impl WebGLExtensionFeatures {
@ -199,7 +199,7 @@ impl WebGLExtensions {
if self.extensions.borrow().is_empty() { if self.extensions.borrow().is_empty() {
let gl_str = cb(); let gl_str = cb();
self.features.borrow_mut().gl_extensions = 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(); self.register_all_extensions();
} }
} }
@ -382,7 +382,7 @@ impl WebGLExtensions {
} }
pub(crate) fn add_tex_compression_formats(&self, formats: &[TexCompression]) { pub(crate) fn add_tex_compression_formats(&self, formats: &[TexCompression]) {
let formats: FnvHashMap<GLenum, TexCompression> = formats let formats: FxHashMap<GLenum, TexCompression> = formats
.iter() .iter()
.map(|&compression| (compression.format.as_gl_constant(), compression)) .map(|&compression| (compression.format.as_gl_constant(), compression))
.collect(); .collect();

View file

@ -4,13 +4,13 @@
// https://www.khronos.org/registry/webgl/specs/latest/1.0/webgl.idl // https://www.khronos.org/registry/webgl/specs/latest/1.0/webgl.idl
use std::cell::Cell; use std::cell::Cell;
use std::collections::HashSet;
use canvas_traits::webgl::{ use canvas_traits::webgl::{
ActiveAttribInfo, ActiveUniformBlockInfo, ActiveUniformInfo, WebGLCommand, WebGLError, ActiveAttribInfo, ActiveUniformBlockInfo, ActiveUniformInfo, WebGLCommand, WebGLError,
WebGLProgramId, WebGLResult, webgl_channel, WebGLProgramId, WebGLResult, webgl_channel,
}; };
use dom_struct::dom_struct; use dom_struct::dom_struct;
use fnv::FnvHashSet;
use crate::canvas_context::CanvasContext; use crate::canvas_context::CanvasContext;
use crate::dom::bindings::cell::{DomRefCell, Ref}; use crate::dom::bindings::cell::{DomRefCell, Ref};
@ -180,8 +180,8 @@ impl WebGLProgram {
let link_info = receiver.recv().unwrap(); let link_info = receiver.recv().unwrap();
{ {
let mut used_locs = FnvHashSet::default(); let mut used_locs = HashSet::new();
let mut used_names = FnvHashSet::default(); let mut used_names = HashSet::new();
for active_attrib in &*link_info.active_attribs { for active_attrib in &*link_info.active_attribs {
let Some(location) = active_attrib.location else { let Some(location) = active_attrib.location else {
continue; continue;

View file

@ -17,6 +17,7 @@ use js::jsapi::JSObject;
use js::rust::MutableHandleValue; use js::rust::MutableHandleValue;
use js::typedarray::Float32Array; use js::typedarray::Float32Array;
use profile_traits::ipc; use profile_traits::ipc;
use rustc_hash::FxBuildHasher;
use stylo_atoms::Atom; use stylo_atoms::Atom;
use webxr_api::{ use webxr_api::{
self, ApiSpace, ContextId as WebXRContextId, Display, EntityTypes, EnvironmentBlendMode, self, ApiSpace, ContextId as WebXRContextId, Display, EntityTypes, EnvironmentBlendMode,
@ -103,7 +104,8 @@ pub(crate) struct XRSession {
#[no_trace] #[no_trace]
next_hit_test_id: Cell<HitTestId>, next_hit_test_id: Cell<HitTestId>,
#[ignore_malloc_size_of = "defined in webxr"] #[ignore_malloc_size_of = "defined in webxr"]
pending_hit_test_promises: DomRefCell<HashMapTracedValues<HitTestId, Rc<Promise>>>, pending_hit_test_promises:
DomRefCell<HashMapTracedValues<HitTestId, Rc<Promise>, FxBuildHasher>>,
/// Opaque framebuffers need to know the session is "outside of a requestAnimationFrame" /// Opaque framebuffers need to know the session is "outside of a requestAnimationFrame"
/// <https://immersive-web.github.io/webxr/#opaque-framebuffer> /// <https://immersive-web.github.io/webxr/#opaque-framebuffer>
outside_raf: Cell<bool>, outside_raf: Cell<bool>,
@ -142,7 +144,7 @@ impl XRSession {
end_promises: DomRefCell::new(vec![]), end_promises: DomRefCell::new(vec![]),
ended: Cell::new(false), ended: Cell::new(false),
next_hit_test_id: Cell::new(HitTestId(0)), 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), outside_raf: Cell::new(true),
input_frames: DomRefCell::new(HashMap::new()), input_frames: DomRefCell::new(HashMap::new()),
framerate: Cell::new(0.0), framerate: Cell::new(0.0),

View file

@ -7,8 +7,8 @@ use std::default::Default;
use base::id::BrowsingContextId; use base::id::BrowsingContextId;
use constellation_traits::{IFrameSizeMsg, ScriptToConstellationMessage, WindowSizeType}; use constellation_traits::{IFrameSizeMsg, ScriptToConstellationMessage, WindowSizeType};
use embedder_traits::ViewportDetails; use embedder_traits::ViewportDetails;
use fnv::FnvHashMap;
use layout_api::IFrameSizes; use layout_api::IFrameSizes;
use rustc_hash::FxHashMap;
use crate::dom::bindings::inheritance::Castable; use crate::dom::bindings::inheritance::Castable;
use crate::dom::bindings::root::{Dom, DomRoot}; use crate::dom::bindings::root::{Dom, DomRoot};
@ -56,7 +56,7 @@ impl IFrameCollection {
// Preserve any old sizes, but only for `<iframe>`s that already have a // Preserve any old sizes, but only for `<iframe>`s that already have a
// BrowsingContextId and a set size. // BrowsingContextId and a set size.
let mut old_sizes: FnvHashMap<_, _> = self let mut old_sizes: FxHashMap<_, _> = self
.iframes .iframes
.iter() .iter()
.filter_map( .filter_map(

View file

@ -55,7 +55,6 @@ use embedder_traits::{
}; };
use euclid::Point2D; use euclid::Point2D;
use euclid::default::Rect; use euclid::default::Rect;
use fnv::FnvHashMap;
use fonts::{FontContext, SystemFontServiceProxy}; use fonts::{FontContext, SystemFontServiceProxy};
use headers::{HeaderMapExt, LastModified, ReferrerPolicy as ReferrerPolicyHeader}; use headers::{HeaderMapExt, LastModified, ReferrerPolicy as ReferrerPolicyHeader};
use http::header::REFRESH; use http::header::REFRESH;
@ -1946,7 +1945,7 @@ impl ScriptThread {
fn handle_set_scroll_states( fn handle_set_scroll_states(
&self, &self,
pipeline_id: PipelineId, pipeline_id: PipelineId,
scroll_states: FnvHashMap<ExternalScrollId, LayoutVector2D>, scroll_states: FxHashMap<ExternalScrollId, LayoutVector2D>,
) { ) {
let Some(window) = self.documents.borrow().find_window(pipeline_id) else { let Some(window) = self.documents.borrow().find_window(pipeline_id) else {
warn!("Received scroll states for closed pipeline {pipeline_id}"); warn!("Received scroll states for closed pipeline {pipeline_id}");

View file

@ -16,13 +16,13 @@ no-wgl = ["surfman/sm-angle-default"]
[dependencies] [dependencies]
base = { workspace = true } base = { workspace = true }
rustc-hash = { workspace = true }
bincode = { workspace = true } bincode = { workspace = true }
bitflags = { workspace = true } bitflags = { workspace = true }
crossbeam-channel = { workspace = true } crossbeam-channel = { workspace = true }
dpi = { version = "0.1" } dpi = { version = "0.1" }
embedder_traits = { workspace = true } embedder_traits = { workspace = true }
euclid = { workspace = true } euclid = { workspace = true }
fnv = { workspace = true }
gleam = { workspace = true } gleam = { workspace = true }
glow = { workspace = true } glow = { workspace = true }
image = { workspace = true } image = { workspace = true }

View file

@ -12,8 +12,8 @@ use base::print_tree::PrintTree;
use bitflags::bitflags; use bitflags::bitflags;
use embedder_traits::ViewportDetails; use embedder_traits::ViewportDetails;
use euclid::SideOffsets2D; use euclid::SideOffsets2D;
use fnv::FnvHashMap;
use malloc_size_of_derive::MallocSizeOf; use malloc_size_of_derive::MallocSizeOf;
use rustc_hash::FxHashMap;
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
use servo_geometry::FastLayoutTransform; use servo_geometry::FastLayoutTransform;
use style::values::specified::Overflow; use style::values::specified::Overflow;
@ -561,7 +561,7 @@ impl ScrollTree {
/// for nodes that actually exist in this tree. /// for nodes that actually exist in this tree.
pub fn set_all_scroll_offsets( pub fn set_all_scroll_offsets(
&mut self, &mut self,
offsets: &FnvHashMap<ExternalScrollId, LayoutVector2D>, offsets: &FxHashMap<ExternalScrollId, LayoutVector2D>,
) { ) {
for node in self.nodes.iter_mut() { for node in self.nodes.iter_mut() {
if let SpatialTreeNodeInfo::Scroll(ref mut scroll_info) = node.info { if let SpatialTreeNodeInfo::Scroll(ref mut scroll_info) = node.info {
@ -587,7 +587,7 @@ impl ScrollTree {
/// Collect all of the scroll offsets of the scrolling nodes of this tree into a /// Collect all of the scroll offsets of the scrolling nodes of this tree into a
/// [`HashMap`] which can be applied to another tree. /// [`HashMap`] which can be applied to another tree.
pub fn scroll_offsets(&self) -> FnvHashMap<ExternalScrollId, LayoutVector2D> { pub fn scroll_offsets(&self) -> FxHashMap<ExternalScrollId, LayoutVector2D> {
HashMap::from_iter(self.nodes.iter().filter_map(|node| match node.info { HashMap::from_iter(self.nodes.iter().filter_map(|node| match node.info {
SpatialTreeNodeInfo::Scroll(ref scroll_info) => { SpatialTreeNodeInfo::Scroll(ref scroll_info) => {
Some((scroll_info.external_id, scroll_info.offset)) Some((scroll_info.external_id, scroll_info.offset))

View file

@ -23,7 +23,6 @@ devtools_traits = { workspace = true }
embedder_traits = { workspace = true } embedder_traits = { workspace = true }
euclid = { workspace = true } euclid = { workspace = true }
fonts_traits = { workspace = true } fonts_traits = { workspace = true }
fnv = { workspace = true }
rustc-hash = { workspace = true } rustc-hash = { workspace = true }
http = { workspace = true } http = { workspace = true }
hyper_serde = { workspace = true } hyper_serde = { workspace = true }

View file

@ -21,7 +21,6 @@ use embedder_traits::{
ViewportDetails, WebDriverMessageId, ViewportDetails, WebDriverMessageId,
}; };
use euclid::default::Size2D as UntypedSize2D; use euclid::default::Size2D as UntypedSize2D;
use fnv::FnvHashMap;
use fonts_traits::SystemFontServiceProxySender; use fonts_traits::SystemFontServiceProxySender;
use http::{HeaderMap, Method}; use http::{HeaderMap, Method};
use ipc_channel::ipc::IpcSender; use ipc_channel::ipc::IpcSender;
@ -32,6 +31,7 @@ use net_traits::storage_thread::StorageType;
use net_traits::{ReferrerPolicy, ResourceThreads}; use net_traits::{ReferrerPolicy, ResourceThreads};
use profile_traits::mem::MemoryReportResult; use profile_traits::mem::MemoryReportResult;
use profile_traits::{mem, time as profile_time}; use profile_traits::{mem, time as profile_time};
use rustc_hash::FxHashMap;
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
use servo_url::{ImmutableOrigin, ServoUrl}; use servo_url::{ImmutableOrigin, ServoUrl};
use strum_macros::IntoStaticStr; use strum_macros::IntoStaticStr;
@ -492,7 +492,7 @@ pub enum ScriptToConstellationMessage {
/* The ids of ports transferred successfully */ /* The ids of ports transferred successfully */
Vec<MessagePortId>, Vec<MessagePortId>,
/* The ids, and buffers, of ports whose transfer failed */ /* The ids, and buffers, of ports whose transfer failed */
FnvHashMap<MessagePortId, PortTransferInfo>, FxHashMap<MessagePortId, PortTransferInfo>,
), ),
/// A new message-port was created or transferred, with corresponding control-sender. /// A new message-port was created or transferred, with corresponding control-sender.
NewMessagePort(MessagePortRouterId, MessagePortId), NewMessagePort(MessagePortRouterId, MessagePortId),

View file

@ -22,11 +22,11 @@ use embedder_traits::{
CompositorHitTestResult, InputEvent, JavaScriptEvaluationId, MediaSessionActionType, Theme, CompositorHitTestResult, InputEvent, JavaScriptEvaluationId, MediaSessionActionType, Theme,
TraversalId, ViewportDetails, WebDriverCommandMsg, WebDriverCommandResponse, TraversalId, ViewportDetails, WebDriverCommandMsg, WebDriverCommandResponse,
}; };
use fnv::FnvHashMap;
pub use from_script_message::*; pub use from_script_message::*;
use ipc_channel::ipc::IpcSender; use ipc_channel::ipc::IpcSender;
use malloc_size_of_derive::MallocSizeOf; use malloc_size_of_derive::MallocSizeOf;
use profile_traits::mem::MemoryReportResult; use profile_traits::mem::MemoryReportResult;
use rustc_hash::FxHashMap;
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
use servo_config::prefs::PrefValue; use servo_config::prefs::PrefValue;
use servo_url::{ImmutableOrigin, ServoUrl}; use servo_url::{ImmutableOrigin, ServoUrl};
@ -42,7 +42,7 @@ pub enum EmbedderToConstellationMessage {
/// Exit the constellation. /// Exit the constellation.
Exit, Exit,
/// Query the constellation to see if the current compositor output is stable /// Query the constellation to see if the current compositor output is stable
IsReadyToSaveImage(FnvHashMap<PipelineId, Epoch>), IsReadyToSaveImage(FxHashMap<PipelineId, Epoch>),
/// Whether to allow script to navigate. /// Whether to allow script to navigate.
AllowNavigationResponse(PipelineId, bool), AllowNavigationResponse(PipelineId, bool),
/// Request to load a page. /// Request to load a page.
@ -95,7 +95,7 @@ pub enum EmbedderToConstellationMessage {
SetWebViewThrottled(WebViewId, bool), SetWebViewThrottled(WebViewId, bool),
/// The Servo renderer scrolled and is updating the scroll states of the nodes in the /// The Servo renderer scrolled and is updating the scroll states of the nodes in the
/// given pipeline via the constellation. /// given pipeline via the constellation.
SetScrollStates(PipelineId, FnvHashMap<ExternalScrollId, LayoutVector2D>), SetScrollStates(PipelineId, FxHashMap<ExternalScrollId, LayoutVector2D>),
/// Notify the constellation that a particular paint metric event has happened for the given pipeline. /// Notify the constellation that a particular paint metric event has happened for the given pipeline.
PaintMetric(PipelineId, PaintMetricEvent), PaintMetric(PipelineId, PaintMetricEvent),
/// Evaluate a JavaScript string in the context of a `WebView`. When execution is complete or an /// Evaluate a JavaScript string in the context of a `WebView`. When execution is complete or an
@ -181,7 +181,7 @@ pub struct PortTransferInfo {
#[allow(clippy::large_enum_variant)] #[allow(clippy::large_enum_variant)]
pub enum MessagePortMsg { pub enum MessagePortMsg {
/// Complete the transfer for a batch of ports. /// Complete the transfer for a batch of ports.
CompleteTransfer(FnvHashMap<MessagePortId, PortTransferInfo>), CompleteTransfer(FxHashMap<MessagePortId, PortTransferInfo>),
/// Complete the transfer of a single port, /// Complete the transfer of a single port,
/// whose transfer was pending because it had been requested /// whose transfer was pending because it had been requested
/// while a previous failed transfer was being rolled-back. /// while a previous failed transfer was being rolled-back.

View file

@ -25,6 +25,7 @@ http = { workspace = true }
hyper_serde = { workspace = true } hyper_serde = { workspace = true }
ipc-channel = { workspace = true } ipc-channel = { workspace = true }
keyboard-types = { workspace = true } keyboard-types = { workspace = true }
rustc-hash = { workspace = true }
log = { workspace = true } log = { workspace = true }
malloc_size_of = { workspace = true } malloc_size_of = { workspace = true }
malloc_size_of_derive = { workspace = true } malloc_size_of_derive = { workspace = true }

View file

@ -15,6 +15,7 @@ use hyper_serde::Serde;
use ipc_channel::ipc::IpcSender; use ipc_channel::ipc::IpcSender;
use keyboard_types::{CompositionEvent, KeyboardEvent}; use keyboard_types::{CompositionEvent, KeyboardEvent};
use pixels::RasterImage; use pixels::RasterImage;
use rustc_hash::FxHashMap;
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
use servo_geometry::DeviceIndependentIntRect; use servo_geometry::DeviceIndependentIntRect;
use servo_url::ServoUrl; use servo_url::ServoUrl;
@ -294,7 +295,7 @@ pub enum WebDriverLoadStatus {
/// to a WebDriver server with information about application state. /// to a WebDriver server with information about application state.
#[derive(Clone, Default)] #[derive(Clone, Default)]
pub struct WebDriverSenders { pub struct WebDriverSenders {
pub load_status_senders: HashMap<WebViewId, GenericSender<WebDriverLoadStatus>>, pub load_status_senders: FxHashMap<WebViewId, GenericSender<WebDriverLoadStatus>>,
pub script_evaluation_interrupt_sender: Option<IpcSender<WebDriverJSResult>>, pub script_evaluation_interrupt_sender: Option<IpcSender<WebDriverJSResult>>,
pub pending_traversals: HashMap<TraversalId, GenericSender<WebDriverLoadStatus>>, pub pending_traversals: HashMap<TraversalId, GenericSender<WebDriverLoadStatus>>,
} }

View file

@ -20,7 +20,6 @@ compositing_traits = { workspace = true }
constellation_traits = { workspace = true } constellation_traits = { workspace = true }
embedder_traits = { workspace = true } embedder_traits = { workspace = true }
euclid = { workspace = true } euclid = { workspace = true }
fnv = { workspace = true }
fonts = { path = "../../fonts" } fonts = { path = "../../fonts" }
fonts_traits = { workspace = true } fonts_traits = { workspace = true }
html5ever = { workspace = true } html5ever = { workspace = true }

View file

@ -28,7 +28,6 @@ use constellation_traits::LoadData;
use embedder_traits::{Cursor, Theme, UntrustedNodeAddress, ViewportDetails}; use embedder_traits::{Cursor, Theme, UntrustedNodeAddress, ViewportDetails};
use euclid::Point2D; use euclid::Point2D;
use euclid::default::{Point2D as UntypedPoint2D, Rect}; use euclid::default::{Point2D as UntypedPoint2D, Rect};
use fnv::FnvHashMap;
use fonts::{FontContext, SystemFontServiceProxy}; use fonts::{FontContext, SystemFontServiceProxy};
pub use layout_damage::LayoutDamage; pub use layout_damage::LayoutDamage;
use libc::c_void; use libc::c_void;
@ -288,7 +287,7 @@ pub trait Layout {
/// Set the scroll states of this layout after a compositor scroll. /// Set the scroll states of this layout after a compositor scroll.
fn set_scroll_offsets_from_renderer( fn set_scroll_offsets_from_renderer(
&mut self, &mut self,
scroll_states: &FnvHashMap<ExternalScrollId, LayoutVector2D>, scroll_states: &FxHashMap<ExternalScrollId, LayoutVector2D>,
); );
/// Get the scroll offset of the given scroll node with id of [`ExternalScrollId`] or `None` if it does /// Get the scroll offset of the given scroll node with id of [`ExternalScrollId`] or `None` if it does
@ -425,7 +424,7 @@ pub struct IFrameSize {
pub viewport_details: ViewportDetails, pub viewport_details: ViewportDetails,
} }
pub type IFrameSizes = FnvHashMap<BrowsingContextId, IFrameSize>; pub type IFrameSizes = FxHashMap<BrowsingContextId, IFrameSize>;
bitflags! { bitflags! {
/// Conditions which cause a [`Document`] to need to be restyled during reflow, which /// Conditions which cause a [`Document`] to need to be restyled during reflow, which

View file

@ -22,6 +22,7 @@ crossbeam-channel = { workspace = true }
data-url = { workspace = true } data-url = { workspace = true }
embedder_traits = { workspace = true } embedder_traits = { workspace = true }
headers = { workspace = true } headers = { workspace = true }
rustc-hash = { workspace = true }
http = { workspace = true } http = { workspace = true }
hyper-util = { workspace = true } hyper-util = { workspace = true }
hyper_serde = { workspace = true } hyper_serde = { workspace = true }

View file

@ -4,7 +4,6 @@
#![deny(unsafe_code)] #![deny(unsafe_code)]
use std::collections::HashMap;
use std::fmt::Display; use std::fmt::Display;
use std::sync::{LazyLock, OnceLock}; use std::sync::{LazyLock, OnceLock};
use std::thread::{self, JoinHandle}; use std::thread::{self, JoinHandle};
@ -26,6 +25,7 @@ use malloc_size_of::malloc_size_of_is_0;
use malloc_size_of_derive::MallocSizeOf; use malloc_size_of_derive::MallocSizeOf;
use mime::Mime; use mime::Mime;
use request::RequestId; use request::RequestId;
use rustc_hash::FxHashMap;
use rustls_pki_types::CertificateDer; use rustls_pki_types::CertificateDer;
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
use servo_rand::RngCore; use servo_rand::RngCore;
@ -604,7 +604,7 @@ pub type BoxedFetchCallback = Box<dyn FnMut(FetchResponseMsg) + Send + 'static>;
struct FetchThread { struct FetchThread {
/// A list of active fetches. A fetch is no longer active once the /// A list of active fetches. A fetch is no longer active once the
/// [`FetchResponseMsg::ProcessResponseEOF`] is received. /// [`FetchResponseMsg::ProcessResponseEOF`] is received.
active_fetches: HashMap<RequestId, BoxedFetchCallback>, active_fetches: FxHashMap<RequestId, BoxedFetchCallback>,
/// A crossbeam receiver attached to the router proxy which converts incoming fetch /// A crossbeam receiver attached to the router proxy which converts incoming fetch
/// updates from IPC messages to crossbeam messages as well as another sender which /// updates from IPC messages to crossbeam messages as well as another sender which
/// handles requests from clients wanting to do fetches. /// handles requests from clients wanting to do fetches.
@ -631,7 +631,7 @@ impl FetchThread {
.name("FetchThread".to_owned()) .name("FetchThread".to_owned())
.spawn(move || { .spawn(move || {
let mut fetch_thread = FetchThread { let mut fetch_thread = FetchThread {
active_fetches: HashMap::new(), active_fetches: FxHashMap::default(),
receiver, receiver,
to_fetch_sender, to_fetch_sender,
}; };

View file

@ -26,7 +26,7 @@ crossbeam-channel = { workspace = true }
devtools_traits = { workspace = true } devtools_traits = { workspace = true }
embedder_traits = { workspace = true } embedder_traits = { workspace = true }
euclid = { workspace = true } euclid = { workspace = true }
fnv = { workspace = true } rustc-hash = { workspace = true }
ipc-channel = { workspace = true } ipc-channel = { workspace = true }
keyboard-types = { workspace = true } keyboard-types = { workspace = true }
malloc_size_of = { workspace = true } malloc_size_of = { workspace = true }

View file

@ -32,7 +32,6 @@ use embedder_traits::{
MediaSessionActionType, ScriptToEmbedderChan, Theme, ViewportDetails, WebDriverScriptCommand, MediaSessionActionType, ScriptToEmbedderChan, Theme, ViewportDetails, WebDriverScriptCommand,
}; };
use euclid::{Rect, Scale, Size2D, UnknownUnit}; use euclid::{Rect, Scale, Size2D, UnknownUnit};
use fnv::FnvHashMap;
use ipc_channel::ipc::{IpcReceiver, IpcSender}; use ipc_channel::ipc::{IpcReceiver, IpcSender};
use keyboard_types::Modifiers; use keyboard_types::Modifiers;
use malloc_size_of_derive::MallocSizeOf; use malloc_size_of_derive::MallocSizeOf;
@ -42,6 +41,7 @@ use net_traits::image_cache::ImageCache;
use net_traits::storage_thread::StorageType; use net_traits::storage_thread::StorageType;
use pixels::PixelFormat; use pixels::PixelFormat;
use profile_traits::mem; use profile_traits::mem;
use rustc_hash::FxHashMap;
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
use servo_config::prefs::PrefValue; use servo_config::prefs::PrefValue;
use servo_url::{ImmutableOrigin, ServoUrl}; use servo_url::{ImmutableOrigin, ServoUrl};
@ -253,7 +253,7 @@ pub enum ScriptThreadMessage {
SetWebGPUPort(IpcReceiver<WebGPUMsg>), SetWebGPUPort(IpcReceiver<WebGPUMsg>),
/// The compositor scrolled and is updating the scroll states of the nodes in the given /// The compositor scrolled and is updating the scroll states of the nodes in the given
/// pipeline via the Constellation. /// pipeline via the Constellation.
SetScrollStates(PipelineId, FnvHashMap<ExternalScrollId, LayoutVector2D>), SetScrollStates(PipelineId, FxHashMap<ExternalScrollId, LayoutVector2D>),
/// Evaluate the given JavaScript and return a result via a corresponding message /// Evaluate the given JavaScript and return a result via a corresponding message
/// to the Constellation. /// to the Constellation.
EvaluateJavaScript(PipelineId, JavaScriptEvaluationId, String), EvaluateJavaScript(PipelineId, JavaScriptEvaluationId, String),

View file

@ -26,6 +26,7 @@ log = { workspace = true }
pixels = { path = "../pixels" } pixels = { path = "../pixels" }
serde = { workspace = true } serde = { workspace = true }
serde_json = { workspace = true } serde_json = { workspace = true }
rustc-hash = { workspace = true }
servo_config = { path = "../config" } servo_config = { path = "../config" }
servo_geometry = { path = "../geometry" } servo_geometry = { path = "../geometry" }
servo_url = { path = "../url" } servo_url = { path = "../url" }

View file

@ -2,7 +2,6 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this * 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/. */ * file, You can obtain one at https://mozilla.org/MPL/2.0/. */
use std::collections::HashSet;
use std::thread; use std::thread;
use std::time::{Duration, Instant}; use std::time::{Duration, Instant};
@ -11,6 +10,7 @@ use embedder_traits::{MouseButtonAction, WebDriverCommandMsg, WebDriverScriptCom
use ipc_channel::ipc; use ipc_channel::ipc;
use keyboard_types::webdriver::KeyInputState; use keyboard_types::webdriver::KeyInputState;
use log::{error, info}; use log::{error, info};
use rustc_hash::FxHashSet;
use webdriver::actions::{ use webdriver::actions::{
ActionSequence, ActionsType, GeneralAction, KeyAction, KeyActionItem, KeyDownAction, ActionSequence, ActionsType, GeneralAction, KeyAction, KeyActionItem, KeyDownAction,
KeyUpAction, NullActionItem, PointerAction, PointerActionItem, PointerDownAction, KeyUpAction, NullActionItem, PointerAction, PointerActionItem, PointerDownAction,
@ -64,7 +64,7 @@ pub(crate) enum InputSourceState {
#[allow(dead_code)] #[allow(dead_code)]
pub(crate) struct PointerInputState { pub(crate) struct PointerInputState {
subtype: PointerType, subtype: PointerType,
pressed: HashSet<u64>, pressed: FxHashSet<u64>,
x: f64, x: f64,
y: f64, y: f64,
} }
@ -73,7 +73,7 @@ impl PointerInputState {
pub fn new(subtype: PointerType) -> PointerInputState { pub fn new(subtype: PointerType) -> PointerInputState {
PointerInputState { PointerInputState {
subtype, subtype,
pressed: HashSet::new(), pressed: FxHashSet::default(),
x: 0.0, x: 0.0,
y: 0.0, y: 0.0,
} }