Skip to content
Open
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion scripts/build/deps/webkit.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
// -lto variants built with ThinLTO (per-module summaries for cross-language
// importing), and the Windows ICU data table filtered + per-item zstd
// compressed (lazily decompressed via bun_icu_decompress.cpp).
export const WEBKIT_VERSION = "4895f45dfbd0d1226c4d41799887bc0ecb9f341b";
export const WEBKIT_VERSION = "autobuild-preview-pr-308-06ecce07";
Comment thread
robobun marked this conversation as resolved.
Outdated

/**
* WebKit (JavaScriptCore) — the JS engine.
Expand Down
2 changes: 1 addition & 1 deletion src/jsc/modules/BunJSCModule.h
Original file line number Diff line number Diff line change
Expand Up @@ -799,7 +799,7 @@ JSC_DEFINE_HOST_FUNCTION(functionGenerateHeapSnapshotForDebugging,
}
scope.releaseAssertNoException();

return JSValue::encode(JSONParse(globalObject, WTF::move(jsonString)));
RELEASE_AND_RETURN(scope, JSValue::encode(JSONParse(globalObject, WTF::move(jsonString))));
}

JSC_DEFINE_HOST_FUNCTION(functionSerialize,
Expand Down
36 changes: 35 additions & 1 deletion test/js/bun/jsc/bun-jsc.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,8 @@
totalCompileTime,
} from "bun:jsc";
import { describe, expect, it } from "bun:test";
import { bunEnv, bunExe, isBuildKite, isWindows } from "harness";
import { bunEnv, bunExe, isASAN, isBuildKite, isDebug, isWindows } from "harness";
import path from "node:path";

describe("bun:jsc", () => {
function count() {
Expand Down Expand Up @@ -556,3 +557,36 @@
const [stdout, stderr, exitCode] = await Promise.all([proc.stdout.text(), proc.stderr.text(), proc.exited]);
expect({ stdout, exitCode }).toEqual({ stdout: "rejected\n65\n", exitCode: 0 });
});

// Objects live in a frame at the moment a loop triggers DFG/FTL tier-up are
// captured into the compilation plan's m_mustHandleValues. Those were rooted
// as RootMarkReason::JITWorkList for the life of the concurrent compile, so a
// gc() issued while plans were queued reported fewer objects collected than the
// program had let go of (node's test-gc-http-client* hit this). The snapshot is
// now treated as weak; every DFG phase that reads it already handles nullopt.
it("gc() does not root user objects from a concurrent DFG plan's OSR-entry snapshot", async () => {
// Reproducing this needs several independent functions to request DFG at
// roughly the same time so most plans are still in the worklist at gc(). The
// http client/server path does that reliably (emit, nextTick drain, stream
// flow all tier up during the first burst of responses). The fixture reports
// how many ClientRequest/IncomingMessage instances the debugging heap
// snapshot attributes directly to the JIT worklist; that count must be zero.
// One compiler thread so plans queue instead of draining in parallel.
await using proc = Bun.spawn({
cmd: [
bunExe(),
"--jsc-numberOfDFGCompilerThreads=1",
"--jsc-numberOfFTLCompilerThreads=1",
path.join(import.meta.dir, "dfg-plan-gc-fixture.js"),
],
env: bunEnv,
stdout: "pipe",
stderr: "pipe",
});
const [stdout, stderr, exitCode] = await Promise.all([proc.stdout.text(), proc.stderr.text(), proc.exited]);
expect(stderr).toBe("");

Check warning on line 587 in test/js/bun/jsc/bun-jsc.test.ts

View check run for this annotation

Claude / Claude Code Review

New subprocess test asserts stderr is exactly empty

REVIEW.md's Subprocess-tests section says never to assert stderr is exactly empty because ASAN/debug builds emit benign warnings — and this test explicitly runs under ASAN (it extends the timeout for it). A benign ASAN warning would fail here before the load-bearing `jitworklist-rooted=0` assertion is reached. The three most-recently-added tests in this file (lines ~490, ~522, ~555) already drop the stderr-empty check; this one can do the same (stderr is already drained by the `Promise.all`, so
Comment thread
robobun marked this conversation as resolved.
Outdated
// The "alive" count is timing dependent (how many plans were queued at the
// first gc()), but no ClientRequest/IncomingMessage may be a JITWorkList root.
expect(stdout.trim()).toMatch(/^jitworklist-rooted=0 alive=\d+$/);
expect(exitCode).toBe(0);
}, isDebug || isASAN ? 30_000 : undefined);
49 changes: 49 additions & 0 deletions test/js/bun/jsc/dfg-plan-gc-fixture.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading