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 commented Oct 22, 2015

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

Review on Reviewable

@highfive
Copy link

highfive commented Oct 22, 2015

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

@bholley bholley force-pushed the bholley:centralize_event_states branch from b3a6f8a to eabcb38 Oct 22, 2015
@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) {} }

This comment has been minimized.

@Manishearth

Manishearth Oct 22, 2015

Member

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

@@ -324,6 +325,12 @@ impl HeapSizeOf for () {
}
}

impl HeapSizeOf for EventState {

This comment has been minimized.

@Manishearth

Manishearth Oct 22, 2015

Member

Stick this in known_heap_size at the bottom

@Manishearth
Copy link
Member

Manishearth commented Oct 22, 2015

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

@bholley bholley force-pushed the bholley:centralize_event_states branch from eabcb38 to a162226 Oct 22, 2015
@SimonSapin
Copy link
Member

SimonSapin commented Oct 23, 2015

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

SimonSapin commented Oct 23, 2015

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

SimonSapin commented Oct 23, 2015

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

SimonSapin commented Oct 24, 2015

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

@bholley bholley force-pushed the bholley:centralize_event_states branch from a162226 to 1e16a66 Oct 26, 2015
@bors-servo
Copy link
Contributor

bors-servo commented Oct 31, 2015

🔒 Merge conflict

@bors-servo
Copy link
Contributor

bors-servo commented Oct 31, 2015

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

@Manishearth
Copy link
Member

Manishearth commented Oct 31, 2015

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

bholley added 2 commits Oct 22, 2015
This is necessary for those selectors to take advantage of restyle hints.
@bholley bholley force-pushed the bholley:centralize_event_states branch from 37fb636 to 79ac365 Oct 31, 2015
@bholley
Copy link
Contributor Author

bholley commented Oct 31, 2015

@bholley bholley removed the S-needs-rebase label Oct 31, 2015
@bholley
Copy link
Contributor Author

bholley commented Oct 31, 2015

@mbrubeck
Copy link
Contributor

mbrubeck commented Oct 31, 2015

@bors-servo r=pcwalton p=1

@bors-servo
Copy link
Contributor

bors-servo commented Oct 31, 2015

📌 Commit 79ac365 has been approved by pcwalton

@bors-servo
Copy link
Contributor

bors-servo commented Oct 31, 2015

Testing commit 79ac365 with merge 521a871...

bors-servo added 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

bors-servo commented Oct 31, 2015

💔 Test failed - linux-rel

@mbrubeck
Copy link
Contributor

mbrubeck commented Oct 31, 2015

@bors-servo
Copy link
Contributor

bors-servo commented Oct 31, 2015

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

bors-servo commented Oct 31, 2015

@bors-servo bors-servo merged commit 79ac365 into servo:master Oct 31, 2015
2 of 3 checks passed
2 of 3 checks passed
code-review/reviewable Review in progress: 0 of 20 files reviewed, 1 unresolved discussion
Details
continuous-integration/travis-ci/pr The Travis CI build passed
Details
homu Test successful
Details
@bholley bholley deleted the bholley:centralize_event_states branch Oct 30, 2016
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Linked issues

Successfully merging this pull request may close these issues.

None yet

9 participants
You can’t perform that action at this time.