Commit Graph

14 Commits

Author SHA1 Message Date
Shelley Vohr
c40c41c285
src: expose LookupAndCompile with parameters
PR-URL: https://github.com/nodejs/node/pull/53886
Reviewed-By: Joyee Cheung <joyeec9h3@gmail.com>
Reviewed-By: Chengzhong Wu <legendecas@gmail.com>
Reviewed-By: James M Snell <jasnell@gmail.com>
2024-07-29 17:55:10 +00:00
Joyee Cheung
3e57b93963
src: compile code eagerly in snapshot builder
By default V8 only compiles the top-level function and
skips code generation for inner functions - that would
only be done when those inner functions are invoked.
Since builtins are compiled as wrapped functions, most
functions that look visually top-level are not actually
included in the built-in code cache. For most of the
builtins this is not too bad because usually only a subset of
all builtin functions are needed by a particular
application and including all their code in the binary
would incur an unnecessary size overhead. But there is also
a subset of more commonly used builtins and it would be
better to include the inner functions in the built-in
code cache because they are more universally used by
most applications.

This patch changes the compilation strategy to eager compilation
(including inner functions) for the following scripts:

1. Primordials (internal/per_context/*), in all situations.
2. Bootstrap scripts (internal/bootstrap/*) and main scripts
   (internal/main/*), when being compiled for built-in code
   cache.
3. Any scripts loaded during built-in snapshot generation.

We can't compile the code eagerly during snapshot generation
and include them into the V8 snapshot itself just now because
we need to start the inspector before context deserialization
for coverage collection to work. So leave that as a TODO.

With this patch the binary size increases by about 666KB
(~0.6% increase) in return the worker startup can be 18-19% faster.

PR-URL: https://github.com/nodejs/node/pull/51672
Reviewed-By: Yagiz Nizipli <yagiz.nizipli@sentry.io>
2024-02-20 21:40:12 +00:00
Joyee Cheung
fe219e0438
bootstrap: do not generate code cache in an unfinalized isolate
V8 now no longer supports serializing code cache in an isolate
with unfinalized read-only space. So guard the code cache regeneration
with the `is_building_snapshot()` flag. When the isolate is created
for snapshot generation, the code cache is going to be serialized
separately anyway, so there is no need to do it in the builtin loader.

PR-URL: https://github.com/nodejs/node/pull/49108
Reviewed-By: Benjamin Gruenbaum <benjamingr@gmail.com>
Reviewed-By: Yagiz Nizipli <yagiz@nizipli.com>
2023-08-17 17:24:46 +00:00
Yagiz Nizipli
7ffa5d7f0d
src: avoid string copy in BuiltinLoader::GetBuiltinIds
PR-URL: https://github.com/nodejs/node/pull/48721
Reviewed-By: Luigi Pinca <luigipinca@gmail.com>
Reviewed-By: Rafael Gonzaga <rafael.nunu@hotmail.com>
2023-08-11 15:31:58 +00:00
Joyee Cheung
e1fa85133f
src: implement natives binding without special casing
This patch removes special case in the internal binding loader
for natives, and implements it using the builtins internal
binding. Internally we do not actually need the natives binding,
so implement it as a legacy wrapper instead.

PR-URL: https://github.com/nodejs/node/pull/48186
Reviewed-By: James M Snell <jasnell@gmail.com>
Reviewed-By: Chengzhong Wu <legendecas@gmail.com>
2023-06-09 15:32:55 +02:00
Joyee Cheung
c0365fd52a
src: avoid prototype access in binding templates
This patch makes the binding templates ObjectTemplates, since we
don't actually need the constructor function. This also avoids
setting the properties on prototype, and instead initializes them
directly on the object template.

Previously the initialization was similar to:

```
function Binding() {}
Binding.prototype.property = ...;
module.exports = new Binding;
```

Now it's similar to:

```
module.exports = { property: ... };
```

PR-URL: https://github.com/nodejs/node/pull/47913
Reviewed-By: Chengzhong Wu <legendecas@gmail.com>
Reviewed-By: James M Snell <jasnell@gmail.com>
2023-05-24 16:45:05 +02:00
Keyhan Vakil
3ef17b6356
src: stop copying code cache, part 2
This removes more copies of the code cache data.

First: for the builtin snapshot, we were copying the code cache to
create a `std::vector<uint8_t>`. This was slowing down static
intialization. Change it to use a good old `uint8_t*` and `size_t`
rather than a vector. For the case of embedder provided snapshots, we
also add an `owning_ptr` so that we can properly cleanup owned values
created from the snapshot.

Second: whenever the code cache was hit, we would remove the bytecode
from the code cache, and then reserialize it from the compiled function.
This was pretty slow. Change the code so that we can reuse the same code
cache multiple times. If the code cache is rejected (say, because the
user added V8 options), then we need to generate the bytecode, in which
case we again use `owning_ptr` to ensure that the underlying code cache
is freed.

Combined, these changes improve the misc/startup.js benchmarks
significantly (p < 0.001):

* process,benchmark/fixtures/require-builtins: 22.15%
* process,test/fixtures/semicolon: 8.55%
* worker,benchmark/fixtures/require-builtins: 26.52%
* worker,test/fixtures/semicolon: 21.52%

PR-URL: https://github.com/nodejs/node/pull/47958
Reviewed-By: Joyee Cheung <joyeec9h3@gmail.com>
Reviewed-By: Minwoo Jung <nodecorelab@gmail.com>
2023-05-15 04:37:24 +00:00
Keyhan Vakil
0736d0b3f5
src: register external references for source code
Currently we use external strings for internalized builtin source code.
However when a snapshot is taken, any external string whose resource
is not registered is flattened into a SeqString (see ref). The
result is that module source code stored in the snapshot does not
use external strings after deserialization. This patch registers an
external string resource for each internalized builtin's source. The
savings are substantial: ~1.9 MB of heap memory per isolate, or ~44%
of an otherwise empty isolate's heap usage:

```console
$ node --expose-gc -p 'gc(),process.memoryUsage().heapUsed'
4190968
$ ./node --expose-gc -p 'gc(),process.memoryUsage().heapUsed'
2327536
```

The savings can be even higher for user snapshots which may include
more internal modules.

The existing UnionBytes implementation was ill-suited, because it only
created an external string resource when ToStringChecked was called,
but we need to register the external string resources before the
isolate even exists. We change UnionBytes to no longer own the data,
and shift ownership of the data to a new external resource class
called StaticExternalByteResource.  StaticExternalByteResource are
either statically allocated (for internalized builtin code) or owned
by the static `externalized_builtin_sources` map, so they will only be
destructed when static resources are destructed. We change JS2C to emit
statements to register a string resource for each internalized builtin.

Refs: d2c8fbe9cc/src/snapshot/serializer.cc (L633)
PR-URL: https://github.com/nodejs/node/pull/47055
Reviewed-By: Joyee Cheung <joyeec9h3@gmail.com>
Reviewed-By: Chengzhong Wu <legendecas@gmail.com>
2023-05-10 11:17:59 +00:00
Anna Henningsen
d896f5befd
src: make BuiltinLoader threadsafe and non-global
As discussed in https://github.com/nodejs/node/pull/45888, using a
global `BuiltinLoader` instance is probably undesirable in a world
in which embedders are able to create Node.js Environments with
different sources and therefore mutually incompatible code
caching properties.

This PR makes it so that `BuiltinLoader` is no longer a global
singleton and instead only shared between `Environment`s that
have a direct relation to each other, and addresses a few
thread safety issues along with that.

PR-URL: https://github.com/nodejs/node/pull/45942
Reviewed-By: Joyee Cheung <joyeec9h3@gmail.com>
2023-01-18 22:03:00 +00:00
Anna Henningsen
21fb98e2bf
src: use simdutf for converting externalized builtins to UTF-16
Remove the dependency on ICU for this part, as well as the
hacky way of converting embedder main sources to UTF-8 via
V8 APIs. Allow `UnionBytes` to own the memory its pointing
to in order to simplify the code on the `BuiltinLoader` side.

PR-URL: https://github.com/nodejs/node/pull/46119
Reviewed-By: Yagiz Nizipli <yagiz@nizipli.com>
Reviewed-By: James M Snell <jasnell@gmail.com>
Reviewed-By: Rafael Gonzaga <rafael.nunu@hotmail.com>
Reviewed-By: Darshan Sen <raisinten@gmail.com>
2023-01-10 11:25:19 +00:00
legendecas
43105220a7
src: define per-isolate internal bindings registration callback
Bindings that need to be loaded in distinct contexts of node::Realm in
the same node::Environment instance needs to share the per-isolate
templates.

Add a new binding registration callback, which is called with
per-IsolateData. This allows bindings to define templates and
share them across realms eagerly, and avoid accidental modification on
the templates when the per-context callback is called multiple times.

This also tracks loaded bindings and built-in modules with node::Realm.

PR-URL: https://github.com/nodejs/node/pull/45547
Refs: https://github.com/nodejs/node/issues/42528
Reviewed-By: Joyee Cheung <joyeec9h3@gmail.com>
Reviewed-By: Colin Ihrig <cjihrig@gmail.com>
Reviewed-By: James M Snell <jasnell@gmail.com>
2022-12-28 11:55:14 +08:00
Michael Dawson
ca5be26b31 src: add support for externally shared js builtins
Refs: https://github.com/nodejs/node/issues/44000

- add infra to support externally shared js builtins in
  support of distos that want to externalize deps that
  include JS/WASM instead of native code
- add support for externalizing
  - cjs_module_lexer/lexer
  - cjs_module_lexer/dist/lexer
  - undici/undici

Signed-off-by: Michael Dawson <mdawson@devrus.com>

PR-URL: https://github.com/nodejs/node/pull/44376
Reviewed-By: Gireesh Punathil <gpunathi@in.ibm.com>
2022-10-11 09:44:48 -04:00
Joyee Cheung
78508028e3
bootstrap: generate bootstrapper arguments in BuiltinLoader
PR-URL: https://github.com/nodejs/node/pull/44488
Reviewed-By: Chengzhong Wu <legendecas@gmail.com>
2022-09-13 08:55:19 +00:00
Joyee Cheung
472edc775d
src: disambiguate terms used to refer to builtins and addons
The term "native module" dates back to some of the oldest code
in the code base. Within the context of Node.js core it usually
refers to modules that are native to Node.js (e.g. fs, http),
but it can cause confusion for people who don't work on this
part of the code base, as "native module" can also refer to
native addons - which is even the case in some of the API
docs and error messages.

This patch tries to make the usage of these terms more consistent.
Now within the context of Node.js core:

- JavaScript scripts that are built-in to Node.js are now referred
  to as "built-in(s)". If they are available as modules,
  they can also be referred to as "built-in module(s)".
- Dynamically-linked shared objects that are loaded into
  the Node.js processes are referred to as "addons".

We will try to avoid using the term "native modules" because it could
be ambiguous.

Changes in this patch:

File names:
- node_native_module.h -> node_builtins.h,
- node_native_module.cc -> node_builtins.cc

C++ binding names:
- `native_module` -> `builtins`

`node::Environment`:
- `native_modules_without_cache` -> `builtins_without_cache`
- `native_modules_with_cache` -> `builtins_with_cache`
- `native_modules_in_snapshot` -> `builtins_in_cache`
- `native_module_require` -> `builtin_module_require`

`node::EnvSerializeInfo`:
- `native_modules` -> `builtins

`node::native_module::NativeModuleLoader`:
- `native_module` namespace -> `builtins` namespace
- `NativeModuleLoader` -> `BuiltinLoader`
- `NativeModuleRecordMap` -> `BuiltinSourceMap`
- `NativeModuleCacheMap` -> `BuiltinCodeCacheMap`
- `ModuleIds` -> `BuiltinIds`
- `ModuleCategories` -> `BuiltinCategories`
- `LoadBuiltinModuleSource` -> `LoadBuiltinSource`

`loader.js`:
- `NativeModule` -> `BuiltinModule` (the `NativeModule` name used in
  `process.moduleLoadList` is kept for compatibility)

And other clarifications in the documentation and comments.

PR-URL: https://github.com/nodejs/node/pull/44135
Fixes: https://github.com/nodejs/node/issues/44036
Reviewed-By: Jacob Smith <jacob@frende.me>
Reviewed-By: Matteo Collina <matteo.collina@gmail.com>
Reviewed-By: Michael Dawson <midawson@redhat.com>
Reviewed-By: Richard Lau <rlau@redhat.com>
Reviewed-By: Jiawen Geng <technicalcute@gmail.com>
Reviewed-By: Chengzhong Wu <legendecas@gmail.com>
Reviewed-By: Mohammed Keyvanzadeh <mohammadkeyvanzade94@gmail.com>
Reviewed-By: Tobias Nießen <tniessen@tnie.de>
Reviewed-By: Jan Krems <jan.krems@gmail.com>
2022-08-09 01:36:49 +08:00