aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGravatar Jarred Sumner <709451+Jarred-Sumner@users.noreply.github.com> 2022-11-19 22:21:35 -0800
committerGravatar Jarred Sumner <709451+Jarred-Sumner@users.noreply.github.com> 2022-11-19 22:21:35 -0800
commit17fa4211ac8676a04a2dc944f24dddd287c2b1fd (patch)
treec7861e771b7645c9759995ecdb79836aee6a931b
parent81a1d8f5896d7f627ec70f9896afe4b17bc4d189 (diff)
downloadbun-17fa4211ac8676a04a2dc944f24dddd287c2b1fd.tar.gz
bun-17fa4211ac8676a04a2dc944f24dddd287c2b1fd.tar.zst
bun-17fa4211ac8676a04a2dc944f24dddd287c2b1fd.zip
Introduce `Bun.unsafe.gcAggressionLevel` API
-rw-r--r--packages/bun-types/bun.d.ts17
-rw-r--r--src/bun.js/api/bun.zig20
-rw-r--r--test/bun.js/gc.js10
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);
+ }
+}