summaryrefslogtreecommitdiff
path: root/core/01_core.js
diff options
context:
space:
mode:
authorDivy Srivastava <dj.srivastava23@gmail.com>2022-10-28 04:20:17 -0700
committerGitHub <noreply@github.com>2022-10-28 16:50:17 +0530
commite18950284f279cfa8ec090cb8a882dbd64e92d4a (patch)
tree2ba6be798fe8d2393f7701693c1c545a237a2575 /core/01_core.js
parentd9e425a9472981e8a1df025c29bbad609123e783 (diff)
Reland "perf(core): generate inlined wrappers for async ops" (#16455)
Reland https://github.com/denoland/deno/pull/16428
Diffstat (limited to 'core/01_core.js')
-rw-r--r--core/01_core.js88
1 files changed, 66 insertions, 22 deletions
diff --git a/core/01_core.js b/core/01_core.js
index 7bee019d9..5df11c382 100644
--- a/core/01_core.js
+++ b/core/01_core.js
@@ -28,7 +28,7 @@
SymbolFor,
setQueueMicrotask,
} = window.__bootstrap.primordials;
- const ops = window.Deno.core.ops;
+ const { ops } = window.Deno.core;
const errorMap = {};
// Builtin v8 / JS errors
@@ -159,21 +159,63 @@
return res;
}
- function opAsync(opName, ...args) {
- const promiseId = nextPromiseId++;
- let p = setPromise(promiseId);
- try {
- ops[opName](promiseId, ...args);
- } catch (err) {
- // Cleanup the just-created promise
- getPromise(promiseId);
- // Rethrow the error
- throw err;
+ function rollPromiseId() {
+ return nextPromiseId++;
+ }
+
+ // Generate async op wrappers. See core/bindings.rs
+ function initializeAsyncOps() {
+ function genAsyncOp(op, name, args) {
+ return new Function(
+ "setPromise",
+ "getPromise",
+ "promiseIdSymbol",
+ "rollPromiseId",
+ "handleOpCallTracing",
+ "op",
+ "unwrapOpResult",
+ "PromisePrototypeThen",
+ `
+ return function ${name}(${args}) {
+ const id = rollPromiseId();
+ let promise = PromisePrototypeThen(setPromise(id), unwrapOpResult);
+ try {
+ op(id, ${args});
+ } catch (err) {
+ // Cleanup the just-created promise
+ getPromise(id);
+ // Rethrow the error
+ throw err;
+ }
+ handleOpCallTracing("${name}", id, promise);
+ promise[promiseIdSymbol] = id;
+ return promise;
+ }
+ `,
+ )(
+ setPromise,
+ getPromise,
+ promiseIdSymbol,
+ rollPromiseId,
+ handleOpCallTracing,
+ op,
+ unwrapOpResult,
+ PromisePrototypeThen,
+ );
}
- p = PromisePrototypeThen(p, unwrapOpResult);
+
+ // { <name>: <argc>, ... }
+ for (const ele of Object.entries(ops.asyncOpsInfo())) {
+ if (!ele) continue;
+ const [name, argc] = ele;
+ const op = ops[name];
+ const args = Array.from({ length: argc }, (_, i) => `arg${i}`).join(", ");
+ ops[name] = genAsyncOp(op, name, args);
+ }
+ }
+
+ function handleOpCallTracing(opName, promiseId, p) {
if (opCallTracingEnabled) {
- // Capture a stack trace by creating a new `Error` object. We remove the
- // first 6 characters (the `Error\n` prefix) to get just the stack trace.
const stack = StringPrototypeSlice(new Error().stack, 6);
MapPrototypeSet(opCallTraces, promiseId, { opName, stack });
p = PromisePrototypeFinally(
@@ -181,9 +223,10 @@
() => MapPrototypeDelete(opCallTraces, promiseId),
);
}
- // Save the id on the promise so it can later be ref'ed or unref'ed
- p[promiseIdSymbol] = promiseId;
- return p;
+ }
+
+ function opAsync(opName, ...args) {
+ return ops[opName](...args);
}
function refOp(promiseId) {
@@ -303,6 +346,7 @@
// Extra Deno.core.* exports
const core = ObjectAssign(globalThis.Deno.core, {
opAsync,
+ initializeAsyncOps,
resources,
metrics,
registerErrorBuilder,
@@ -322,11 +366,11 @@
setPromiseHooks,
close: (rid) => ops.op_close(rid),
tryClose: (rid) => ops.op_try_close(rid),
- read: opAsync.bind(null, "op_read"),
- readAll: opAsync.bind(null, "op_read_all"),
- write: opAsync.bind(null, "op_write"),
- writeAll: opAsync.bind(null, "op_write_all"),
- shutdown: opAsync.bind(null, "op_shutdown"),
+ read: (rid, buffer) => ops.op_read(rid, buffer),
+ readAll: (rid) => ops.op_read_all(rid),
+ write: (rid, buffer) => ops.op_write(rid, buffer),
+ writeAll: (rid, buffer) => ops.op_write_all(rid, buffer),
+ shutdown: (rid) => ops.op_shutdown(rid),
print: (msg, isErr) => ops.op_print(msg, isErr),
setMacrotaskCallback: (fn) => ops.op_set_macrotask_callback(fn),
setNextTickCallback: (fn) => ops.op_set_next_tick_callback(fn),