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

perf: v8 code cache #23081

Merged
merged 23 commits into from
Apr 17, 2024
Merged

perf: v8 code cache #23081

merged 23 commits into from
Apr 17, 2024

Conversation

igorzi
Copy link
Contributor

@igorzi igorzi commented Mar 26, 2024

This PR enables V8 code cache for ES modules and for require scripts through op_eval_context. Code cache artifacts are transparently stored and fetched using sqlite db and are passed to V8. --no-code-cache can be used to disable.

@igorzi igorzi changed the title feat(cli): v8 code cache perf: v8 code cache Mar 27, 2024
cli/module_loader.rs Outdated Show resolved Hide resolved
cli/module_loader.rs Outdated Show resolved Hide resolved
cli/module_loader.rs Outdated Show resolved Hide resolved
cli/module_loader.rs Show resolved Hide resolved
runtime/worker.rs Outdated Show resolved Hide resolved
tests/integration/run_tests.rs Outdated Show resolved Hide resolved
@igorzi igorzi requested a review from bartlomieju March 31, 2024 07:30
Copy link
Member

@bartlomieju bartlomieju left a comment

Choose a reason for hiding this comment

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

Drive-by pass. I'll do a deeper dive once CI is fixed and I'll revert unrelated changes.

tests/unit/process_test.ts Outdated Show resolved Hide resolved
tests/util/std Outdated Show resolved Hide resolved
@@ -14,4 +14,4 @@ setTimeout(async () => {

setTimeout(() => {
console.log("Success");
}, 50);
}, 200);
Copy link
Contributor Author

Choose a reason for hiding this comment

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

@bartlomieju - I needed to change this to make this test pass on windows. otherwise Success is printed too early. perhaps code cache changed the execution timing a bit and 50ms wasn't enough.

Copy link
Contributor

Choose a reason for hiding this comment

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

Is it possible it was a flake on Windows? I don't see anything in your PR that should affect this. This smells like a deno_core bug.

I'm also not sure why we are using an async function in the setTimeout above. That could be part of the problem.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

It's possible that it flaked on Windows; it failed consistently for several runs though. I'll try to do more runs with/without this change.

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 confirmed again that the test is consistently failing on windows, and a higher timeout makes the output appear as expected.

cli/module_loader.rs Outdated Show resolved Hide resolved
cli/module_loader.rs Outdated Show resolved Hide resolved
cli/worker.rs Outdated Show resolved Hide resolved
.get_module_source_hash(specifier, code_source.media_type)
.ok()
.flatten();
let code_timestamp = specifier_to_file_path(specifier)
Copy link
Contributor

Choose a reason for hiding this comment

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

Do we actually need the timestamp for code cache? Should the source hash be sufficient?

What would happen if we just avoided code cache for modules that didn't have a source cache in the ModuleInfoCache?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Do we actually need the timestamp for code cache? Should the source hash be sufficient?

2 reasons:

  1. For some modules ModuleInfoCache doesn't provide the source hash
  2. The other part of this PR deals with code cache for op_eval_context scripts, for which we don't compute/maintain hashes. Since op_eval_context scripts always come from the local file system, it seems that we could rely on timestamps rather than adding additional overhead to compute hashes.

What would happen if we just avoided code cache for modules that didn't have a source cache in the ModuleInfoCache?

Yes, I think we could do that for ES modules. And then we can make it such that ES modules provide a hash, while op_eval_context scripts provide a timestamp.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Imported npm modules don't have source hash in ModuleInfoCache. I'm assuming that's intentional and we don't want to introduce hash computation for them. I'm making a change to fallback to timestamps in that case.

Copy link
Member

Choose a reason for hiding this comment

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

The other part of this PR deals with code cache for op_eval_context scripts, for which we don't compute/maintain hashes. Since op_eval_context scripts always come from the local file system, it seems that we could rely on timestamps rather than adding additional overhead to compute hashes.

That's not entirely true, the other case is that when you require() something we use op_eval_context that has a generated source code (that wraps something loaded from the FS).

Copy link
Contributor Author

Choose a reason for hiding this comment

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

For this case, what is the specifier?

Copy link
Member

Choose a reason for hiding this comment

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

Ah in this particular case it will be file:///<original specifier> so I guess you're right here.

@@ -517,6 +517,7 @@ pub struct Flags {
pub unstable_config: UnstableConfig,
pub unsafely_ignore_certificate_errors: Option<Vec<String>>,
pub v8_flags: Vec<String>,
pub code_cache_enabled: bool,
Copy link
Contributor

Choose a reason for hiding this comment

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

We do have negative-sense flags in this flags struct -- see no_npm, no_prompt, etc. It would simplify the test changes required for this file.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Unfortunately big test change will still be needed in this file because we're only enabling code cache for run command initially.

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 ended up keeping this the same. With the negative no_code_cache flag there are actually more test changes needed (because code cache is disabled for non-run commands).

cli/cache/code_cache.rs Outdated Show resolved Hide resolved
cli/cache/deno_dir.rs Outdated Show resolved Hide resolved
cli/module_loader.rs Outdated Show resolved Hide resolved
cli/module_loader.rs Outdated Show resolved Hide resolved
runtime/worker.rs Outdated Show resolved Hide resolved
@bartlomieju bartlomieju added this to the 1.43 milestone Apr 14, 2024
@bartlomieju
Copy link
Member

@igorzi looks like you accidently committed WPT update. Please revert, other than that LGTM

@igorzi igorzi merged commit b3d7df5 into main Apr 17, 2024
17 checks passed
@igorzi igorzi deleted the code_cache branch April 17, 2024 14:19
littledivy pushed a commit to littledivy/deno that referenced this pull request Apr 19, 2024
This PR enables V8 code cache for ES modules and for `require` scripts
through `op_eval_context`. Code cache artifacts are transparently stored
and fetched using sqlite db and are passed to V8. `--no-code-cache` can
be used to disable.

---------

Co-authored-by: Bartek Iwańczuk <biwanczuk@gmail.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.

None yet

3 participants