diff options
author | Anatoli Papirovski <apapirovski@mac.com> | 2018-01-24 23:25:20 -0500 |
---|---|---|
committer | Anatoli Papirovski <apapirovski@mac.com> | 2018-01-29 11:51:01 -0500 |
commit | bb27bfe1e1697df5f0bc35289ecc39463a02a63d (patch) | |
tree | 172834824035a4150200358debb3b106d4ec59d1 /lib | |
parent | eeede3b19c8bdb78605764eec75bea327c9014ff (diff) | |
download | android-node-v8-bb27bfe1e1697df5f0bc35289ecc39463a02a63d.tar.gz android-node-v8-bb27bfe1e1697df5f0bc35289ecc39463a02a63d.tar.bz2 android-node-v8-bb27bfe1e1697df5f0bc35289ecc39463a02a63d.zip |
process: JS fast path for bindings
Currently, both process.binding and internalBinding have to call into
C++ regardless of whether the module has been cached or not. This
creates significant overhead to all binding calls and unfortunately
the rest of the codebase doesn't really optimize the amount of times
that bindings are required (as an example: 12 files require the
async_wrap binding).
Changing all the usage of this function throughout the codebase would
introduce a lot of churn (and is kind of a hassle) so instead this PR
introduces a JS fast path for both functions for cases where the
binding has already been cached. While micro benchmarks are not super
meaningful here (it's not like we call binding that often...), this
does speed up the cached call by 400%.
In addition, move moduleLoadList creation and management entirely into
JS-land as it requires less code and is more efficient.
PR-URL: https://github.com/nodejs/node/pull/18365
Reviewed-By: Tiancheng "Timothy" Gu <timothygu99@gmail.com>
Reviewed-By: Ben Noordhuis <info@bnoordhuis.nl>
Reviewed-By: Joyee Cheung <joyeec9h3@gmail.com>
Reviewed-By: Anna Henningsen <anna@addaleax.net>
Reviewed-By: James M Snell <jasnell@gmail.com>
Reviewed-By: Jeremiah Senkpiel <fishrock123@rocketmail.com>
Diffstat (limited to 'lib')
-rw-r--r-- | lib/internal/bootstrap_node.js | 53 |
1 files changed, 49 insertions, 4 deletions
diff --git a/lib/internal/bootstrap_node.js b/lib/internal/bootstrap_node.js index b11f5901a1..f3f3264f35 100644 --- a/lib/internal/bootstrap_node.js +++ b/lib/internal/bootstrap_node.js @@ -21,9 +21,6 @@ setupProcessObject(); - internalBinding = process._internalBinding; - delete process._internalBinding; - // do this good and early, since it handles errors. setupProcessFatal(); @@ -246,6 +243,54 @@ perf.markMilestone(NODE_PERFORMANCE_MILESTONE_BOOTSTRAP_COMPLETE); } + const moduleLoadList = []; + Object.defineProperty(process, 'moduleLoadList', { + value: moduleLoadList, + configurable: true, + enumerable: true, + writable: false + }); + + { + const bindingObj = Object.create(null); + + const getBinding = process.binding; + process.binding = function binding(module) { + module = String(module); + let mod = bindingObj[module]; + if (typeof mod !== 'object') { + mod = bindingObj[module] = getBinding(module); + moduleLoadList.push(`Binding ${module}`); + } + return mod; + }; + + const getLinkedBinding = process._linkedBinding; + process._linkedBinding = function _linkedBinding(module) { + module = String(module); + let mod = bindingObj[module]; + if (typeof mod !== 'object') + mod = bindingObj[module] = getLinkedBinding(module); + return mod; + }; + } + + { + const bindingObj = Object.create(null); + + const getInternalBinding = process._internalBinding; + delete process._internalBinding; + + internalBinding = function internalBinding(module) { + let mod = bindingObj[module]; + if (typeof mod !== 'object') { + mod = bindingObj[module] = getInternalBinding(module); + moduleLoadList.push(`Internal Binding ${module}`); + } + return mod; + }; + } + function setupProcessObject() { process._setupProcessObject(pushValueToArray); @@ -550,7 +595,7 @@ throw err; } - process.moduleLoadList.push(`NativeModule ${id}`); + moduleLoadList.push(`NativeModule ${id}`); const nativeModule = new NativeModule(id); |