diff options
author | 2022-11-19 22:21:35 -0800 | |
---|---|---|
committer | 2022-11-19 22:21:35 -0800 | |
commit | 17fa4211ac8676a04a2dc944f24dddd287c2b1fd (patch) | |
tree | c7861e771b7645c9759995ecdb79836aee6a931b | |
parent | 81a1d8f5896d7f627ec70f9896afe4b17bc4d189 (diff) | |
download | bun-17fa4211ac8676a04a2dc944f24dddd287c2b1fd.tar.gz bun-17fa4211ac8676a04a2dc944f24dddd287c2b1fd.tar.zst bun-17fa4211ac8676a04a2dc944f24dddd287c2b1fd.zip |
Introduce `Bun.unsafe.gcAggressionLevel` API
-rw-r--r-- | packages/bun-types/bun.d.ts | 17 | ||||
-rw-r--r-- | src/bun.js/api/bun.zig | 20 | ||||
-rw-r--r-- | test/bun.js/gc.js | 10 |
3 files changed, 47 insertions, 0 deletions
diff --git a/packages/bun-types/bun.d.ts b/packages/bun-types/bun.d.ts index 252e50055..bab5f5810 100644 --- a/packages/bun-types/bun.d.ts +++ b/packages/bun-types/bun.d.ts @@ -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; diff --git a/src/bun.js/api/bun.zig b/src/bun.js/api/bun.zig index 131e08b6e..a56d4f79f 100644 --- a/src/bun.js/api/bun.zig +++ b/src/bun.js/api/bun.zig @@ -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, diff --git a/test/bun.js/gc.js b/test/bun.js/gc.js index 350f279a1..6c444126f 100644 --- a/test/bun.js/gc.js +++ b/test/bun.js/gc.js @@ -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); + } +} |