Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

reuse the bloom filter and style sharing cache across traversals #17701

Merged
merged 4 commits into from Jul 13, 2017
Merged
Changes from all commits
Commits
File filter...
Filter file types
Jump to…
Jump to file
Failed to load files.

Always

Just for now

Some generated files are not rendered by default. Learn more.

@@ -26,7 +26,7 @@ log = "0.3.5"
msg = {path = "../msg"}
net_traits = {path = "../net_traits"}
ordered-float = "0.4"
parking_lot = "0.3.3"
parking_lot = "0.4"
profile_traits = {path = "../profile_traits"}
range = {path = "../range"}
rayon = "0.8"
@@ -23,7 +23,7 @@ lazy_static = "0.2"
log = "0.3.5"
msg = {path = "../msg"}
net_traits = {path = "../net_traits"}
parking_lot = {version = "0.3.3", features = ["nightly"]}
parking_lot = {version = "0.4", features = ["nightly"]}
profile_traits = {path = "../profile_traits"}
rayon = "0.8"
script = {path = "../script"}
@@ -65,7 +65,7 @@ net_traits = {path = "../net_traits"}
num-traits = "0.1.32"
offscreen_gl_context = { version = "0.11", features = ["serde"] }
open = "1.1.1"
parking_lot = "0.3"
parking_lot = "0.4"
phf = "0.7.18"
profile_traits = {path = "../profile_traits"}
range = {path = "../range"}
@@ -14,5 +14,6 @@ servo = ["serde", "heapsize"]

[dependencies]
heapsize = {version = "0.4.0", optional = true}
serde = {version = "1.0", optional = true}
nodrop = {version = "0.1.8"}
serde = {version = "1.0", optional = true}
stable_deref_trait = "1.0.0"
@@ -22,14 +22,16 @@
// duplicate those here.
#![allow(missing_docs)]

#[cfg(feature = "servo")] extern crate serde;
extern crate nodrop;
#[cfg(feature = "servo")] extern crate serde;
extern crate stable_deref_trait;

#[cfg(feature = "servo")]
use heapsize::HeapSizeOf;
use nodrop::NoDrop;
#[cfg(feature = "servo")]
use serde::{Deserialize, Serialize};
use stable_deref_trait::{CloneStableDeref, StableDeref};
use std::{isize, usize};
use std::borrow;
use std::cmp::Ordering;
@@ -432,6 +434,9 @@ 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
// sound. See https://github.com/servo/heapsize/issues/37
#[cfg(feature = "servo")]
@@ -54,7 +54,8 @@ num_cpus = {version = "1.1.0", optional = true}
num-integer = "0.1.32"
num-traits = "0.1.32"
ordered-float = "0.4"
parking_lot = "0.3.3"
owning_ref = "0.3.3"
parking_lot = "0.4"
pdqsort = "0.1.0"
precomputed-hash = "0.1"
rayon = "0.8"
@@ -7,9 +7,18 @@

#![deny(missing_docs)]

use atomic_refcell::{AtomicRefMut, AtomicRefCell};
use dom::{SendElement, TElement};
use owning_ref::OwningHandle;
use selectors::bloom::BloomFilter;
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
/// selector-matching.
@@ -43,8 +52,11 @@ use smallvec::SmallVec;
/// immutable during a restyle.
///
pub struct StyleBloom<E: TElement> {
/// The bloom filter per se.
filter: Box<BloomFilter>,
/// A handle to the bloom filter from the thread upon which this StyleBloom
/// was created. We use AtomicRefCell so that this is all |Send|, which allows
/// 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
/// number of hashes pushed for each element.
@@ -101,11 +113,23 @@ 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> {
/// Create an empty `StyleBloom`.
/// Create an empty `StyleBloom`. Because StyleBloom acquires the thread-
/// local filter buffer, creating multiple live StyleBloom instances at
/// the same time on the same thread will panic.
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 {
filter: Box::new(BloomFilter::new()),
filter: filter,
elements: Default::default(),
pushed_hashes: Default::default(),
}
@@ -67,6 +67,7 @@ pub extern crate nsstring_vendor as nsstring;
extern crate num_integer;
extern crate num_traits;
extern crate ordered_float;
extern crate owning_ref;
extern crate parking_lot;
extern crate pdqsort;
#[cfg(feature = "gecko")] extern crate precomputed_hash;
ProTip! Use n and p to navigate between commits in a pull request.
You can’t perform that action at this time.