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

Versioned dom #8227

Merged
merged 3 commits into from Nov 9, 2015
Merged

Versioned dom #8227

merged 3 commits into from Nov 9, 2015

Conversation

@asajeffrey
Copy link
Member

asajeffrey commented Oct 27, 2015

This PR adds versioning to the DOM. There are now node.get_version and node.get_descendent_version methods that return a counter that is bumped when the node is dirtied. This is used to implement cache invalidation for caching HTMLCollection state. Caching HTMCollections gets a 1000x speedup in the Dromaeo DOM query tests.

Addresses #6901, #3381 and #1916.

Replaces PR #6927.

Review on Reviewable

@asajeffrey
Copy link
Member Author

asajeffrey commented Oct 27, 2015

The PR in its current state needs squashing, which I'll do if it passes review.

@eefriedman
Copy link
Contributor

eefriedman commented Oct 27, 2015

More comments would be nice.


Review status: 0 of 6 files reviewed at latest revision, 7 unresolved discussions, some commit checks failed.


components/script/dom/document.rs, line 1214 [r1] (raw file):
Maybe tag_map?


components/script/dom/document.rs, line 1428 [r1] (raw file):
Consider using HashMap::entry instead of get. (Also in other places.)


components/script/dom/document.rs, line 1433 [r1] (raw file):
Whitespace.


components/script/dom/document.rs, line 1452 [r1] (raw file):
Whitespace.


components/script/dom/htmlcollection.rs, line 30 [r1] (raw file):
Consider using u64 for version? It's easy to overflow a u32 on a modern processor.


components/script/dom/htmlcollection.rs, line 171 [r1] (raw file):
Whitespace.


components/script/dom/htmlcollection.rs, line 282 [r1] (raw file):
Whitespace.


Comments from the review on Reviewable.io

@asajeffrey
Copy link
Member Author

asajeffrey commented Oct 27, 2015

Thanks! I'll have a look at your review comments tomorrow. Also get test-tidy to pass, sigh.

@asajeffrey
Copy link
Member Author

asajeffrey commented Oct 28, 2015

Review status: 0 of 6 files reviewed at latest revision, 3 unresolved discussions, some commit checks failed.


components/script/dom/document.rs, line 1214 [r1] (raw file):
The name was just for consistency with idmap. I'm happy to change all of them.


components/script/dom/document.rs, line 1428 [r1] (raw file):
Good point. I'm still learning my way round the rust stdlib.


components/script/dom/htmlcollection.rs, line 30 [r1] (raw file):
Tradeoff of space vs correctness? The u32 is only a problem if there's an overflow and a version comparison with exactly the right old version. The u64 uses an extra word per DOM node.


Comments from the review on Reviewable.io

@eefriedman
Copy link
Contributor

eefriedman commented Oct 28, 2015

Review status: 0 of 6 files reviewed at latest revision, 3 unresolved discussions, some commit checks failed.


components/script/dom/htmlcollection.rs, line 30 [r1] (raw file):
I'm not convinced saving a word is worth compromising correctness... but if you really want it to wrap, at least use Wrapping<u32> so it doesn't panic in overflow-checked builds.


Comments from the review on Reviewable.io

@asajeffrey
Copy link
Member Author

asajeffrey commented Oct 28, 2015

Review status: 0 of 6 files reviewed at latest revision, 3 unresolved discussions, some commit checks failed.


components/script/dom/htmlcollection.rs, line 30 [r1] (raw file):
On reflection, I think the space saving probably isn't worth it, I'll change this to u64.


Comments from the review on Reviewable.io

@asajeffrey
Copy link
Member Author

asajeffrey commented Oct 28, 2015

Review status: 0 of 6 files reviewed at latest revision, 3 unresolved discussions, some commit checks failed.


components/script/dom/document.rs, line 1428 [r1] (raw file):
On looking at the code again, I don't think I can use HashMap::entry, because of rooting.


Comments from the review on Reviewable.io

@eefriedman
Copy link
Contributor

eefriedman commented Oct 28, 2015

