summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--core/core.js56
1 files changed, 44 insertions, 12 deletions
diff --git a/core/core.js b/core/core.js
index 40a8270e3..3ec5c3e41 100644
--- a/core/core.js
+++ b/core/core.js
@@ -9,12 +9,53 @@
let opsCache = {};
const errorMap = {};
let nextPromiseId = 1;
- const promiseTable = new Map();
+ const promiseMap = new Map();
+ const RING_SIZE = 4 * 1024;
+ const NO_PROMISE = null; // Alias to null is faster than plain nulls
+ const promiseRing = new Array(RING_SIZE).fill(NO_PROMISE);
function init() {
recv(handleAsyncMsgFromRust);
}
+ function setPromise(promiseId) {
+ const idx = promiseId % RING_SIZE;
+ // Move old promise from ring to map
+ const oldPromise = promiseRing[idx];
+ if (oldPromise !== NO_PROMISE) {
+ const oldPromiseId = promiseId - RING_SIZE;
+ promiseMap.set(oldPromiseId, oldPromise);
+ }
+ // Set new promise
+ return promiseRing[idx] = newPromise();
+ }
+
+ function getPromise(promiseId) {
+ // Check if out of ring bounds, fallback to map
+ const outOfBounds = promiseId < nextPromiseId - RING_SIZE;
+ if (outOfBounds) {
+ const promise = promiseMap.get(promiseId);
+ promiseMap.delete(promiseId);
+ return promise;
+ }
+ // Otherwise take from ring
+ const idx = promiseId % RING_SIZE;
+ const promise = promiseRing[idx];
+ promiseRing[idx] = NO_PROMISE;
+ return promise;
+ }
+
+ function newPromise() {
+ let resolve, reject;
+ const promise = new Promise((resolve_, reject_) => {
+ resolve = resolve_;
+ reject = reject_;
+ });
+ promise.resolve = resolve;
+ promise.reject = reject;
+ return promise;
+ }
+
function ops() {
// op id 0 is a special value to retrieve the map of registered ops.
const newOpsCache = Object.fromEntries(send(0));
@@ -71,15 +112,7 @@
const maybeError = dispatch(opName, promiseId, args, zeroCopy);
// Handle sync error (e.g: error parsing args)
if (maybeError) processResponse(maybeError);
- let resolve, reject;
- const promise = new Promise((resolve_, reject_) => {
- resolve = resolve_;
- reject = reject_;
- });
- promise.resolve = resolve;
- promise.reject = reject;
- promiseTable.set(promiseId, promise);
- return promise;
+ return setPromise(promiseId);
}
function jsonOpSync(opName, args = null, zeroCopy = null) {
@@ -87,8 +120,7 @@
}
function opAsyncHandler(promiseId, res) {
- const promise = promiseTable.get(promiseId);
- promiseTable.delete(promiseId);
+ const promise = getPromise(promiseId);
if (!isErr(res)) {
promise.resolve(res);
} else {