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

rustdoc: Cleanup html::render::Context #82356

Merged
merged 8 commits into from
Mar 9, 2021
Merged

Conversation

camelid
Copy link
Member

@camelid camelid commented Feb 21, 2021

  • Move most shared fields to SharedContext (except for cache, which
    isn't mutated anyway)
  • Replace a use of Arc with Rc
  • Make a bunch of fields private
  • Add static size assertion for Context
  • Don't share id_map and deref_id_map

@camelid camelid added C-cleanup Category: PRs that clean code up or issues documenting cleanup. T-rustdoc Relevant to the rustdoc team, which will review and decide on the PR/issue. labels Feb 21, 2021
@rust-highfive
Copy link
Collaborator

r? @GuillaumeGomez

(rust-highfive has picked a reviewer for you, use r? to override)

@rust-highfive rust-highfive added the S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. label Feb 21, 2021
@camelid
Copy link
Member Author

camelid commented Feb 21, 2021

rustdoc: Don't put the renderer in the queue

The key question is whether the testsuite will still pass after this :)

@rust-log-analyzer

This comment has been minimized.

@camelid
Copy link
Member Author

camelid commented Feb 21, 2021

test result: FAILED. 119 passed; 299 failed; 2 ignored; 0 measured; 0 filtered out; finished in 30.01s

Seems like a bad sign 🤣

} else if item.name.is_some() {
prof.generic_activity_with_arg("render_item", &*item.name.unwrap_or(unknown).as_str())
.run(|| cx.item(item))?;
.run(|| format_renderer.item(item))?;
}
}
Copy link
Member Author

Choose a reason for hiding this comment

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

Why does the code work this way, where it constantly clones the Context?

Copy link
Member

@GuillaumeGomez GuillaumeGomez Feb 21, 2021

Choose a reason for hiding this comment

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

Because some Context fields are rc, meaning they're not clone so to speak. ;)

Copy link
Member Author

Choose a reason for hiding this comment

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

Hm, so maybe a way to clean this up could be to make SharedContext the only thing that's actually shared?

/// The map used to ensure all generated 'id=' attributes are unique.
id_map: Rc<RefCell<IdMap>>,
id_map: RefCell<IdMap>,
Copy link
Member

Choose a reason for hiding this comment

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

I think removing the Rc and Arc is having much more side-effects that you might expect. :)

Copy link
Member

Choose a reason for hiding this comment

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

Right, I have the same comment as before: this is a change in behavior and should probably be dropped.

Copy link
Member

Choose a reason for hiding this comment

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

@jyn514 Still think so?

Copy link
Member Author

@camelid camelid Feb 28, 2021

Choose a reason for hiding this comment

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

The diff is confusing: That change (and comment) is old, but the new change from #82424 prevents it from being "outdated" from GitHub's point of view.

Before I was trying to get rid of the cloning of Context and get rid of the shared state in Context, so I removed the Rc and RefCell. Now the code still clones Context, but all the shared mutable state is moved to SharedContext, and id_map isn't shared.

id_map wasn't shared before, either. Quoting from f8bd38d:

I'm not sure why they were shared before. I think the reason id_map
worked as a shared value before is that it is cleared before rendering
each item (in render_item). [...]

Note that id_map currently still has to be cleared because otherwise
child items would inherit the id_map of their parent. I'm hoping to
figure out a way to stop cloning Context, but until then we have to
reset id_map.

I think this thread can be marked as resolved.

Copy link
Member

Choose a reason for hiding this comment

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

Now the code still clones Context, but all the shared mutable state is moved to SharedContext, and id_map isn't shared.

I don't quite follow - isn't id_map shared because the same Context is used everywhere? What do you mean by shared?

Can you link to where Context is cloned? It still seems like a change in behavior to me since cloning will no longer update the same id_map in both places.

Copy link
Member Author

Choose a reason for hiding this comment

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

@jyn514
Copy link
Member

jyn514 commented Feb 21, 2021

This will be really hard to get working with all these changes. I'd strongly suggest separating them into separate PRs so you can find what actually caused the test failures.

@jyn514
Copy link
Member

jyn514 commented Feb 21, 2021

Oh err I didn't realize it was a 30 line diff. In that case, maybe just bisect the test failures with git.

src/librustdoc/formats/renderer.rs Show resolved Hide resolved
src/librustdoc/html/render/mod.rs Outdated Show resolved Hide resolved
/// The map used to ensure all generated 'id=' attributes are unique.
id_map: Rc<RefCell<IdMap>>,
id_map: RefCell<IdMap>,
Copy link
Member

Choose a reason for hiding this comment

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

Right, I have the same comment as before: this is a change in behavior and should probably be dropped.

@camelid
Copy link
Member Author

camelid commented Feb 21, 2021

My guess is the root issue here is that Context has some fields that are shared and some that are not, despite there also being a SharedContext.

@rust-log-analyzer

This comment has been minimized.

@camelid camelid marked this pull request as ready for review February 21, 2021 23:05
src/librustdoc/html/render/mod.rs Outdated Show resolved Hide resolved
src/librustdoc/html/render/mod.rs Outdated Show resolved Hide resolved
@rust-log-analyzer

