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

refactor(core): cleanup feature flags for js source inclusion #19463

Merged
merged 9 commits into from
Jun 13, 2023

Conversation

nayeemrmn
Copy link
Collaborator

@nayeemrmn nayeemrmn commented Jun 11, 2023

Remove ExtensionFileSourceCode::LoadedFromFsDuringSnapshot and feature include_js_for_snapshotting since they leak paths that are only applicable in this repo to embedders. Replace with feature exclude_js_sources. Additionally the feature force_include_js_sources allows negating it, if both features are set. We need both of these because features are additive and there must be a way of force including sources for snapshot creation while still having the exclude_js_sources feature. force_include_js_sources is only set for build deps, so sources are still excluded from the final binary.

You can also specify force_include_js_sources on any extension to override the above features for that extension. Towards #19398.

But there was still the snapshot-from-snapshot situation where code could be executed twice, I addressed that by making mod_evaluate() and scripts like core/01_core.js behave idempotently. This allowed unifying ext::init_ops() and ext::init_ops_and_esm() into ext::init().

@nayeemrmn nayeemrmn marked this pull request as draft June 12, 2023 10:10
@nayeemrmn nayeemrmn marked this pull request as ready for review June 12, 2023 10:40
ext/broadcast_channel/lib.rs Outdated Show resolved Hide resolved
@nayeemrmn nayeemrmn changed the title refactor: exclude extension js sources per-crate refactor(core): cleanup feature flags for js source inclusion Jun 13, 2023
Copy link
Contributor

@mmastrac mmastrac left a comment

Choose a reason for hiding this comment

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

LGTM with latest changes. Much cleaner.

@mmastrac mmastrac merged commit ceb03cf into denoland:main Jun 13, 2023
@nayeemrmn nayeemrmn deleted the extension-js-exclude-per-crate branch June 13, 2023 17:14
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.

I'm late to the party, but I have a few questions. Overall I will revert this PR because it causes 3.5Mb regression in the binary size, because the source code is included in the binary for snapshotted code.

Comment on lines +368 to +370
PollState::Parked => {
w.parked_thread.replace(thread::current());
}
Copy link
Member

Choose a reason for hiding this comment

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

Why was this change needed?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

I meant to inquire if that was correct but forgot.. There were some inspector test failures on fc0f65a because that variant was being hit now for some reason. That fixed it. But I don't know what changed there.

Copy link
Member

Choose a reason for hiding this comment

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

Huh, interesting! I would be interested in fixing this for sure, any chance you could try to create a test that would hit this code path? Inspector is quite brittle and esoteric bit of code so I would encourage a lot of caution when changing its logic.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

any chance you could try to create a test that would hit this code path?

It's hit by the test failures on https://github.com/denoland/deno/actions/runs/5242046717/jobs/9464946684, caused by something in the rest of this PR.

core/modules.rs Show resolved Hide resolved
@@ -949,6 +949,7 @@ dependencies = [
"anyhow",
"bytes",
"deno_ast",
"deno_core",
Copy link
Member

Choose a reason for hiding this comment

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

I wonder if this will cause problems during publishing... I never seen crate depend on itself

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

It's a dev dependency to turn the force-include feature on for testing.

std::path::PathBuf::from(env!("CARGO_MANIFEST_DIR")).join($file)
),
},)+
code: include_str!($file),
Copy link
Member

Choose a reason for hiding this comment

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

This will cause the source code to be included in the resulting binary even though it's snapshotted. Which is visible in the benchmark page https://deno.com/benchmarks for binary size

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

It's supposed to work because no ExtensionFileSources are registered in the final binary in the first place, they are replaced by an empty vec in include_js_files!(). I debug printed the esm files for extension builders after the ext.esm() call and they were all empty. But something apparently went wrong...

One difference this PR makes is that the static sources are included in the compilation of the build.rs scripts, where as before they were loaded at runtime of the build.rs. That shouldn't make a difference should it?

Copy link
Member

Choose a reason for hiding this comment

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

One difference this PR makes is that the static sources are included in the compilation of the build.rs scripts, where as before they were loaded at runtime of the build.rs. That shouldn't make a difference should it?

I would assume that would be the case, I can't say for sure off the top of my head.

Comment on lines +1852 to +1864
if status == v8::ModuleStatus::Evaluated {
let (sender, receiver) = oneshot::channel();
sender.send(Ok(())).unwrap();
return receiver;
}
if status == v8::ModuleStatus::Errored {
let (sender, receiver) = oneshot::channel();
let exception = module.get_exception();
sender
.send(exception_to_err_result(tc_scope, exception, false))
.unwrap();
return receiver;
}
Copy link
Member

Choose a reason for hiding this comment

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

I really don't like this bit - while it might be fine for our own internal code, this will hide problems in module loading logic for user code

@bartlomieju
Copy link
Member

Overall I like this cleanup - it would be ideal to have only a single method for defining extensions, but we need stricter control using cargo flags to decide if something should be included or not. I'm working on #19399 which also touches this subject, I will raise an alternative PR (which will probably build on this PR).

bartlomieju added a commit that referenced this pull request Jun 13, 2023
#19490)

… (#19463)"

This reverts commit ceb03cf.

This is being reverted because it causes 3.5Mb increase in the binary
size,
due to runtime JS code being included in the binary, even though it's
already snapshotted.

CC @nayeemrmn
@bartlomieju
Copy link
Member

@nayeemrmn I suggest we land this PR in more bite-sized pieces - I like the idea of having only ext::init() and what is does is controlled via Cargo flags. Can you revert changes to ExtensionFileSourceCode::LoadedFromFsDuringSnapshot so we don't regress on the binary size?

bartlomieju pushed a commit that referenced this pull request Jun 15, 2023
Remove `ExtensionFileSourceCode::LoadedFromFsDuringSnapshot` and feature
`include_js_for_snapshotting` since they leak paths that are only
applicable in this repo to embedders. Replace with feature
`exclude_js_sources`. Additionally the feature
`force_include_js_sources` allows negating it, if both features are set.
We need both of these because features are additive and there must be a
way of force including sources for snapshot creation while still having
the `exclude_js_sources` feature. `force_include_js_sources` is only set
for build deps, so sources are still excluded from the final binary.

You can also specify `force_include_js_sources` on any extension to
override the above features for that extension. Towards #19398.

But there was still the snapshot-from-snapshot situation where code
could be executed twice, I addressed that by making `mod_evaluate()` and
scripts like `core/01_core.js` behave idempotently. This allowed
unifying `ext::init_ops()` and `ext::init_ops_and_esm()` into
`ext::init()`.
bartlomieju added a commit that referenced this pull request Jun 15, 2023
#19490)

… (#19463)"

This reverts commit ceb03cf.

This is being reverted because it causes 3.5Mb increase in the binary
size,
due to runtime JS code being included in the binary, even though it's
already snapshotted.

CC @nayeemrmn
bartlomieju pushed a commit that referenced this pull request Jun 25, 2023
#19519)

Relands #19463. This time the `ExtensionFileSourceCode` enum is
preserved, so this effectively just splits feature
`include_js_for_snapshotting` into `exclude_js_sources` and
`runtime_js_sources`, adds a `force_include_js_sources` option on
`extension!()`, and unifies `ext::Init_ops_and_esm()` and
`ext::init_ops()` into `ext::init()`.
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.

3 participants