Repository navigation
Conversation
`cell values survive a full GC between the width and render passes` ran `Bun.gc(true)` in each of its 64 getters. One full GC takes about 50 ms on a debug build, so the test took 2.3 to 3.6 s of the 5 s default timeout, and timed out when the machine had other load. Run the GC in getters 0, 16, 32 and 48. The rows and the assertion do not change.
Contributor
|
Warning Review limit reachedYou've used all free OSS reviews for now. Wait for the free limit to reset to keep reviewing this public repository. Next included review available in 1 minute. View limit details
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
Collaborator
Author
|
Status: ready for review. Waiting for CI. Reproduction.
With this branch.
PR: #47004 |
Collaborator
Author
|
Updated 11:56 AM PT - Oct 26th, 2026
✅ @robobun, your commit 085b985445aeb234579c568f90a6f4eaafde2b91 passed in 🧪 To try this PR locally: bunx bun-pr 47004That installs a local version of the PR into your bun-47004 --bun |
This branch has not been deployed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Problem
cell values survive a full GC between the width and render passestakes 2.3 to 3.6 s on an idle machine, and fails withthis test timed out after 5000msunder load. Six open PRs report that timeout.Bun.gc(true)in each of its 64 getters. One full GC takes about 50 ms on a debug build.--timeout=90000(scripts/runner.node.ts:1167).Fix
Vec<JSValue>(a local change), 47 of 64 ids are missing on debug and release builds. The old test: 62.test/js/bun/console/console-table.test.tson a debug build, 32 pass in 10 of 10 runs, and the test takes 0.18 to 0.30 s. Also a release build.Background
console.tableformats each cell one time, in its width pass (console.table: invoke each cell getter once #32924). An earlier revision kept the cell values for the render pass, and the test guards that design against a GC between the passes.id.N = 8with a GC in each getter: 8 GCs, and 6 missing ids. ConsideredisDebug: a release build finds the bug with 4 GCs too.Notes
All measurements: Linux x64, 12 cores. The debug build is
bun bdof main 449877f (debug, ASAN). The release build for the timings is 367d939.Timings of the test
The whole file on the debug build: 4.45 to 5.70 s before, 2.32 to 2.42 s after.
Cost of one full GC.
Bun.gc(true)in the getter takes 24 to 155 ms on the debug build, with a median of 41 to 61 ms (two runs of 64 calls).fullGC()frombun:jsccosts the same.Bun.gc(false)only requests a concurrent collection, so it cannot replace the call.The local change that frees cell values.
TablePrinter::collect_row(src/jsc/ConsoleObject.rs) formats a cell as soon as it reads it. For the experiment it stores the value, andprint_tableformats the stored values after the last row:The GC does not scan the
Vec, so a full GC in a later getter frees the stored objects.REVIEW.mdnames this bug: "Root or copy every JSValue held beyond the current call". Two builds have the change: the debug build, and a release build of 449877f (--profile=release --lto=off).What the new test prints with the local change. Both builds print the same table. Rows 0 to 46 show the id of a row from 47 to 63:
The assertion fails with the ids 0 to 46 in
missing. In each build the whole file has 1 fail and 31 pass, so no other test in the file finds this bug.Ids missing from the table with the local change. One scratch test for each row of this table. Each count is the same in every run (3 or more runs for each build).
N = 8)N = 2)Why getter 0 runs a GC. On the release build, the values that the getters return before the first GC do not show the bug. With GCs in getters 8, 24, 40 and 56, ids 0 to 7 are not missing. One GC in getter 32, or in getter 63, finds nothing. With a GC in getter 0, the two builds give the same count: all the rows before the last GC, less one.
CI.
.buildkite/ci.tshas release lanes and oneasanlane, which is a release build with ASAN (--asan=on). No lane tests a debug build.--timeout=90000tobun test, and--timeout=270000on the ASAN lane (scripts/runner.node.ts:1167,:267). The 5 s default applies only to a directbun test, for examplebun bd test.test/expected-durations.jsonhas 1160 ms for theasancolumn and 140 ms for the default lane.History.
MarkedArgumentBufferfor the render pass. The final revision formats each cell in the width pass and keeps no value.console.table reads each cell oncefail and this test passes, with the old test and with the new test.MarkedArgumentBufferholds 8 values inline. The new test keeps 64 rows, so a design with such a buffer still goes past its inline storage before the second GC.undefinedornullproperties argument #45027, console: print [Circular] for %j of a cyclic value #45325, Remove dead code from the code generators, the build scripts, and ten crate roots #45709, console.table: log only the first argument when it is not an object #46313, console.table: skippropertiesentries whose key is a Symbol #46986.