-
Notifications
You must be signed in to change notification settings - Fork 29.7k
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
src: implement minimal v8 snapshot integration #27321
Conversation
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
Benchmark: https://ci.nodejs.org/view/Node.js%20benchmark/job/benchmark-node-micro-benchmarks/350/ Results:
|
CI is green. PTAL, thanks! @hashseed @nodejs/build-files @nodejs/process |
This looks good, although it’ll take some time for me to get used to spelling it “indexes” 😄 |
@addaleax wait..is it "indices"? 🤦♀️ (Funny enough there are 1206 "indexes" in the code base and 950 "indices") |
indices is linguistically correct, but indexes is acceptable as well
|
Allows instantiating a NodeMainInstance with an isolate whose initialization and disposal are controlled by the caller.
This patch allows serializing per-isolate data into an isolate snapshot and deserializing them from an isolate snapthot.
Implements a node_mksnapshot target that generates a snapshot blob from a Node.js main instance's isolate, and serializes the data blob with other additional data into a C++ file that can be embedded into the Node.js binary.
Enable serializing the isolate from an isolate snapshot generated by node_mksnapshot with per-isolate data.
At build time, snapshot the context after running per-context scripts in the main instance, and in the final build, deserialize the context in the main instance. This provides a ~5% in the misc/startup benchmark when the instance is launched within a process that runs test/fixtures/semicolon.js.
f8a6cb9
to
8248be6
Compare
This comment has been minimized.
This comment has been minimized.
Rebased now that the first commit landed in #27276 |
@@ -885,8 +885,25 @@ int Start(int argc, char** argv) { | |||
} | |||
|
|||
{ | |||
NodeMainInstance main_instance( | |||
uv_default_loop(), result.args, result.exec_args); | |||
Isolate::CreateParams params; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why not move this bit into the NodeMainInstance::main_instance
overload? Sine 2 out of 3 params are anyway calculated using NodeMainInstance::
static methods, and the third is {nullptr}
;
i.e. something like:
NodeMainInstance main_instance({nullptr},
uv_default_loop(),
per_process::v8_platform.Platform(),
result.args,
result.exec_args);
...
NodeMainInstance main_instance(const std::vector<intptr_t> external_references&&,
uv_loop_t* event_loop,
MultiIsolatePlatform* platform,
const std::vector<std::string>& args,
const std::vector<std::string>& exec_args);
Isolate::CreateParams params;
v8::StartupData* blob = NodeMainInstance::GetEmbeddedSnapshotBlob();
const NodeMainInstance::IndexArray* indexes =
NodeMainInstance::GetIsolateDataIndexes();
if (blob != nullptr) {
params.external_references = external_references.data();
params.snapshot_blob = blob;
}
...
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I was thinking about moving the GetEmbeddedSnapshotBlob()
etc. out of NodeMainInstance
at some point when we add support for other snapshots, e.g. workers, and maybe restructuring the class somehow so we could reuse it in the cctest, it would be easier to experiment if the deserialization can be switched off by the caller even when the binary is built with embedded snapshot.
YAAAS! Great work! Two build related comments:
|
I have thought about that, but as a start I'd like to pay a little bit more build time and keep the two targets separate, since those are both pretty new and we may need to turn them on/off when new bugs come in (e.g. #27307 is still a confirmed bug, and it's not really fixed yet - pending a upstream CL - it only shows up in a specific case in the CI because it's very GC sensitive but it could still reproduce in the wild). I think we could observe for a while and when they are stable enough, merge the two into one - at that point it's unlikely that we'd want to go back and revert them.
The first is always done by the cross-compiled builds right? But second step is not currently done for the them. Before we enable this for the cross-compiled builds, keeping V8's snapshot at least gives them one. |
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
isolate->SetPromiseRejectCallback(task_queue::PromiseRejectCallback); | ||
v8::CpuProfiler::UseDetailedSourcePositionsForProfiling(isolate); | ||
SetIsolateUpForNode(isolate, IsolateSettingCategories::kErrorHandlers); | ||
SetIsolateUpForNode(isolate, IsolateSettingCategories::kMisc); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is kind of a bad API (although it's not a public API so it matters less) in that order might be important but that's easy to get wrong for callers. A single call where you pass in an options bitmask would be more robust.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
For the APIs that are called here...I don't think the order actually matters for now? The only dangerous bit is that you could call with one category twice, but that's also true before this change.
I think the current categories is not good as final for sure, but I don't really know the use cases for this other than this patch, so we might as well polish it as we add more use cases (I tried to organize the setup a bit better in another cctest attempt before but that didn't really go anywhere).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
For the APIs that are called here...I don't think the order actually matters for now?
No, but as a caller I don't know that unless I (closely) read the function's source. It would just be a bit easier all around if I could just say "do this and that" without having to worry about order. Declarative vs. imperative if you will.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No, but as a caller I don't know that unless I (closely) read the function's source. It would just be a bit easier all around if I could just say "do this and that" without having to worry about order. Declarative vs. imperative if you will.
This is more like a temporary DRY thing here, when we figure out other use cases we could just tweak it for them, but it’s probably too early to spend time designing it. In the initial prototype I actually copy pasted this into SetIsolateUpForSnapshot() but it looked worse..
Landed in d66c7e3...d5d9c34 |
Allows instantiating a NodeMainInstance with an isolate whose initialization and disposal are controlled by the caller. PR-URL: #27321 Refs: #17058 Reviewed-By: Anna Henningsen <anna@addaleax.net> Reviewed-By: Refael Ackermann <refack@gmail.com> Reviewed-By: James M Snell <jasnell@gmail.com> Reviewed-By: Ben Noordhuis <info@bnoordhuis.nl>
This patch allows serializing per-isolate data into an isolate snapshot and deserializing them from an isolate snapthot. PR-URL: #27321 Refs: #17058 Reviewed-By: Anna Henningsen <anna@addaleax.net> Reviewed-By: Refael Ackermann <refack@gmail.com> Reviewed-By: James M Snell <jasnell@gmail.com> Reviewed-By: Ben Noordhuis <info@bnoordhuis.nl>
Implements a node_mksnapshot target that generates a snapshot blob from a Node.js main instance's isolate, and serializes the data blob with other additional data into a C++ file that can be embedded into the Node.js binary. PR-URL: #27321 Refs: #17058 Reviewed-By: Anna Henningsen <anna@addaleax.net> Reviewed-By: Refael Ackermann <refack@gmail.com> Reviewed-By: James M Snell <jasnell@gmail.com> Reviewed-By: Ben Noordhuis <info@bnoordhuis.nl>
Enable serializing the isolate from an isolate snapshot generated by node_mksnapshot with per-isolate data. PR-URL: #27321 Refs: #17058 Reviewed-By: Anna Henningsen <anna@addaleax.net> Reviewed-By: Refael Ackermann <refack@gmail.com> Reviewed-By: James M Snell <jasnell@gmail.com> Reviewed-By: Ben Noordhuis <info@bnoordhuis.nl>
At build time, snapshot the context after running per-context scripts in the main instance, and in the final build, deserialize the context in the main instance. This provides a ~5% in the misc/startup benchmark when the instance is launched within a process that runs test/fixtures/semicolon.js. PR-URL: #27321 Refs: #17058 Reviewed-By: Anna Henningsen <anna@addaleax.net> Reviewed-By: Refael Ackermann <refack@gmail.com> Reviewed-By: James M Snell <jasnell@gmail.com> Reviewed-By: Ben Noordhuis <info@bnoordhuis.nl>
Allows instantiating a NodeMainInstance with an isolate whose initialization and disposal are controlled by the caller. PR-URL: #27321 Refs: #17058 Reviewed-By: Anna Henningsen <anna@addaleax.net> Reviewed-By: Refael Ackermann <refack@gmail.com> Reviewed-By: James M Snell <jasnell@gmail.com> Reviewed-By: Ben Noordhuis <info@bnoordhuis.nl>
This patch allows serializing per-isolate data into an isolate snapshot and deserializing them from an isolate snapthot. PR-URL: #27321 Refs: #17058 Reviewed-By: Anna Henningsen <anna@addaleax.net> Reviewed-By: Refael Ackermann <refack@gmail.com> Reviewed-By: James M Snell <jasnell@gmail.com> Reviewed-By: Ben Noordhuis <info@bnoordhuis.nl>
Implements a node_mksnapshot target that generates a snapshot blob from a Node.js main instance's isolate, and serializes the data blob with other additional data into a C++ file that can be embedded into the Node.js binary. PR-URL: #27321 Refs: #17058 Reviewed-By: Anna Henningsen <anna@addaleax.net> Reviewed-By: Refael Ackermann <refack@gmail.com> Reviewed-By: James M Snell <jasnell@gmail.com> Reviewed-By: Ben Noordhuis <info@bnoordhuis.nl>
Enable serializing the isolate from an isolate snapshot generated by node_mksnapshot with per-isolate data. PR-URL: #27321 Refs: #17058 Reviewed-By: Anna Henningsen <anna@addaleax.net> Reviewed-By: Refael Ackermann <refack@gmail.com> Reviewed-By: James M Snell <jasnell@gmail.com> Reviewed-By: Ben Noordhuis <info@bnoordhuis.nl>
At build time, snapshot the context after running per-context scripts in the main instance, and in the final build, deserialize the context in the main instance. This provides a ~5% in the misc/startup benchmark when the instance is launched within a process that runs test/fixtures/semicolon.js. PR-URL: #27321 Refs: #17058 Reviewed-By: Anna Henningsen <anna@addaleax.net> Reviewed-By: Refael Ackermann <refack@gmail.com> Reviewed-By: James M Snell <jasnell@gmail.com> Reviewed-By: Ben Noordhuis <info@bnoordhuis.nl>
This PR adds minimal support for embedded v8 snapshot. The generated snapshot currently includes:
At the moment, we do not create any external reference at the point when the snapshot is captured.
To snapshot more of the bootstrap result, we'll need to implement external reference bookkeeping
in a future PR.
In this PR the setup of the error handlers is delayed until after the context is created, because
attaching the error message handler creates an external reference to the C++ function.
This means any errors thrown during the snapshot generation will be handled by the default
handler and won't have the fancy error stack traces generated by
node:: PrintException
,but that should be rare and should only happen during local development (it was broken until
#27236 anyway).
src: allow creating NodeMainInstance that does not own the isolate
Allows instantiating a NodeMainInstance with an isolate
whose initialization and disposal are controlled by the caller.
src: implement IsolateData serialization and deserialization
This patch allows serializing per-isolate data into an isolate
snapshot and deserializing them from an isolate snapshot.
tools: implement node_mksnapshot
Implements a node_mksnapshot target that generates a snapshot blob
from a Node.js main instance's isolate, and serializes the data blob
with other additional data into a C++ file that can be embedded into
the Node.js binary.
src: enable snapshot with per-isolate data
Enable serializing the isolate from an isolate snapshot generated
by node_mksnapshot with per-isolate data.
src: enable context snapshot after running per-context scripts
At build time, snapshot the context after running per-context scripts
in the main instance, and in the final build, deserialize the
context in the main instance.
This provides a ~5% in the misc/startup benchmark when the instance
is launched within a process that runs test/fixtures/semicolon.js.
Refs: #17058
Checklist
make -j4 test
(UNIX), orvcbuild test
(Windows) passes