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

Turn crate store into a resolver output #65625

Merged
merged 10 commits into from
Oct 25, 2019
Merged

Conversation

petrochenkov
Copy link
Contributor

Crate store (CStore) is a vector of data (CrateMetadata) associated with extern crates loaded during the current compilation session.

All crates are loaded in the resolver when resolving either paths pointing to extern prelude or extern crate items. (There are also a couple of crates like panic runtime that are loaded kind of like implicit extern crates, but that also happens in resolve.)

The use of CStore from rustc_plugin (which is outside of the resolver) was unnecessary because legacy plugins are not added to the crate store and don't use CrateNums.

So, CStore can be produced by the resolver instead of being kept in some really global data (rustc_interface::Compiler) like now.

As a result of crate store being more "local" we can now remove some locks and Lrcs.

pub struct CStore {
metas: RwLock<IndexVec<CrateNum, Option<Lrc<CrateMetadata>>>>,
crate metadata_loader: Box<dyn MetadataLoader + Sync>,
metas: IndexVec<CrateNum, Option<Lrc<CrateMetadata>>>,
Copy link
Contributor Author

@petrochenkov petrochenkov Oct 20, 2019

Choose a reason for hiding this comment

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

Unfortunately we cannot remove this Lrc because CStore has to be cloneable.
EDIT: The reason - #65625 (comment).

Copy link
Member

Choose a reason for hiding this comment

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

Wow, I didn't even realize that was a thing. Do you know where the clones are coming from?

Copy link
Contributor

Choose a reason for hiding this comment

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

I guess we could get rid of it by having the expansion query produce the CStore structure and redirect later uses to that instead. That would make the structure more like before this PR. It doesn't seem like a huge win right now though. It might be worth waiting on moving things into TyCtxt. Maybe we'd replace it by a crate_metadata(CrateNum) -> &'tcx CrateMetadata query or something.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yeah, this certainly can be done later if "later" is a better time due to other changes (like TyCtxt).
The clone itself (the primary effect) is cheap - only a vector of Lrcs is cloned.
The locks around CrateMetadata::{dependencies,dep_kind,extern_crate} (the secondary effect) are also unlikely to be accessed often and cause performance issues.

@petrochenkov
Copy link
Contributor Author

Regarding locks in CrateMetadata:

  • source_map_import_info and dep_node_index are created lazily on the first use, so they need synchronization, but can probably use some of the Once primitives instead.
  • dependencies, dep_kind and extern_crate are only under locks because CrateMetadata is under Lrc (Turn crate store into a resolver output #65625 (comment)), they are used only from inside the crate loader and could just use mutable references otherwise.

@@ -211,7 +171,7 @@ impl BoxedResolver {
Err(resolver) => {
let resolver = &*resolver;
resolver.borrow_mut().access(|resolver| {
ExpansionResult::from_resolver_ref(resolver)
ExpansionResult::from_resolver_outputs(resolver.clone_outputs())
Copy link
Contributor Author

Choose a reason for hiding this comment

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

This is why we can't have nice things.
This case puts the cloneability requirement on resolver outputs (https://github.com/rust-lang/rust/pull/65625/files#r336780545), but it actually never happens in rustc, only in rustdoc and perhaps other tools using rustc_interface.

Copy link
Member

Choose a reason for hiding this comment

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

Why would cloning be needed? Is this that support for resolving things after rustc_resolve finishes?
In that case I'm not sure why we need to clone the outputs - is it to be able to keep the original resolver around?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Not sure, rustc_interface is very hard to reason about. ¯_(ツ)_/¯
It needs some investigation, but I'm not sure I'll get to it until the next weekend.

Copy link
Contributor

Choose a reason for hiding this comment

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

This clone only happens with rustdoc since it needs the resolver available at a later stage. It would be nicer if we could extract the information rustdoc needs instead.

Copy link
Member

Choose a reason for hiding this comment

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

Can we split the resolver up so that we can pass a &CStore later to the parts of it that we need to keep around? (i.e. the local module tree)

Copy link
Contributor

Choose a reason for hiding this comment

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

We could make expansion query produce the final CStore structure and I said in my other comment. That won't help to get rid of the clone here though.

Copy link
Member

Choose a reason for hiding this comment

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

I'd prefer if rustdoc didn't cause that clone to happen but instead did its resolving in some other way.

Copy link
Member

Choose a reason for hiding this comment

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

It really feels like the new code is not worse, right? So we can definitely leave this for a future PR (filing an issue wouldn't hurt). I'd rather not block this PR on that cleanup.

Copy link
Contributor

Choose a reason for hiding this comment

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

This clone was there before this PR.

@petrochenkov
Copy link
Contributor Author

cc @rust-lang/compiler @Mark-Simulacrum
Several people may be interested in this PR because it touches rustc_interface and removes locks.

@petrochenkov
Copy link
Contributor Author

r? @Mark-Simulacrum or @Zoxc probably

@petrochenkov petrochenkov added the S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. label Oct 20, 2019
Copy link
Member

@Mark-Simulacrum Mark-Simulacrum left a comment

Choose a reason for hiding this comment

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

Overall looks great, excellent cleanup!

I agree with @eddyb that the cloning is unfortunate but ultimately seems 'fine' for now, we can clean it up in a future PR.

@@ -191,6 +191,8 @@ pub trait MetadataLoader {
-> Result<MetadataRef, String>;
}

pub type MetadataLoaderDyn = dyn MetadataLoader + Sync;
Copy link
Member

Choose a reason for hiding this comment

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

Do we need this to be Sync even in the non-parallel compiler case? Maybe we want sync::Sync here which is either the proper marker trait from core or the data structures one which is just auto for everything?

Copy link
Contributor

Choose a reason for hiding this comment

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

The metadata loaders have no fields, so it doesn't matter which Sync trait is used.

@@ -159,13 +156,12 @@ pub fn configure_and_expand(
}

pub struct ExpansionResult {
Copy link
Member

Choose a reason for hiding this comment

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

Is there a reason to re-wrap the resolve outputs here? I guess we do get Steal...

Copy link
Contributor Author

Choose a reason for hiding this comment

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

ExpansionResult is removed.

@Mark-Simulacrum
Copy link
Member

r=me unless you want to investigate my comments in this PR

@Zoxc
Copy link
Contributor

Zoxc commented Oct 20, 2019

This PR looks good to me too.

@petrochenkov petrochenkov added S-waiting-on-author Status: This is awaiting some action (such as code changes or more information) from the author. and removed S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. labels Oct 21, 2019
@petrochenkov
Copy link
Contributor Author

Let's run perf on this.
@bors try @rust-timer queue

@rust-timer
Copy link
Collaborator

Awaiting bors try build completion

@bors
Copy link
Contributor

bors commented Oct 21, 2019

⌛ Trying commit 2a329d24c0f81e3485ab3148ea4be60e3beea33b with merge fb82105b083af835f36cba113878eabd97ab8573...

@petrochenkov petrochenkov added S-waiting-on-perf Status: Waiting on a perf run to be completed. and removed S-waiting-on-author Status: This is awaiting some action (such as code changes or more information) from the author. labels Oct 21, 2019
@bors
Copy link
Contributor

bors commented Oct 22, 2019

☀️ Try build successful - checks-azure
Build commit: fb82105b083af835f36cba113878eabd97ab8573 (fb82105b083af835f36cba113878eabd97ab8573)

@rust-timer
Copy link
Collaborator

Queued fb82105b083af835f36cba113878eabd97ab8573 with parent 10f12fe, future comparison URL.

@petrochenkov
Copy link
Contributor Author

Let's run perf on this.

Not sure why I did that, there should be ~no changes for the non-parallel case.
@bors r=Mark-Simulacrum,Zoxc

@bors
Copy link
Contributor

bors commented Oct 22, 2019

📌 Commit 2a329d24c0f81e3485ab3148ea4be60e3beea33b has been approved by Mark-Simulacrum,Zoxc

@bors bors added the S-waiting-on-bors Status: Waiting on bors to run and complete tests. Bors will change the label on completion. label Oct 22, 2019
@rust-timer
Copy link
Collaborator

Finished benchmarking try commit fb82105b083af835f36cba113878eabd97ab8573, comparison URL.

@petrochenkov petrochenkov removed the S-waiting-on-perf Status: Waiting on a perf run to be completed. label Oct 22, 2019
@bors
Copy link
Contributor

bors commented Oct 24, 2019

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

@bors bors added S-waiting-on-author Status: This is awaiting some action (such as code changes or more information) from the author. and removed S-waiting-on-bors Status: Waiting on bors to run and complete tests. Bors will change the label on completion. labels Oct 24, 2019
@petrochenkov
Copy link
Contributor Author

@bors r=Mark-Simulacrum,Zoxc

@bors
Copy link
Contributor

bors commented Oct 24, 2019

📌 Commit 94216ce has been approved by Mark-Simulacrum,Zoxc

@bors
Copy link
Contributor

bors commented Oct 24, 2019

🌲 The tree is currently closed for pull requests below priority 1000, this pull request will be tested once the tree is reopened

@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-author Status: This is awaiting some action (such as code changes or more information) from the author. labels Oct 24, 2019
Centril added a commit to Centril/rust that referenced this pull request Oct 24, 2019
…rum,Zoxc

Turn crate store into a resolver output

Crate store (`CStore`) is a vector of data (`CrateMetadata`) associated with extern crates loaded during the current compilation session.

All crates are loaded in the resolver when resolving either paths pointing to extern prelude or `extern crate` items. (There are also a couple of crates like panic runtime that are loaded kind of like implicit `extern crate`s, but that also happens in resolve.)

The use of `CStore` from `rustc_plugin` (which is outside of the resolver) was unnecessary because legacy plugins are not added to the crate store and don't use `CrateNum`s.

So, `CStore` can be produced by the resolver instead of being kept in some really global data (`rustc_interface::Compiler`) like now.

As a result of crate store being more "local" we can now remove some locks and `Lrc`s.
bors added a commit that referenced this pull request Oct 25, 2019
Rollup of 8 pull requests

Successful merges:

 - #65625 (Turn crate store into a resolver output)
 - #65627 (Forbid non-`structural_match` types in const generics)
 - #65710 (Update cargo)
 - #65729 (Update test cases for vxWorks)
 - #65746 (Tweak format string error to point at arguments always)
 - #65753 (Don't assert for different instance on impl trait alias)
 - #65755 (Avoid ICE when adjusting bad self ty)
 - #65766 (Update hashbrown to 0.6.2)

Failed merges:

r? @ghost
@bors bors merged commit 94216ce into rust-lang:master Oct 25, 2019
@bors
Copy link
Contributor

bors commented Oct 25, 2019

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

@bors bors added S-waiting-on-author Status: This is awaiting some action (such as code changes or more information) from the author. and removed S-waiting-on-bors Status: Waiting on bors to run and complete tests. Bors will change the label on completion. labels Oct 25, 2019
@jyn514 jyn514 mentioned this pull request Apr 1, 2021
6 tasks
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
S-waiting-on-author Status: This is awaiting some action (such as code changes or more information) from the author.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

7 participants