From 94c3bdb483095967c64debe73667958d2a5a8e37 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bartek=20Iwa=C5=84czuk?= Date: Tue, 24 Sep 2019 18:14:12 +0200 Subject: [PATCH] Deno.core.getOps() --- core/examples/http_bench.js | 50 ++++++++++++++++---- core/shared_queue.js | 73 ++++++------------------------ deno_typescript/lib.deno_core.d.ts | 3 +- 3 files changed, 55 insertions(+), 71 deletions(-) diff --git a/core/examples/http_bench.js b/core/examples/http_bench.js index 06f74f241d3c9f..b8d6faef5e2d56 100644 --- a/core/examples/http_bench.js +++ b/core/examples/http_bench.js @@ -1,20 +1,47 @@ // This is not a real HTTP server. We read blindly one time into 'requestBuf', // then write this fixed 'responseBuf'. The point of this benchmark is to // exercise the event loop in a simple yet semi-realistic way. -class HttpOp extends Deno.core.Op { +const registry = {}; + +function initOps(opsMap) { + for (const [name, opId] of Object.entries(opsMap)) { + const op = registry[name]; + + if (!op) { + continue; + } + + op.setOpId(opId); + } +} + +class Op { + constructor(name) { + if (typeof registry[name] !== "undefined") { + throw new Error(`Duplicate op: ${name}`); + } + + this.name = name; + this.opId = 0; + registry[name] = this; + } + + setOpId(opId) { + this.opId = opId; + } + static handleAsyncMsgFromRust(opId, buf) { const record = recordFromBuf(buf); - const { promiseId, result } = record; + const { promiseId } = record; const p = promiseMap.get(promiseId); promiseMap.delete(promiseId); - p.resolve(result); + p.resolve(record); } /** Returns i32 number */ static sendSync(opId, arg, zeroCopy) { const buf = send(0, opId, arg, zeroCopy); - const record = recordFromBuf(buf); - return record.result; + return recordFromBuf(buf); } /** Returns Promise */ @@ -25,13 +52,17 @@ class HttpOp extends Deno.core.Op { send(promiseId, opId, arg, zeroCopy); return p; } +} +class HttpOp extends Op { sendSync(arg, zeroCopy = null) { - return HttpOp.sendSync(this.opId, arg, zeroCopy); + const res = HttpOp.sendSync(this.opId, arg, zeroCopy); + return res.result; } - sendAsync(arg, zeroCopy = null) { - return HttpOp.sendAsync(this.opId, arg, zeroCopy); + async sendAsync(arg, zeroCopy = null) { + const res = await HttpOp.sendAsync(this.opId, arg, zeroCopy); + return res.result; } } @@ -132,7 +163,8 @@ async function serve(rid) { } async function main() { - Deno.core.initOps(); + Deno.core.setAsyncHandler(Op.handleAsyncMsgFromRust); + initOps(Deno.core.getOps()); Deno.core.print("http_bench.js start\n"); const listenerRid = listen(); diff --git a/core/shared_queue.js b/core/shared_queue.js index e3c7f39995ddff..4aa1b11a9dd337 100644 --- a/core/shared_queue.js +++ b/core/shared_queue.js @@ -38,9 +38,6 @@ SharedQueue Binary Layout let sharedBytes; let shared32; - let rustOpsMap; - const jsOpsMap = new Map(); - let jsOpsAsyncHandlers; let initialized = false; function maybeInit() { @@ -61,24 +58,10 @@ SharedQueue Binary Layout Deno.core.recv(handleAsyncMsgFromRust); } - function initOps() { + function getOps() { const opsMapBytes = Deno.core.send(0, new Uint8Array([]), null); const opsMapJson = String.fromCharCode.apply(null, opsMapBytes); - rustOpsMap = JSON.parse(opsMapJson); - const opVector = new Array(Object.keys(rustOpsMap).length); - - for (const [name, opId] of Object.entries(rustOpsMap)) { - const op = jsOpsMap.get(name); - - if (!op) { - continue; - } - - op.setOpId(opId); - opVector[opId] = op.constructor.handleAsyncMsgFromRust; - } - - jsOpsAsyncHandlers = opVector; + return JSON.parse(opsMapJson); } function assert(cond) { @@ -107,17 +90,18 @@ SharedQueue Binary Layout return shared32[INDEX_NUM_RECORDS] - shared32[INDEX_NUM_SHIFTED_OFF]; } - // TODO(ry) rename to setMeta - function setMeta(index, end, opId) { + function setMeta(index, end, opId, promiseId) { shared32[INDEX_OFFSETS + 2 * index] = end; shared32[INDEX_OFFSETS + 2 * index + 1] = opId; + shared32[INDEX_OFFSETS + 2 * index + 2] = promiseId; } function getMeta(index) { if (index < numRecords()) { const buf = shared32[INDEX_OFFSETS + 2 * index]; const opId = shared32[INDEX_OFFSETS + 2 * index + 1]; - return [opId, buf]; + const promiseId = shared32[INDEX_OFFSETS + 2 * index + 2]; + return [opId, promiseId, buf]; } else { return null; } @@ -135,7 +119,7 @@ SharedQueue Binary Layout } } - function push(opId, buf) { + function push(opId, promiseId, buf) { const off = head(); const end = off + buf.byteLength; const index = numRecords(); @@ -143,7 +127,7 @@ SharedQueue Binary Layout // console.log("shared_queue.js push fail"); return false; } - setMeta(index, end, opId); + setMeta(index, end, opId, promiseId); assert(end - off == buf.byteLength); sharedBytes.set(buf, off); shared32[INDEX_NUM_RECORDS] += 1; @@ -160,7 +144,7 @@ SharedQueue Binary Layout } const off = getOffset(i); - const [opId, end] = getMeta(i); + const [opId, promiseId, end] = getMeta(i); if (size() > 1) { shared32[INDEX_NUM_SHIFTED_OFF] += 1; @@ -171,7 +155,7 @@ SharedQueue Binary Layout assert(off != null); assert(end != null); const buf = sharedBytes.subarray(off, end); - return [opId, buf]; + return [opId, promiseId, buf]; } let asyncHandler; @@ -184,16 +168,14 @@ SharedQueue Binary Layout function handleAsyncMsgFromRust(opId, buf) { if (buf) { // This is the overflow_response case of deno::Isolate::poll(). - const cb = asyncHandler ? asyncHandler : jsOpsAsyncHandlers[opId]; - cb(opId, buf); + asyncHandler(opId, buf); } else { while (true) { const opIdBuf = shift(); if (opIdBuf == null) { break; } - const cb = asyncHandler ? asyncHandler : jsOpsAsyncHandlers[opIdBuf[0]]; - cb(...opIdBuf); + asyncHandler(opId, buf); } } } @@ -203,34 +185,6 @@ SharedQueue Binary Layout return Deno.core.send(opId, control, zeroCopy); } - class Op { - constructor(name) { - if (typeof jsOpsMap.get(name) !== "undefined") { - throw new Error(`Duplicate op: ${name}`); - } - - this.name = name; - this.opId = 0; - jsOpsMap.set(name, this); - } - - setOpId(opId) { - this.opId = opId; - } - - static handleAsyncMsgFromRust(_opId, _buf) { - throw new Error("Unimplemented"); - } - - static sendSync(_opId, _control, _zeroCopy = null) { - throw new Error("Unimplemented"); - } - - static sendAsync(_opId, _control, _zeroCopy = null) { - throw new Error("Unimplemented"); - } - } - const denoCore = { setAsyncHandler, dispatch, @@ -243,8 +197,7 @@ SharedQueue Binary Layout reset, shift }, - initOps, - Op + getOps }; assert(window[GLOBAL_NAMESPACE] != null); diff --git a/deno_typescript/lib.deno_core.d.ts b/deno_typescript/lib.deno_core.d.ts index 1961f385e212fd..d8f2b5f044880b 100644 --- a/deno_typescript/lib.deno_core.d.ts +++ b/deno_typescript/lib.deno_core.d.ts @@ -58,8 +58,7 @@ declare interface DenoCore { shift(): Uint8Array | null; }; - Op: typeof Op; - initOps(): void; + getOps(): Record; recv(cb: MessageCallback): void;