Skip to content

Commit

Permalink
Auto merge of #18904 - emilio:invalidator-less-dependencies, r=heycam…
Browse files Browse the repository at this point in the history
…,jdm,nox

style: Stop threading the ElementData around the invalidator.

<!-- 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/18904)
<!-- Reviewable:end -->
  • Loading branch information
bors-servo committed Oct 17, 2017
2 parents 7704fa0 + 96b7175 commit c1e0889
Show file tree
Hide file tree
Showing 11 changed files with 218 additions and 305 deletions.
100 changes: 33 additions & 67 deletions components/layout_thread/dom_wrapper.rs
Expand Up @@ -68,7 +68,7 @@ use style::attr::AttrValue;
use style::computed_values::display;
use style::context::SharedStyleContext;
use style::data::ElementData;
use style::dom::{LayoutIterator, NodeInfo, OpaqueNode};
use style::dom::{DomChildren, LayoutIterator, NodeInfo, OpaqueNode};
use style::dom::{PresentationalHintsSynthesizer, TElement, TNode};
use style::element_state::*;
use style::font_metrics::ServoMetricsProvider;
Expand Down Expand Up @@ -159,26 +159,39 @@ impl<'ln> NodeInfo for ServoLayoutNode<'ln> {

impl<'ln> TNode for ServoLayoutNode<'ln> {
type ConcreteElement = ServoLayoutElement<'ln>;
type ConcreteChildrenIterator = ServoChildrenIterator<'ln>;

fn parent_node(&self) -> Option<Self> {
unsafe {
self.node.parent_node_ref().map(|node| self.new_with_this_lifetime(&node))
}
}

fn children(&self) -> LayoutIterator<ServoChildrenIterator<'ln>> {
LayoutIterator(ServoChildrenIterator {
current: self.first_child(),
})
fn first_child(&self) -> Option<Self> {
unsafe {
self.node.first_child_ref().map(|node| self.new_with_this_lifetime(&node))
}
}

fn traversal_parent(&self) -> Option<ServoLayoutElement<'ln>> {
self.parent_element()
fn last_child(&self) -> Option<Self> {
unsafe {
self.node.last_child_ref().map(|node| self.new_with_this_lifetime(&node))
}
}

fn prev_sibling(&self) -> Option<Self> {
unsafe {
self.node.prev_sibling_ref().map(|node| self.new_with_this_lifetime(&node))
}
}

fn traversal_children(&self) -> LayoutIterator<ServoChildrenIterator<'ln>> {
self.children()
fn next_sibling(&self) -> Option<Self> {
unsafe {
self.node.next_sibling_ref().map(|node| self.new_with_this_lifetime(&node))
}
}

fn traversal_parent(&self) -> Option<ServoLayoutElement<'ln>> {
self.parent_element()
}

fn opaque(&self) -> OpaqueNode {
Expand All @@ -200,23 +213,6 @@ impl<'ln> TNode for ServoLayoutNode<'ln> {
unsafe fn set_can_be_fragmented(&self, value: bool) {
self.node.set_flag(CAN_BE_FRAGMENTED, value)
}

fn is_in_doc(&self) -> bool {
unsafe { (*self.node.unsafe_get()).is_in_doc() }
}
}

pub struct ServoChildrenIterator<'a> {
current: Option<ServoLayoutNode<'a>>,
}

impl<'a> Iterator for ServoChildrenIterator<'a> {
type Item = ServoLayoutNode<'a>;
fn next(&mut self) -> Option<ServoLayoutNode<'a>> {
let node = self.current;
self.current = node.and_then(|node| node.next_sibling());
node
}
}

