From 0bbdbace02d8b17a02bd3c631b82f508d0effa4a Mon Sep 17 00:00:00 2001 From: Matt Mastracci Date: Tue, 6 Jun 2023 03:01:28 -0600 Subject: [PATCH] refactor(core): ensureFastOps is an op-generating proxy (#19377) Startup benchmark shows no changes (within 1ms, identical system/user times). --- core/01_core.js | 41 ++++++++----------- .../http_bench_json_ops.js | 5 +-- core/runtime.rs | 4 +- ext/fs/30_fs.js | 8 +--- ext/http/00_serve.js | 20 +-------- ext/http/01_http.js | 2 +- ext/node/polyfills/internal/crypto/random.ts | 6 +-- ext/web/02_timers.js | 5 +-- ext/websocket/01_websocket.js | 9 +--- ext/websocket/02_websocketstream.js | 8 +--- 10 files changed, 26 insertions(+), 82 deletions(-) diff --git a/core/01_core.js b/core/01_core.js index c3033fcf9a..13aa17c7ed 100644 --- a/core/01_core.js +++ b/core/01_core.js @@ -22,6 +22,7 @@ PromiseReject, PromiseResolve, PromisePrototypeThen, + Proxy, RangeError, ReferenceError, ReflectHas, @@ -762,19 +763,19 @@ for (let i = 0; i < 10; i++) { setUpAsyncStub(opName); } - function generateAsyncOpHandler(/* opNames... */) { - const fastOps = {}; - for (const opName of new SafeArrayIterator(arguments)) { - if (ops[opName] === undefined) { - throw new Error(`Unknown or disabled op '${opName}'`); - } - if (asyncOps[opName] !== undefined) { - fastOps[opName] = setUpAsyncStub(opName); - } else { - fastOps[opName] = ops[opName]; - } - } - return fastOps; + function ensureFastOps() { + return new Proxy({}, { + get(_target, opName) { + if (ops[opName] === undefined) { + throw new Error(`Unknown or disabled op '${opName}'`); + } + if (asyncOps[opName] !== undefined) { + return setUpAsyncStub(opName); + } else { + return ops[opName]; + } + }, + }); } const { @@ -787,22 +788,12 @@ for (let i = 0; i < 10; i++) { op_read_sync: readSync, op_write_sync: writeSync, op_shutdown: shutdown, - } = generateAsyncOpHandler( - "op_close", - "op_try_close", - "op_read", - "op_read_all", - "op_write", - "op_write_all", - "op_read_sync", - "op_write_sync", - "op_shutdown", - ); + } = ensureFastOps(); // Extra Deno.core.* exports const core = ObjectAssign(globalThis.Deno.core, { asyncStub, - generateAsyncOpHandler, + ensureFastOps, opAsync, resources, metrics, diff --git a/core/examples/http_bench_json_ops/http_bench_json_ops.js b/core/examples/http_bench_json_ops/http_bench_json_ops.js index 6cf2a8be24..a840e4e9f9 100644 --- a/core/examples/http_bench_json_ops/http_bench_json_ops.js +++ b/core/examples/http_bench_json_ops/http_bench_json_ops.js @@ -9,10 +9,7 @@ const { op_listen } = Deno.core.ops; const { op_accept, op_read_socket, -} = Deno.core.generateAsyncOpHandler( - "op_accept", - "op_read_socket", -); +} = Deno.core.ensureFastOps(); const requestBuf = new Uint8Array(64 * 1024); const responseBuf = new Uint8Array( diff --git a/core/runtime.rs b/core/runtime.rs index fdcb81e9e2..a27717a8b4 100644 --- a/core/runtime.rs +++ b/core/runtime.rs @@ -2852,7 +2852,7 @@ pub mod tests { .execute_script_static( "filename.js", r#" - const { op_test } = Deno.core.generateAsyncOpHandler("op_test"); + const { op_test } = Deno.core.ensureFastOps(); let zero_copy_a = new Uint8Array([0]); op_test(null, zero_copy_a); "#, @@ -4942,7 +4942,7 @@ Deno.core.opAsync("op_async_serialize_object_with_numbers_as_keys", { throw new Error(); } - const { op_test_async } = Deno.core.generateAsyncOpHandler("op_test_async"); + const { op_test_async } = Deno.core.ensureFastOps(); if (op_test_async.name !== "op_test_async") { throw new Error(); } diff --git a/ext/fs/30_fs.js b/ext/fs/30_fs.js index f14fcd5d1b..f7c07f26a7 100644 --- a/ext/fs/30_fs.js +++ b/ext/fs/30_fs.js @@ -10,13 +10,7 @@ const { op_fs_truncate_async, op_fs_link_async, op_fs_flock_async, -} = Deno.core.generateAsyncOpHandler( - "op_fs_chmod_async", - "op_fs_ftruncate_async", - "op_fs_truncate_async", - "op_fs_link_async", - "op_fs_flock_async", -); +} = Deno.core.ensureFastOps(); const primordials = globalThis.__bootstrap.primordials; const { ArrayPrototypeFilter, diff --git a/ext/http/00_serve.js b/ext/http/00_serve.js index ba8080e27b..fa55079e77 100644 --- a/ext/http/00_serve.js +++ b/ext/http/00_serve.js @@ -70,25 +70,7 @@ const { op_http_upgrade_websocket_next, op_http_try_wait, op_http_wait, -} = core.generateAsyncOpHandler( - "op_http_get_request_headers", - "op_http_get_request_method_and_url", - "op_http_read_request_body", - "op_http_serve", - "op_http_serve_on", - "op_http_set_promise_complete", - "op_http_set_response_body_bytes", - "op_http_set_response_body_resource", - "op_http_set_response_body_stream", - "op_http_set_response_body_text", - "op_http_set_response_header", - "op_http_set_response_headers", - "op_http_set_response_trailers", - "op_http_upgrade_raw", - "op_http_upgrade_websocket_next", - "op_http_try_wait", - "op_http_wait", -); +} = core.ensureFastOps(); const _upgraded = Symbol("_upgraded"); function internalServerError() { diff --git a/ext/http/01_http.js b/ext/http/01_http.js index 92fd8e2858..f9a8d2cdbc 100644 --- a/ext/http/01_http.js +++ b/ext/http/01_http.js @@ -6,7 +6,7 @@ const core = globalThis.Deno.core; const internals = globalThis.__bootstrap.internals; const primordials = globalThis.__bootstrap.primordials; const { BadResourcePrototype, InterruptedPrototype, ops } = core; -const { op_http_write } = Deno.core.generateAsyncOpHandler("op_http_write"); +const { op_http_write } = Deno.core.ensureFastOps(); import * as webidl from "ext:deno_webidl/00_webidl.js"; import { InnerBody } from "ext:deno_fetch/22_body.js"; import { Event, setEventTargetData } from "ext:deno_web/02_event.js"; diff --git a/ext/node/polyfills/internal/crypto/random.ts b/ext/node/polyfills/internal/crypto/random.ts index 4890e158ad..9156ab4e1a 100644 --- a/ext/node/polyfills/internal/crypto/random.ts +++ b/ext/node/polyfills/internal/crypto/random.ts @@ -37,11 +37,7 @@ const { op_node_gen_prime_async, op_node_check_prime_bytes_async, op_node_check_prime_async, -} = Deno.core.generateAsyncOpHandler( - "op_node_gen_prime_async", - "op_node_check_prime_bytes_async", - "op_node_check_prime_async", -); +} = Deno.core.ensureFastOps(); export type LargeNumberLike = | ArrayBufferView diff --git a/ext/web/02_timers.js b/ext/web/02_timers.js index 7603f67668..19ebfaa0e4 100644 --- a/ext/web/02_timers.js +++ b/ext/web/02_timers.js @@ -27,10 +27,7 @@ const { import * as webidl from "ext:deno_webidl/00_webidl.js"; import { reportException } from "ext:deno_web/02_event.js"; import { assert } from "ext:deno_web/00_infra.js"; -const { op_sleep, op_void_async_deferred } = core.generateAsyncOpHandler( - "op_sleep", - "op_void_async_deferred", -); +const { op_sleep, op_void_async_deferred } = core.ensureFastOps(); const hrU8 = new Uint8Array(8); const hr = new Uint32Array(TypedArrayPrototypeGetBuffer(hrU8)); diff --git a/ext/websocket/01_websocket.js b/ext/websocket/01_websocket.js index e71cae44a8..01dd265792 100644 --- a/ext/websocket/01_websocket.js +++ b/ext/websocket/01_websocket.js @@ -57,14 +57,7 @@ const { op_ws_send_text, op_ws_next_event, op_ws_send_ping, -} = core.generateAsyncOpHandler( - "op_ws_create", - "op_ws_close", - "op_ws_send_binary", - "op_ws_send_text", - "op_ws_next_event", - "op_ws_send_ping", -); +} = core.ensureFastOps(); webidl.converters["sequence or DOMString"] = ( V, diff --git a/ext/websocket/02_websocketstream.js b/ext/websocket/02_websocketstream.js index 2c5df262ac..00d5bdaecf 100644 --- a/ext/websocket/02_websocketstream.js +++ b/ext/websocket/02_websocketstream.js @@ -39,13 +39,7 @@ const { op_ws_next_event, op_ws_create, op_ws_close, -} = core.generateAsyncOpHandler( - "op_ws_send_text", - "op_ws_send_binary", - "op_ws_next_event", - "op_ws_create", - "op_ws_close", -); +} = core.ensureFastOps(); webidl.converters.WebSocketStreamOptions = webidl.createDictionaryConverter( "WebSocketStreamOptions",