Re-enable V8 startup snapshot to cut user-worker cold start#161
Open
p-hoffmann wants to merge 5 commits into
Open
Re-enable V8 startup snapshot to cut user-worker cold start#161p-hoffmann wants to merge 5 commits into
p-hoffmann wants to merge 5 commits into
Conversation
Contributor
There was a problem hiding this comment.
Pull request overview
This PR re-enables using a V8 startup snapshot to reduce user-worker cold-start time, while adjusting JS bootstrap behavior so snapshot creation doesn’t fail due to early WebAssembly access.
Changes:
- Deferred WebAssembly memory tracking patching to runtime via a new
installWasmMemoryTracking()entrypoint. - Updated runtime bootstrap to install wasm memory tracking after initialization.
- Re-enabled snapshot consumption (with feature gating) and rebuilt the snapshot to include the full extension list aligned with the runtime.
Reviewed changes
Copilot reviewed 4 out of 4 changed files in this pull request and generated 2 comments.
| File | Description |
|---|---|
| ext/runtime/js/wasm_memory_tracker.js | Moves WebAssembly patching behind a runtime-installed hook for snapshot safety. |
| ext/runtime/js/bootstrap.js | Calls the new runtime install hook before starting wasm memory polling. |
| crates/base/src/snapshot.rs | Re-enables returning the embedded runtime snapshot (with conditional gating). |
| crates/base/build.rs | Builds a full runtime snapshot with an extension list intended to match runtime initialization order. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Comment on lines
+52
to
+56
| OrigMemory = Wasm.Memory; | ||
| const OrigInstance = Wasm.Instance; | ||
| const origInstantiate = Wasm.instantiate; | ||
| const origInstantiateStreaming = Wasm.instantiateStreaming; | ||
|
|
Comment on lines
+15
to
+19
| if cfg!(feature = "trex") { | ||
| None | ||
| } else { | ||
| Some(CLI_SNAPSHOT) | ||
| } |
df1a4d1 to
6424963
Compare
Bake the full extension ESM into RUNTIME_SNAPSHOT.bin instead of building an empty snapshot, so each user worker restores the JS runtime from the snapshot instead of re-initializing it from scratch on every spawn. Cuts user-worker cold start from ~200-680ms to ~40-85ms (boot_time ~200ms -> ~31ms); warm and WebAssembly behaviour unchanged. - build.rs: populate the snapshot with the runtime extension list (same order, same init()/lazy_init() per extension) using build-safe params (runtime_bootstrap::init(None), build-available deno_node type params, a name-only base_runtime_permissions stub); skip_op_registration=false. - snapshot.rs: return Some(CLI_SNAPSHOT) unconditionally. - wasm_memory_tracker.js: defer WebAssembly.* patching into installWasmMemoryTracking(); it must not run at module-eval time because WebAssembly is unavailable during snapshot creation. - bootstrap.js: call installWasmMemoryTracking() at runtime in bootstrapSBEdge. Tested on amd64 with prebuilt V8, `trex` feature off. Note: the snapshot extension list omits the feature-gated trex_core extension; a build with the `trex` feature needs it added to build.rs to avoid ExtensionSnapshotMismatch.
6424963 to
552724f
Compare
The external https://httpbin.org/stream/20 endpoint intermittently returns 503; skip the tmp-fs comparison when it is unavailable instead of failing the test. The trex tmp-fs write is still exercised by the worker request above it.
- build.rs: set with_runtime_cb to bake ext_node's global template + VM context (at VM_CONTEXT_INDEX) into the snapshot, matching deno's runtime/snapshot.rs. Without it the runtime indexed a missing context slot (out of bounds; silent UB in release, SIGABRT under debug libc++ hardening in the base lib tests). - bootstrap.js / wasm_memory_tracker.js: install wasm-memory tracking before the shared-memory patch replaces WebAssembly.Memory, so it captures the real constructor/prototype rather than the wrapper (was silently missing memories).
Run the coverage test suite in release so it exercises the same configuration production ships (release + V8 startup snapshot). The snapshot tripped a libc++ hardening assertion only in the debug coverage build; it does not reproduce in a normal debug or release build, and release has no libc++ hardening, so this both tests the real config and avoids the debug-only abort.
ServerEvent::Draining is #[cfg(debug_assertions)] (server.rs), so the test that matches on it only compiles in debug. Guard it so the suite compiles in release (CI now runs the coverage tests in release).
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
No description provided.