Skip to content

Commit c12711e

Browse files
joyeecheungUlisesGascon
authored andcommitted
lib: implement WeakReference on top of JS WeakRef
The C++ implementation can now be done entirely in JS using WeakRef. Re-implement it in JS instead to simplify the code. PR-URL: #49053 Reviewed-By: Anna Henningsen <[email protected]> Reviewed-By: Yagiz Nizipli <[email protected]> Reviewed-By: Rafael Gonzaga <[email protected]> Reviewed-By: Benjamin Gruenbaum <[email protected]>
1 parent ca9f801 commit c12711e

File tree

6 files changed

+39
-9
lines changed

6 files changed

+39
-9
lines changed

lib/diagnostics_channel.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ const {
2828

2929
const { triggerUncaughtException } = internalBinding('errors');
3030

31-
const { WeakReference } = internalBinding('util');
31+
const { WeakReference } = require('internal/util');
3232

3333
// Can't delete when weakref count reaches 0 as it could increment again.
3434
// Only GC can be used as a valid time to clean up the channels map.

lib/domain.js

+1-2
Original file line numberDiff line numberDiff line change
@@ -52,9 +52,8 @@ const {
5252
const { createHook } = require('async_hooks');
5353
const { useDomainTrampoline } = require('internal/async_hooks');
5454

55-
// TODO(addaleax): Use a non-internal solution for this.
5655
const kWeak = Symbol('kWeak');
57-
const { WeakReference } = internalBinding('util');
56+
const { WeakReference } = require('internal/util');
5857

5958
// Overwrite process.domain with a getter/setter that will allow for more
6059
// effective optimizations

lib/internal/util.js

+34
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ const {
3333
SafeMap,
3434
SafeSet,
3535
SafeWeakMap,
36+
SafeWeakRef,
3637
StringPrototypeReplace,
3738
StringPrototypeToLowerCase,
3839
StringPrototypeToUpperCase,
@@ -797,6 +798,38 @@ function guessHandleType(fd) {
797798
return handleTypes[type];
798799
}
799800

801+
class WeakReference {
802+
#weak = null;
803+
#strong = null;
804+
#refCount = 0;
805+
constructor(object) {
806+
this.#weak = new SafeWeakRef(object);
807+
}
808+
809+
incRef() {
810+
this.#refCount++;
811+
if (this.#refCount === 1) {
812+
const derefed = this.#weak.deref();
813+
if (derefed !== undefined) {
814+
this.#strong = derefed;
815+
}
816+
}
817+
return this.#refCount;
818+
}
819+
820+
decRef() {
821+
this.#refCount--;
822+
if (this.#refCount === 0) {
823+
this.#strong = null;
824+
}
825+
return this.#refCount;
826+
}
827+
828+
get() {
829+
return this.#weak.deref();
830+
}
831+
}
832+
800833
module.exports = {
801834
getLazy,
802835
assertCrypto,
@@ -855,4 +888,5 @@ module.exports = {
855888
kEnumerableProperty,
856889
setOwnProperty,
857890
pendingDeprecate,
891+
WeakReference,
858892
};

test/fixtures/snapshot/weak-reference-gc.js

+1-2
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
'use strict';
22

3-
const { internalBinding } = require('internal/test/binding');
4-
const { WeakReference } = internalBinding('util');
3+
const { WeakReference } = require('internal/util');
54
const {
65
setDeserializeMainFunction
76
} = require('v8').startupSnapshot

test/fixtures/snapshot/weak-reference.js

+1-2
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
'use strict';
22

3-
const { internalBinding } = require('internal/test/binding');
4-
const { WeakReference } = internalBinding('util');
3+
const { WeakReference } = require('internal/util');
54
const {
65
setDeserializeMainFunction
76
} = require('v8').startupSnapshot

test/parallel/test-internal-util-weakreference.js

+1-2
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,7 @@
22
'use strict';
33
const common = require('../common');
44
const assert = require('assert');
5-
const { internalBinding } = require('internal/test/binding');
6-
const { WeakReference } = internalBinding('util');
5+
const { WeakReference } = require('internal/util');
76

87
let obj = { hello: 'world' };
98
const ref = new WeakReference(obj);

0 commit comments

Comments
 (0)