Introduce Bun.unsafe.gcAggressionLevel API

This commit is contained in:
Jarred Sumner
2022-11-19 22:21:35 -08:00
parent 81a1d8f589
commit 17fa4211ac
3 changed files with 47 additions and 0 deletions

View File

@@ -1699,6 +1699,23 @@ declare module "bun" {
/** Mock bun's segfault handler. You probably don't want to use this */
segfault(): void;
/**
* Force the garbage collector to run extremely often,
* especially inside `bun:test`.
*
* - `0`: default, disable
* - `1`: asynchronously call the garbage collector more often
* - `2`: synchronously call the garbage collector more often.
*
* This is a global setting. It's useful for debugging seemingly random crashes.
*
* `BUN_GARBAGE_COLLECTOR_LEVEL` environment variable is also supported.
*
* @param level
* @returns The previous level
*/
gcAggressionLevel(level: 0 | 1 | 2): 0 | 1 | 2;
}
export const unsafe: unsafe;

View File

@@ -1990,10 +1990,30 @@ pub const Unsafe = struct {
.arrayBufferToString = .{
.rfn = arrayBufferToString,
},
.gcAggressionLevel = .{
.rfn = JSC.wrapWithHasContainer(Unsafe, "gcAggressionLevel", false, false, false),
},
},
.{},
);
pub fn gcAggressionLevel(
globalThis: *JSC.JSGlobalObject,
value_: ?JSValue,
) JSValue {
const ret = JSValue.jsNumber(@as(i32, @enumToInt(globalThis.bunVM().aggressive_garbage_collection)));
if (value_) |value| {
switch (value.coerce(i32, globalThis)) {
1 => globalThis.bunVM().aggressive_garbage_collection = .mild,
2 => globalThis.bunVM().aggressive_garbage_collection = .aggressive,
0 => globalThis.bunVM().aggressive_garbage_collection = .none,
else => {},
}
}
return ret;
}
// For testing the segfault handler
pub fn __debug__doSegfault(
_: void,

View File

@@ -12,3 +12,13 @@ export function gcTick(trace = false) {
setTimeout(resolve, 0);
});
}
export function withoutAggressiveGC(block) {
const origGC = Bun.unsafe.gcAggressionLevel();
Bun.unsafe.gcAggressionLevel(0);
try {
return block();
} finally {
Bun.unsafe.gcAggressionLevel(origGC);
}
}