Because of rooting? Hmm... that sounds like we just need to update the whitelist in the lint plugin; std::collections::hash_map::Entry should always be fine to store on the stack. (https://github.com/servo/servo/blob/master/components/plugins/lints/unrooted_must_root.rs#L53 .)

@asajeffrey
Copy link
Member Author

asajeffrey commented Oct 28, 2015

The problem isn't that Entry needs rooted, it's that the code would end up being something like:

self.foo_map.entry(key).or_insert(|| mk_foo().r() ).root()

that is, in the case of a cache miss, we build a rooted result, then unroot it, then root it again.

This is because the cache is being kept unrooted: should the cache be the rooted versions?


Review status: 0 of 6 files reviewed at latest revision, 3 unresolved discussions, all commit checks successful.


Comments from the review on Reviewable.io

@eefriedman
Copy link
Contributor

eefriedman commented Oct 28, 2015

That doesn't seem like a big deal; rooting isn't an expensive operation.

If you really want to avoid it, you can do match foo_map.entry(key) { VacantEntry(e) => {}...


Review status: 0 of 6 files reviewed at latest revision, 3 unresolved discussions, all commit checks successful.


Comments from the review on Reviewable.io

@metajack
Copy link
Contributor

metajack commented Oct 28, 2015

I believe that @asajeffrey has shown that rooting is expensive. It's certianly showing up in his profiles from what I understand.

@asajeffrey
Copy link
Member Author

asajeffrey commented Oct 28, 2015

The problem with rooting is that it uses a Vec for roots, so the code includes the case where the vector has to grow, which means problems for code inlining. It's more of a code size and optimization problem than a time problem, since in the common case rooting is just a vector push into a vector which already has enough backing store.

I'll update to using HashMap::entry.


Review status: 0 of 6 files reviewed at latest revision, 3 unresolved discussions, all commit checks successful.


Comments from the review on Reviewable.io

@tschneidereit
Copy link
Contributor

tschneidereit commented Oct 30, 2015

1 similar comment
@Manishearth
Copy link
Member

Manishearth commented Oct 30, 2015

@bors-servo
Copy link
Contributor

bors-servo commented Oct 30, 2015

Trying commit 89248e8 with merge 4554d8a...

bors-servo added a commit that referenced this pull request Oct 30, 2015
Versioned dom

This PR adds versioning to the DOM. There are now node.get_version and node.get_descendent_version methods that return a counter that is bumped when the node is dirtied. This is used to implement cache invalidation for caching HTMLCollection state. Caching HTMCollections gets a 1000x speedup in the Dromaeo DOM query tests.

Addresses #6901, #3381 and #1916.

Replaces PR #6927.

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

bors-servo commented Oct 30, 2015

💔 Test failed - linux-rel

@Manishearth
Copy link
Member

Manishearth commented Oct 30, 2015

(Artificial failure)

@bors-servo
Copy link
Contributor

bors-servo commented Oct 31, 2015

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

@asajeffrey asajeffrey force-pushed the asajeffrey:versioned_dom branch from 89248e8 to 854675e Oct 31, 2015
@asajeffrey
Copy link
Member Author

asajeffrey commented Nov 2, 2015

I responded to @eefriedman and rebased to builld with master. Anything else?

@jdm jdm removed the S-needs-rebase label Nov 2, 2015
@jdm
Copy link
Member

jdm commented Nov 2, 2015

@eefriedman Are you doing a full review of this, or just drive-by? Please set the assignee field for the former, so it's clear who's responsible for the next step here.

@eefriedman eefriedman self-assigned this Nov 2, 2015
@eefriedman
Copy link
Contributor

eefriedman commented Nov 6, 2015

I'll try to merge #8315, and then you can rebase.

@asajeffrey
Copy link
Member Author

asajeffrey commented Nov 6, 2015

Thanks! I'll rebase... Grumble mutter dependent PRs.

asajeffrey added 3 commits Nov 6, 2015
There is now an inclusive_descendants_version field of each node, which
increases each time the node, or any of its descendants, is dirtied.
This can be used for cache invalidation, by caching a version number
and comparting the current version number against the cached version number.
We cache the state of any live HTMLCollection, keeping track of

a) the optional cached length of the collection, and
b) an optional cursor into the collection (a node in the collection plus its index).

The cache is invalidated based on the version number of the node.

We use these caches for speeding up random access to the collection.
When returning coll[i], we search from the cursor, if it exists,
and otherwise search from the front of the collection.
In particular, both a forward for-loop and a backward for-loop
through the collection will now have each access take O(1)
time rather than O(n) time.

This gets 1000x speed-up on the relevant Dromaeo DOM query tests.
@asajeffrey asajeffrey force-pushed the asajeffrey:versioned_dom branch from 3e4cc15 to 237ddc3 Nov 6, 2015
@eefriedman
Copy link
Contributor

eefriedman commented Nov 9, 2015

@bors-servo
Copy link
Contributor

bors-servo commented Nov 9, 2015

📌 Commit 237ddc3 has been approved by eefriedman

@bors-servo
Copy link
Contributor

bors-servo commented Nov 9, 2015

Testing commit 237ddc3 with merge 9dbd5dd...

bors-servo added a commit that referenced this pull request Nov 9, 2015
Versioned dom

This PR adds versioning to the DOM. There are now node.get_version and node.get_descendent_version methods that return a counter that is bumped when the node is dirtied. This is used to implement cache invalidation for caching HTMLCollection state. Caching HTMCollections gets a 1000x speedup in the Dromaeo DOM query tests.

Addresses #6901, #3381 and #1916.

Replaces PR #6927.

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

bors-servo commented Nov 9, 2015

💔 Test failed - gonk

@eefriedman
Copy link
Contributor

eefriedman commented Nov 9, 2015

@bors-servo
Copy link
Contributor

bors-servo commented Nov 9, 2015

Testing commit 237ddc3 with merge f39faaf...

bors-servo added a commit that referenced this pull request Nov 9, 2015
Versioned dom

This PR adds versioning to the DOM. There are now node.get_version and node.get_descendent_version methods that return a counter that is bumped when the node is dirtied. This is used to implement cache invalidation for caching HTMLCollection state. Caching HTMCollections gets a 1000x speedup in the Dromaeo DOM query tests.

Addresses #6901, #3381 and #1916.

Replaces PR #6927.

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

bors-servo commented Nov 9, 2015

@bors-servo bors-servo merged commit 237ddc3 into servo:master Nov 9, 2015
2 of 3 checks passed
2 of 3 checks passed
code-review/reviewable Review in progress: 0 of 7 files reviewed, 2 unresolved discussions
Details
continuous-integration/travis-ci/pr The Travis CI build passed
Details
homu Test successful
Details
bholley referenced this pull request in bholley/servo Nov 10, 2015
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.