impl<'ln> LayoutNode for ServoLayoutNode<'ln> {
Expand Down Expand Up @@ -248,30 +244,6 @@ impl<'ln> LayoutNode for ServoLayoutNode<'ln> {
unsafe fn take_style_and_layout_data(&self) -> OpaqueStyleAndLayoutData {
self.get_jsmanaged().take_style_and_layout_data()
}

fn first_child(&self) -> Option<ServoLayoutNode<'ln>> {
unsafe {
self.node.first_child_ref().map(|node| self.new_with_this_lifetime(&node))
}
}

fn last_child(&self) -> Option<ServoLayoutNode<'ln>> {
unsafe {
self.node.last_child_ref().map(|node| self.new_with_this_lifetime(&node))
}
}

fn prev_sibling(&self) -> Option<ServoLayoutNode<'ln>> {
unsafe {
self.node.prev_sibling_ref().map(|node| self.new_with_this_lifetime(&node))
}
}

fn next_sibling(&self) -> Option<ServoLayoutNode<'ln>> {
unsafe {
self.node.next_sibling_ref().map(|node| self.new_with_this_lifetime(&node))
}
}
}

impl<'ln> GetLayoutData for ServoLayoutNode<'ln> {
Expand Down Expand Up @@ -320,8 +292,8 @@ impl<'ld> ServoLayoutDocument<'ld> {
ServoLayoutNode::from_layout_js(self.document.upcast())
}

pub fn root_node(&self) -> Option<ServoLayoutNode<'ld>> {
self.as_node().children().find(ServoLayoutNode::is_element)
pub fn root_element(&self) -> Option<ServoLayoutElement<'ld>> {
self.as_node().dom_children().flat_map(|n| n.as_element()).next()
}

