Repository navigation
Conversation
WEBKIT_VERSION points at the preview build of oven-sh/WebKit#923, which merges upstream WebKit e8f704815e94 into the fork. Move it to the release of the merge commit before this lands. test/js/bun/jsc/webkit-upgrade-e8f704815e.test.ts pins four things the new engine changes and the behavior it had to keep in code that the merge rewrote. The snapshot of bundler_bytecode_portable.test.ts has the new serialized bytecode. Its entry for libraries.js keeps the old value until CI reports the new one: the bundle of that entry differs on the machine the other values come from.
|
Updated 7:05 PM PT - Oct 29th, 2026
❌ @robobun, your commit 75bc370 has some failures in 🧪 To try this PR locally: bunx bun-pr 47112That installs a local version of the PR into your bun-47112 --bun |
|
Status: ready for review. oven-sh/WebKit#923 is merged, and
|
Every platform of build 133970 serializes the same bytes for this entry: 21177768 bytes, sha256 620db040f8b0...194fced. The other 22 entries, which came from a local build, match CI as they are.
…7c88a8 That pull request has four commits after the merge commit, for what its first CI run found. None of them changes a library that Bun links: they change how the programs of the Linux lanes are linked, and tests. Its CI is green at this head, and this is the preview build of that head.
main got the ahead-of-time compiler (#45631) and WebKit fcc1ea0973a4 (#47125) after this branch was cut. scripts/build/deps/webkit.ts is the one conflict. WEBKIT_VERSION is the preview build of oven-sh/WebKit#923 at 0e103663, which has main's WebKit (oven-sh/WebKit#914) merged into the upstream upgrade. Upstream deleted one JavaScript builtin of the engine (defaultAsyncFromAsyncIteratorWithNext, runtime function 23), so every engine runtime function behind it is one lower. Five tests under test/aot/engine-tests name such a function by number: every is 30, filter 32, from 46, map 64 and some 88. The numbers of Bun's own functions start at 0x10000 and stay.
…d362b3 That head has a repair for Bun.JSONL: with the object loop that upstream rewrote, a streaming parse could give an object a Structure that a collection had freed (bcd362b31e over there, with a stress test). It also has the fork's main merged in again (oven-sh/WebKit#886 and #926). Its CI is green.
main has #47129, the Bun side of oven-sh/WebKit#927 and #930. The one conflict is WEBKIT_VERSION. It is now the preview build of oven-sh/WebKit#923 at 35b64c4a: the upstream merge, the fork's main up to f495db1d24 (what main pins) and the commit that keeps the generic copy for a spread of a function.
Upstream WebKit 37aa2b5bd94d deleted the builtin defaultAsyncFromAsyncIteratorWithNext, which was number 23 of the engine's functions that are written in JavaScript. Every later number is one lower. #47129 brought 1,222 more files to test/aot/engine-tests. 2,636 numbers in 366 of them change: each number from 24 on behind `runtimefunction id=` and `enclosingRuntimeFunction=`, and behind `runtimefunction` in a comment. The five files that this branch had already changed stay as they are. Checked against the list of the pinned engine: no file names a number that the list does not have, and 1,165 functions carry the number of the builtin they are named like.
main has #47281 and pins oven-sh/WebKit 8c6c963e3c (ICU 79.1, no address space ballast). The one conflict is WEBKIT_VERSION. It is now the preview build of oven-sh/WebKit#923 at b67a0b1a, which is the upstream merge on top of that same 8c6c963e3c.
The instance of a compiled program holds one word for every link-time constant of the engine. Upstream WebKit 37aa2b5bd94d deleted one (defaultAsyncFromAsyncIteratorWithNext), so every field behind that list is eight bytes lower: 8040 is 8032, 8168 is 8160, 8192 is 8184, 8216 is 8208 and 8264 is 8256. Nine tests check the B3 of a function line by line and have those offsets in 19 lines. test/aot/tools/update-ir-tests.ts wrote them anew with a release testaot on Linux x64. Nothing else in the files changed. With that testaot, test/aot/engine-tests passes: 1599 files, 2 todo.
compile-aot-size.test.ts: hello world with --aot --trim maps 25,777,292 bytes in CI where the bound is 25,700,000. The canary of main maps 25,584,836. The engine is larger: .text of jsc grows by 143,376 bytes with the 360 upstream commits. The bound is 25,880,000 now, with the slack it had before. The bound without --trim still holds (68,285,580 of 68,440,000). test/aot/parallel/arrays/searches-folds-and-flat-maps-...: the executable holds 42 functions where the bound is 40, and 24 on main. Upstream's Array.from (37aa2b5bd94d) steps an iterator by a call of its `next` and closes it by a call of its `return`. The 18 more functions are the two helpers that do that and the `next`, `return` and `throw` of the library's iterators. The bound is 48 now. Both are a maintainer's call. This commit can be reverted alone.
|
A note on the function counts, from a build of this branch ( The 18 functions behind the new bound of 48 are the smaller part of what the hand-stepped
The cause is how With that form, 390 lines of iterator protocol probes print the same compiled and under I am preparing this as a separate pull request against |
oven-sh/WebKit#923 is merged. Its merge commit has the same tree as the head that the preview build autobuild-preview-pr-923-b67a0b1a was made from, and that preview release goes away now that the pull request is merged.
… runs out of stack test() records only where the match is. A read of RegExp.lastMatch, RegExp.$1 and the other legacy static properties runs the match again for the captures. When that second run failed, the read ended the process: Segmentation fault at address 0x4 (#44697). Upstream WebKit 191803bb2304, which this upgrade brings, throws a RangeError there. The test runs the program of upstream's stress test in a child with BUN_JSC_maxRegExpStackSize=65536 and compares every line it prints.
CI build 135015 maps 25,752,644 bytes for hello world with --aot --trim, and the canary of the same commit of main maps 25,584,836: 167,808 bytes more. The comment said 183,000.
There was a problem hiding this comment.
Nothing blocking. The comments below are optional suggestions. There is no need to push a fix for them before merging.
Beyond the inline finding, I also checked that the old WebKit SHA (8c6c963e3c49) has no remaining duplicates anywhere in the repo, and that the new RegExp legacy-static-properties crash test is a spawned fixture that drains both pipes concurrently and asserts exact stdout/stderr before the exit code. The two raised test bounds (--trim mapped bytes and ImageFunctionsEmitted) are the parts that still need a maintainer's judgment.
Extended reasoning...
The change pins WEBKIT_VERSION to a7b59e61de2e in scripts/build/deps/webkit.ts, mechanically renumbers builtin ids and shifts nine B3 load offsets across 378 .ir engine tests, refreshes bytecode snapshots, raises two size/function-count bounds, and adds two new jsc tests. It touches no security-sensitive surface in this repo, but it swaps the JS engine itself, and the author explicitly flags two loosened test bounds as needing maintainer agreement, so a human look is warranted.
…tion's The case for Proxy.revocable expected ["length", "name"] from Reflect.ownKeys(revoke) after `length` was deleted and defined again. That list is JavaScriptCore's order for every function, and the specification asks for the order of creation. A test that writes the list down would fail the day the engine follows the specification. What the upstream change guarantees is that the revoke function is an ordinary function. The case now treats an arrow function the same way and expects the two lists of keys to be equal. The old engine still fails it: its revoke function lists name before length, and its arrow function does not.
|
An update to my note above. #47316 (commit b49dbef) now expands
The last row is the test whose bound this branch raises from 40 to 48. With #47316 it keeps 25 functions, so the bound of 40 holds again once that pull request is in. |
Fixes #44697
Problem
RegExp.lastMatchafter atest()that matched can end the process:panic(main thread): Segmentation fault at address 0x4.Math.sumPrecise([-1])is-1.0000000000000002, and an async function that awaits itself throughPromise.allrepeats its frame inError.stack.Fix
WEBKIT_VERSIONis a7b59e61de2e, the merge commit of Upgrade to upstream WebKit e8f704815e94 WebKit#923: the engine ofmainplus the upstream merge.test/aot/engine-tests, 2,648 builtin numbers are one lower and 19 instance offsets eight bytes lower. Loop bytecode changes, sobundler_bytecode_portable.test.tshas new snapshots.--trimsize incompile-aot-size.test.tsand the function count of one program (Notes).test/js/bun/jsc/webkit-upgrade-e8f704815e.test.ts(new, 17 cases, Bun 1.4.3-canary fails 4) andtest/js/bun/jsc/regexp-legacy-static-properties.test.ts(new, the panic on Bun 1.4.3-canary).test/aot/engine-testspasses with a releasetestaot.Background
WEBKIT_VERSION(scripts/build/deps/webkit.ts) names the oven-sh/WebKit release whose JavaScriptCore the build downloads.Downsides
--aot --trimmaps 167,808 bytes more. A compiled program that callsArray.fromholds 22 functions, was 6.Proxy.revocablerevoke function now start withlengthandname.Notes
The WebKit side
oven-sh/WebKit#923 merges upstream
e8f704815e94into the fork. Its description lists the 16 conflicts and how each one is resolved.The first CI run of that pull request built every lane and published a preview release. Its test jobs failed for three reasons. None of them is in the libraries that Bun links:
-z pack-relative-relocs(WebKit/WebKit@c47b7c073c). ThejscandtestFFIprograms of the Linux lanes then need glibc 2.36. The arm64 test runner has glibc 2.35.stress/regexp-legacy-static-properties-rematch-failure.js) cannot pass in two test modes that only the fork has.That pull request has a commit for each of them. After that, the fork's
maingot oven-sh/WebKit#914, #886 and #926, and Bun'smaingot the ahead-of-time compiler (#45631) with that WebKit (#47125). Both are merged in, over there and here.A review of the merged head found one defect of the merge itself: with the object loop of
JSON.parsethat upstream rewrote,Bun.JSONLcould give an object a Structure that a collection had freed.bcd362b31eover there repairs it and adds a stress test. With thejscof the build before it, that test ends inSIGSEGVin 6 runs of 6.The fork's
mainthen moved three more times, and each time its Bun side had to be on Bun'smainbefore this branch could pin a build with it:mainbe93e08e3635b64c4afbb67a0b1a3a780dc90982over there turns upstream's fast path for{ ...fn }off in builds with the ahead-of-time compiler (see "What Bun's CI showed").a7b59e61de, andWEBKIT_VERSIONis that commit. It has the same tree asb67a0b1a3a, the head whose preview build (autobuild-preview-pr-923-b67a0b1a) this branch pinned before. That is8c6c963e3c, whichmainpins since Remove the address space ballast and the mimalloc patches, upgrade mimalloc to v3.6.0 and ICU to 79.1 #47281, plus the upstream merge. The CI of Upgrade to upstream WebKit e8f704815e94 WebKit#923 was green at that head: 84 jobs, withtestFFI,TestWTF,testaotandrun-javascriptcore-testson Linux x64 and arm64.maindoes not work. With the preview of780dc90982andmainbefore AOT: fixes for modules, classes and Workers, WebKit upgrade, shorter compiler docs #47129, the build stopped atsrc/jsc/bindings/BunCompiledModules.cpp:756(too few arguments to function call,JSC::AOT::tryReservePagesForNewThread), and with that call changed everybun build --compile --aotended withIdOutOfRange.The release zip sizes of an earlier version of this description compared builds 133970 and 133646: between -0.15% and +0.12% over the 12 release zips (
bun-linux-x64.zip-38,546 bytes).What Bun's CI showed
The head is
e22cf6a525now. On top of3688162c4cit has the pin of the merge commit, the test for #44697 and one corrected comment. The engine source is the same as in build 135015.Build 135015 ran
3688162c4c, the head with the answers below. 184 of its 188 jobs passed and none failed: every build, and every test job on Linux, Windows and macOS on ARM64. The four macOS x64 test jobs had not started when this was written. No agent of that queue was free, and three attempts of each job expired after an hour of waiting. Four tests failed once and passed on a retry or alone (bun-serve-html.test.ts,no-leak-records-at-exit.test.ts,hot.test.ts,process-stdin.test.ts).Build 134977 ran the head before that, with
mainup to #47129 and the preview of35b64c4afb. Three things failed that do not pass on a retry.3688162c4canswers each:test/aot/engine/ir-1,ir-3,ir-5,ir-6(nine.irfiles, Linux x64)lower-to-b3: output line 7 does not match: Int64 b@22 = Load(b@10, offset = 8264, ..); nearest: .. offset = 8256 ..test/aot/parallel/arrays/searches-folds-and-flat-maps-of-a-list-bring-in-only-the-functions-that-do-them.jsImageFunctionsEmitted <= 40, but the build counted 42test/bundler/compile-aot-size.test.ts--trimmaps 25,777,292 bytes, and the bound is 25,700,000Eight more tests failed and passed on a retry or alone (
plugin-requests-run-ahead.test.ts,no-leak-records-at-exit.test.ts,compile-aot-run-time.test.ts,43831.test.ts,filesink.test.ts,process-stdin.test.ts,body.test.ts,test-cluster-shared-leak.js).The function count. The program calls
Array.from({ length: 16 })and six array methods. Its executable holds 24 functions with the canary ofmainand 42 here.Array.from(WebKit/WebKit@37aa2b5bd94d) steps an iterator by a call of itsnextand closes it by a call of itsreturn. The old text was afor-ofloop.Array.from, so the compiler keeps what that call ofnextcan reach by name. The 18 more functions are the two helpersiteratorGenericNextanditeratorGenericClose, one part ofArray.fromthat is moved out of line, and thenext,returnandthrowof array iterators, generators, iterator helpers and wrapped iterators.console.log(Array.from([1, 2, 3], x => x + 1).join())holds 22 functions wheremainholds 6. Its bound is 24.main. The bound of 48 is needed only until then.The size.
test/bundler/compile-aot-size.test.ts, Linux x64 with glibc. Build 135015 is the commit of the canary plus this upgrade:main(081ace731d)--aot--aot --trimBoth grow by 167,808 bytes.
.textofjscgrows by 143,376 bytes with the 360 upstream commits. The test says that its bounds only go down, so this is a maintainer's call. The new bound has about the slack the old one had (127,356 bytes, it was 115,164). The comment beside it says 183,000 bytes, which was measured on an older commit ofmain. The next push corrects it to 168,000.Earlier runs (builds 134164 and 134232, before #47129, with the test names of that time) showed two more causes. Both are answered on the WebKit side:
{ ...fn }. Bun names a frame by the own propertynameof the callee first, and bydisplayNameafter it. A copy that looks every key up makesnamea property of a function. Upstream WebKit/WebKit@e04a6f9faecf copies from a function by its Structure and leavesnamealone, and the run time of compiled programs still looks the keys up. Three programs printed another frame compiled than plain. A maintainer chose to turn upstream's fast path off in builds with the ahead-of-time compiler (780dc90982of Upgrade to upstream WebKit e8f704815e94 WebKit#923). With a local debug build of this branch,errors/frames-functions-display-name-statement.js,errors/frames-functions-given-display-name-far.mjsanderrors/names-frames-new-function-objects-names.mjsprint the same compiled and plain. The cost:{ ...fn }does not get upstream's speedup (160 ms against 50 ms onJSTests/microbenchmarks/object-spread-function.js).Array.fromin a compiled program held 441 functions. The flow analysis took the call ofnextinside the helperiteratorGenericNextfor a call of a value nobody knows. [JSC] AOT: flow follows Proxy and the library helpers; typed JSON.parse; the main module WebKit#930 changed that rule, and 22 functions are left (above).Build 134164 also showed a crash under collector stress (
SIGSEGVat address 0 inWTF::findAtomBeforeAdding). Its cause was onmaintoo:AOT::nameOfBuiltin()makes an atom while a collection ends, whereHeap::pruneDeadReferences()has set the atom table of the thread to null.The engine tests
test/aot/engine-testshas the IR text tests of the engine that need entries of Bun's table of builtins (1,601 files since #47129).defaultAsyncFromAsyncIteratorWithNext, which was number 23. Every number from 24 on is one lower: 2,648 numbers in 371 files.everyis 30 (was 31),find34,from46,map64 andsome88. The numbers of Bun's own functions start at 0x10000 and do not move. No file names a number that the engine's list does not have.test/aot/tools/update-ir-tests.tswrote them anew with a releasetestaoton Linux x64, and nothing else in those files changed.testaotandjscbuilt from this branch,testaot run test/aot/engine-testspasses: 1,599 files, 2 todo.The new test file
test/js/bun/jsc/webkit-upgrade-e8f704815e.test.tshas 17 cases. Four of them fail on Bun 1.4.3-canary, because the engine changes there:Math.sumPrecise([-1])-1.0000000000000002-1Proxy.revocable, afterlengthis deleted and defined again, against those of an arrow function after the same stepsname,length)length,name)Error.stackof an async function that awaits its own promise throughPromise.all[x, y].sort(boundComparator)when the comparator leaves optimized code (the program of oven-sh/WebKit#885)Array.prototype.sortitselfThe other 13 cases pass on both engines. They cover the code that the merge rewrote by hand: spread and rest of a function, the iterator protocol of
Array.from,Object.groupBy,Map.groupByand the iterator helpers,Array.fromAsync,Array.prototype.join,JSON.parseof objects with the same keys (also-0, invalid input and a reviver),Bun.JSONL.parseChunkcut at every position, loops that end in a null test or a negated comparison, and an anchored RegExp and aswitchon a substring.The bytecode snapshots
test/bundler/bundler_bytecode_portable.test.tscompares a hash of the serialized bytecode. 22 entries come from a local debug build with the merged engine. The entrybun build --bytecode libraries.jscomes from CI: the bundle of that entry differs on the machine the other values come from. All ten test platforms of build 133970 reported the same value for it, and accepted the other 22.Bun's CI on the first preview build
Build 133970 ran this branch with
autobuild-preview-pr-923-b6e34894. One test failed on every platform: the snapshot entry above, which had its old value then. Eight other tests failed and passed on a retry (bake.test.ts,hot.test.ts,no-orphans.test.ts,spawn_waiter_thread.test.ts,test-zlib-invalid-input-memory.js,nth-anplusb-ident.test.ts,process.test.js,bun.test.ts).The zip sizes in "The WebKit side" compare the release zips of that build with those of build 133646, which is
mainat the commit this branch started from. The range is over the 12 release zips. The unpacked binaries were not measured: the artifact store of CI is not reachable from the machine this was written on.The crash of #44697
test()records only where the match is. A read ofRegExp.lastMatch,RegExp.$1or another legacy static property runs the match again for the captures. That second run can need more stack than the first, and when it failed,RegExpGlobalData::getBackrefread through a null pointer. Upstream WebKit/WebKit@191803bb2304, which is in this range, throws aRangeErrorthere.true, thenpanic(main thread): Segmentation fault at address 0x4.true, thenRangeError: Out of memory, also forRegExp.$1,RegExp.$9,RegExp["$&"]andRegExp.lastParen.test/js/bun/jsc/regexp-legacy-static-properties.test.tsruns the program of upstream's stress test in a child withBUN_JSC_maxRegExpStackSize=65536and compares every line that the child prints:matched: truefor the firsttest(), aRangeErrorfor each read and for an assignment toRegExp.input, and the values of the properties after the next match.USE_SYSTEM_BUN=1 bun testfails it with the panic, andbun bd testpasses it. The test comes from #47160, which had the upstream commit alone (oven-sh/WebKit#929, closed now).What ran locally
webkit-upgrade-e8f704815e.test.tspasses 17 of 17, andregexp-legacy-static-properties.test.tspasses.bun run build:localagainst the merged WebKit (Debug, no ASAN).-p '42'prints42.test/js/bun/jsc: 215 pass. Twodomjit.test.tscases pass their 20 s limit in this Debug build. The same two take 42 s on a debug build ofmain.test/js/bun/jsonl, the worker tests, the GC tests and the heap snapshot tests pass.JSType.h,OptionsList.h, the WebCore bindings scripts and the structured clone sources have no upstream change in this range.src/jsc/JSType.rsneeds no change.The three assertion commits
WebKit/WebKit@0bf94cf0c1, WebKit/WebKit@4bc9ad4d7f and WebKit/WebKit@cf89f1571e check the bits of
Heap::m_worldStatewithRELEASE_ASSERT, in the functions through which a thread takes or gives up its access to the heap. Bun gives up heap access while the event loop waits (Bun__JSC_onBeforeWait) and takes it again after the wait. That order is the one the assertions check.Upstream changes
Range:
f59345e04a8d(2026-10-22) ..e8f704815e94(2026-10-27). 59 of the 360 upstream commits touchSource/JavaScriptCore,Source/WTForSource/bmalloc. 20 of the 59 change nothing that a JSCOnly build compiles: they touch a preferences yaml, a sandbox profile, the Xcode project, or code for Swift, GLib or Cocoa only.Highlights
JSON.parsereads the keys it already knows in a loop of their own (6f5f583b55). A key found inJSONCache's name table, and a value that is a cached string or an integer of at most nine digits, are read through a local cursor. The lexer is only used for the other values. Upstream measures 1.13x on its JSON benchmarks (geometric mean), up to 1.32x.e04a6f9fae):{ ...fn }andlet { a, ...rest } = fnare 5x faster. PostCSS does this once perLazyResult.Array.from,%TypedArray%.from,Object.groupBy,Map.groupByandIterator.prototype.flatMap/some/every/finddrive the iterator themselves (37aa2b5bd9). They no longer build a wrapper object for afor-ofloop: 1.1x to 1.6x on theArray.frommicrobenchmarks.Proxy.revocableis 2.9x faster (fad04e2527). The revoke function is aJSFunctionWithFieldswith a cached executable, and the result object has a cached Structure. The classProxyRevokeis gone.bd50166362). A null test or a negated compare that feeds a backward conditional jump is fused into the jump (jneq_null,jnless, ...). No opcode is new, but the bytecode of most loops changes.b92d6a6bea), andString#matchwith a constant anchored RegExp uses the filter in the DFG. The same commit makes DFG/FTLswitchon a substring rope read the width of the base string, not the bit cached in the rope.Array#sortcomparator returned past thesortcall (f274ef4c03), and a cross-instance Wasm tail call copied its frame from onerestoreFrameSizetoo low (0927910cf9).0bf94cf0c1,4bc9ad4d7f,cf89f1571e). A mutator that takes or gives up heap access in a state the protocol does not allow crashes now.Math.sumPreciseis correct for negative sums (8ee560d748):Math.sumPrecise([-1])was-1.0000000000000002.Runtime & builtins
e04a6f9fae(328286):@copyDataPropertiesand@cloneObjectaccept aJSFunctionsource on the path that reads the Structure, through the newJSFunction::canPerformFastEnumerablePropertyEnumeration(VM&). It needs an unmodifiednameandlength, no accessors and no own__proto__. object-spread-function 4.99x, object-rest-function 5.54x.37aa2b5bd9(328563): Five builtin files call@iteratorGenericNextin afor (;;)loop and close the iterator with@ifAbruptCloseIterator. The link-time constantdefaultAsyncFromAsyncIteratorWithNextis removed, anddefaultAsyncFromAsyncIteratorhas its body now.fad04e2527(328635):Proxy.revocable: see Highlights. Removed:ProxyRevoke.{h,cpp},ProxyRevokeInlines.h,proxyRevokeSpace,JSGlobalObject::proxyRevokeStructure(). Added:proxyRevocableResultStructure(),VM::proxyRevokeExecutable(),JSFunctionWithFields::Field::RevocableProxy, the identifiersproxyandrevoke. Observable: the own keys of the revoke function listlengthandnamefirst, like any function.e81441a5ec(328769):JSOnlyStringsAndInt32sJoineris renamedJSExactLengthJoiner.Array#joinkeeps its exact-length path for arrays that also hold booleans,undefinedornull.8ee560d748(315450):WTF::Xsum::XsumSmall::compute()rounded a negative sum away from zero when it must not.Math.sumPrecise([-Number.MAX_VALUE])was-Infinity.071ce01fcb(328147):Interpreter::getAsyncStackTracestops at the second visit of a promise combinator. An async function that awaits its own promise throughPromise.allno longer repeats its frame up toError.stackTraceLimit, or hangs.be583048f3(328788):Identifier::addno longer does one atomic ref and one deref of theAtomStringImplit returns.ca48e0119c(328786): The last twoUSE(BIGINT32)blocks are deleted. Dead code.Parser / bytecode generator
bd50166362(328623):emitJumpIfTrueandemitJumpIfFalseno longer require a forward target for their fusions.while (node != null)anddo {} while (!(a < b))end in one fused jump. The subject names only the null tests. The diff also covers the ten negated compares.4e5e850636(328770):BytecodeGeneratorBase<Traits>is folded intoBytecodeGenerator.GenericLabelandGenericBoundLabelare the plain classesLabelandBoundLabel, andLabel::bindtakes the instruction writer.BytecodeGeneratorBase.his deleted andBytecodeGeneratorBaseInlines.his renamedBytecodeGeneratorInlines.h.BytecodeList.rbloses the unused type:WasmBoundLabel, and no opcode.DFG / FTL
f274ef4c03(327983): An inlined bound function keeps the call kind of its caller.InlineCallFrame::BoundFunctionCallandBoundFunctionTailCallare removed. A bound comparator inlined intoArray#sortis anArraySortComparatorCall, so an OSR exit inside it restarts thesort. A recursive tail call through a bound function can become a jump in the FTL.b92d6a6bea(328389): See Highlights.compileRegExpMatchFast(DFG) returnsnullwithout a call when the first byte cannot start a match.RegExp
59e81f3e12(328828): A match array getsindex,input,groupsandindiceswritten into its butterfly before the array cell exists.tryCreateUninitializedRegExpMatchesArrayhas a fifth parameter, andJSArray::tryCreateUninitializedRestrictedButterflyis new.1984003fd9(328895): On x86_64 the Yarr JIT copies fewer than 16ParenContextframe slots with straight-line code, and eight per loop iteration above that. regexp-parencontext-frame-slots 1.80x.191803bb23(328417):RegExp.lastMatch,RegExp.$1and the other legacy properties throw aRangeErrorwhen the lazy re-match fails. Before, they read a null array.JSON
6f5f583b55(328615): See Highlights. The object branch ofLiteralParser::parseRecursivelyis one loop with the lambdasparseValue,putWithTransitionandfinishObject.Lexer::skipWhitespaceBeforeKey()is removed,Lexer::setPtr()andend()are new, andnumberOfDigitsForSafeInt32moves toParseInt.h.2dff3f1dbf(329046): Compile fix for the commit above with clang 20: three lambdas capturevmby name.GC / heap
0bf94cf0c1(328987):Heap::stopTheMutatorasserts that no mutator holds the conn, where it had a branch that returned false.4bc9ad4d7f(329005):Heap::resumeTheMutatorasserts that the mutator is stopped, has no heap access and no conn. It returned early when the mutator was not stopped.cf89f1571e(329038): Release asserts onHeap::m_worldStateinacquireAccessSlow,releaseAccessSlow,setNeedCollectionEpilogue,setMutatorWaiting,clearMutatorWaiting,Collector::beginCollectionInEachHeap,finishChangingPhaseandstopThePeriphery.Collector::requestCollectiongets two debug asserts.Heap::needCollectionEpilogue()is new.WebAssembly
0927910cf9(329002):Wasm::emitRestoreInstanceFrameIfNeededstarts its copy at the stack pointer from before the adjustment.WTF
45f193ae80(328940):Thread::tryCreate()returns null when the thread cannot be created.Thread::create()calls it and still crashes.$.agent.startin thejscshell throws.e8f704815e(329066): The defaults ofLOG_DISABLED,ASSERT_MSG_DISABLED,ASSERT_ARG_DISABLED,BACKTRACE_DISABLED,FATAL_DISABLEDandERROR_DISABLEDmove fromAssertions.htoPlatformEnable.h.bbfbc41dc9(327419): TheRELEASE_LOG*macros are defined once, on top of aWTF_RELEASE_LOG_SENDper backend.LOGF,SD_JOURNAL_SENDandLOG_ANDROID_SENDare removed.3757158274(328861):allowCompactPointers<T>()looks at theAllowCompactPointers<T*>specialization first.WTF_ALLOW_COMPACT_POINTERS_TO_INCOMPLETE_TYPE(JSC::JSCell)moves fromMicrotaskQueue.htoJSCJSValue.h.2b85a5e547(328859):printInternal(PrintStream&, String&)is defined inPrintStream.cpp, not inline.38418ba096(328643):NeverDestroyedandLazyNeverDestroyedread their storage throughstd::launder.701620c269(328791):Vector::appendRange(Range&&)for a sized range. The rest of the commit is WebCore.272972fe8c(328652):WTF::initializeObjectIdentifierDomain(). Only WebKit's GPU process calls it.961981e9e8(MediaTimeordering),2c813011e9(WeakListHashSetconst iterator),3e90cc907c(LoggingHashMap),474bb3fa62(BitSet::setEachNthBitassertsn).bmalloc / libpas
Bun's JavaScriptCore allocates through mimalloc, and the ASAN builds through the system allocator, so none of these changes what a shipped
bundoes.c8ce68fbaa(328247): Each page config of a heap has its own minimum of objects per page.PAS_MIN_OBJECTS_PER_PAGEis renamedPAS_DEFAULT_MIN_OBJECTS_PER_PAGE, andPAS_MAX_OBJECT_SIZEtakes the minimum as an argument.37e9021372(328674): Medium segregated pages take objects up to 18432 bytes (from 11776).ad3ad2c6ea(328277): Free small segregated pages stay committed 450 ms longer (900 ms on macOS).1ae8574624(328282): Four more size classes in the designated intrinsic heap: 112, 144, 272 and 384 bytes.Build system
9c5e8c5fc1(328481): CMake Debug builds compile bmalloc andFastMalloc.cppwith-O3, except with MSVC and clang-cl.3c41f3fb2f(329015): Symbols that only offlineasm output references getREFERENCED_FROM_ASM, for GCC LTO.Nothing for a JSCOnly build (20)
2fe794df22,a46f812bfd,0ae4c9d112,da8e478d08,1d91ff5512,ac53330cbd,319a9b6c84,8655634bf3,e381818e3a,280384b995,933708cada,3b48f12459,17d262face,4e2a07134b,d71f3d702b,500be61de4,ad490a9bef,58ebe7bde3,8bd119f86f,48fd938fe4: web preferences, sandbox profiles, the Xcode project, Swift bridging, GLib and GTK/WPE build files.no test proof · iteration 7 · platform-specific test(s) that do not run on this machine, deferring to CI, which covers all platforms: test/bundler/compile-aot-size.test.ts, test/bundler/bundler_bytecode_portable.test.ts