From 841b758d0d2d7985ce7ae6ecca3b2787527bc207 Mon Sep 17 00:00:00 2001 From: Matt Mastracci Date: Sun, 24 Dec 2023 06:04:32 -0700 Subject: [PATCH] chore: ensure that each op provided to ensureFastOps is only used once (#21689) When we migrate to op-import-per-extension, we will want to ensure that ops have one and only one place where they are imported. This tackles the ops that are imported via `ensureFastOps`, but does not yet tackle direct `ops` imports. Landing ahead of https://github.com/denoland/deno_core/pull/393 --- cli/bench/async_ops_deferred.js | 22 ------------ ext/broadcast_channel/01_broadcast_channel.js | 10 +----- ext/web/02_timers.js | 8 +++++ ext/web/06_streams.js | 1 + ext/web/13_message_port.js | 3 +- ext/websocket/00_ops.js | 35 +++++++++++++++++++ ext/websocket/01_websocket.js | 20 +++++------ ext/websocket/02_websocketstream.js | 18 +++++----- ext/websocket/lib.rs | 2 +- 9 files changed, 67 insertions(+), 52 deletions(-) delete mode 100644 cli/bench/async_ops_deferred.js create mode 100644 ext/websocket/00_ops.js diff --git a/cli/bench/async_ops_deferred.js b/cli/bench/async_ops_deferred.js deleted file mode 100644 index 2751ad2261..0000000000 --- a/cli/bench/async_ops_deferred.js +++ /dev/null @@ -1,22 +0,0 @@ -// Copyright 2018-2023 the Deno authors. All rights reserved. MIT license. -const queueMicrotask = globalThis.queueMicrotask || process.nextTick; -let [total, count] = typeof Deno !== "undefined" - ? Deno.args - : [process.argv[2], process.argv[3]]; - -total = total ? parseInt(total, 0) : 50; -count = count ? parseInt(count, 10) : 1000000; - -async function bench(fun) { - const start = Date.now(); - for (let i = 0; i < count; i++) await fun(); - const elapsed = Date.now() - start; - const rate = Math.floor(count / (elapsed / 1000)); - console.log(`time ${elapsed} ms rate ${rate}`); - if (--total) queueMicrotask(() => bench(fun)); -} - -const core = Deno[Deno.internal].core; -const ops = core.ops; -const opVoidAsyncDeferred = ops.op_void_async_deferred; -bench(() => opVoidAsyncDeferred()); diff --git a/ext/broadcast_channel/01_broadcast_channel.js b/ext/broadcast_channel/01_broadcast_channel.js index 6ee857474a..0e95fe3cd7 100644 --- a/ext/broadcast_channel/01_broadcast_channel.js +++ b/ext/broadcast_channel/01_broadcast_channel.js @@ -12,13 +12,13 @@ import { setIsTrusted, setTarget, } from "ext:deno_web/02_event.js"; +import { defer } from "ext:deno_web/02_timers.js"; import DOMException from "ext:deno_web/01_dom_exception.js"; const { ArrayPrototypeIndexOf, ArrayPrototypePush, ArrayPrototypeSplice, ObjectPrototypeIsPrototypeOf, - PromisePrototypeThen, Symbol, SymbolFor, Uint8Array, @@ -68,14 +68,6 @@ function dispatch(source, name, data) { defer(go); } } - -// Defer to avoid starving the event loop. Not using queueMicrotask() -// for that reason: it lets promises make forward progress but can -// still starve other parts of the event loop. -function defer(go) { - PromisePrototypeThen(core.ops.op_void_async_deferred(), () => go()); -} - class BroadcastChannel extends EventTarget { [_name]; [_closed] = false; diff --git a/ext/web/02_timers.js b/ext/web/02_timers.js index 27a9fcbdef..c7dc90c82c 100644 --- a/ext/web/02_timers.js +++ b/ext/web/02_timers.js @@ -386,9 +386,17 @@ function unrefTimer(id) { core.unrefOpPromise(timerInfo.promise); } +// Defer to avoid starving the event loop. Not using queueMicrotask() +// for that reason: it lets promises make forward progress but can +// still starve other parts of the event loop. +function defer(go) { + PromisePrototypeThen(op_void_async_deferred(), () => go()); +} + export { clearInterval, clearTimeout, + defer, handleTimerMacrotask, opNow, refTimer, diff --git a/ext/web/06_streams.js b/ext/web/06_streams.js index 1df3753282..988f1d990c 100644 --- a/ext/web/06_streams.js +++ b/ext/web/06_streams.js @@ -6895,6 +6895,7 @@ export { errorReadableStream, getReadableStreamResourceBacking, getWritableStreamResourceBacking, + isDetachedBuffer, isReadableStreamDisturbed, ReadableByteStreamController, ReadableStream, diff --git a/ext/web/13_message_port.js b/ext/web/13_message_port.js index c1ba3f4c4b..9645f5f115 100644 --- a/ext/web/13_message_port.js +++ b/ext/web/13_message_port.js @@ -17,6 +17,7 @@ import { setEventTargetData, setIsTrusted, } from "ext:deno_web/02_event.js"; +import { isDetachedBuffer } from "ext:deno_web/06_streams.js"; import DOMException from "ext:deno_web/01_dom_exception.js"; const { ArrayBufferPrototype, @@ -282,7 +283,7 @@ function serializeJsMessageData(data, transferables) { if (ObjectPrototypeIsPrototypeOf(ArrayBufferPrototype, t)) { if ( ArrayBufferPrototypeGetByteLength(t) === 0 && - ops.op_arraybuffer_was_detached(t) + isDetachedBuffer(t) ) { throw new DOMException( `ArrayBuffer at index ${j} is already detached`, diff --git a/ext/websocket/00_ops.js b/ext/websocket/00_ops.js new file mode 100644 index 0000000000..38628f8c3e --- /dev/null +++ b/ext/websocket/00_ops.js @@ -0,0 +1,35 @@ +// Copyright 2018-2023 the Deno authors. All rights reserved. MIT license. +import { core } from "ext:core/mod.js"; +const { + op_ws_create, + op_ws_close, + op_ws_send_binary, + op_ws_send_binary_ab, + op_ws_send_text, + op_ws_next_event, + op_ws_get_buffer, + op_ws_get_buffer_as_string, + op_ws_get_error, + op_ws_send_ping, + op_ws_get_buffered_amount, + op_ws_send_text_async, + op_ws_send_binary_async, + op_ws_check_permission_and_cancel_handle, +} = core.ensureFastOps(); + +export { + op_ws_check_permission_and_cancel_handle, + op_ws_close, + op_ws_create, + op_ws_get_buffer, + op_ws_get_buffer_as_string, + op_ws_get_buffered_amount, + op_ws_get_error, + op_ws_next_event, + op_ws_send_binary, + op_ws_send_binary_ab, + op_ws_send_binary_async, + op_ws_send_ping, + op_ws_send_text, + op_ws_send_text_async, +}; diff --git a/ext/websocket/01_websocket.js b/ext/websocket/01_websocket.js index 2aea080716..e2ff26c6cd 100644 --- a/ext/websocket/01_websocket.js +++ b/ext/websocket/01_websocket.js @@ -44,20 +44,20 @@ const { SymbolFor, TypedArrayPrototypeGetByteLength, } = primordials; -const { op_ws_check_permission_and_cancel_handle } = core.ops; -const { - op_ws_create, +import { + op_ws_check_permission_and_cancel_handle, op_ws_close, - op_ws_send_binary, - op_ws_send_binary_ab, - op_ws_send_text, - op_ws_next_event, + op_ws_create, op_ws_get_buffer, op_ws_get_buffer_as_string, - op_ws_get_error, - op_ws_send_ping, op_ws_get_buffered_amount, -} = core.ensureFastOps(); + op_ws_get_error, + op_ws_next_event, + op_ws_send_binary, + op_ws_send_binary_ab, + op_ws_send_ping, + op_ws_send_text, +} from "ext:deno_websocket/00_ops.js"; webidl.converters["sequence or DOMString"] = ( V, diff --git a/ext/websocket/02_websocketstream.js b/ext/websocket/02_websocketstream.js index 16346e73b8..62124bd451 100644 --- a/ext/websocket/02_websocketstream.js +++ b/ext/websocket/02_websocketstream.js @@ -3,7 +3,6 @@ /// import { core, primordials } from "ext:core/mod.js"; -const ops = core.ops; import * as webidl from "ext:deno_webidl/00_webidl.js"; import { createFilteredInspectProxy } from "ext:deno_console/01_console.js"; import { Deferred, writableStreamClose } from "ext:deno_web/06_streams.js"; @@ -32,16 +31,17 @@ const { TypedArrayPrototypeGetByteLength, Uint8ArrayPrototype, } = primordials; -const { - op_ws_send_text_async, - op_ws_send_binary_async, - op_ws_next_event, +import { + op_ws_check_permission_and_cancel_handle, + op_ws_close, + op_ws_create, op_ws_get_buffer, op_ws_get_buffer_as_string, op_ws_get_error, - op_ws_create, - op_ws_close, -} = core.ensureFastOps(); + op_ws_next_event, + op_ws_send_binary_async, + op_ws_send_text_async, +} from "ext:deno_websocket/00_ops.js"; webidl.converters.WebSocketStreamOptions = webidl.createDictionaryConverter( "WebSocketStreamOptions", @@ -146,7 +146,7 @@ class WebSocketStream { fillHeaders(headers, options.headers); } - const cancelRid = ops.op_ws_check_permission_and_cancel_handle( + const cancelRid = op_ws_check_permission_and_cancel_handle( "WebSocketStream.abort()", this[_url], true, diff --git a/ext/websocket/lib.rs b/ext/websocket/lib.rs index c8e0921c9f..d25f7ecbdd 100644 --- a/ext/websocket/lib.rs +++ b/ext/websocket/lib.rs @@ -843,7 +843,7 @@ deno_core::extension!(deno_websocket, op_ws_send_pong, op_ws_get_buffered_amount, ], - esm = [ "01_websocket.js", "02_websocketstream.js" ], + esm = [ "00_ops.js", "01_websocket.js", "02_websocketstream.js" ], options = { user_agent: String, root_cert_store_provider: Option>,