зеркало из https://github.com/mozilla/gecko-dev.git
servo: Merge #17710 - Revert "Auto merge of #17701 - bholley:reuse_allocations, r=emilio" (from emilio:revert-bloom-sharing); r=heycam
This reverts commit ebfc8f585834948f9b7564ffe382a6e266edf738, reversing changes made to 5585ff2c440dc27c8e98e834c9c0e9d956581b8e. Animation code can reenter and create a new TLS context from the traversal SequentialTask, so this won't work as written, and it's making test fails. Source-Repo: https://github.com/servo/servo Source-Revision: 9d74ae890b31fc45452ae60af7d89573fc52a86f --HG-- extra : subtree_source : https%3A//hg.mozilla.org/projects/converted-servo-linear extra : subtree_revision : b993fffb20fc8371a4aa42163e6712b9f1ebf33d
This commit is contained in:
Родитель
9b1bba24c6
Коммит
781f10d63c
|
@ -1022,7 +1022,7 @@ dependencies = [
|
||||||
"libc 0.2.23 (registry+https://github.com/rust-lang/crates.io-index)",
|
"libc 0.2.23 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"log 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
"log 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"nsstring_vendor 0.1.0",
|
"nsstring_vendor 0.1.0",
|
||||||
"parking_lot 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
"parking_lot 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"selectors 0.19.0",
|
"selectors 0.19.0",
|
||||||
"style 0.0.1",
|
"style 0.0.1",
|
||||||
"style_traits 0.0.1",
|
"style_traits 0.0.1",
|
||||||
|
@ -1451,7 +1451,7 @@ dependencies = [
|
||||||
"msg 0.0.1",
|
"msg 0.0.1",
|
||||||
"net_traits 0.0.1",
|
"net_traits 0.0.1",
|
||||||
"ordered-float 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"ordered-float 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"parking_lot 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
"parking_lot 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"profile_traits 0.0.1",
|
"profile_traits 0.0.1",
|
||||||
"range 0.0.1",
|
"range 0.0.1",
|
||||||
"rayon 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
"rayon 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
@ -1497,7 +1497,7 @@ dependencies = [
|
||||||
"log 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
"log 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"msg 0.0.1",
|
"msg 0.0.1",
|
||||||
"net_traits 0.0.1",
|
"net_traits 0.0.1",
|
||||||
"parking_lot 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
"parking_lot 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"profile_traits 0.0.1",
|
"profile_traits 0.0.1",
|
||||||
"rayon 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
"rayon 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"script 0.0.1",
|
"script 0.0.1",
|
||||||
|
@ -2068,18 +2068,15 @@ dependencies = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "owning_ref"
|
name = "owning_ref"
|
||||||
version = "0.3.3"
|
version = "0.2.4"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
dependencies = [
|
|
||||||
"stable_deref_trait 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "parking_lot"
|
name = "parking_lot"
|
||||||
version = "0.4.4"
|
version = "0.3.8"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"owning_ref 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
"owning_ref 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"parking_lot_core 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
"parking_lot_core 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"thread-id 3.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"thread-id 3.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
]
|
]
|
||||||
|
@ -2453,7 +2450,7 @@ dependencies = [
|
||||||
"num-traits 0.1.37 (registry+https://github.com/rust-lang/crates.io-index)",
|
"num-traits 0.1.37 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"offscreen_gl_context 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"offscreen_gl_context 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"open 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"open 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"parking_lot 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
"parking_lot 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"phf 0.7.21 (registry+https://github.com/rust-lang/crates.io-index)",
|
"phf 0.7.21 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"phf_codegen 0.7.21 (registry+https://github.com/rust-lang/crates.io-index)",
|
"phf_codegen 0.7.21 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"phf_shared 0.7.21 (registry+https://github.com/rust-lang/crates.io-index)",
|
"phf_shared 0.7.21 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
@ -2760,7 +2757,6 @@ dependencies = [
|
||||||
"heapsize 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"heapsize 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"nodrop 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
"nodrop 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"serde 1.0.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
"serde 1.0.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"stable_deref_trait 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
@ -2912,11 +2908,6 @@ dependencies = [
|
||||||
"heapsize 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"heapsize 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "stable_deref_trait"
|
|
||||||
version = "1.0.0"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "string_cache"
|
name = "string_cache"
|
||||||
version = "0.6.0"
|
version = "0.6.0"
|
||||||
|
@ -2983,8 +2974,7 @@ dependencies = [
|
||||||
"num-traits 0.1.37 (registry+https://github.com/rust-lang/crates.io-index)",
|
"num-traits 0.1.37 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"num_cpus 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"num_cpus 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"ordered-float 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"ordered-float 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"owning_ref 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
"parking_lot 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"parking_lot 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
|
||||||
"pdqsort 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
"pdqsort 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"precomputed-hash 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"precomputed-hash 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"rayon 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
"rayon 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
|
@ -3023,7 +3013,7 @@ dependencies = [
|
||||||
"cssparser 0.17.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"cssparser 0.17.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"euclid 0.15.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
"euclid 0.15.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"html5ever 0.18.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"html5ever 0.18.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"parking_lot 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
"parking_lot 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"rayon 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
"rayon 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"rustc-serialize 0.3.24 (registry+https://github.com/rust-lang/crates.io-index)",
|
"rustc-serialize 0.3.24 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"selectors 0.19.0",
|
"selectors 0.19.0",
|
||||||
|
@ -3756,8 +3746,8 @@ dependencies = [
|
||||||
"checksum ordered-float 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "da12c96037889ae0be29dd2bdd260e5a62a7df24e6466d5a15bb8131c1c200a8"
|
"checksum ordered-float 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "da12c96037889ae0be29dd2bdd260e5a62a7df24e6466d5a15bb8131c1c200a8"
|
||||||
"checksum osmesa-src 12.0.1 (git+https://github.com/servo/osmesa-src)" = "<none>"
|
"checksum osmesa-src 12.0.1 (git+https://github.com/servo/osmesa-src)" = "<none>"
|
||||||
"checksum osmesa-sys 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "88cfece6e95d2e717e0872a7f53a8684712ad13822a7979bc760b9c77ec0013b"
|
"checksum osmesa-sys 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "88cfece6e95d2e717e0872a7f53a8684712ad13822a7979bc760b9c77ec0013b"
|
||||||
"checksum owning_ref 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "cdf84f41639e037b484f93433aa3897863b561ed65c6e59c7073d7c561710f37"
|
"checksum owning_ref 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)" = "9d52571ddcb42e9c900c901a18d8d67e393df723fcd51dd59c5b1a85d0acb6cc"
|
||||||
"checksum parking_lot 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)" = "37f364e2ce5efa24c7d0b6646d5bb61145551a0112f107ffd7499f1a3e322fbd"
|
"checksum parking_lot 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)" = "fa12d706797d42551663426a45e2db2e0364bd1dbf6aeada87e89c5f981f43e9"
|
||||||
"checksum parking_lot_core 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "0ad2c4d148942b3560034785bf19df586ebba53351e8c78f84984147d5795eef"
|
"checksum parking_lot_core 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "0ad2c4d148942b3560034785bf19df586ebba53351e8c78f84984147d5795eef"
|
||||||
"checksum parse-hosts 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "9aebf4a4f84ce5d940a30a919c93325a66ab4ddb646f5f0a3d77483eb99595a6"
|
"checksum parse-hosts 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "9aebf4a4f84ce5d940a30a919c93325a66ab4ddb646f5f0a3d77483eb99595a6"
|
||||||
"checksum pdqsort 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "ceca1642c89148ca05611cc775a0c383abef355fc4907c4e95f49f7b09d6287c"
|
"checksum pdqsort 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "ceca1642c89148ca05611cc775a0c383abef355fc4907c4e95f49f7b09d6287c"
|
||||||
|
@ -3815,7 +3805,6 @@ dependencies = [
|
||||||
"checksum skeptic 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "dd7d8dc1315094150052d0ab767840376335a98ac66ef313ff911cdf439a5b69"
|
"checksum skeptic 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "dd7d8dc1315094150052d0ab767840376335a98ac66ef313ff911cdf439a5b69"
|
||||||
"checksum slab 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "17b4fcaed89ab08ef143da37bc52adbcc04d4a69014f4c1208d6b51f0c47bc23"
|
"checksum slab 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "17b4fcaed89ab08ef143da37bc52adbcc04d4a69014f4c1208d6b51f0c47bc23"
|
||||||
"checksum smallvec 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "2e40af10aafe98b4d8294ae8388d8a5cd0707c65d364872efe72d063ec44bee0"
|
"checksum smallvec 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "2e40af10aafe98b4d8294ae8388d8a5cd0707c65d364872efe72d063ec44bee0"
|
||||||
"checksum stable_deref_trait 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "15132e0e364248108c5e2c02e3ab539be8d6f5d52a01ca9bbf27ed657316f02b"
|
|
||||||
"checksum string_cache 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "23429a3aca80e7cc7f0060853a97fbba9a90e30ef36b29d13e22559cd7f3dc54"
|
"checksum string_cache 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "23429a3aca80e7cc7f0060853a97fbba9a90e30ef36b29d13e22559cd7f3dc54"
|
||||||
"checksum string_cache_codegen 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "479cde50c3539481f33906a387f2bd17c8e87cb848c35b6021d41fb81ff9b4d7"
|
"checksum string_cache_codegen 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "479cde50c3539481f33906a387f2bd17c8e87cb848c35b6021d41fb81ff9b4d7"
|
||||||
"checksum string_cache_shared 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b1884d1bc09741d466d9b14e6d37ac89d6909cbcac41dd9ae982d4d063bbedfc"
|
"checksum string_cache_shared 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b1884d1bc09741d466d9b14e6d37ac89d6909cbcac41dd9ae982d4d063bbedfc"
|
||||||
|
|
|
@ -26,7 +26,7 @@ log = "0.3.5"
|
||||||
msg = {path = "../msg"}
|
msg = {path = "../msg"}
|
||||||
net_traits = {path = "../net_traits"}
|
net_traits = {path = "../net_traits"}
|
||||||
ordered-float = "0.4"
|
ordered-float = "0.4"
|
||||||
parking_lot = "0.4"
|
parking_lot = "0.3.3"
|
||||||
profile_traits = {path = "../profile_traits"}
|
profile_traits = {path = "../profile_traits"}
|
||||||
range = {path = "../range"}
|
range = {path = "../range"}
|
||||||
rayon = "0.8"
|
rayon = "0.8"
|
||||||
|
|
|
@ -23,7 +23,7 @@ lazy_static = "0.2"
|
||||||
log = "0.3.5"
|
log = "0.3.5"
|
||||||
msg = {path = "../msg"}
|
msg = {path = "../msg"}
|
||||||
net_traits = {path = "../net_traits"}
|
net_traits = {path = "../net_traits"}
|
||||||
parking_lot = {version = "0.4", features = ["nightly"]}
|
parking_lot = {version = "0.3.3", features = ["nightly"]}
|
||||||
profile_traits = {path = "../profile_traits"}
|
profile_traits = {path = "../profile_traits"}
|
||||||
rayon = "0.8"
|
rayon = "0.8"
|
||||||
script = {path = "../script"}
|
script = {path = "../script"}
|
||||||
|
|
|
@ -65,7 +65,7 @@ net_traits = {path = "../net_traits"}
|
||||||
num-traits = "0.1.32"
|
num-traits = "0.1.32"
|
||||||
offscreen_gl_context = { version = "0.11", features = ["serde"] }
|
offscreen_gl_context = { version = "0.11", features = ["serde"] }
|
||||||
open = "1.1.1"
|
open = "1.1.1"
|
||||||
parking_lot = "0.4"
|
parking_lot = "0.3"
|
||||||
phf = "0.7.18"
|
phf = "0.7.18"
|
||||||
profile_traits = {path = "../profile_traits"}
|
profile_traits = {path = "../profile_traits"}
|
||||||
range = {path = "../range"}
|
range = {path = "../range"}
|
||||||
|
|
|
@ -14,6 +14,5 @@ servo = ["serde", "heapsize"]
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
heapsize = {version = "0.4.0", optional = true}
|
heapsize = {version = "0.4.0", optional = true}
|
||||||
nodrop = {version = "0.1.8"}
|
|
||||||
serde = {version = "1.0", optional = true}
|
serde = {version = "1.0", optional = true}
|
||||||
stable_deref_trait = "1.0.0"
|
nodrop = {version = "0.1.8"}
|
||||||
|
|
|
@ -22,16 +22,14 @@
|
||||||
// duplicate those here.
|
// duplicate those here.
|
||||||
#![allow(missing_docs)]
|
#![allow(missing_docs)]
|
||||||
|
|
||||||
extern crate nodrop;
|
|
||||||
#[cfg(feature = "servo")] extern crate serde;
|
#[cfg(feature = "servo")] extern crate serde;
|
||||||
extern crate stable_deref_trait;
|
extern crate nodrop;
|
||||||
|
|
||||||
#[cfg(feature = "servo")]
|
#[cfg(feature = "servo")]
|
||||||
use heapsize::HeapSizeOf;
|
use heapsize::HeapSizeOf;
|
||||||
use nodrop::NoDrop;
|
use nodrop::NoDrop;
|
||||||
#[cfg(feature = "servo")]
|
#[cfg(feature = "servo")]
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
use stable_deref_trait::{CloneStableDeref, StableDeref};
|
|
||||||
use std::{isize, usize};
|
use std::{isize, usize};
|
||||||
use std::borrow;
|
use std::borrow;
|
||||||
use std::cmp::Ordering;
|
use std::cmp::Ordering;
|
||||||
|
@ -434,9 +432,6 @@ impl<T: ?Sized> AsRef<T> for Arc<T> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
unsafe impl<T: ?Sized> StableDeref for Arc<T> {}
|
|
||||||
unsafe impl<T: ?Sized> CloneStableDeref for Arc<T> {}
|
|
||||||
|
|
||||||
// This is what the HeapSize crate does for regular arc, but is questionably
|
// This is what the HeapSize crate does for regular arc, but is questionably
|
||||||
// sound. See https://github.com/servo/heapsize/issues/37
|
// sound. See https://github.com/servo/heapsize/issues/37
|
||||||
#[cfg(feature = "servo")]
|
#[cfg(feature = "servo")]
|
||||||
|
|
|
@ -54,8 +54,7 @@ num_cpus = {version = "1.1.0", optional = true}
|
||||||
num-integer = "0.1.32"
|
num-integer = "0.1.32"
|
||||||
num-traits = "0.1.32"
|
num-traits = "0.1.32"
|
||||||
ordered-float = "0.4"
|
ordered-float = "0.4"
|
||||||
owning_ref = "0.3.3"
|
parking_lot = "0.3.3"
|
||||||
parking_lot = "0.4"
|
|
||||||
pdqsort = "0.1.0"
|
pdqsort = "0.1.0"
|
||||||
precomputed-hash = "0.1"
|
precomputed-hash = "0.1"
|
||||||
rayon = "0.8"
|
rayon = "0.8"
|
||||||
|
|
|
@ -7,18 +7,9 @@
|
||||||
|
|
||||||
#![deny(missing_docs)]
|
#![deny(missing_docs)]
|
||||||
|
|
||||||
use atomic_refcell::{AtomicRefMut, AtomicRefCell};
|
|
||||||
use dom::{SendElement, TElement};
|
use dom::{SendElement, TElement};
|
||||||
use owning_ref::OwningHandle;
|
|
||||||
use selectors::bloom::BloomFilter;
|
use selectors::bloom::BloomFilter;
|
||||||
use smallvec::SmallVec;
|
use smallvec::SmallVec;
|
||||||
use stylearc::Arc;
|
|
||||||
|
|
||||||
/// Bloom filters are large allocations, so we store them in thread-local storage
|
|
||||||
/// such that they can be reused across style traversals. StyleBloom is responsible
|
|
||||||
/// for ensuring that the bloom filter is zeroed when it is dropped.
|
|
||||||
thread_local!(static BLOOM_KEY: Arc<AtomicRefCell<BloomFilter>> =
|
|
||||||
Arc::new(AtomicRefCell::new(BloomFilter::new())));
|
|
||||||
|
|
||||||
/// A struct that allows us to fast-reject deep descendant selectors avoiding
|
/// A struct that allows us to fast-reject deep descendant selectors avoiding
|
||||||
/// selector-matching.
|
/// selector-matching.
|
||||||
|
@ -52,11 +43,8 @@ thread_local!(static BLOOM_KEY: Arc<AtomicRefCell<BloomFilter>> =
|
||||||
/// immutable during a restyle.
|
/// immutable during a restyle.
|
||||||
///
|
///
|
||||||
pub struct StyleBloom<E: TElement> {
|
pub struct StyleBloom<E: TElement> {
|
||||||
/// A handle to the bloom filter from the thread upon which this StyleBloom
|
/// The bloom filter per se.
|
||||||
/// was created. We use AtomicRefCell so that this is all |Send|, which allows
|
filter: Box<BloomFilter>,
|
||||||
/// StyleBloom to live in ThreadLocalStyleContext, which is dropped from the
|
|
||||||
/// parent thread.
|
|
||||||
filter: OwningHandle<Arc<AtomicRefCell<BloomFilter>>, AtomicRefMut<'static, BloomFilter>>,
|
|
||||||
|
|
||||||
/// The stack of elements that this bloom filter contains, along with the
|
/// The stack of elements that this bloom filter contains, along with the
|
||||||
/// number of hashes pushed for each element.
|
/// number of hashes pushed for each element.
|
||||||
|
@ -113,23 +101,11 @@ fn each_relevant_element_hash<E, F>(element: E, mut f: F)
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<E: TElement> Drop for StyleBloom<E> {
|
|
||||||
fn drop(&mut self) {
|
|
||||||
// Leave the reusable bloom filter in a zeroed state.
|
|
||||||
self.clear();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<E: TElement> StyleBloom<E> {
|
impl<E: TElement> StyleBloom<E> {
|
||||||
/// Create an empty `StyleBloom`. Because StyleBloom acquires the thread-
|
/// Create an empty `StyleBloom`.
|
||||||
/// local filter buffer, creating multiple live StyleBloom instances at
|
|
||||||
/// the same time on the same thread will panic.
|
|
||||||
pub fn new() -> Self {
|
pub fn new() -> Self {
|
||||||
let bloom_arc = BLOOM_KEY.with(|b| b.clone());
|
|
||||||
let filter = OwningHandle::new_with_fn(bloom_arc, |x| unsafe { x.as_ref() }.unwrap().borrow_mut());
|
|
||||||
debug_assert!(filter.is_zeroed(), "Forgot to zero the bloom filter last time");
|
|
||||||
StyleBloom {
|
StyleBloom {
|
||||||
filter: filter,
|
filter: Box::new(BloomFilter::new()),
|
||||||
elements: Default::default(),
|
elements: Default::default(),
|
||||||
pushed_hashes: Default::default(),
|
pushed_hashes: Default::default(),
|
||||||
}
|
}
|
||||||
|
|
|
@ -67,7 +67,6 @@ pub extern crate nsstring_vendor as nsstring;
|
||||||
extern crate num_integer;
|
extern crate num_integer;
|
||||||
extern crate num_traits;
|
extern crate num_traits;
|
||||||
extern crate ordered_float;
|
extern crate ordered_float;
|
||||||
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;
|
#[cfg(feature = "gecko")] extern crate precomputed_hash;
|
||||||
|
|
|
@ -66,7 +66,6 @@
|
||||||
|
|
||||||
use Atom;
|
use Atom;
|
||||||
use applicable_declarations::ApplicableDeclarationBlock;
|
use applicable_declarations::ApplicableDeclarationBlock;
|
||||||
use atomic_refcell::{AtomicRefCell, AtomicRefMut};
|
|
||||||
use bit_vec::BitVec;
|
use bit_vec::BitVec;
|
||||||
use bloom::StyleBloom;
|
use bloom::StyleBloom;
|
||||||
use cache::{LRUCache, LRUCacheMutIterator};
|
use cache::{LRUCache, LRUCacheMutIterator};
|
||||||
|
@ -74,15 +73,12 @@ use context::{SelectorFlagsMap, SharedStyleContext, StyleContext};
|
||||||
use data::{ElementData, ElementStyles};
|
use data::{ElementData, ElementStyles};
|
||||||
use dom::{TElement, SendElement};
|
use dom::{TElement, SendElement};
|
||||||
use matching::{ChildCascadeRequirement, MatchMethods};
|
use matching::{ChildCascadeRequirement, MatchMethods};
|
||||||
use owning_ref::OwningHandle;
|
|
||||||
use properties::ComputedValues;
|
use properties::ComputedValues;
|
||||||
use selector_parser::RestyleDamage;
|
use selector_parser::RestyleDamage;
|
||||||
use selectors::matching::{ElementSelectorFlags, VisitedHandlingMode};
|
use selectors::matching::{ElementSelectorFlags, VisitedHandlingMode};
|
||||||
use smallvec::SmallVec;
|
use smallvec::SmallVec;
|
||||||
use std::marker::PhantomData;
|
|
||||||
use std::mem;
|
use std::mem;
|
||||||
use std::ops::Deref;
|
use std::ops::Deref;
|
||||||
use stylearc::Arc;
|
|
||||||
use stylist::Stylist;
|
use stylist::Stylist;
|
||||||
|
|
||||||
mod checks;
|
mod checks;
|
||||||
|
@ -97,8 +93,7 @@ mod checks;
|
||||||
/// improvements (e.g. 3x fewer styles having to be resolved than at size 8) and
|
/// improvements (e.g. 3x fewer styles having to be resolved than at size 8) and
|
||||||
/// slight performance improvements. Sizes larger than 32 haven't really been
|
/// slight performance improvements. Sizes larger than 32 haven't really been
|
||||||
/// tested.
|
/// tested.
|
||||||
pub const SHARING_CACHE_SIZE: usize = 31;
|
pub const STYLE_SHARING_CANDIDATE_CACHE_SIZE: usize = 31;
|
||||||
const SHARING_CACHE_BACKING_STORE_SIZE: usize = SHARING_CACHE_SIZE + 1;
|
|
||||||
|
|
||||||
/// Controls whether the style sharing cache is used.
|
/// Controls whether the style sharing cache is used.
|
||||||
#[derive(Clone, Copy, PartialEq)]
|
#[derive(Clone, Copy, PartialEq)]
|
||||||
|
@ -216,21 +211,14 @@ impl ValidationData {
|
||||||
/// Note that this information is stored in TLS and cleared after the traversal,
|
/// Note that this information is stored in TLS and cleared after the traversal,
|
||||||
/// and once here, the style information of the element is immutable, so it's
|
/// and once here, the style information of the element is immutable, so it's
|
||||||
/// safe to access.
|
/// safe to access.
|
||||||
///
|
|
||||||
/// Important: If you change the members/layout here, You need to do the same for
|
|
||||||
/// FakeCandidate below.
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct StyleSharingCandidate<E: TElement> {
|
pub struct StyleSharingCandidate<E: TElement> {
|
||||||
/// The element.
|
/// The element. We use SendElement here so that the cache may live in
|
||||||
element: E,
|
/// ScopedTLS.
|
||||||
|
element: SendElement<E>,
|
||||||
validation_data: ValidationData,
|
validation_data: ValidationData,
|
||||||
}
|
}
|
||||||
|
|
||||||
struct FakeCandidate {
|
|
||||||
_element: usize,
|
|
||||||
_validation_data: ValidationData,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<E: TElement> Deref for StyleSharingCandidate<E> {
|
impl<E: TElement> Deref for StyleSharingCandidate<E> {
|
||||||
type Target = E;
|
type Target = E;
|
||||||
|
|
||||||
|
@ -243,12 +231,12 @@ impl<E: TElement> Deref for StyleSharingCandidate<E> {
|
||||||
impl<E: TElement> StyleSharingCandidate<E> {
|
impl<E: TElement> StyleSharingCandidate<E> {
|
||||||
/// Get the classlist of this candidate.
|
/// Get the classlist of this candidate.
|
||||||
fn class_list(&mut self) -> &[Atom] {
|
fn class_list(&mut self) -> &[Atom] {
|
||||||
self.validation_data.class_list(self.element)
|
self.validation_data.class_list(*self.element)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Get the pres hints of this candidate.
|
/// Get the pres hints of this candidate.
|
||||||
fn pres_hints(&mut self) -> &[ApplicableDeclarationBlock] {
|
fn pres_hints(&mut self) -> &[ApplicableDeclarationBlock] {
|
||||||
self.validation_data.pres_hints(self.element)
|
self.validation_data.pres_hints(*self.element)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Compute the bit vector of revalidation selector match results
|
/// Compute the bit vector of revalidation selector match results
|
||||||
|
@ -259,7 +247,7 @@ impl<E: TElement> StyleSharingCandidate<E> {
|
||||||
bloom: &StyleBloom<E>,
|
bloom: &StyleBloom<E>,
|
||||||
) -> &BitVec {
|
) -> &BitVec {
|
||||||
self.validation_data.revalidation_match_results(
|
self.validation_data.revalidation_match_results(
|
||||||
self.element,
|
*self.element,
|
||||||
stylist,
|
stylist,
|
||||||
bloom,
|
bloom,
|
||||||
/* bloom_known_valid = */ false,
|
/* bloom_known_valid = */ false,
|
||||||
|
@ -469,81 +457,35 @@ pub enum StyleSharingResult {
|
||||||
StyleWasShared(usize, ChildCascadeRequirement),
|
StyleWasShared(usize, ChildCascadeRequirement),
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Style sharing caches are are large allocations, so we store them in thread-local
|
|
||||||
/// storage such that they can be reused across style traversals. Ideally, we'd just
|
|
||||||
/// stack-allocate these buffers with uninitialized memory, but right now rustc can't
|
|
||||||
/// avoid memmoving the entire cache during setup, which gets very expensive. See
|
|
||||||
/// issues like [1] and [2].
|
|
||||||
///
|
|
||||||
/// Given that the cache stores entries of type TElement, we transmute to usize
|
|
||||||
/// before storing in TLS. This is safe as long as we make sure to empty the cache
|
|
||||||
/// before we let it go.
|
|
||||||
///
|
|
||||||
/// [1] https://github.com/rust-lang/rust/issues/42763
|
|
||||||
/// [2] https://github.com/rust-lang/rust/issues/13707
|
|
||||||
type SharingCacheBase<Candidate> = LRUCache<[Candidate; SHARING_CACHE_BACKING_STORE_SIZE]>;
|
|
||||||
type SharingCache<E> = SharingCacheBase<StyleSharingCandidate<E>>;
|
|
||||||
type TypelessSharingCache = SharingCacheBase<FakeCandidate>;
|
|
||||||
type StoredSharingCache = Arc<AtomicRefCell<TypelessSharingCache>>;
|
|
||||||
|
|
||||||
thread_local!(static SHARING_CACHE_KEY: StoredSharingCache =
|
|
||||||
Arc::new(AtomicRefCell::new(LRUCache::new())));
|
|
||||||
|
|
||||||
/// An LRU cache of the last few nodes seen, so that we can aggressively try to
|
/// An LRU cache of the last few nodes seen, so that we can aggressively try to
|
||||||
/// reuse their styles.
|
/// reuse their styles.
|
||||||
///
|
///
|
||||||
/// Note that this cache is flushed every time we steal work from the queue, so
|
/// Note that this cache is flushed every time we steal work from the queue, so
|
||||||
/// storing nodes here temporarily is safe.
|
/// storing nodes here temporarily is safe.
|
||||||
pub struct StyleSharingCandidateCache<E: TElement> {
|
pub struct StyleSharingCandidateCache<E: TElement> {
|
||||||
/// The LRU cache, with the type cast away to allow persisting the allocation.
|
cache: LRUCache<[StyleSharingCandidate<E>; STYLE_SHARING_CANDIDATE_CACHE_SIZE + 1]>,
|
||||||
cache_typeless: OwningHandle<StoredSharingCache, AtomicRefMut<'static, TypelessSharingCache>>,
|
|
||||||
/// Bind this structure to the lifetime of E, since that's what we effectively store.
|
|
||||||
marker: PhantomData<SendElement<E>>,
|
|
||||||
/// The DOM depth we're currently at. This is used as an optimization to
|
/// The DOM depth we're currently at. This is used as an optimization to
|
||||||
/// clear the cache when we change depths, since we know at that point
|
/// clear the cache when we change depths, since we know at that point
|
||||||
/// nothing in the cache will match.
|
/// nothing in the cache will match.
|
||||||
dom_depth: usize,
|
dom_depth: usize,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<E: TElement> Drop for StyleSharingCandidateCache<E> {
|
|
||||||
fn drop(&mut self) {
|
|
||||||
self.clear();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<E: TElement> StyleSharingCandidateCache<E> {
|
impl<E: TElement> StyleSharingCandidateCache<E> {
|
||||||
fn cache(&self) -> &SharingCache<E> {
|
|
||||||
let base: &TypelessSharingCache = &*self.cache_typeless;
|
|
||||||
unsafe { mem::transmute(base) }
|
|
||||||
}
|
|
||||||
|
|
||||||
fn cache_mut(&mut self) -> &mut SharingCache<E> {
|
|
||||||
let base: &mut TypelessSharingCache = &mut *self.cache_typeless;
|
|
||||||
unsafe { mem::transmute(base) }
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Create a new style sharing candidate cache.
|
/// Create a new style sharing candidate cache.
|
||||||
pub fn new() -> Self {
|
pub fn new() -> Self {
|
||||||
assert_eq!(mem::size_of::<SharingCache<E>>(), mem::size_of::<TypelessSharingCache>());
|
|
||||||
assert_eq!(mem::align_of::<SharingCache<E>>(), mem::align_of::<TypelessSharingCache>());
|
|
||||||
let cache_arc = SHARING_CACHE_KEY.with(|c| c.clone());
|
|
||||||
let cache = OwningHandle::new_with_fn(cache_arc, |x| unsafe { x.as_ref() }.unwrap().borrow_mut());
|
|
||||||
debug_assert_eq!(cache.num_entries(), 0);
|
|
||||||
|
|
||||||
StyleSharingCandidateCache {
|
StyleSharingCandidateCache {
|
||||||
cache_typeless: cache,
|
cache: LRUCache::new(),
|
||||||
marker: PhantomData,
|
|
||||||
dom_depth: 0,
|
dom_depth: 0,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns the number of entries in the cache.
|
/// Returns the number of entries in the cache.
|
||||||
pub fn num_entries(&self) -> usize {
|
pub fn num_entries(&self) -> usize {
|
||||||
self.cache().num_entries()
|
self.cache.num_entries()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn iter_mut(&mut self) -> LRUCacheMutIterator<StyleSharingCandidate<E>> {
|
fn iter_mut(&mut self) -> LRUCacheMutIterator<StyleSharingCandidate<E>> {
|
||||||
self.cache_mut().iter_mut()
|
self.cache.iter_mut()
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Tries to insert an element in the style sharing cache.
|
/// Tries to insert an element in the style sharing cache.
|
||||||
|
@ -588,20 +530,20 @@ impl<E: TElement> StyleSharingCandidateCache<E> {
|
||||||
self.clear();
|
self.clear();
|
||||||
self.dom_depth = dom_depth;
|
self.dom_depth = dom_depth;
|
||||||
}
|
}
|
||||||
self.cache_mut().insert(StyleSharingCandidate {
|
self.cache.insert(StyleSharingCandidate {
|
||||||
element: *element,
|
element: unsafe { SendElement::new(*element) },
|
||||||
validation_data: validation_data,
|
validation_data: validation_data,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Touch a given index in the style sharing candidate cache.
|
/// Touch a given index in the style sharing candidate cache.
|
||||||
pub fn touch(&mut self, index: usize) {
|
pub fn touch(&mut self, index: usize) {
|
||||||
self.cache_mut().touch(index);
|
self.cache.touch(index);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Clear the style sharing candidate cache.
|
/// Clear the style sharing candidate cache.
|
||||||
pub fn clear(&mut self) {
|
pub fn clear(&mut self) {
|
||||||
self.cache_mut().evict_all()
|
self.cache.evict_all()
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Attempts to share a style with another node.
|
/// Attempts to share a style with another node.
|
||||||
|
@ -668,7 +610,7 @@ impl<E: TElement> StyleSharingCandidateCache<E> {
|
||||||
}
|
}
|
||||||
|
|
||||||
debug!("{:?} Cannot share style: {} cache entries", target.element,
|
debug!("{:?} Cannot share style: {} cache entries", target.element,
|
||||||
self.cache().num_entries());
|
self.cache.num_entries());
|
||||||
|
|
||||||
StyleSharingResult::CannotShare
|
StyleSharingResult::CannotShare
|
||||||
}
|
}
|
||||||
|
|
|
@ -21,7 +21,7 @@ env_logger = {version = "0.4", default-features = false} # disable `regex` to re
|
||||||
libc = "0.2"
|
libc = "0.2"
|
||||||
log = {version = "0.3.5", features = ["release_max_level_info"]}
|
log = {version = "0.3.5", features = ["release_max_level_info"]}
|
||||||
nsstring_vendor = {path = "../../components/style/gecko_bindings/nsstring_vendor"}
|
nsstring_vendor = {path = "../../components/style/gecko_bindings/nsstring_vendor"}
|
||||||
parking_lot = "0.4"
|
parking_lot = "0.3"
|
||||||
selectors = {path = "../../components/selectors"}
|
selectors = {path = "../../components/selectors"}
|
||||||
style = {path = "../../components/style", features = ["gecko"]}
|
style = {path = "../../components/style", features = ["gecko"]}
|
||||||
style_traits = {path = "../../components/style_traits"}
|
style_traits = {path = "../../components/style_traits"}
|
||||||
|
|
|
@ -18,7 +18,7 @@ app_units = "0.5"
|
||||||
cssparser = "0.17.0"
|
cssparser = "0.17.0"
|
||||||
euclid = "0.15"
|
euclid = "0.15"
|
||||||
html5ever = "0.18"
|
html5ever = "0.18"
|
||||||
parking_lot = "0.4"
|
parking_lot = "0.3"
|
||||||
rayon = "0.8"
|
rayon = "0.8"
|
||||||
rustc-serialize = "0.3"
|
rustc-serialize = "0.3"
|
||||||
selectors = {path = "../../../components/selectors"}
|
selectors = {path = "../../../components/selectors"}
|
||||||
|
|
Загрузка…
Ссылка в новой задаче