mirror of
https://github.com/oven-sh/bun
synced 2026-02-10 02:48:50 +00:00
Co-authored-by: Kai Tamkun <kai@tamkun.io> Co-authored-by: Jarred Sumner <jarred@jarredsumner.com> Co-authored-by: Ashcon Partovi <ashcon@partovi.net> Co-authored-by: Ciro Spaciari <ciro.spaciari@gmail.com> Co-authored-by: Dylan Conway <35280289+dylan-conway@users.noreply.github.com> Co-authored-by: 190n <190n@users.noreply.github.com>
139 lines
3.6 KiB
JavaScript
Generated
139 lines
3.6 KiB
JavaScript
Generated
// UNUSED as of #14501
|
|
const nativeTests = require("./build/Debug/napitests.node");
|
|
|
|
function usage() {
|
|
return process.memoryUsage.rss();
|
|
}
|
|
|
|
function gc() {
|
|
if (typeof Bun == "object") {
|
|
Bun.gc(true);
|
|
} else {
|
|
global.gc();
|
|
}
|
|
}
|
|
|
|
async function test(fn, warmupRuns, testRuns, maxDeltaMB) {
|
|
gc();
|
|
// warmup
|
|
for (let i = 0; i < warmupRuns; i++) {
|
|
console.log(`warmup ${i}/${warmupRuns}`);
|
|
fn();
|
|
await new Promise(resolve => setTimeout(resolve, 0));
|
|
gc();
|
|
}
|
|
const initial = usage() / 1024 / 1024;
|
|
|
|
// test
|
|
for (let i = 0; i < testRuns; i++) {
|
|
console.log(`test ${i}/${testRuns}`);
|
|
fn();
|
|
await new Promise(resolve => setTimeout(resolve, 0));
|
|
gc();
|
|
}
|
|
const after = usage() / 1024 / 1024;
|
|
|
|
const deltaMB = after - initial;
|
|
console.log(`RSS ${initial} -> ${after} MiB`);
|
|
console.log(`Delta ${deltaMB} MB`);
|
|
if (deltaMB > maxDeltaMB) {
|
|
throw new Error("leaked!");
|
|
}
|
|
}
|
|
|
|
// Create a bunch of weak references and delete them
|
|
// Checks that napi_delete_reference cleans up memory associated with the napi_ref itself
|
|
function batchWeakRefs(n) {
|
|
if (typeof n != "number") throw new TypeError();
|
|
for (let i = 0; i < n; i++) {
|
|
// create tons of weak references to objects that get destroyed
|
|
nativeTests.add_weak_refs({});
|
|
}
|
|
// free all the weak refs
|
|
nativeTests.clear_weak_refs();
|
|
}
|
|
|
|
// Checks that strong references don't keep the value
|
|
function batchStrongRefs(n) {
|
|
if (typeof n != "number") throw new TypeError();
|
|
for (let i = 0; i < n; i++) {
|
|
const array = new Uint8Array(10_000_000);
|
|
array.fill(i);
|
|
nativeTests.create_and_delete_strong_ref(array);
|
|
}
|
|
}
|
|
|
|
function batchWrappedObjects(n) {
|
|
if (typeof n != "number") throw new TypeError();
|
|
let wraps = [];
|
|
for (let i = 0; i < n; i++) {
|
|
const s = Math.random().toString();
|
|
const wrapped = nativeTests.wrapped_object_factory(
|
|
s,
|
|
!process.isBun, // supports_node_api_post_finalize
|
|
);
|
|
wraps.push(wrapped);
|
|
if (wrapped.get() != s) {
|
|
throw new Error("wrong value");
|
|
}
|
|
}
|
|
gc();
|
|
for (const w of wraps) {
|
|
w.get();
|
|
}
|
|
// now GC them
|
|
}
|
|
|
|
function batchExternals(n) {
|
|
if (typeof n != "number") throw new TypeError();
|
|
let externals = [];
|
|
for (let i = 0; i < n; i++) {
|
|
const s = Math.random().toString();
|
|
const external = nativeTests.external_factory(s);
|
|
externals.push(external);
|
|
if (nativeTests.external_get(external) != s) {
|
|
throw new Error("wrong value");
|
|
}
|
|
}
|
|
gc();
|
|
for (const e of externals) {
|
|
nativeTests.external_get(e);
|
|
}
|
|
}
|
|
|
|
function batchThreadsafeFunctions(n, maxQueueSize) {
|
|
if (typeof n != "number") throw new TypeError();
|
|
const callback = () => {};
|
|
for (let i = 0; i < n; i++) {
|
|
nativeTests.create_and_delete_threadsafe_function(callback, maxQueueSize);
|
|
}
|
|
gc();
|
|
}
|
|
|
|
(async () => {
|
|
// TODO(@190n) get the rest of these tests working
|
|
// await test(() => batchWeakRefs(100), 10, 50, 8);
|
|
// await test(() => batchStrongRefs(100), 10, 50, 8);
|
|
// await test(() => batchWrappedObjects(1000), 20, 50, 20);
|
|
// await test(() => batchExternals(1000), 10, 400, 15);
|
|
|
|
// a queue size of 10,000 would leak 80 kB (each queue item is a void*), so 400 iterations
|
|
// would be a 32MB leak
|
|
// call with a preallocated queue
|
|
const threadsafeFunctionJsCallback = () => {};
|
|
await test(
|
|
() => nativeTests.create_and_delete_threadsafe_function(threadsafeFunctionJsCallback, 10_000, 10_000),
|
|
100,
|
|
400,
|
|
10,
|
|
);
|
|
|
|
// call with a dynamic queue
|
|
await test(
|
|
() => nativeTests.create_and_delete_threadsafe_function(threadsafeFunctionJsCallback, 0, 10_000),
|
|
100,
|
|
400,
|
|
10,
|
|
);
|
|
})();
|