Hook the recursive invalidation traversal up to the stack checker machinery.

MozReview-Commit-ID: 3tX3gHFTBT
This commit is contained in:
Emilio Cobos Álvarez 2017-08-25 13:06:07 -07:00 committed by Bobby Holley
parent 2136dd2bb7
commit 8c3cc9ba1f
4 changed files with 33 additions and 13 deletions

View file

@ -4,7 +4,7 @@
//! Per-node data used in style calculation. //! Per-node data used in style calculation.
use context::SharedStyleContext; use context::{SharedStyleContext, StackLimitChecker};
use dom::TElement; use dom::TElement;
use invalidation::element::restyle_hints::RestyleHint; use invalidation::element::restyle_hints::RestyleHint;
use properties::ComputedValues; use properties::ComputedValues;
@ -327,8 +327,9 @@ impl ElementData {
pub fn invalidate_style_if_needed<'a, E: TElement>( pub fn invalidate_style_if_needed<'a, E: TElement>(
&mut self, &mut self,
element: E, element: E,
shared_context: &SharedStyleContext) shared_context: &SharedStyleContext,
{ stack_limit_checker: Option<&StackLimitChecker>,
) {
// In animation-only restyle we shouldn't touch snapshot at all. // In animation-only restyle we shouldn't touch snapshot at all.
if shared_context.traversal_flags.for_animation_only() { if shared_context.traversal_flags.for_animation_only() {
return; return;
@ -349,6 +350,7 @@ impl ElementData {
element, element,
Some(self), Some(self),
shared_context, shared_context,
stack_limit_checker,
); );
invalidator.invalidate(); invalidator.invalidate();
unsafe { element.set_handled_snapshot() } unsafe { element.set_handled_snapshot() }

View file

@ -6,7 +6,7 @@
//! element styles need to be invalidated. //! element styles need to be invalidated.
use Atom; use Atom;
use context::SharedStyleContext; use context::{SharedStyleContext, StackLimitChecker};
use data::ElementData; use data::ElementData;
use dom::{TElement, TNode}; use dom::{TElement, TNode};
use element_state::{ElementState, IN_VISITED_OR_UNVISITED_STATE}; use element_state::{ElementState, IN_VISITED_OR_UNVISITED_STATE};
@ -40,6 +40,7 @@ pub struct TreeStyleInvalidator<'a, 'b: 'a, E>
// descendants if an element has no data, though. // descendants if an element has no data, though.
data: Option<&'a mut ElementData>, data: Option<&'a mut ElementData>,
shared_context: &'a SharedStyleContext<'b>, shared_context: &'a SharedStyleContext<'b>,
stack_limit_checker: Option<&'a StackLimitChecker>,
} }
type InvalidationVector = SmallVec<[Invalidation; 10]>; type InvalidationVector = SmallVec<[Invalidation; 10]>;
@ -130,11 +131,13 @@ impl<'a, 'b: 'a, E> TreeStyleInvalidator<'a, 'b, E>
element: E, element: E,
data: Option<&'a mut ElementData>, data: Option<&'a mut ElementData>,
shared_context: &'a SharedStyleContext<'b>, shared_context: &'a SharedStyleContext<'b>,
stack_limit_checker: Option<&'a StackLimitChecker>,
) -> Self { ) -> Self {
Self { Self {
element: element, element,
data: data, data,
shared_context: shared_context, shared_context,
stack_limit_checker,
} }
} }
@ -276,7 +279,8 @@ impl<'a, 'b: 'a, E> TreeStyleInvalidator<'a, 'b, E>
let mut sibling_invalidator = TreeStyleInvalidator::new( let mut sibling_invalidator = TreeStyleInvalidator::new(
sibling, sibling,
sibling_data, sibling_data,
self.shared_context self.shared_context,
self.stack_limit_checker,
); );
let mut invalidations_for_descendants = InvalidationVector::new(); let mut invalidations_for_descendants = InvalidationVector::new();
@ -338,7 +342,8 @@ impl<'a, 'b: 'a, E> TreeStyleInvalidator<'a, 'b, E>
let mut child_invalidator = TreeStyleInvalidator::new( let mut child_invalidator = TreeStyleInvalidator::new(
child, child,
child_data, child_data,
self.shared_context self.shared_context,
self.stack_limit_checker,
); );
let mut invalidations_for_descendants = InvalidationVector::new(); let mut invalidations_for_descendants = InvalidationVector::new();
@ -448,12 +453,21 @@ impl<'a, 'b: 'a, E> TreeStyleInvalidator<'a, 'b, E>
match self.data { match self.data {
None => return false, None => return false,
Some(ref data) => { Some(ref data) => {
// FIXME(emilio): Only needs to check RESTYLE_DESCENDANTS,
// really.
if data.restyle.hint.contains_subtree() { if data.restyle.hint.contains_subtree() {
return false; return false;
} }
} }
} }
if let Some(checker) = self.stack_limit_checker {
if checker.limit_exceeded() {
self.data.as_mut().unwrap().restyle.hint.insert(RESTYLE_DESCENDANTS);
return true;
}
}
let mut any_descendant = false; let mut any_descendant = false;
if let Some(anon_content) = self.element.xbl_binding_anonymous_content() { if let Some(anon_content) = self.element.xbl_binding_anonymous_content() {

View file

@ -139,7 +139,7 @@ pub trait DomTraversal<E: TElement> : Sync {
fn pre_traverse( fn pre_traverse(
root: E, root: E,
shared_context: &SharedStyleContext, shared_context: &SharedStyleContext,
traversal_flags: TraversalFlags traversal_flags: TraversalFlags,
) -> PreTraverseToken { ) -> PreTraverseToken {
// If this is an unstyled-only traversal, the caller has already verified // If this is an unstyled-only traversal, the caller has already verified
// that there's something to traverse, and we don't need to do any // that there's something to traverse, and we don't need to do any
@ -155,7 +155,7 @@ pub trait DomTraversal<E: TElement> : Sync {
if let Some(ref mut data) = data { if let Some(ref mut data) = data {
// Invalidate our style, and the one of our siblings and descendants // Invalidate our style, and the one of our siblings and descendants
// as needed. // as needed.
data.invalidate_style_if_needed(root, shared_context); data.invalidate_style_if_needed(root, shared_context, None);
// Make sure we don't have any stale RECONSTRUCTED_ANCESTOR bits from // Make sure we don't have any stale RECONSTRUCTED_ANCESTOR bits from
// the last traversal (at a potentially-higher root). From the // the last traversal (at a potentially-higher root). From the
@ -828,7 +828,11 @@ where
// as needed. // as needed.
// //
// NB: This will be a no-op if there's no snapshot. // NB: This will be a no-op if there's no snapshot.
child_data.invalidate_style_if_needed(child, &context.shared); child_data.invalidate_style_if_needed(
child,
&context.shared,
Some(&context.thread_local.stack_limit_checker)
);
} }
if D::element_needs_traversal(child, flags, child_data.map(|d| &*d), Some(data)) { if D::element_needs_traversal(child, flags, child_data.map(|d| &*d), Some(data)) {

View file

@ -3701,6 +3701,6 @@ pub extern "C" fn Servo_ProcessInvalidations(set: RawServoStyleSetBorrowed,
let mut data = data.as_mut().map(|d| &mut **d); let mut data = data.as_mut().map(|d| &mut **d);
if let Some(ref mut data) = data { if let Some(ref mut data) = data {
data.invalidate_style_if_needed(element, &shared_style_context); data.invalidate_style_if_needed(element, &shared_style_context, None);
} }
} }