Skip to content

child_process: pass spawn options to the binding positionally#63930

Open
anonrig wants to merge 1 commit into
nodejs:mainfrom
anonrig:process-wrap-fast-spawn-options
Open

child_process: pass spawn options to the binding positionally#63930
anonrig wants to merge 1 commit into
nodejs:mainfrom
anonrig:process-wrap-fast-spawn-options

Conversation

@anonrig

@anonrig anonrig commented Jun 15, 2026

Copy link
Copy Markdown
Member

ChildProcess.prototype.spawn() handed a single options object to the
ProcessWrap::Spawn() binding, which then read roughly a dozen properties back
out one at a time with Object::Get(). Each of those is a property lookup
across the JS/C++ boundary on every spawn.

This passes file, args, cwd, envPairs, stdio, uid and gid as
positional arguments, and packs the boolean flags (detached, windowsHide,
windowsVerbatimArguments) into a single integer whose bit values are exported
from the binding as constants (keeping a single source of truth between the JS
and C++ sides). The native side now reads each value directly from the call
arguments instead of looking them up by name.

Scope / expectations

This is a refactor, not a measurable speedup on its own. End-to-end spawn
wall-clock time is dominated by the operating system's process-creation cost, so
spawn throughput is unchanged within noise (verified by an A/B build, see
below). The benefit is reduced per-spawn work on the main thread and a clearer,
narrower contract between the JS and C++ layers — useful groundwork for moving
more of the child_process handling into the native layer.

Verification

  • lib/internal/child_process.js + src/process_wrap.cc build cleanly.
  • test/parallel/test-child-process-* (108 tests), the test/sequential
    child-process tests, and test/parallel/test-cluster-* all pass.
  • cpplint, eslint, and git-clang-format are clean on the changed lines.
  • A/B benchmark (child-process-spawn-options.js, envc=1024 argc=64,
    n=3000): old ≈ 422 spawns/s vs new ≈ 405 spawns/s — i.e. no change beyond
    run-to-run noise, confirming there is no regression.

There is no observable behavior change.

@nodejs-github-bot nodejs-github-bot added c++ Issues and PRs that require attention from people who are familiar with C++. child_process Issues and PRs related to the child_process subsystem. needs-ci PRs that need a full CI run. labels Jun 15, 2026
@anonrig anonrig force-pushed the process-wrap-fast-spawn-options branch from 7b1bdfc to 91a67db Compare June 15, 2026 15:46
ChildProcess.prototype.spawn() handed a single options object to the
ProcessWrap::Spawn() binding, which then read about a dozen properties
back out individually with Object::Get(). Each of those is a property
lookup across the JS/C++ boundary on every spawn.

Pass file, args, cwd, envPairs, stdio, uid and gid as positional
arguments and pack the boolean flags (detached, windowsHide,
windowsVerbatimArguments) into a single integer whose bit values are
exported from the binding as `constants`. The native side then reads
each value directly from the call arguments.

Add internal typings for the process_wrap binding (previously untyped)
describing the new positional spawn() signature and the exported
constants.

There is no observable behavior change. Spawn wall-clock time is
dominated by the operating system process-creation cost and is
unchanged; this reduces the per-spawn work done on the main thread and
clarifies the contract between the JS and C++ layers.

Signed-off-by: Yagiz Nizipli <yagiz@nizipli.com>
@anonrig anonrig force-pushed the process-wrap-fast-spawn-options branch from 91a67db to 883bf77 Compare June 15, 2026 15:47
@anonrig anonrig requested review from jasnell, lemire and mcollina June 15, 2026 16:00

@mcollina mcollina left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

lgtm

@anonrig anonrig added request-ci Add this label to start a Jenkins CI on a PR. commit-queue Add this label to land a pull request using GitHub Actions. labels Jun 15, 2026
@github-actions github-actions Bot removed the request-ci Add this label to start a Jenkins CI on a PR. label Jun 15, 2026
@nodejs-github-bot

Copy link
Copy Markdown
Collaborator

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

c++ Issues and PRs that require attention from people who are familiar with C++. child_process Issues and PRs related to the child_process subsystem. commit-queue Add this label to land a pull request using GitHub Actions. needs-ci PRs that need a full CI run.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants