From 194af023ac9394bc9526ea694309304449db1309 Mon Sep 17 00:00:00 2001 From: Basit Chonka Date: Wed, 6 Jul 2022 11:25:37 +0200 Subject: [PATCH 1/3] listener: use bitset to save memory --- 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 bd153c972ae276..8db63700a45364 100644 --- a/lib/internal/event_target.js +++ b/lib/internal/event_target.js @@ -347,6 +347,13 @@ function weakListeners() { return { registry: weakListenersState, map: objectToWeakListenerMap }; } +const FLAG_ONCE = 1; +const FLAG_CAPTURE = 2; +const FLAG_PASSIVE = 4; +const FLAG_NODE_STYLE = 8; +const FLAG_WEAK = 16; +const FLAG_REMOVED = 32; + // 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 @@ -362,13 +369,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 |= FLAG_ONCE; + if (capture) + flags |= FLAG_CAPTURE; + if (passive) + flags |= FLAG_PASSIVE; + if (isNodeStyleListener) + flags |= FLAG_NODE_STYLE; + if (Boolean(weak)) + flags |= FLAG_WEAK; + this.flags = flags; + this.removed = false; - this.weak = Boolean(weak); // Don't retain the object if (this.weak) { this.callback = new SafeWeakRef(listener); @@ -388,6 +403,31 @@ class Listener { } } + get once() { + return Boolean(this.flags & FLAG_ONCE); + } + get capture() { + return Boolean(this.flags & FLAG_CAPTURE); + } + get passive() { + return Boolean(this.flags & FLAG_PASSIVE); + } + get isNodeEventTarget() { + return Boolean(this.flags & FLAG_NODE_STYLE); + } + get weak() { + return Boolean(this.flags & FLAG_WEAK); + } + get removed() { + return Boolean(this.flags & FLAG_REMOVED); + } + set removed(value) { + if (value) + this.flags |= FLAG_REMOVED; + else + this.flags &= ~FLAG_REMOVED; + } + same(listener, capture) { const myListener = this.weak ? this.listener.deref() : this.listener; return myListener === listener && this.capture === capture; From e344b4b31fe4e0960884182dfbb03686c62f91a9 Mon Sep 17 00:00:00 2001 From: Basit Chonka Date: Wed, 6 Jul 2022 13:49:23 +0200 Subject: [PATCH 2/3] events: code styles and use bit shifts --- lib/internal/event_target.js | 44 ++++++++++++++++++------------------ 1 file changed, 22 insertions(+), 22 deletions(-) diff --git a/lib/internal/event_target.js b/lib/internal/event_target.js index 8db63700a45364..ea26771291ed2d 100644 --- a/lib/internal/event_target.js +++ b/lib/internal/event_target.js @@ -347,12 +347,12 @@ function weakListeners() { return { registry: weakListenersState, map: objectToWeakListenerMap }; } -const FLAG_ONCE = 1; -const FLAG_CAPTURE = 2; -const FLAG_PASSIVE = 4; -const FLAG_NODE_STYLE = 8; -const FLAG_WEAK = 16; -const FLAG_REMOVED = 32; +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 @@ -371,16 +371,16 @@ class Listener { this.listener = listener; let flags = 0b0; - if (once) - flags |= FLAG_ONCE; - if (capture) - flags |= FLAG_CAPTURE; + if (once) + flags |= kFlagOnce; + if (capture) + flags |= kFlagCapture; if (passive) - flags |= FLAG_PASSIVE; + flags |= kFlagPassive; if (isNodeStyleListener) - flags |= FLAG_NODE_STYLE; - if (Boolean(weak)) - flags |= FLAG_WEAK; + flags |= kFlagNodeStyle; + if (weak) + flags |= kFlagWeak; this.flags = flags; this.removed = false; @@ -404,28 +404,28 @@ class Listener { } get once() { - return Boolean(this.flags & FLAG_ONCE); + return Boolean(this.flags & kFlagOnce); } get capture() { - return Boolean(this.flags & FLAG_CAPTURE); + return Boolean(this.flags & kFlagCapture); } get passive() { - return Boolean(this.flags & FLAG_PASSIVE); + return Boolean(this.flags & kFlagPassive); } get isNodeEventTarget() { - return Boolean(this.flags & FLAG_NODE_STYLE); + return Boolean(this.flags & kFlagNodeStyle); } get weak() { - return Boolean(this.flags & FLAG_WEAK); + return Boolean(this.flags & kFlagWeak); } get removed() { - return Boolean(this.flags & FLAG_REMOVED); + return Boolean(this.flags & kFlagRemoved); } set removed(value) { if (value) - this.flags |= FLAG_REMOVED; + this.flags |= kFlagRemoved; else - this.flags &= ~FLAG_REMOVED; + this.flags &= ~kFlagRemoved; } same(listener, capture) { From 73a689eb0ba22e0d8d4b9d1424cd5b2b9ec33abf Mon Sep 17 00:00:00 2001 From: Basit <1305718+mabaasit@users.noreply.github.com> Date: Fri, 8 Jul 2022 12:44:05 +0200 Subject: [PATCH 3/3] Update lib/internal/event_target.js fix typo Co-authored-by: Anna Henningsen --- lib/internal/event_target.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/internal/event_target.js b/lib/internal/event_target.js index ea26771291ed2d..458bb9a624ac73 100644 --- a/lib/internal/event_target.js +++ b/lib/internal/event_target.js @@ -412,7 +412,7 @@ class Listener { get passive() { return Boolean(this.flags & kFlagPassive); } - get isNodeEventTarget() { + get isNodeStyleListener() { return Boolean(this.flags & kFlagNodeStyle); } get weak() {