Skip to content

Commit d960a15

Browse files
joyeecheungaduh95
authored andcommitted
doc: improve internal documentation on built-in snapshot
Part of the tools/snapshot/README.md is out of date since we have made more progress on the snapshot integration, so update it accordingly with some details about the various snapshots in the snapshot blob. Also update the section in src/README.md about external reference registration for clarification. PR-URL: #56505 Reviewed-By: Chengzhong Wu <legendecas@gmail.com>
1 parent dd07b6d commit d960a15

File tree

2 files changed

+72
-7
lines changed

2 files changed

+72
-7
lines changed

src/README.md

+13-4
Original file line numberDiff line numberDiff line change
@@ -467,10 +467,16 @@ void Initialize(Local<Object> target,
467467
NODE_BINDING_CONTEXT_AWARE_INTERNAL(cares_wrap, Initialize)
468468
```
469469
470-
If the C++ binding is loaded during bootstrap, it needs to be registered
471-
with the utilities in `node_external_reference.h`, like this:
470+
#### Registering binding functions used in bootstrap
471+
472+
If the C++ binding is loaded during bootstrap, in addition to registering it
473+
using `NODE_BINDING_CONTEXT_AWARE_INTERNAL` for `internalBinding()` lookup,
474+
it also needs to be registered with `NODE_BINDING_EXTERNAL_REFERENCE` so that
475+
the external references can be resolved from the built-in snapshot, like this:
472476
473477
```cpp
478+
#include "node_external_reference.h"
479+
474480
namespace node {
475481
namespace util {
476482
void RegisterExternalReferences(ExternalReferenceRegistry* registry) {
@@ -498,7 +504,8 @@ Unknown external reference 0x107769200.
498504
/bin/sh: line 1: 6963 Illegal instruction: 4 out/Release/node_mksnapshot out/Release/gen/node_snapshot.cc
499505
```
500506

501-
You can try using a debugger to symbolicate the external reference. For example,
507+
You can try using a debugger to symbolicate the external reference in order to find
508+
out the binding functions that you forget to register. For example,
502509
with lldb's `image lookup --address` command (with gdb it's `info symbol`):
503510

504511
```console
@@ -514,7 +521,9 @@ Process 7012 stopped
514521
```
515522

516523
Which explains that the unregistered external reference is
517-
`node::util::GetHiddenValue` defined in `node_util.cc`.
524+
`node::util::GetHiddenValue` defined in `node_util.cc`, and should be registered
525+
using `registry->Register()` in a registration function marked by
526+
`NODE_BINDING_EXTERNAL_REFERENCE`.
518527

519528
<a id="per-binding-state"></a>
520529

tools/snapshot/README.md

+59-3
Original file line numberDiff line numberDiff line change
@@ -8,9 +8,46 @@ instead of executing code to bootstrap, it can deserialize the context from
88
an embedded snapshot, which readily contains the result of the bootstrap, so
99
that Node.js can start up faster.
1010

11-
Currently only the main context of the main Node.js instance supports snapshot
12-
deserialization, and the snapshot does not yet cover the entire bootstrap
13-
process. Work is being done to expand the support.
11+
The built-in snapshot consists of the following snapshots:
12+
13+
## Isolate snapshot
14+
15+
Which is used whenever a `v8::Isolate` is created using the data returned by
16+
`node::SnapshotBuilder::GetEmbeddedSnapshotData`.
17+
18+
## Context snapshots
19+
20+
Which are used when a `v8::Context` is created from a `v8::Isolate` deserialized
21+
from the snapshot. There are four context snapshots in the snapshot blob.
22+
23+
1. The default context snapshot, used for contexts created by
24+
`v8::Context::New()`, it only contains V8 built-ins, matching the
25+
layout of the isolate snapshot.
26+
1. The vm context snapshot, which can be deserialized using
27+
`v8::Context::FromSnapshot(isolate, node::SnapshotData::kNodeVMContextIndex, ...)`.
28+
It captures initializations specific to vm contexts done by
29+
`node::contextify::ContextifyContext::CreateV8Context()`.
30+
1. The base context snapshot, which can be deserialized using
31+
`v8::Context::FromSnapshot(isolate, node::SnapshotData::kNodeBaseContextIndex, ...)`.
32+
It currently captures initializations done by `node::NewContext()`
33+
but is intended to include more as a basis for worker thread
34+
contexts.
35+
1. The main context snapshot, which can be deserialized using
36+
`v8::Context::FromSnapshot(isolate, node::SnapshotData::kNodeMainContextIndex, ...)`.
37+
This is the snapshot for the main context on the main thread, and
38+
captures initializations done by `node::CommonEnvironmentSetup::CreateForSnapshotting()`,
39+
most notably `node::CreateEnvironment()`, which runs the following scripts via
40+
`node::Realm::RunBootstrapping()` for the main context as a principal realm,
41+
so that at runtime, these scripts do not need to be run. Instead only the context
42+
initialized by them is deserialized at runtime.
43+
1. `internal/bootstrap/realm`
44+
2. `internal/bootstrap/node`
45+
3. `internal/bootstrap/web/exposed-wildcard`
46+
4. `internal/bootstrap/web/exposed-window-or-worker`
47+
5. `internal/bootstrap/switches/is_main_thread`
48+
6. `internal/bootstrap/switches/does_own_process_state`
49+
50+
For more information about these contexts, see the comment in `src/node_context_data.h`.
1451

1552
## How it's built and used
1653

@@ -39,3 +76,22 @@ For debugging, Node.js can be built without Node.js's own snapshot if
3976
`--without-node-snapshot` is passed to `configure`. A Node.js executable
4077
with Node.js snapshot embedded can also be launched without deserializing
4178
from it if the command line argument `--no-node-snapshot` is passed.
79+
80+
### When `node_mksnapshot` crashes..
81+
82+
Due to this two-phase building process, sometimes when there is an issue
83+
in the code, the build may crash early at executing `node_mksnapshot` instead of crashing
84+
at executing the final executable `node`. If the crash can be reproduced when running
85+
the `node` executable built with `--without-node-snapshot`, it means the crash likely
86+
has nothing to do with snapshots, and only shows up in `node_mksnapshot` because it's
87+
the first Node.js executable being run.
88+
89+
If the crash comes from a `mksnapshot` executable (notice that it doesn't have the `node_`
90+
prefix), that comes from V8's own snapshot building process, not the one in Node.js, and the
91+
fix likely needs to be in V8 or the build configurations of V8.
92+
93+
If it `node_mksnapshot` crashes with an error message containing
94+
something like `Unknown external reference 0x107769200`, see
95+
[Registering binding functions used in bootstrap][] on how to fix it.
96+
97+
[Registering binding functions used in bootstrap]: ../../src/README.md#registering-binding-functions-used-in-bootstrap

0 commit comments

Comments
 (0)