mirror of
https://github.com/servo/servo.git
synced 2025-08-06 06:00:15 +01:00
style: Avoid hashing the precomputed hash atoms already have.
This shaves a fair amount of time of stylist rebuild. Most of the extra remaining overhead are memory allocations... I'll try to get those sorted out next, though fixing that may overlap quite a bit with the work Cameron is doing in bug 1382925. MozReview-Commit-ID: 3j2SBY4QnKf Signed-off-by: Emilio Cobos Álvarez <emilio@crisal.io>
This commit is contained in:
parent
0041125858
commit
720b17a54b
2 changed files with 44 additions and 9 deletions
|
@ -71,7 +71,7 @@ extern crate ordered_float;
|
||||||
extern crate owning_ref;
|
extern crate owning_ref;
|
||||||
extern crate parking_lot;
|
extern crate parking_lot;
|
||||||
extern crate pdqsort;
|
extern crate pdqsort;
|
||||||
#[cfg(feature = "gecko")] extern crate precomputed_hash;
|
extern crate precomputed_hash;
|
||||||
extern crate rayon;
|
extern crate rayon;
|
||||||
extern crate selectors;
|
extern crate selectors;
|
||||||
#[cfg(feature = "servo")] #[macro_use] extern crate serde;
|
#[cfg(feature = "servo")] #[macro_use] extern crate serde;
|
||||||
|
|
|
@ -9,19 +9,54 @@ use {Atom, LocalName};
|
||||||
use applicable_declarations::ApplicableDeclarationBlock;
|
use applicable_declarations::ApplicableDeclarationBlock;
|
||||||
use context::QuirksMode;
|
use context::QuirksMode;
|
||||||
use dom::TElement;
|
use dom::TElement;
|
||||||
use fnv::FnvHashMap;
|
|
||||||
use pdqsort::sort_by;
|
use pdqsort::sort_by;
|
||||||
|
use precomputed_hash::PrecomputedHash;
|
||||||
use rule_tree::CascadeLevel;
|
use rule_tree::CascadeLevel;
|
||||||
use selector_parser::SelectorImpl;
|
use selector_parser::SelectorImpl;
|
||||||
use selectors::matching::{matches_selector, MatchingContext, ElementSelectorFlags};
|
use selectors::matching::{matches_selector, MatchingContext, ElementSelectorFlags};
|
||||||
use selectors::parser::{Component, Combinator, SelectorIter};
|
use selectors::parser::{Component, Combinator, SelectorIter};
|
||||||
use selectors::parser::LocalName as LocalNameSelector;
|
use selectors::parser::LocalName as LocalNameSelector;
|
||||||
use smallvec::{SmallVec, VecLike};
|
use smallvec::{SmallVec, VecLike};
|
||||||
use std::collections::HashMap;
|
use std::collections::{HashMap, HashSet};
|
||||||
use std::collections::hash_map;
|
use std::collections::hash_map;
|
||||||
use std::hash::Hash;
|
use std::hash::{BuildHasherDefault, Hash, Hasher};
|
||||||
use stylist::Rule;
|
use stylist::Rule;
|
||||||
|
|
||||||
|
/// A hasher implementation that doesn't hash anything, because it expects its
|
||||||
|
/// input to be a suitable u32 hash.
|
||||||
|
pub struct PrecomputedHasher {
|
||||||
|
hash: u32,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Default for PrecomputedHasher {
|
||||||
|
fn default() -> Self {
|
||||||
|
Self { hash: 0 }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// A simple alias for a hashmap using PrecomputedHasher.
|
||||||
|
pub type PrecomputedHashMap<K, V> = HashMap<K, V, BuildHasherDefault<PrecomputedHasher>>;
|
||||||
|
|
||||||
|
/// A simple alias for a hashset using PrecomputedHasher.
|
||||||
|
pub type PrecomputedHashSet<K> = HashSet<K, BuildHasherDefault<PrecomputedHasher>>;
|
||||||
|
|
||||||
|
impl Hasher for PrecomputedHasher {
|
||||||
|
#[inline]
|
||||||
|
fn write(&mut self, _: &[u8]) {
|
||||||
|
unreachable!()
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn write_u32(&mut self, i: u32) {
|
||||||
|
self.hash = i;
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn finish(&self) -> u64 {
|
||||||
|
self.hash as u64
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// A trait to abstract over a given selector map entry.
|
/// A trait to abstract over a given selector map entry.
|
||||||
pub trait SelectorMapEntry : Sized + Clone {
|
pub trait SelectorMapEntry : Sized + Clone {
|
||||||
/// Gets the selector we should use to index in the selector map.
|
/// Gets the selector we should use to index in the selector map.
|
||||||
|
@ -63,7 +98,7 @@ pub struct SelectorMap<T> {
|
||||||
/// A hash from a class name to rules which contain that class selector.
|
/// A hash from a class name to rules which contain that class selector.
|
||||||
pub class_hash: MaybeCaseInsensitiveHashMap<Atom, SmallVec<[T; 1]>>,
|
pub class_hash: MaybeCaseInsensitiveHashMap<Atom, SmallVec<[T; 1]>>,
|
||||||
/// A hash from local name to rules which contain that local name selector.
|
/// A hash from local name to rules which contain that local name selector.
|
||||||
pub local_name_hash: FnvHashMap<LocalName, SmallVec<[T; 1]>>,
|
pub local_name_hash: PrecomputedHashMap<LocalName, SmallVec<[T; 1]>>,
|
||||||
/// Rules that don't have ID, class, or element selectors.
|
/// Rules that don't have ID, class, or element selectors.
|
||||||
pub other: Vec<T>,
|
pub other: Vec<T>,
|
||||||
/// The number of entries in this map.
|
/// The number of entries in this map.
|
||||||
|
@ -434,7 +469,7 @@ pub fn get_local_name(iter: SelectorIter<SelectorImpl>)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn find_push<Str: Eq + Hash, V, VL>(map: &mut FnvHashMap<Str, VL>,
|
fn find_push<Str: Eq + Hash, V, VL>(map: &mut PrecomputedHashMap<Str, VL>,
|
||||||
key: Str,
|
key: Str,
|
||||||
value: V)
|
value: V)
|
||||||
where VL: VecLike<V> + Default
|
where VL: VecLike<V> + Default
|
||||||
|
@ -442,15 +477,15 @@ fn find_push<Str: Eq + Hash, V, VL>(map: &mut FnvHashMap<Str, VL>,
|
||||||
map.entry(key).or_insert_with(VL::default).push(value)
|
map.entry(key).or_insert_with(VL::default).push(value)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Wrapper for FnvHashMap that does ASCII-case-insensitive lookup in quirks mode.
|
/// Wrapper for PrecomputedHashMap that does ASCII-case-insensitive lookup in quirks mode.
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
#[cfg_attr(feature = "servo", derive(HeapSizeOf))]
|
#[cfg_attr(feature = "servo", derive(HeapSizeOf))]
|
||||||
pub struct MaybeCaseInsensitiveHashMap<K: Hash + Eq, V>(FnvHashMap<K, V>);
|
pub struct MaybeCaseInsensitiveHashMap<K: PrecomputedHash + Hash + Eq, V>(PrecomputedHashMap<K, V>);
|
||||||
|
|
||||||
impl<V> MaybeCaseInsensitiveHashMap<Atom, V> {
|
impl<V> MaybeCaseInsensitiveHashMap<Atom, V> {
|
||||||
/// Empty map
|
/// Empty map
|
||||||
pub fn new() -> Self {
|
pub fn new() -> Self {
|
||||||
MaybeCaseInsensitiveHashMap(FnvHashMap::default())
|
MaybeCaseInsensitiveHashMap(PrecomputedHashMap::default())
|
||||||
}
|
}
|
||||||
|
|
||||||
/// HashMap::entry
|
/// HashMap::entry
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue