worker_threads: don't build fd stdio or reify all of process at worker startup
What does this PR do?
Since #31216 every node:worker_threads Worker runs a bootstrap on the worker thread that rebinds process.stdout/stderr/stdin to port-backed streams. Two things in it were pure waste, paid per worker:
- It used
Object.defineProperty(process, "stdout", { value }), which first builds the real fd-backed stream (loadsnode:fs,internal/fs/streams, …) and then throws it away — for all three streams. - It
deleted four main-thread-onlyprocessstubs. Deleting any static-table property reifies the whole table, which builds the nextTick queue and every other lazyprocessproperty.
Now the parent's stdio ports are registered on the worker's global and the existing lazy process.std* getters build the port-backed streams directly; the four stubs are just not installed on a worker's process; and node:worker_threads is loaded by a native hook before preloads/entry instead of being injected as an ESM preload. Semantics are unchanged (stdio and console are still set up eagerly, as in Node).
new Worker() → first message, Linux x64, CI release artifacts on the same machine: main 15.9 ms → 10.2 ms (min), 18.4 → 11.8 ms (median).
Split out of #39528; process.moduleLoadList is now its own PR.
How did you verify your code works?
test/js/node/worker_threads/*.test.ts, test/js/web/workers/worker.test.ts and the node test-worker-*.js files match main on a release build; drove captured / auto-piped stdout (incl. process.exit() flush), stdin: true and parentPort echo on the debug build with BUN_JSC_validateExceptionChecks=1.