Search code examples
javascriptv8webassemblyemscripten

How to share compiled JS code across Isolates


I have a 1 MB JS+WASM file (say, xyz.js) compiled through Emscripten that acts as a library to be called by some custom JavaScript code in a C++ application using the V8 API.

Currently, I am loading xyz.js using v8::String::NewFromUtf8 and compiling it with v8::Script::Compile. v8::String::NewFromUtf8takes the handle to corresponding Isolate, which means I have to create an isolate before calling this function.

The problem is that I need to run multiple isolates on different threads in parallel, and having to re-compile the same file in every isolate add up both performance and memory overhead. What I would like to be able to do is to load and compile this file once, and then share it in all isolates (similar to how an OS may share the memory pages of shared libraries across processes).

Is there any way to achieve this?

PS. There is an eight year old question asking about the same thing, but it's possible that some new features may have been to added to V8 since then.


Solution

  • (V8 developer here.)

    This hasn't changed. Compiled JavaScript code is isolate-specific and cannot be shared across isolates. This is in particular because it contains isolate-specific pointers (as immediates in the instruction stream). We have experimented with isolate-independent optimized code, but it turned out to be so much slower that we discarded the experiment.

    Compiled Wasm code, OTOH, is shared across the entire process. You can't directly control that, but you can just instantiate the module wherever you need it, and trust that V8 will reuse existing code under the hood. For the record, this may or may not change in the future: we have plans to experiment with how much faster Wasm code could get if we allowed it to make isolate- or instance-specific assumptions. So far it's unclear whether that would be worth it, but new ecosystem developments such as toolchains making increasing use of module splitting and then wanting the performance benefits of cross-module inlining could change the picture.