Skip to content

Instantly share code, notes, and snippets.

@mhofman
Last active April 8, 2019 20:00
Show Gist options
  • Save mhofman/386fb3f641a0e7b23491da8647d42fe2 to your computer and use it in GitHub Desktop.
Save mhofman/386fb3f641a0e7b23491da8647d42fe2 to your computer and use it in GitHub Desktop.
Spidermonkey memory leak in async functions. Run in JS Shell.
let nextId = 0;
let weakMap;
let savedCallback;
function createWeakMap(callback) {
weakMap = new WeakMap();
savedCallback = callback;
}
const tests = [
// Success
function() {
let object = { id: ++nextId };
console.log(`created object ${object.id}`);
createWeakMap(() => {});
weakMap.set(object, object.id);
},
// Success
async function() {
let object = { id: ++nextId };
console.log(`created object ${object.id}`);
createWeakMap(() => {});
weakMap.set(object, object.id);
object = undefined;
},
// Fails
async function() {
let object = { id: ++nextId };
console.log(`created object ${object.id}`);
createWeakMap(() => {});
weakMap.set(object, object.id);
}
];
(async () => {
for (const test of tests) {
await test();
assertEq(nondeterministicGetWeakMapKeys(weakMap).length, 1);
gc();
if (nondeterministicGetWeakMapKeys(weakMap).length !== 0) {
console.log(`Error: object ${nextId} could not get collected`);
}
}
})();
let nextId = 0;
let weakRef;
let savedCallback;
function createWeakMap(callback) {
savedCallback = callback;
}
const tests = [
// Success
function() {
let object = { id: ++nextId };
console.log(`created object ${object.id}`);
createWeakMap(() => {});
weakRef = new WeakRef(object);
},
// Success
async function() {
let object = { id: ++nextId };
console.log(`created object ${object.id}`);
createWeakMap(() => {});
weakRef = new WeakRef(object);
object = undefined;
},
// Success
async function() {
let object = { id: ++nextId };
console.log(`created object ${object.id}`);
createWeakMap(() => {});
weakRef = new WeakRef(object);
}
];
(async () => {
for (const test of tests) {
await test();
if (!weakRef.deref()) {
console.log(`Can't check object, it's gone`)
}
await new Promise(resolve => setTimeout(resolve, 0))
gc();
if (weakRef.deref()) {
console.log(`Error: object ${nextId} could not get collected`);
}
}
})();
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment