Auto merge of #18334 - Manishearth:hashglobe, r=emilio,Gankro

Add fallible hashmaps from HashGlobe for stylo

HashGlobe code is r=emilio,Gankro

integration code is r=emilio from https://bugzilla.mozilla.org/show_bug.cgi?id=1393656

<!-- Reviewable:start -->
---
This change is [<img src="https://reviewable.io/review_button.svg" height="34" align="absmiddle" alt="Reviewable"/>](https://reviewable.io/reviews/servo/servo/18334)
<!-- Reviewable:end -->
This commit is contained in:
bors-servo 2017-09-01 16:09:53 -05:00 committed by GitHub
commit ac7cf53692
24 changed files with 6801 additions and 14 deletions

View file

@ -41,6 +41,7 @@ cssparser = "0.19.5"
encoding = {version = "0.2", optional = true}
euclid = "0.15"
fnv = "1.0"
hashglobe = { path = "../hashglobe" }
heapsize = {version = "0.4", optional = true}
heapsize_derive = {version = "0.1", optional = true}
itertools = "0.5"

View file

@ -8,13 +8,13 @@
use Atom;
use cssparser::{Delimiter, Parser, ParserInput, SourcePosition, Token, TokenSerializationType};
use hash::{HashMap, HashSet};
use parser::ParserContext;
use properties::{CSSWideKeyword, DeclaredValue};
use selectors::parser::SelectorParseError;
use servo_arc::Arc;
use std::ascii::AsciiExt;
use std::borrow::{Borrow, Cow};
use std::collections::{HashMap, HashSet};
use std::fmt;
use std::hash::Hash;
use style_traits::{ToCss, StyleParseError, ParseError};

View file

@ -28,7 +28,7 @@ use servo_arc::{Arc, ArcBorrow};
use shared_lock::Locked;
use smallvec::VecLike;
use std::fmt;
#[cfg(feature = "gecko")] use std::collections::HashMap;
#[cfg(feature = "gecko")] use hash::HashMap;
use std::fmt::Debug;
use std::hash::Hash;
use std::ops::Deref;

View file

@ -66,6 +66,7 @@ use gecko_bindings::structs::nsChangeHint;
use gecko_bindings::structs::nsIDocument_DocumentTheme as DocumentTheme;
use gecko_bindings::structs::nsRestyleHint;
use gecko_bindings::sugar::ownership::{HasArcFFI, HasSimpleFFI};
use hash::HashMap;
use logical_geometry::WritingMode;
use media_queries::Device;
use properties::{ComputedValues, parse_style_attribute};
@ -83,7 +84,6 @@ use selectors::sink::Push;
use servo_arc::{Arc, ArcBorrow, RawOffsetArc};
use shared_lock::Locked;
use std::cell::RefCell;
use std::collections::HashMap;
use std::fmt;
use std::hash::{Hash, Hasher};
use std::mem;
@ -1361,7 +1361,7 @@ impl<'le> TElement for GeckoElement<'le> {
after_change_style: &ComputedValues)
-> bool {
use gecko_bindings::structs::nsCSSPropertyID;
use std::collections::HashSet;
use hash::HashSet;
debug_assert!(self.might_need_transitions_update(Some(before_change_style),
after_change_style),

32
components/style/hash.rs Normal file
View file

@ -0,0 +1,32 @@
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
//! Reexports of hashglobe types in Gecko mode, and stdlib hashmap shims in Servo mode
//!
//! Can go away when the stdlib gets fallible collections
//! https://github.com/rust-lang/rfcs/pull/2116
use fnv;
#[cfg(feature = "gecko")]
pub use hashglobe::hash_map::HashMap;
#[cfg(feature = "gecko")]
pub use hashglobe::hash_set::HashSet;
#[cfg(feature = "servo")]
pub use hashglobe::fake::{HashMap, HashSet};
/// Appropriate reexports of hash_map types
pub mod map {
#[cfg(feature = "gecko")]
pub use hashglobe::hash_map::{Entry, Iter};
#[cfg(feature = "servo")]
pub use std::collections::hash_map::{Entry, Iter};
}
/// Hash map that uses the FNV hasher
pub type FnvHashMap<K, V> = HashMap<K, V, fnv::FnvBuildHasher>;
/// Hash set that uses the FNV hasher
pub type FnvHashSet<T> = HashSet<T, fnv::FnvBuildHasher>;

View file

@ -49,6 +49,7 @@ extern crate bitflags;
extern crate euclid;
extern crate fnv;
#[cfg(feature = "gecko")] #[macro_use] pub mod gecko_string_cache;
extern crate hashglobe;
#[cfg(feature = "servo")] extern crate heapsize;
#[cfg(feature = "servo")] #[macro_use] extern crate heapsize_derive;
extern crate itertools;
@ -112,6 +113,7 @@ pub mod font_face;
pub mod font_metrics;
#[cfg(feature = "gecko")] #[allow(unsafe_code)] pub mod gecko;
#[cfg(feature = "gecko")] #[allow(unsafe_code)] pub mod gecko_bindings;
pub mod hash;
pub mod invalidation;
#[allow(missing_docs)] // TODO.
pub mod logical_geometry;

View file

@ -31,7 +31,7 @@ use selectors::parser::SelectorParseError;
use smallvec::SmallVec;
use std::borrow::Cow;
use std::cmp;
#[cfg(feature = "gecko")] use fnv::FnvHashMap;
#[cfg(feature = "gecko")] use hash::FnvHashMap;
use style_traits::ParseError;
use super::ComputedValues;
#[cfg(feature = "gecko")]

View file

@ -416,7 +416,7 @@ ${helpers.predefined_type("object-position",
products="gecko"
animation_value_type="discrete"
boxed="True">
use std::collections::HashMap;
use hash::HashMap;
use std::fmt;
use std::ops::Range;
use str::HTML_SPACE_CHARACTERS;

View file

@ -13,7 +13,7 @@
#[cfg(feature = "servo")] use app_units::Au;
use servo_arc::{Arc, UniqueArc};
use std::borrow::Cow;
use std::collections::HashSet;
use hash::HashSet;
use std::{fmt, mem, ops};
#[cfg(feature = "gecko")] use std::ptr;

View file

@ -1007,7 +1007,7 @@ impl StrongRuleNode {
unsafe fn assert_free_list_has_no_duplicates_or_null(&self) {
assert!(cfg!(debug_assertions), "This is an expensive check!");
use std::collections::HashSet;
use hash::HashSet;
let me = &*self.ptr();
assert!(me.is_root());

View file

@ -9,6 +9,8 @@ use {Atom, LocalName};
use applicable_declarations::ApplicableDeclarationBlock;
use context::QuirksMode;
use dom::TElement;
use hash::{HashMap, HashSet};
use hash::map as hash_map;
use pdqsort::sort_by;
use precomputed_hash::PrecomputedHash;
use rule_tree::CascadeLevel;
@ -16,8 +18,6 @@ use selector_parser::SelectorImpl;
use selectors::matching::{matches_selector, MatchingContext, ElementSelectorFlags};
use selectors::parser::{Component, Combinator, SelectorIter};
use smallvec::{SmallVec, VecLike};
use std::collections::{HashMap, HashSet};
use std::collections::hash_map;
use std::hash::{BuildHasherDefault, Hash, Hasher};
use stylist::Rule;
@ -93,7 +93,7 @@ pub trait SelectorMapEntry : Sized + Clone {
/// TODO: Tune the initial capacity of the HashMap
#[derive(Debug)]
#[cfg_attr(feature = "servo", derive(HeapSizeOf))]
pub struct SelectorMap<T> {
pub struct SelectorMap<T: 'static> {
/// A hash from an ID to rules which contain that ID selector.
pub id_hash: MaybeCaseInsensitiveHashMap<Atom, SmallVec<[T; 1]>>,
/// A hash from a class name to rules which contain that class selector.
@ -111,7 +111,10 @@ fn sort_by_key<T, F: Fn(&T) -> K, K: Ord>(v: &mut [T], f: F) {
sort_by(v, |a, b| f(a).cmp(&f(b)))
}
impl<T> SelectorMap<T> {
// FIXME(Manishearth) the 'static bound can be removed when
// our HashMap fork (hashglobe) is able to use NonZero,
// or when stdlib gets fallible collections
impl<T: 'static> SelectorMap<T> {
/// Trivially constructs an empty `SelectorMap`.
pub fn new() -> Self {
SelectorMap {
@ -461,9 +464,12 @@ fn find_push<Str: Eq + Hash, V, VL>(map: &mut PrecomputedHashMap<Str, VL>,
/// Wrapper for PrecomputedHashMap that does ASCII-case-insensitive lookup in quirks mode.
#[derive(Debug)]
#[cfg_attr(feature = "servo", derive(HeapSizeOf))]
pub struct MaybeCaseInsensitiveHashMap<K: PrecomputedHash + Hash + Eq, V>(PrecomputedHashMap<K, V>);
pub struct MaybeCaseInsensitiveHashMap<K: PrecomputedHash + Hash + Eq, V: 'static>(PrecomputedHashMap<K, V>);
impl<V> MaybeCaseInsensitiveHashMap<Atom, V> {
// FIXME(Manishearth) the 'static bound can be removed when
// our HashMap fork (hashglobe) is able to use NonZero,
// or when stdlib gets fallible collections
impl<V: 'static> MaybeCaseInsensitiveHashMap<Atom, V> {
/// Empty map
pub fn new() -> Self {
MaybeCaseInsensitiveHashMap(PrecomputedHashMap::default())