pub fn drain_pending_restyles(&self) -> Vec<(ServoLayoutElement<'ld>, PendingRestyle)> {
Expand Down Expand Up @@ -380,13 +352,18 @@ impl<'le> PresentationalHintsSynthesizer for ServoLayoutElement<'le> {

impl<'le> TElement for ServoLayoutElement<'le> {
type ConcreteNode = ServoLayoutNode<'le>;
type TraversalChildrenIterator = DomChildren<Self::ConcreteNode>;

type FontMetricsProvider = ServoMetricsProvider;

fn as_node(&self) -> ServoLayoutNode<'le> {
ServoLayoutNode::from_layout_js(self.element.upcast())
}

fn traversal_children(&self) -> LayoutIterator<Self::TraversalChildrenIterator> {
LayoutIterator(self.as_node().dom_children())
}

fn style_attribute(&self) -> Option<ArcBorrow<StyleLocked<PropertyDeclarationBlock>>> {
unsafe {
(*self.element.style_attribute()).as_ref().map(|x| x.borrow_arc())
Expand Down Expand Up @@ -629,7 +606,7 @@ impl<'le> ::selectors::Element for ServoLayoutElement<'le> {
}

fn first_child_element(&self) -> Option<ServoLayoutElement<'le>> {
self.as_node().children().filter_map(|n| n.as_element()).next()
self.as_node().dom_children().filter_map(|n| n.as_element()).next()
}

fn last_child_element(&self) -> Option<ServoLayoutElement<'le>> {
Expand Down Expand Up @@ -690,7 +667,7 @@ impl<'le> ::selectors::Element for ServoLayoutElement<'le> {
}

fn is_empty(&self) -> bool {
self.as_node().children().all(|node| match node.script_type_id() {
self.as_node().dom_children().all(|node| match node.script_type_id() {
NodeTypeId::Element(..) => false,
NodeTypeId::CharacterData(CharacterDataTypeId::Text) => unsafe {
node.node.downcast().unwrap().data_for_layout().is_empty()
Expand Down Expand Up @@ -850,20 +827,14 @@ impl<'ln> ServoThreadSafeLayoutNode<'ln> {
}
}

// NB: The implementation here is a bit tricky because elements implementing
// pseudos are supposed to return false for is_element().
impl<'ln> NodeInfo for ServoThreadSafeLayoutNode<'ln> {
fn is_element(&self) -> bool {
self.pseudo == PseudoElementType::Normal && self.node.is_element()
self.node.is_element()
}

fn is_text_node(&self) -> bool {
self.node.is_text_node()
}

fn needs_layout(&self) -> bool {
self.node.is_text_node() || self.node.is_element()
}
}

impl<'ln> ThreadSafeLayoutNode for ServoThreadSafeLayoutNode<'ln> {
Expand All @@ -883,11 +854,6 @@ impl<'ln> ThreadSafeLayoutNode for ServoThreadSafeLayoutNode<'ln> {
}
}

#[inline]
fn type_id_without_excluding_pseudo_elements(&self) -> LayoutNodeType {
self.node.type_id()
}

fn parent_style(&self) -> Arc<ComputedValues> {
let parent = self.node.parent_node().unwrap().as_element().unwrap();
let parent_data = parent.get_data().unwrap().borrow();
Expand Down
4 changes: 2 additions & 2 deletions components/layout_thread/lib.rs
Expand Up @@ -1067,7 +1067,7 @@ impl LayoutThread {

let mut rw_data = possibly_locked_rw_data.lock();

let element: ServoLayoutElement = match document.root_node() {
let element = match document.root_element() {
None => {
// Since we cannot compute anything, give spec-required placeholders.
debug!("layout: No root node: bailing");
Expand Down Expand Up @@ -1112,7 +1112,7 @@ impl LayoutThread {
}
return;
},
Some(x) => x.as_element().unwrap(),
Some(x) => x,
};

debug!("layout: processing reflow request for: {:?} ({}) (query={:?})",
Expand Down
20 changes: 0 additions & 20 deletions components/script_layout_interface/wrapper_traits.rs
Expand Up @@ -100,14 +100,6 @@ pub trait LayoutNode: Debug + GetLayoutData + TNode {
fn traverse_preorder(self) -> TreeIterator<Self> {
TreeIterator::new(self)
}

fn first_child(&self) -> Option<Self>;

fn last_child(&self) -> Option<Self>;

fn prev_sibling(&self) -> Option<Self>;

fn next_sibling(&self) -> Option<Self>;
}

pub struct ReverseChildrenIterator<ConcreteNode> where ConcreteNode: LayoutNode {
Expand Down Expand Up @@ -169,10 +161,6 @@ pub trait ThreadSafeLayoutNode: Clone + Copy + Debug + GetLayoutData + NodeInfo
/// Returns `None` if this is a pseudo-element; otherwise, returns `Some`.
fn type_id(&self) -> Option<LayoutNodeType>;

/// Returns the type ID of this node, without discarding pseudo-elements as
/// `type_id` does.
fn type_id_without_excluding_pseudo_elements(&self) -> LayoutNodeType;

/// Returns the style for a text node. This is computed on the fly from the
/// parent style to avoid traversing text nodes in the style system.
///
Expand All @@ -183,14 +171,6 @@ pub trait ThreadSafeLayoutNode: Clone + Copy + Debug + GetLayoutData + NodeInfo
/// the parent until all the children have been processed.
fn parent_style(&self) -> Arc<ComputedValues>;

#[inline]
fn is_element_or_elements_pseudo(&self) -> bool {
match self.type_id_without_excluding_pseudo_elements() {
LayoutNodeType::Element(..) => true,
_ => false,
}
}

fn get_before_pseudo(&self) -> Option<Self> {
self.as_element().and_then(|el| el.get_before_pseudo()).map(|el| el.as_node())
}
Expand Down
10 changes: 7 additions & 3 deletions components/style/data.rs
Expand Up @@ -259,11 +259,15 @@ impl ElementData {
return InvalidationResult::empty();
}

let mut processor = StateAndAttrInvalidationProcessor;
let mut processor = StateAndAttrInvalidationProcessor::new(
shared_context,
element,
self,
);

let invalidator = TreeStyleInvalidator::new(
element,
Some(self),
shared_context,
shared_context.quirks_mode(),
stack_limit_checker,
nth_index_cache,
&mut processor,
Expand Down

0 comments on commit c1e0889

Please sign in to comment.