From eac875e5c9e98c4657f7f0447517dd2b5c1564ca Mon Sep 17 00:00:00 2001 From: Basit Chonka Date: Wed, 6 Jul 2022 11:25:37 +0200 Subject: [PATCH] events: use bitset to save memory MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit PR-URL: https://github.com/nodejs/node/pull/43700 Reviewed-By: Gerhard Stöbich Reviewed-By: Benjamin Gruenbaum Reviewed-By: Anna Henningsen Reviewed-By: James M Snell --- lib/internal/event_target.js | 52 +++++++++++++++++++++++++++++++----- 1 file changed, 46 insertions(+), 6 deletions(-) diff --git a/lib/internal/event_target.js b/lib/internal/event_target.js index 22e43190e9bace..5388b5c8139a10 100644 --- a/lib/internal/event_target.js +++ b/lib/internal/event_target.js @@ -389,6 +389,13 @@ function weakListeners() { return { registry: weakListenersState, map: objectToWeakListenerMap }; } +const kFlagOnce = 1 << 0; +const kFlagCapture = 1 << 1; +const kFlagPassive = 1 << 2; +const kFlagNodeStyle = 1 << 3; +const kFlagWeak = 1 << 4; +const kFlagRemoved = 1 << 5; + // The listeners for an EventTarget are maintained as a linked list. // Unfortunately, the way EventTarget is defined, listeners are accounted // using the tuple [handler,capture], and even if we don't actually make @@ -404,13 +411,21 @@ class Listener { previous.next = this; this.previous = previous; this.listener = listener; - // TODO(benjamingr) these 4 can be 'flags' to save 3 slots - this.once = once; - this.capture = capture; - this.passive = passive; - this.isNodeStyleListener = isNodeStyleListener; + + let flags = 0b0; + if (once) + flags |= kFlagOnce; + if (capture) + flags |= kFlagCapture; + if (passive) + flags |= kFlagPassive; + if (isNodeStyleListener) + flags |= kFlagNodeStyle; + if (weak) + flags |= kFlagWeak; + this.flags = flags; + this.removed = false; - this.weak = Boolean(weak); // Don't retain the object if (this.weak) { this.callback = new SafeWeakRef(listener); @@ -430,6 +445,31 @@ class Listener { } } + get once() { + return Boolean(this.flags & kFlagOnce); + } + get capture() { + return Boolean(this.flags & kFlagCapture); + } + get passive() { + return Boolean(this.flags & kFlagPassive); + } + get isNodeStyleListener() { + return Boolean(this.flags & kFlagNodeStyle); + } + get weak() { + return Boolean(this.flags & kFlagWeak); + } + get removed() { + return Boolean(this.flags & kFlagRemoved); + } + set removed(value) { + if (value) + this.flags |= kFlagRemoved; + else + this.flags &= ~kFlagRemoved; + } + same(listener, capture) { const myListener = this.weak ? this.listener.deref() : this.listener; return myListener === listener && this.capture === capture;