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

Centralize event states in rust-selectors #8162

Merged
merged 2 commits into from
Oct 31, 2015

Conversation

bholley
Copy link
Contributor

@bholley bholley commented Oct 22, 2015

This still needs a rev bump on rust-selectors once servo/rust-selectors#55 gets merged.

Review on Reviewable

@highfive highfive added the S-awaiting-review There is new code that needs to be reviewed. label Oct 22, 2015
@highfive
Copy link

warning Warning warning

  • These commits modify layout code, but no reftests are modified. Please consider adding a reftest!

@bholley
Copy link
Contributor Author

bholley commented Oct 22, 2015

r? @Manishearth

@bholley
Copy link
Contributor Author

bholley commented Oct 22, 2015

Added rust-selectors rev bump.

}
// NB: We can't [derive(..)] this because it's defined in rust-selectors, which
// doesn't know about JS<T>.
impl JSTraceable for EventState { fn trace(&self, _trc: *mut JSTracer) {} }
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

no_jsmanaged_fields! is what we should use here (grep the source for it)

@Manishearth
Copy link
Member

Reviewed 15 of 15 files at r2.
Review status: all files reviewed at latest revision, 3 unresolved discussions, some commit checks pending.


components/script/dom/htmlinputelement.rs, line 245 [r2] (raw file):
There's some extra logic in update_checked_state, let's move the set_state there


Comments from the review on Reviewable.io

@bholley
Copy link
Contributor Author

bholley commented Oct 22, 2015

Review status: all files reviewed at latest revision, 1 unresolved discussion, all commit checks successful.


components/script/dom/htmlinputelement.rs, line 245 [r2] (raw file):
Whoops, good catch!


Comments from the review on Reviewable.io

@bholley
Copy link
Contributor Author

bholley commented Oct 22, 2015

Review status: all files reviewed at latest revision, 1 unresolved discussion, all commit checks successful.


components/script/dom/htmlinputelement.rs, line 245 [r2] (raw file):
Done.


Comments from the review on Reviewable.io

@jdm jdm added S-needs-code-changes Changes have not yet been made that were requested by a reviewer. and removed S-awaiting-review There is new code that needs to be reviewed. labels Oct 22, 2015
@SimonSapin SimonSapin added the S-awaiting-answer Someone asked a question that requires an answer. label Oct 23, 2015
@SimonSapin
Copy link
Member

r-