This comment has been minimized.

@camelid
Copy link
Member Author

camelid commented Feb 22, 2021

Huh, it compiled locally. Is Context a different size on CI somehow?

@jyn514
Copy link
Member

jyn514 commented Feb 22, 2021

@camelid the size is target dependent, you need to add #[cfg(target_arch = "x86_64")].

@camelid
Copy link
Member Author

camelid commented Feb 22, 2021

@camelid the size is target dependent, you need to add #[cfg(target_arch = "x86_64")].

Will that work even though the assert is done on the host machine?

@jyn514
Copy link
Member

jyn514 commented Feb 22, 2021

I don't understand the question? The size is dependent on the target, not the host. If you cross compile from x86_64 to x86 I'd expect you to get the same error as on CI.

@camelid
Copy link
Member Author

camelid commented Feb 22, 2021

Okay, I wasn't sure if std::mem::size_of always returned the size as viewed from the target.

@camelid
Copy link
Member Author

camelid commented Feb 28, 2021

I squashed the commits down a bit to remove fixup-esque commits. @GuillaumeGomez ready for review!

Also create issue for removing shared mutable state.
It's cloned a lot, so we don't want it to grow in size unexpectedly.

Only run the assert on x86-64 since the size is architecture-dependent.
All the tests passed, so it doesn't seem they need to be shared.
Plus they should be item/page-specific.

I'm not sure why they were shared before. I think the reason `id_map`
worked as a shared value before is that it is cleared before rendering
each item (in `render_item`). And then I'm guessing `deref_id_map`
worked because it's a hashmap keyed by `DefId`, so there was no overlap
(though I'm guessing we could have had issues in the future).

Note that `id_map` currently still has to be cleared because otherwise
child items would inherit the `id_map` of their parent. I'm hoping to
figure out a way to stop cloning `Context`, but until then we have to
reset `id_map`.
Reduced from 152 bytes to 88 bytes.
There was no need to clone `id_map` because it was reset before each
item was rendered. `deref_id_map` was not reset, but it was keyed by
`DefId` and thus was unlikely to have collisions (at least for now).

Now we just clone the fields that need to be cloned, and instead create
fresh versions of the others.
I don't think the boxing helped performance, in fact I think it
potentially made it worse. The data was still being copied, but now it
was through a pointer. Thinking about it more, I think boxing might only
help when you're passing a big object around by value all the time,
rather than the slowdown being that you're cloning it.
@camelid
Copy link
Member Author

camelid commented Mar 6, 2021

Wow, that was the longest and trickiest rebase I've ever done 😅

@camelid
Copy link
Member Author

camelid commented Mar 6, 2021

@GuillaumeGomez This is ready for review! You may want to take a look at #82356 (comment) and #82356 (comment).

@GuillaumeGomez
Copy link
Member

Thanks!

@bors: r+

@bors
Copy link
Contributor

bors commented Mar 7, 2021

📌 Commit 5b74097 has been approved by GuillaumeGomez

@bors bors added S-waiting-on-bors Status: Waiting on bors to run and complete tests. Bors will change the label on completion. and removed S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. labels Mar 7, 2021
@bors
Copy link
Contributor

bors commented Mar 8, 2021

⌛ Testing commit 5b74097 with merge 931ff787d37676e7c93bbd127dadd0d9564df501...

@bors
Copy link
Contributor

bors commented Mar 8, 2021

💥 Test timed out

@bors bors added S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. and removed S-waiting-on-bors Status: Waiting on bors to run and complete tests. Bors will change the label on completion. labels Mar 8, 2021
@rust-log-analyzer
Copy link
Collaborator

A job failed! Check out the build log: (web) (plain)

Click to see the possible cause of the failure (guessed by this bot)

@camelid
Copy link
Member Author

camelid commented Mar 9, 2021

Seems spurious. @bors retry

@bors bors added S-waiting-on-bors Status: Waiting on bors to run and complete tests. Bors will change the label on completion. and removed S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. labels Mar 9, 2021
@bors
Copy link
Contributor

bors commented Mar 9, 2021

⌛ Testing commit 5b74097 with merge 4b9f5cc...

@bors
Copy link
Contributor

bors commented Mar 9, 2021

☀️ Test successful - checks-actions
Approved by: GuillaumeGomez
Pushing 4b9f5cc to master...

@bors bors added the merged-by-bors This PR was explicitly merged by bors. label Mar 9, 2021
@bors bors merged commit 4b9f5cc into rust-lang:master Mar 9, 2021
@rustbot rustbot added this to the 1.52.0 milestone Mar 9, 2021
@camelid camelid deleted the render-cleanup branch March 9, 2021 20:08
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
C-cleanup Category: PRs that clean code up or issues documenting cleanup. merged-by-bors This PR was explicitly merged by bors. S-waiting-on-bors Status: Waiting on bors to run and complete tests. Bors will change the label on completion. T-rustdoc Relevant to the rustdoc team, which will review and decide on the PR/issue.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

8 participants