style: Introduce StyleBloom

The idea is this will fix the bad behavior of the bloom filter in parallel
traversal.
This commit is contained in:
Emilio Cobos Álvarez 2016-11-23 23:37:27 +01:00 committed by Emilio Cobos Álvarez
parent 7d69f53794
commit 84a50ed5cb
No known key found for this signature in database
GPG key ID: 056B727BB9C1027C
7 changed files with 318 additions and 172 deletions

View file

@ -18,9 +18,7 @@ use style::data::ElementData;
use style::dom::{StylingMode, TElement, TNode};
use style::selector_parser::RestyleDamage;
use style::servo::restyle_damage::{BUBBLE_ISIZES, REFLOW, REFLOW_OUT_OF_FLOW, REPAINT};
use style::traversal::{DomTraversalContext, put_thread_local_bloom_filter};
use style::traversal::{recalc_style_at, remove_from_bloom_filter};
use style::traversal::take_thread_local_bloom_filter;
use style::traversal::{DomTraversalContext, recalc_style_at, remove_from_bloom_filter};
use util::opts;
use wrapper::{GetRawData, LayoutNodeHelpers, LayoutNodeLayoutData};
@ -79,32 +77,12 @@ impl<'lc, N> DomTraversalContext<N> for RecalcStyleAndConstructFlows<'lc>
// done by the HTML parser.
node.initialize_data();
if node.is_text_node() {
// FIXME(bholley): Stop doing this silly work to maintain broken bloom filter
// invariants.
//
// Longer version: The bloom filter is entirely busted for parallel traversal. Because
// parallel traversal is breadth-first, each sibling rejects the bloom filter set up
// by the previous sibling (which is valid for children, not siblings) and recreates
// it. Similarly, the fixup performed in the bottom-up traversal is useless, because
// threads perform flow construction up the parent chain until they find a parent with
// other unprocessed children, at which point they bail to the work queue and find a
// different node.
//
// Nevertheless, the remove_from_bloom_filter call at the end of flow construction
// asserts that the bloom filter is valid for the current node. This breaks when we
// stop calling recalc_style_at for text nodes, because the recursive chain of
// construct_flows_at calls is no longer necessarily rooted in a call that sets up the
// thread-local bloom filter for the leaf node.
//
// The bloom filter stuff is all going to be rewritten, so we just hackily duplicate
// the bloom filter manipulation from recalc_style_at to maintain invariants.
let parent = node.parent_node().unwrap().as_element();
let bf = take_thread_local_bloom_filter(parent, self.root, self.context.shared_context());
put_thread_local_bloom_filter(bf, &node.to_unsafe(), self.context.shared_context());
} else {
// FIXME(emilio): Get it!
let traversal_depth = None;
if !node.is_text_node() {
let el = node.as_element().unwrap();
recalc_style_at::<_, _, Self>(&self.context, self.root, el);
recalc_style_at::<_, _, Self>(&self.context, traversal_depth, el);
}
}
@ -174,9 +152,9 @@ fn construct_flows_at<'a, N: LayoutNode>(context: &'a LayoutContext<'a>, root: O
if let Some(el) = node.as_element() {
el.mutate_data().unwrap().persist();
unsafe { el.unset_dirty_descendants(); }
}
remove_from_bloom_filter(context, root, node);
remove_from_bloom_filter(context, root, el);
}
}
/// The bubble-inline-sizes traversal, the first part of layout computation. This computes