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

Speed up stylist rebuilds #16659

Merged
merged 5 commits into from Apr 30, 2017
Merged
Changes from 1 commit
Commits
File filter...
Filter file types
Jump to…
Jump to file
Failed to load files.

Always

Just for now

Prev

Make note_selector more efficient.

My measurements are inconclusive as to whether this really moves the
needle, but it seems like the right way to do it in any case.

MozReview-Commit-ID: 7OuCc2aQ7jH
  • Loading branch information
bholley committed Apr 29, 2017
commit a6ef89a7fee2e168f46722df452f44d1fc6b3d1e
@@ -525,56 +525,63 @@ impl DependencySet {

/// Adds a selector to this `DependencySet`.
pub fn note_selector(&mut self, selector: &Selector<SelectorImpl>) {
let mut is_pseudo_element = selector.pseudo_element.is_some();

let mut next = Some(selector.inner.complex.clone());
let mut combinator = None;
let mut iter = selector.inner.complex.iter();
let mut index = 0;

while let Some(current) = next.take() {
// Set up our visitor.
loop {
let sequence_start = index;
let mut visitor = SensitivitiesVisitor {
sensitivities: Sensitivities::new()
};
let mut hint = combinator_to_restyle_hint(combinator);

if is_pseudo_element {
// TODO(emilio): use more fancy restyle hints to avoid restyling
// the whole subtree when pseudos change.
//
// We currently need is_pseudo_element to handle eager pseudos
// (so the style the parent stores doesn't become stale), and
// restyle_descendants to handle all of them (::before and
// ::after, because we find them in the subtree, and other lazy
// pseudos for the same reason).
hint |= RESTYLE_SELF | RESTYLE_DESCENDANTS;
is_pseudo_element = false;
}

{
// Visit all the simple selectors.
let mut iter = current.iter();
let mut index = 0usize;
for ss in &mut iter {
ss.visit(&mut visitor);
index += 1;
}

// Prepare the next sequence of simple selectors.
if let Some(next_combinator) = iter.next_sequence() {
next = Some(current.slice_from(index + 1));
combinator = Some(next_combinator);
}
// Visit all the simple selectors in this sequence.
//
// Note that this works because we can't have combinators nested
// inside simple selectors (i.e. in :not() or :-moz-any()). If we
// ever support that we'll need to visit complex selectors as well.
for ss in &mut iter {
ss.visit(&mut visitor);
index += 1; // Account for the simple selector.
}

// Note what we found.
// If we found a sensitivity, add an entry in the dependency set.
if !visitor.sensitivities.is_empty() {
let mut hint = combinator_to_restyle_hint(combinator);
let dep_selector;
if sequence_start == 0 {
if selector.pseudo_element.is_some() {
// TODO(emilio): use more fancy restyle hints to avoid
// restyling the whole subtree when pseudos change.
//
// We currently need is_pseudo_element to handle eager
// pseudos (so the style the parent stores doesn't
// become stale), and restyle_descendants to handle all
// of them (::before and ::after, because we find them
// in the subtree, and other lazy pseudos for the same
// reason).
hint |= RESTYLE_SELF | RESTYLE_DESCENDANTS;
}

// Reuse the bloom hashes if this is the base selector.
dep_selector = selector.inner.clone();
} else {
dep_selector = SelectorInner::new(selector.inner.complex.slice_from(sequence_start));
}

self.add_dependency(Dependency {
sensitivities: visitor.sensitivities,
hint: hint,
selector: SelectorInner::new(current),
})
selector: dep_selector,
});
}

combinator = iter.next_sequence();
if combinator.is_none() {
break;
}

index += 1; // Account for the combinator.
}
}

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