Closed Bug 1360767 Opened 8 years ago Closed 8 years ago

stylo: Speed up stylist rebuilds

Categories

(Core :: CSS Parsing and Computation, enhancement, P1)

enhancement

Tracking

()

RESOLVED FIXED

People

(Reporter: bholley, Assigned: bholley)

References

(Blocks 1 open bug)

Details

Attachments

(4 files, 2 obsolete files)

I have patches to optimize some of this stuff.
This makes things more readable, and easier to profile (since the Gecko profiler doesn't have any intra-function granularity, so I tend to make helpers non-inline when drilling down into what's expensive). It allows us to iterate the selector list once, which could help cache locality for rules with many selectors.
Attachment #8863085 - Flags: review?(emilio+bugs)
Right now in the common case we're doing twice the work during stylist update, and also checking is_html_element_in_html_document twice during lookup. This patch aligns us with what Gecko does. MozReview-Commit-ID: D4TyG30BP8C
Attachment #8863086 - Flags: review?(emilio+bugs)
MozReview-Commit-ID: HhVi72K4yp0
Attachment #8863087 - Flags: review?(emilio+bugs)
Attached patch Part 4 - Make note_selector more efficient. v1 (obsolete) (deleted) — Splinter Review
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
Attachment #8863088 - Flags: review?(emilio+bugs)
Rebased. MozReview-Commit-ID: GdFtgrbYCIu
Attachment #8863089 - Flags: review?(emilio+bugs)
Attachment #8863085 - Attachment is obsolete: true
Attachment #8863085 - Flags: review?(emilio+bugs)
Comment on attachment 8863086 [details] [diff] [review] Part 2 - Use a single rule hash for both lower_name and name. v1 Review of attachment 8863086 [details] [diff] [review]: ----------------------------------------------------------------- I'm not sure this patch is correct, mind to explain why it is? ::: servo/components/style/stylist.rs @@ +1262,5 @@ > + // of whether it's an html element in an html document (in which case > + // we match against lower_name) or not (in which case we match against > + // name). > + if name != lower_name { > + find_push(&mut self.local_name_hash, lower_name, rule.clone()); Hmmm... I may be missing something, but what prevents us to match incorrectly? i.e., if I have an non-HTML element, with a local name which is all lowercase, and a selector that is _not_ lowercase, we won't be matching it before this patch, but we would with it, right? * Can that happen? * Do we have tests for this?
Attachment #8863086 - Flags: review?(emilio+bugs)
Comment on attachment 8863087 [details] [diff] [review] Part 3 - Clean up note_selector a bit and stop handling combinators in two places. v1 Review of attachment 8863087 [details] [diff] [review]: ----------------------------------------------------------------- Now we don't have combinators in :not this is fine, but if we ever do that we need to revert this patch... I think a comment would be nice, at least. r=me if you think this is worth. ::: servo/components/style/restyle_hints.rs @@ -490,5 @@ > - > - fn visit_complex_selector(&mut self, > - _: SelectorIter<SelectorImpl>, > - combinator: Option<Combinator>) -> bool { > - self.hint |= combinator_to_restyle_hint(combinator); So the difference with this is that this handled correctly combinators inside :not, etc. I think we've removed that, but perhaps it's worth to keep it anyway? (or a comment, perhaps?)
Attachment #8863087 - Flags: review?(emilio+bugs) → review+
Comment on attachment 8863088 [details] [diff] [review] Part 4 - Make note_selector more efficient. v1 Review of attachment 8863088 [details] [diff] [review]: ----------------------------------------------------------------- ::: servo/components/style/restyle_hints.rs @@ +545,4 @@ > if !visitor.sensitivities.is_empty() { > + let mut hint = combinator_to_restyle_hint(combinator); > + let dep_selector; > + if index == 0 { I'm having trouble to see how this is right, too. So, let's say we have a selector like: .foo::before. Before this patch, we're inserting the descendants hint because the selector is a pseudo-element, so we need to arrive to ::before. After this, we'd traverse `.foo`, then set `index` to 1, and then never reach this code. Is this the intention? I think this only works now because we still restyle all descendants, but...
Attachment #8863088 - Flags: review?(emilio+bugs)
Comment on attachment 8863089 [details] [diff] [review] Part 1 - Factor out the various things stylist does per-selector into helpers. v2 Review of attachment 8863089 [details] [diff] [review]: ----------------------------------------------------------------- This is quite nice, thanks for cleaning this up :)
Attachment #8863089 - Flags: review?(emilio+bugs) → review+
(In reply to Emilio Cobos Álvarez [:emilio] from comment #6) > Comment on attachment 8863086 [details] [diff] [review] > Part 2 - Use a single rule hash for both lower_name and name. v1 > > Review of attachment 8863086 [details] [diff] [review]: > ----------------------------------------------------------------- > > I'm not sure this patch is correct, mind to explain why it is? > > ::: servo/components/style/stylist.rs > @@ +1262,5 @@ > > + // of whether it's an html element in an html document (in which case > > + // we match against lower_name) or not (in which case we match against > > + // name). > > + if name != lower_name { > > + find_push(&mut self.local_name_hash, lower_name, rule.clone()); > > Hmmm... I may be missing something, but what prevents us to match > incorrectly? > > i.e., if I have an non-HTML element, with a local name which is all > lowercase, and a selector that is _not_ lowercase, we won't be matching it > before this patch, but we would with it, right? We will find it in the rule hash where we didn't before, but selector matching will still reject it. That's a tradeoff we have to make in order to avoid calling is_html_element_in_html_document() twice inserting into the rule hash twice.
Attachment #8863086 - Flags: review?(emilio+bugs)
(In reply to Emilio Cobos Álvarez [:emilio] from comment #8) > Comment on attachment 8863088 [details] [diff] [review] > Part 4 - Make note_selector more efficient. v1 > > Review of attachment 8863088 [details] [diff] [review]: > ----------------------------------------------------------------- > > ::: servo/components/style/restyle_hints.rs > @@ +545,4 @@ > > if !visitor.sensitivities.is_empty() { > > + let mut hint = combinator_to_restyle_hint(combinator); > > + let dep_selector; > > + if index == 0 { > > I'm having trouble to see how this is right, too. > > So, let's say we have a selector like: > > .foo::before. > > Before this patch, we're inserting the descendants hint because the selector > is a pseudo-element, so we need to arrive to ::before. > > After this, we'd traverse `.foo`, then set `index` to 1, and then never > reach this code. Is this the intention? I think this only works now because > we still restyle all descendants, but... Sorry, this should have been sequence_start. I'll attach a patch.
MozReview-Commit-ID: 7OuCc2aQ7jH
Attachment #8863104 - Flags: review?(emilio+bugs)
Attachment #8863088 - Attachment is obsolete: true
Comment on attachment 8863086 [details] [diff] [review] Part 2 - Use a single rule hash for both lower_name and name. v1 Review of attachment 8863086 [details] [diff] [review]: ----------------------------------------------------------------- Ok, makes sense, thanks for explaining. r=me with a note saying that either where we insert the map, or where the member is defined.
Attachment #8863086 - Flags: review?(emilio+bugs) → review+
Comment on attachment 8863104 [details] [diff] [review] Part 4 - Make note_selector more efficient. v2 Review of attachment 8863104 [details] [diff] [review]: ----------------------------------------------------------------- ok, r=me ::: servo/components/style/restyle_hints.rs @@ +545,4 @@ > if !visitor.sensitivities.is_empty() { > + let mut hint = combinator_to_restyle_hint(combinator); > + let dep_selector; > + if sequence_start == 0 { nit: perhaps: let dep_selector = if sequence_start == 0 { ... } else { ... };
Attachment #8863104 - Flags: review?(emilio+bugs) → review+
(In reply to Emilio Cobos Álvarez [:emilio] from comment #14) > Comment on attachment 8863104 [details] [diff] [review] > Part 4 - Make note_selector more efficient. v2 > > Review of attachment 8863104 [details] [diff] [review]: > ----------------------------------------------------------------- > > ok, r=me > > ::: servo/components/style/restyle_hints.rs > @@ +545,4 @@ > > if !visitor.sensitivities.is_empty() { > > + let mut hint = combinator_to_restyle_hint(combinator); > > + let dep_selector; > > + if sequence_start == 0 { > > nit: perhaps: > > let dep_selector = if sequence_start == 0 { ... } else { ... }; I did this at first, but then decided that the side-effect mutation to |hint| in the first branch made this less understandable.
Status: NEW → RESOLVED
Closed: 8 years ago
Resolution: --- → FIXED
You need to log in before you can comment on or make changes to this bug.

Attachment

General

Created:
Updated:
Size: