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

chore: Add strategy for caching the parsing layer #3849

Closed
wants to merge 4 commits into from

Conversation

kevaundray
Copy link
Contributor

Description

This PR demonstrates how parsing would roughly look if we did it entirely as a separate layer.

Problem*

Resolves

Summary*

Additional Context

Documentation*

Check one:

  • No documentation needed.
  • Documentation included in this PR.
  • [Exceptional Case] Documentation to be submitted in a separate PR.

PR Checklist*

  • I have tested the changes locally.
  • I have formatted the changes with Prettier and/or cargo fmt on default settings.

Comment on lines 59 to 72
fn populate_cache_with_file_manager(&mut self) {
for file_id in self.file_manager.as_file_map().all_file_ids() {
let file_path = self.file_manager.path(*file_id);
let file_extension =
file_path.extension().expect("expected all file paths to have an extension");
// TODO: Another reason we may not want to have this method here
// TODO: is the fact that we want to not have the compiler worry
// TODO about the nr file extension
if file_extension != "nr" {
continue;
}
self.file_to_ast_cache.insert(*file_id, parse_file(&self.file_manager, *file_id));
}
}
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 the main change, notice that with this we can now parallelize parsing and given that the FileIds are deterministic, we can also avoid parsing unchanged things we've already parsed.

On the other hand, it may be easier to always parse everything. A future problem is that incremental compilation may not work effectively if the FileIds are not deterministic -- we can just hash the file_path in order to get the file_id in that case.

@kevaundray
Copy link
Contributor Author

This is likely failing because we are parsing all the files in the FileManager when Context is created, however the stdlib files are not in Context at that particular point in time, so it never populates the cache with stdlib file.

prepare_crate populates the file manager with stdlib content, however by the the Context has already been created

@kevaundray
Copy link
Contributor Author

#3844 adds file_manager_with_stdlib which mitigates this issue, if it is that

Comment on lines +74 to +88
// TODO: Do not merge with this method!
pub fn repopulate_cache(&mut self) {
for file_id in self.file_manager.as_file_map().all_file_ids() {
let file_path = self.file_manager.path(*file_id);
let file_extension =
file_path.extension().expect("expected all file paths to have an extension");
// TODO: Another reason we may not want to have this method here
// TODO: is the fact that we want to not have the compiler worry
// TODO about the nr file extension
if file_extension != "nr" {
continue;
}
self.file_to_ast_cache.insert(*file_id, parse_file(&self.file_manager, *file_id));
}
}
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Here is the hack, I added to repopulate the cache once I know we have added the stdlib to the file manager

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I just copied the above method and made this one public

@TomAFrench TomAFrench closed this Jan 18, 2024
github-merge-queue bot pushed a commit that referenced this pull request Jan 18, 2024
# Description
Rework of #3849 after
file_manager_with_stdlib was created. Also as @kevaundray suggested
extracted the parsing above the context.

Resolves #3838
## Problem\*
Parsing is currently done when collecting, allowing only to parse files
used, but making it very difficult to do parallel parsing or to have
cached parsing.

## Summary\*

This PR extracts parsing to its own pass, and makes the Context take the
parsed files. The creator of the context is the one in charge to do the
parsing of the file manager, so Nargo, the LSP and wasm need to handle
the parsed files. This PR uses rayon to do parallel parsing in Nargo &
LSP. It reduces the time taken to process the on save notification in
the LSP from ~700ms on protocol circuits to ~250ms.

With parsing being in its own pass, this opens the door for the LSP to
cache parsing. It has access to the file manager and the parsed files,
so it can detect which files have changed on disk and only parse those
when necessary.

## Additional Context



## Documentation\*

Check one:
- [x] No documentation needed.
- [ ] Documentation included in this PR.
- [ ] **[Exceptional Case]** Documentation to be submitted in a separate
PR.

# PR Checklist\*

- [x] I have tested the changes locally.
- [x] I have formatted the changes with [Prettier](https://prettier.io/)
and/or `cargo fmt` on default settings.

---------

Co-authored-by: Koby Hall <102518238+kobyhallx@users.noreply.github.com>
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.

2 participants