Skip to content

Commit

Permalink
lib: implement WeakReference on top of JS WeakRef
Browse files Browse the repository at this point in the history
The C++ implementation can now be done entirely in JS using WeakRef.
Re-implement it in JS instead to simplify the code.
  • Loading branch information
joyeecheung committed Aug 7, 2023
1 parent 096fefd commit 3f5d3e4
Show file tree
Hide file tree
Showing 6 changed files with 38 additions and 9 deletions.
2 changes: 1 addition & 1 deletion lib/diagnostics_channel.js
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ const {

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

const { WeakReference } = internalBinding('util');
const { WeakReference } = require('internal/util');

// Can't delete when weakref count reaches 0 as it could increment again.
// Only GC can be used as a valid time to clean up the channels map.
Expand Down
3 changes: 1 addition & 2 deletions lib/domain.js
Original file line number Diff line number Diff line change
Expand Up @@ -52,9 +52,8 @@ const {
const { createHook } = require('async_hooks');
const { useDomainTrampoline } = require('internal/async_hooks');

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

// Overwrite process.domain with a getter/setter that will allow for more
// effective optimizations
Expand Down
33 changes: 33 additions & 0 deletions lib/internal/util.js
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ const {
SafeMap,
SafeSet,
SafeWeakMap,
SafeWeakRef,
StringPrototypeReplace,
StringPrototypeToLowerCase,
StringPrototypeToUpperCase,
Expand Down Expand Up @@ -797,6 +798,37 @@ function guessHandleType(fd) {
return handleTypes[type];
}

class WeakReference {
constructor(object) {
this.weak = new SafeWeakRef(object);
this.strong = null;
this.refCount = 0;
}

incRef() {
this.refCount++;
if (this.refCount === 1) {
const derefed = this.weak.deref();
if (derefed !== undefined) {
this.strong = derefed;
}
}
return this.refCount;
}

decRef() {
this.refCount--;
if (this.refCount === 0) {
this.strong = null;
}
return this.refCount;
}

get() {
return this.weak.deref();
}
}

module.exports = {
getLazy,
assertCrypto,
Expand Down Expand Up @@ -855,4 +887,5 @@ module.exports = {
kEnumerableProperty,
setOwnProperty,
pendingDeprecate,
WeakReference,
};
3 changes: 1 addition & 2 deletions test/fixtures/snapshot/weak-reference-gc.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
'use strict';

const { internalBinding } = require('internal/test/binding');
const { WeakReference } = internalBinding('util');
const { WeakReference } = require('internal/util');
const {
setDeserializeMainFunction
} = require('v8').startupSnapshot
Expand Down
3 changes: 1 addition & 2 deletions test/fixtures/snapshot/weak-reference.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
'use strict';

const { internalBinding } = require('internal/test/binding');
const { WeakReference } = internalBinding('util');
const { WeakReference } = require('internal/util');
const {
setDeserializeMainFunction
} = require('v8').startupSnapshot
Expand Down
3 changes: 1 addition & 2 deletions test/parallel/test-internal-util-weakreference.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,7 @@
'use strict';
const common = require('../common');
const assert = require('assert');
const { internalBinding } = require('internal/test/binding');
const { WeakReference } = internalBinding('util');
const { WeakReference } = require('internal/util');

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

0 comments on commit 3f5d3e4

Please sign in to comment.