0
0
mirror of https://github.com/nodejs/node.git synced 2024-12-01 16:10:02 +01:00
Commit Graph

9 Commits

Author SHA1 Message Date
Joyee Cheung
6967f91368
process: split execution into main scripts
This patch splits the execution mode selection from the environment
setup in `lib/internal/bootstrap/node.js`, and split the entry point
of different execution mode into main scripts under
`lib/internal/main`:

- `check_syntax.js`: used when `-c`/`--check` which only checks the
  syntax of the input instead of executing it.
- `eval_stdin.js`: used when `-e` is passed without value and stdin
  is not a TTY (e.g. something is piped).
- `eval_string`: used when `-e` is passed along with a string argument
- `inspect.js`: for `node inspect`/`node debug`
- `print_bash_completion.js`: for `--completion-bash`
- `print_help.js`: for `--help`
- `prof_process.js`: for `--prof-process`
- `repl.js`: for the REPL
- `run_main_module.js`: used when a main module is passed
- `run_third_party_main.js`: for the legacy `_third_party_main.js`
  support
- `worker_thread.js`: for workers

This makes the entry points easier to navigate and paves the way
for customized v8 snapshots (that do not need to deserialize
execution mode setup) and better embedder APIs.

As an example, after this patch, for the most common case where
Node.js executes a user module as an entry point, it essentially
goes through:

- `lib/internal/per_context.js` to setup the v8 Context (which is
  also run when setting up contexts for the `vm` module)
- `lib/internal/bootstrap/loaders.js` to set up internal binding
  and builtin module loaders (that are separate from the loaders
  accessible in the user land).
- `lib/internal/bootstrap/node.js`: to set up the rest of the
  environment, including various globals and the process object
- `lib/internal/main/run_main_module.js`: which is selected from
  C++ to prepare execution of the user module.

This patch also removes `NativeModuleLoader::CompileAndCall` and
exposes `NativeModuleLoader::LookupAndCompile` directly so that
we can handle syntax errors and runtime errors of bootstrap
scripts differently.

PR-URL: https://github.com/nodejs/node/pull/25667
Reviewed-By: Anna Henningsen <anna@addaleax.net>
2019-01-30 21:03:17 +08:00
Joyee Cheung
92e95f17b6
src: simplify NativeModule caching and remove redundant data
- Remove `NativeModule._source` - the compilation is now entirely
  done in C++ and `process.binding('natives')` is implemented
  directly in the binding loader so there is no need to store
  additional source code strings.
- Instead of using an object as `NativeModule._cached` and insert
  into it after compilation of each native module, simply prebuild
  a JS map filled with all the native modules and infer the
  state of compilation through `mod.loading`/`mod.loaded`.
- Rename `NativeModule.nonInternalExists` to
  `NativeModule.canBeRequiredByUsers` and precompute that
  property for all the native modules during bootstrap instead
  of branching in every require call during runtime. This also fixes
  the bug where `worker_threads` can be made available with
  `--expose-internals`.
- Rename `NativeModule.requireForDeps` to
  `NativeModule.requireWithFallbackInDeps`.
- Add a test to make sure we do not accidentally leak any module
  to the global namespace.

PR-URL: https://github.com/nodejs/node/pull/25352
Reviewed-By: Anna Henningsen <anna@addaleax.net>
2019-01-12 22:56:02 +08:00
Joyee Cheung
0858e5d9d8
src: always compile and store code cache for native modules
This patch changes the NativeModuleLoader to always try to find
code cache for native modules when it compiles them, and always
produce and store the code cache after compilation. The cache
map is protected by a mutex and can be accessed by different
threads - including the worker threads and the main thread. Hence any
thread can reuse the code cache if the native module has already
been compiled by another thread - in particular the cache of the
bootstrappers and per_context.js will always be hit when a new thread
is spun.

This results in a ~6% startup overhead in the worst case
(when only the main thread is launched without requiring any additional
native module - it now needs to do the extra work of finding and
storing caches), which balances out the recent improvements by moving
the compilation to C++, but it also leads to a ~60% improvement in
the best case (when a worker thread is spun and requires a lot of native
modules thus hitting the cache compiled by the main thread).

PR-URL: https://github.com/nodejs/node/pull/24950
Reviewed-By: Anna Henningsen <anna@addaleax.net>
2018-12-18 18:02:11 +08:00
Joyee Cheung
ceb6635223
src: remove code cache integrity check
In preparation of sharing code cache among different threads -
we simply rely on v8 to reject invalid cache, since there isn't
any serious consequence when the cache is invalid anyway.

PR-URL: https://github.com/nodejs/node/pull/24950
Reviewed-By: Anna Henningsen <anna@addaleax.net>
2018-12-18 18:02:08 +08:00
Joyee Cheung
7778c035a0
src: use STL containers instead of v8 values for static module data
Instead of putting the source code and the cache in v8::Objects,
put them in per-process std::maps. This has the following benefits:

- It's slightly lighter in weight compared to storing things on the
  v8 heap. Also it may be slightly faster since the preivous v8::Object
  is already in dictionary mode - though the difference is very small
  given the number of native modules is limited.
- The source and code cache generation templates are now much simpler
  since they just initialize static arrays and manipulate STL
  constructs.
- The static native module data can be accessed independently of any
  Environment or Isolate, and it's easy to look them up from the
  C++'s side.
- It's now impossible to mutate the source code used to compile
  native modules from the JS land since it's completely separate
  from the v8 heap. We can still get the constant strings from
  process.binding('natives') but that's all.

A few drive-by fixes:

- Remove DecorateErrorStack in LookupAndCompile - We don't need to
  capture the exception to decorate when we encounter
  errors during native module compilation, as those errors should be
  syntax errors and v8 is able to decorate them well. We use
  CompileFunctionInContext so there is no need to worry about
  wrappers either.
- The code cache could be rejected when node is started with v8 flags.
  Instead of aborting in that case, simply keep a record in the
  native_module_without_cache set.
- Refactor js2c.py a bit, reduce code duplication and inline Render()
  to make the one-byte/two-byte special treatment easier to read.

PR-URL: https://github.com/nodejs/node/pull/24384
Fixes: https://github.com/Remove
Reviewed-By: Anna Henningsen <anna@addaleax.net>
Reviewed-By: Franziska Hinkelmann <franziska.hinkelmann@gmail.com>
Reviewed-By: Tiancheng "Timothy" Gu <timothygu99@gmail.com>
Reviewed-By: James M Snell <jasnell@gmail.com>
2018-11-20 01:17:15 +08:00
Joyee Cheung
bd765d61d7
src: compile native modules and their code cache in C++
This patch refactors out a part of NativeModule.prototype.compile
(in JS land) into a C++ NativeModule class, this enables a
couple of possibilities:

1. By moving the code to the C++ land, we have more opportunity
  to specialize the compilation process of the native modules
  (e.g. compilation options, code cache) that is orthogonal to
  how user land modules are compiled
2. We can reuse the code to compile bootstrappers and context
  fixers and enable them to be compiled with the code cache later,
  since they are not loaded by NativeModule in the JS land their
  caching must be done in C++.
3. Since there is no need to pass the static data to JS for
  compilation anymore, this enables us to use
  (std::map<std::string, const char*>) in the generated
  node_code_cache.cc and node_javascript.cc later, and scope
  every actual access to the source of native modules to a
  std::map lookup instead of a lookup on a v8::Object in
  dictionary mode.

This patch also refactor the code cache generator and tests
a bit and trace the `withCodeCache` and `withoutCodeCache`
in a Set instead of an Array, and makes sure that all the cachable
builtins are tested.

PR-URL: https://github.com/nodejs/node/pull/24221
Reviewed-By: Refael Ackermann <refack@gmail.com>
Reviewed-By: Anna Henningsen <anna@addaleax.net>
2018-11-15 02:30:40 +08:00
Joyee Cheung
010a3f8c23
test: run code cache test by default and test generator
- Add the code cache tests to the default test suite, and test
  the bookkeeping when the binary is not built with the code cache.
- Test the code cache generator to make sure we do not accidentally
  break it - until we enable code cache in the CI.

Refs: https://github.com/nodejs/node/issues/21563
PR-URL: https://github.com/nodejs/node/pull/23855
Reviewed-By: Michaël Zasso <targos@protonmail.com>
Reviewed-By: Refael Ackermann <refack@gmail.com>
Reviewed-By: Colin Ihrig <cjihrig@gmail.com>
Reviewed-By: James M Snell <jasnell@gmail.com>
2018-10-30 14:38:27 +08:00
Joyee Cheung
186c2fb6d8
build: create V8 code cache after script is run
This patch makes it possible to generate the code cache
for the builtins directly from the original script object
(instead of compiling a new one) and after the script has
been run (via `NativeModule.require`). Before this patch
only the top level functions (the wrapped ones)
are included in the cache, after this patch the inner
functions in those modules will be included as well.

Also blacklists modules from dependencies like V8 and
node-inspect since we cannot guarantee that they are suitable
to be executed directly.

PR-URL: https://github.com/nodejs/node/pull/21567
Refs: https://github.com/nodejs/node/issues/21563
Reviewed-By: James M Snell <jasnell@gmail.com>
Reviewed-By: Tiancheng "Timothy" Gu <timothygu99@gmail.com>
Reviewed-By: Gus Caplan <me@gus.host>
Reviewed-By: John-David Dalton <john.david.dalton@gmail.com>
Reviewed-By: Colin Ihrig <cjihrig@gmail.com>
2018-07-27 14:51:27 +08:00
Joyee Cheung
4750ce26f2
build: speed up startup with V8 code cache
This patch speeds up the startup time and reduce the startup memory
footprint by using V8 code cache when comiling builtin modules.

The current approach is demonstrated in the `with-code-cache`
Makefile target (no corresponding Windows target at the moment).

1. Build the binary normally (`src/node_code_cache_stub.cc` is used),
  by now `internalBinding('code_cache')` is an empty object
2. Run `tools/generate_code_cache.js` with the binary, which generates
  the code caches by reading source code of builtin modules off source
  code exposed by `require('internal/bootstrap/cache').builtinSource`
  and then generate a C++ file containing static char arrays of the
  code cache, using a format similar to `node_javascript.cc`
3. Run `configure` with the `--code-cache-path` option so that
  the newly generated C++ file will be used when compiling the
  new binary. The generated C++ file will put the cache into
  the `internalBinding('code_cache')` object with the module
  ids as keys
4. The new binary tries to read the code cache from
  `internalBinding('code_cache')` and use it to compile
  builtin modules. If the cache is used, it will put the id
  into `require('internal/bootstrap/cache').compiledWithCache`
  for bookkeeping, otherwise the id will be pushed into
  `require('internal/bootstrap/cache').compiledWithoutCache`

This patch also added tests that verify the code cache is
generated and used when compiling builtin modules.

The binary with code cache:

- Is ~1MB bigger than the binary without code cahe
- Consumes ~1MB less memory during start up
- Starts up about 60% faster

PR-URL: https://github.com/nodejs/node/pull/21405
Reviewed-By: John-David Dalton <john.david.dalton@gmail.com>
Reviewed-By: Anna Henningsen <anna@addaleax.net>
Reviewed-By: Gus Caplan <me@gus.host>
2018-06-27 21:11:31 +08:00