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

Hoist bloom filter into scoped TLS, and remove a bunch of complexity and unsafety from the style system #14662

Merged
merged 5 commits into from Dec 22, 2016

Hoist SendElement into dom.rs, label construction as unsafe, and add …

…corresponding SendNode.
  • Loading branch information
bholley committed Dec 22, 2016
commit 96dc0d1eacc54a23635c9cf9c8a982bdbed7dac7
@@ -16,6 +16,7 @@ use selector_parser::{ElementExt, PreExistingComputedValues, PseudoElement};
use sink::Push;
use std::fmt;
use std::fmt::Debug;
use std::ops::Deref;
use std::sync::Arc;
use stylist::ApplicableDeclarationBlock;

@@ -262,3 +263,38 @@ pub trait TElement : PartialEq + Debug + Sized + Copy + Clone + ElementExt + Pre
/// native anonymous content can opt out of this style fixup.)
fn skip_root_and_item_based_display_fixup(&self) -> bool;
}

/// TNode and TElement aren't Send because we want to be careful and explicit
/// about our parallel traversal. However, there are certain situations
/// (including but not limited to the traversal) where we need to send DOM
/// objects to other threads.

#[derive(Debug, PartialEq)]
pub struct SendNode<N: TNode>(N);

This comment has been minimized.

@emilio

emilio Dec 22, 2016

Member

Please add a size_of test in the unit tests with Servo's DOM (and presumably with Gecko's), to ensure this type stays small, since we allocate it all over the place.

unsafe impl<N: TNode> Send for SendNode<N> {}
impl<N: TNode> SendNode<N> {
pub unsafe fn new(node: N) -> Self {
SendNode(node)
}
}
impl<N: TNode> Deref for SendNode<N> {
type Target = N;
fn deref(&self) -> &N {
&self.0
}
}

#[derive(Debug, PartialEq)]
pub struct SendElement<E: TElement>(E);
unsafe impl<E: TElement> Send for SendElement<E> {}
impl<E: TElement> SendElement<E> {
pub unsafe fn new(el: E) -> Self {
SendElement(el)
}
}
impl<E: TElement> Deref for SendElement<E> {
type Target = E;
fn deref(&self) -> &E {
&self.0
}
}
@@ -13,7 +13,7 @@ use cache::LRUCache;
use cascade_info::CascadeInfo;
use context::{SharedStyleContext, StyleContext};
use data::{ComputedStyle, ElementData, ElementStyles, PseudoStyles};
use dom::{TElement, TNode};
use dom::{SendElement, TElement, TNode};
use properties::{CascadeFlags, ComputedValues, SHAREABLE, SKIP_ROOT_AND_ITEM_BASED_DISPLAY_FIXUP, cascade};
use properties::longhands::display::computed_value as display;
use rule_tree::StrongRuleNode;
@@ -65,19 +65,13 @@ impl MatchResults {
}
}

// TElement isn't Send because we want to be careful and explicit about our
// parallel traversal, but we need the candidates to be Send so that we can stick
// them in ScopedTLS.
#[derive(Debug, PartialEq)]
struct SendElement<E: TElement>(pub E);
unsafe impl<E: TElement> Send for SendElement<E> {}

/// Information regarding a candidate.
///
/// TODO: We can stick a lot more info here.
#[derive(Debug)]
struct StyleSharingCandidate<E: TElement> {
/// The element.
/// The element. We use SendElement here so that the cache may live in
/// ScopedTLS.
element: SendElement<E>,
/// The cached common style affecting attribute info.
common_style_affecting_attributes: Option<CommonStyleAffectingAttributes>,
@@ -353,7 +347,7 @@ impl<E: TElement> StyleSharingCandidateCache<E> {
element, parent);

self.cache.insert(StyleSharingCandidate {
element: SendElement(*element),
element: unsafe { SendElement::new(*element) },
common_style_affecting_attributes: None,
class_attributes: None,
}, ());
@@ -501,9 +495,8 @@ trait PrivateMatchMethods: TElement {
shared_context: &SharedStyleContext,
candidate: &mut StyleSharingCandidate<Self>)
-> Result<ComputedStyle, CacheMiss> {
let candidate_element = candidate.element.0;
element_matches_candidate(self, candidate, &candidate_element,
shared_context)
let candidate_element = *candidate.element;
element_matches_candidate(self, candidate, &candidate_element, shared_context)
}
}

ProTip! Use n and p to navigate between commits in a pull request.
You can’t perform that action at this time.