This change is unjustified, seems unnecessary to me (is there a benefit I don’t see?), and the corresponding rust-selectors change (servo/rust-selectors#55) forces users to either keep all state in a single u16 of bit flags like Servo does, or do mork work than necessary gathering all state when only one bit is used.

Please explain motivation for this change and the rust-selectors one.

@bholley
Copy link
Contributor Author

bholley commented Oct 23, 2015

@SimonSapin:
See servo/rust-selectors#55 (comment) , and the email I just sent.

@SimonSapin
Copy link
Member

Can we discuss in public, where people other than me can find it later?

@bholley
Copy link
Contributor Author

bholley commented Oct 23, 2015

@SimonSapin I need to run, and there's not an easy way to convert an email thread to a github issue thread. But feel free to post/summarize, and I can respond in a few hours when I get back.

@bholley
Copy link
Contributor Author

bholley commented Oct 23, 2015

A bit more context here now that I have a few minutes (sorry for the delay):

My high-level goal here is to fix #6942 by implementing restyle hints in Servo. This logic needs to live at the intersection of layout, style, and rust-selectors, and therefore will understandably involve changes to rust-selectors.

Restyle hints work by batching up a series of EventState changes for a given Element and then asking the style system for an upper-bound of the categories of elements (self, subtree, siblings, etc) that may need restyling. In order to ask this question, rust-selectors and layout need a common bitfield type by which to represent a set of event states. Given the dependency tree, this type needs to live in rust-selectors, hence this change.

Once we have this common representation, it seems like an obvious simplification to remove the per-state methods from the trait definition and pass this information with a single method. This removes a lot of boilerplate code (duplicated across tree.rs, element.rs, and wrapper.rs), and makes it possible to access the entire set of state values with a single virtual call. More importantly, it eliminates the chicken-and-egg dependency problem that causes Servo to break when rust-selectors adds support for a new EventState. This bit me today with #8142 , and I wanted to prevent it from biting other people.

The one downside is the one mentioned in [1], whereby other theoretical consumers without a centralized EventState representation will pay a performance cost when aggregating their state. However, optimizing performance for multiple consumer designs is pretty hard. Any consumer that wants maximal performance is going to want to centralize EventState to take advantage of restyle hints (and subsequent optimizations beyond it), so I'm not convinced that this should block what we do here.

[1] #8162 (comment)

@bholley
Copy link
Contributor Author

bholley commented Oct 23, 2015

@Ms2ger explained to me that our use of generics allows us to bypass virtual calls on the trait impls (which is super neat!). I think the rest of the points are still valid though.

@SimonSapin
Copy link
Member

https://github.com/SimonSapin/kuchiki is not theoretical. It doesn’t have many users yet (as far as I know?), but there was demand for it repetitively.

I’m not buying the preformance thing. As you mentioned @Ms2ger explained, the compiler generates separate code for generic functions/methods for each concrete type arguments. Moving the bitfield.contains() call to rust-selectors might not even affect the generated code (assuming sufficiently advanced inlining). Dynamic dispatch (and type ereasure / heterogenous collections) can be opted into by using trait objects instead of generics.

Repetitive code probably wouldn’t be hard to generate with macro_rules!.

Please explain motivation in pull request messages. Restyle hints does make servo/rust-selectors#55 seem less gratuitous than it first did in isolation.

Still, it’s not clear to me: why does rust-selectors need to know about this bitfield?

@bholley
Copy link
Contributor Author

bholley commented Oct 23, 2015

Please explain motivation in pull request messages.

Sorry. The motivation is explained in commit messages and comments of other dependent commits, but I was trying to get this piece landed separately, since it requires me to update Servo's rust-selectors dependency, and I wanted to isolate any issues that might be caused by that step.

The larger context here is that @pcwalton and I are investigating what it would take to plug Servo's style system into Gecko. In order to familiarize myself with Servo's style system (and Rust in general), I'm implementing restyle hints.

Still, it’s not clear to me: why does rust-selectors need to know about this bitfield?

When testing restyle hints, we need to match against selectors while ignoring the subset of pseudo-selectors corresponding to the EventStates that changed. Suppose a selector S of the form a b:invalid:focus:hover c exists in a stylesheet, and we change the focus and hover state of an element foo. The restyle hint algorithm would then want to match against the effective selector T of the form a b:invalid in order to determine whether the event changes in foo might affect the set of elements in the document matching S.

However, T may not exist in any stylesheet, and it cannot be computed before match time because it depends on the set of EventStates that changed. So we need to pass an optional bitfield to selector matching instructing rust-selectors which pseudo-classes to ignore. This is why rust-selectors needs EventState (or something isomorphic), and my primary motivation for moving it.

Another side-benefit is that it consolidates the two existing enumerates of states (EventState and SimpleSelector) into the same library, making it easier to change both of them together (see my complaint about :target). Landing coordinated mutually-dependent changes to multiple libraries is a barrier to contribution that I'd like to remove.

Repetitive code probably wouldn’t be hard to generate with macro_rules!

Potentially yes, but we still need to enumerate those states in all of the places I mentioned, making us susceptible to cross-library breakage.

All that being said, coalescing the API was an attempt to simplify the API and improve the cross-library ergonomic footguns that I was encountering. We could revert that change if you like without scuttling restyle hints, though I do think that doing so would make our lives harder on the whole.

@SimonSapin
Copy link
Member

Please see my proposed changes in servo/rust-selectors#56 and discuss them there. Let’s block this in the mean time.

@SimonSapin SimonSapin added S-needs-decision A decision is required and has not been made. and removed S-awaiting-answer Someone asked a question that requires an answer. labels Oct 24, 2015
@highfive highfive added S-awaiting-review There is new code that needs to be reviewed. and removed S-needs-code-changes Changes have not yet been made that were requested by a reviewer. labels Oct 26, 2015
@bors-servo
Copy link
Contributor

🔒 Merge conflict

@bors-servo
Copy link
Contributor

☔ The latest upstream changes (presumably #8114) made this pull request unmergeable. Please resolve the merge conflicts.

@highfive highfive added S-needs-rebase There are merge conflict errors. and removed S-awaiting-merge The PR is in the process of compiling and running tests on the automated CI. labels Oct 31, 2015
@Manishearth
Copy link
Member

Probably should start using p=1 for PRs which have a tendency to bitrot often. (@bors-servo p=1 works)

This is necessary for those selectors to take advantage of restyle hints.
@highfive highfive added S-awaiting-review There is new code that needs to be reviewed. and removed S-tests-failed The changes caused existing tests to fail. labels Oct 31, 2015
@bholley
Copy link
Contributor Author

bholley commented Oct 31, 2015

@Manishearth r?

@bholley bholley removed the S-needs-rebase There are merge conflict errors. label Oct 31, 2015
@bholley
Copy link
Contributor Author

bholley commented Oct 31, 2015

@bors-servo p=1

@mbrubeck
Copy link
Contributor

@bors-servo r=pcwalton p=1

@bors-servo
Copy link
Contributor

📌 Commit 79ac365 has been approved by pcwalton

@highfive highfive added S-awaiting-merge The PR is in the process of compiling and running tests on the automated CI. and removed S-awaiting-review There is new code that needs to be reviewed. labels Oct 31, 2015
@bors-servo
Copy link
Contributor

⌛ Testing commit 79ac365 with merge 521a871...

bors-servo pushed a commit that referenced this pull request Oct 31, 2015
Centralize event states in rust-selectors

This still needs a rev bump on rust-selectors once servo/rust-selectors#55 gets merged.

<!-- Reviewable:start -->
[<img src="https://reviewable.io/review_button.png" height=40 alt="Review on Reviewable"/>](https://reviewable.io/reviews/servo/servo/8162)
<!-- Reviewable:end -->
@bors-servo
Copy link
Contributor

💔 Test failed - linux-rel

@highfive highfive added S-tests-failed The changes caused existing tests to fail. and removed S-awaiting-merge The PR is in the process of compiling and running tests on the automated CI. labels Oct 31, 2015
@mbrubeck
Copy link
Contributor

@bors-servo retry

#8157

@bors-servo
Copy link
Contributor

⚡ Previous build results for android, gonk, linux-dev, mac-dev-ref-unit, mac-rel-css, mac-rel-wpt are reusable. Rebuilding only linux-rel...

@bors-servo
Copy link
Contributor

☀️ Test successful - android, gonk, linux-dev, linux-rel, mac-dev-ref-unit, mac-rel-css, mac-rel-wpt

@bors-servo bors-servo merged commit 79ac365 into servo:master Oct 31, 2015
@SimonSapin SimonSapin removed the S-tests-failed The changes caused existing tests to fail. label Jan 27, 2016
@bholley bholley deleted the centralize_event_states branch October 30, 2016 22:24
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

9 participants