'use strict'; // Flags: --expose-gc const common = require('../../common'); const { gcUntil } = require('../../common/gc'); // Verify that addons can create GarbageCollected objects and // have them traced properly. const assert = require('assert'); const { CppGCed, states, kDestructCount, kTraceCount, } = require(`./build/${common.buildType}/binding`); const GC_OPTIONS = { type: 'major', execution: 'sync', }; assert.strictEqual(states[kDestructCount], 0); assert.strictEqual(states[kTraceCount], 0); let array = []; const count = 100; for (let i = 0; i < count; ++i) { array.push(new CppGCed()); } globalThis.gc(); setTimeout(common.mustCall(() => (async function() { // GC should have invoked Trace() on at least some of the CppGCed objects, // but they should all be alive at this point. assert.strictEqual(states[kDestructCount], 0); assert.notStrictEqual(states[kTraceCount], 0); // Replace the old CppGCed objects with new ones, after GC we should have // destructed all the old ones and called Trace() on the // new ones. for (let i = 0; i < count; ++i) { array[i] = new CppGCed(); } await gcUntil( 'All old CppGCed are destroyed', () => states[kDestructCount] === count, undefined, GC_OPTIONS, ); // Release all the CppGCed objects, after GC we should have destructed // all of them. array = null; globalThis.gc(); await gcUntil( 'All old CppGCed are destroyed', () => states[kDestructCount] === count * 2, undefined, GC_OPTIONS, ); })().then(common.mustCall())), 1);