summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--benchmark/process/queue-microtask-breadth.js21
-rw-r--r--benchmark/process/queue-microtask-depth.js17
-rw-r--r--lib/internal/process/task_queues.js36
3 files changed, 59 insertions, 15 deletions
diff --git a/benchmark/process/queue-microtask-breadth.js b/benchmark/process/queue-microtask-breadth.js
new file mode 100644
index 0000000000..8bb33f6fde
--- /dev/null
+++ b/benchmark/process/queue-microtask-breadth.js
@@ -0,0 +1,21 @@
+'use strict';
+
+const common = require('../common.js');
+const bench = common.createBenchmark(main, {
+ n: [4e5]
+});
+
+function main({ n }) {
+ var j = 0;
+
+ function cb() {
+ j++;
+ if (j === n)
+ bench.end(n);
+ }
+
+ bench.start();
+ for (var i = 0; i < n; i++) {
+ queueMicrotask(cb);
+ }
+}
diff --git a/benchmark/process/queue-microtask-depth.js b/benchmark/process/queue-microtask-depth.js
new file mode 100644
index 0000000000..407feb1b32
--- /dev/null
+++ b/benchmark/process/queue-microtask-depth.js
@@ -0,0 +1,17 @@
+'use strict';
+const common = require('../common.js');
+const bench = common.createBenchmark(main, {
+ n: [12e5]
+});
+
+function main({ n }) {
+ let counter = n;
+ bench.start();
+ queueMicrotask(onNextTick);
+ function onNextTick() {
+ if (--counter)
+ queueMicrotask(onNextTick);
+ else
+ bench.end(n);
+ }
+}
diff --git a/lib/internal/process/task_queues.js b/lib/internal/process/task_queues.js
index 65ac093802..5f5ca5a008 100644
--- a/lib/internal/process/task_queues.js
+++ b/lib/internal/process/task_queues.js
@@ -37,6 +37,8 @@ const {
} = require('internal/errors').codes;
const FixedQueue = require('internal/fixed_queue');
+const FunctionBind = Function.call.bind(Function.prototype.bind);
+
// *Must* match Environment::TickInfo::Fields in src/env.h.
const kHasTickScheduled = 0;
@@ -149,28 +151,32 @@ function createMicrotaskResource() {
});
}
+function runMicrotask() {
+ this.runInAsyncScope(() => {
+ const callback = this.callback;
+ try {
+ callback();
+ } catch (error) {
+ // TODO(devsnek) remove this if
+ // https://bugs.chromium.org/p/v8/issues/detail?id=8326
+ // is resolved such that V8 triggers the fatal exception
+ // handler for microtasks
+ triggerFatalException(error);
+ } finally {
+ this.emitDestroy();
+ }
+ });
+}
+
function queueMicrotask(callback) {
if (typeof callback !== 'function') {
throw new ERR_INVALID_ARG_TYPE('callback', 'function', callback);
}
const asyncResource = createMicrotaskResource();
+ asyncResource.callback = callback;
- enqueueMicrotask(() => {
- asyncResource.runInAsyncScope(() => {
- try {
- callback();
- } catch (error) {
- // TODO(devsnek) remove this if
- // https://bugs.chromium.org/p/v8/issues/detail?id=8326
- // is resolved such that V8 triggers the fatal exception
- // handler for microtasks
- triggerFatalException(error);
- } finally {
- asyncResource.emitDestroy();
- }
- });
- });
+ enqueueMicrotask(FunctionBind(runMicrotask, asyncResource));
}
module.exports = {