Repository navigation
fix(ffi): double-free segfault with symbols object - #919
Merged
Merged
Conversation
1 task
sosukesuzuki
pushed a commit
that referenced
this pull request
Oct 30, 2026
Fixes #44697 ### Problem - Bun's JavaScriptCore is 360 upstream commits behind WebKit/WebKit@e8f704815e94. 59 touch JavaScriptCore, WTF or bmalloc. - `RegExp.lastMatch` after a `test()` that matched can end the process: `panic(main thread): Segmentation fault at address 0x4`. - Two results are wrong: `Math.sumPrecise([-1])` is `-1.0000000000000002`, and an async function that awaits itself through `Promise.all` repeats its frame in `Error.stack`. ### Fix - `WEBKIT_VERSION` is a7b59e61de2e, the merge commit of oven-sh/WebKit#923: the engine of `main` plus the upstream merge. - Upstream deleted one builtin: in `test/aot/engine-tests`, 2,648 builtin numbers are one lower and 19 instance offsets eight bytes lower. Loop bytecode changes, so `bundler_bytecode_portable.test.ts` has new snapshots. - **Two test bounds go up, which needs a maintainer's yes**: the `--trim` size in `compile-aot-size.test.ts` and the function count of one program (Notes). - Verified, local debug build: `test/js/bun/jsc/webkit-upgrade-e8f704815e.test.ts` (new, 17 cases, Bun 1.4.3-canary fails 4) and `test/js/bun/jsc/regexp-legacy-static-properties.test.ts` (new, the panic on Bun 1.4.3-canary). `test/aot/engine-tests` passes with a release `testaot`. ### Background - `WEBKIT_VERSION` (`scripts/build/deps/webkit.ts`) names the oven-sh/WebKit release whose JavaScriptCore the build downloads. - The ahead-of-time compiler numbers the engine's JavaScript builtins by name order, and the instance of a compiled program has one word per link-time constant. ### Downsides - Size: hello world with `--aot --trim` maps 167,808 bytes more. A compiled program that calls `Array.from` holds 22 functions, was 6. - A thread that breaks the collector's stop-the-world protocol now crashes a release build (Notes). - The own keys of the `Proxy.revocable` revoke function now start with `length` and `name`. <details><summary>Notes</summary> #### The WebKit side oven-sh/WebKit#923 merges upstream `e8f704815e94` into 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: - Upstream now links its programs with `-z pack-relative-relocs` (WebKit/WebKit@c47b7c073c). The `jsc` and `testFFI` programs of the Linux lanes then need glibc 2.36. The arm64 test runner has glibc 2.35. - One new upstream test (`stress/regexp-legacy-static-properties-rematch-failure.js`) cannot pass in two test modes that only the fork has. - Upstream deleted one JavaScript builtin. The tests of the ahead-of-time compiler name builtins by number, and the numbers behind the deleted one moved. That pull request has a commit for each of them. After that, the fork's `main` got oven-sh/WebKit#914, #886 and #926, and Bun's `main` got 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.parse` that upstream rewrote, `Bun.JSONL` could give an object a Structure that a collection had freed. `bcd362b31e` over there repairs it and adds a stress test. With the `jsc` of the build before it, that test ends in `SIGSEGV` in 6 runs of 6. The fork's `main` then moved three more times, and each time its Bun side had to be on Bun's `main` before this branch could pin a build with it: | oven-sh/WebKit `main` | Bun side | merged into oven-sh/WebKit#923 at | |---|---|---| | #927 | #47129 | `be93e08e36` | | #930 | #47129 | `35b64c4afb` | | #919, #936 (ICU 79.1), #937 | #47281 | `b67a0b1a3a` | - `780dc90982` over there turns upstream's fast path for `{ ...fn }` off in builds with the ahead-of-time compiler (see "What Bun's CI showed"). - oven-sh/WebKit#923 is merged as `a7b59e61de`, and `WEBKIT_VERSION` is that commit. It has the same tree as `b67a0b1a3a`, the head whose preview build (`autobuild-preview-pr-923-b67a0b1a`) this branch pinned before. That is `8c6c963e3c`, which `main` pins since #47281, plus the upstream merge. The CI of oven-sh/WebKit#923 was green at that head: 84 jobs, with `testFFI`, `TestWTF`, `testaot` and `run-javascriptcore-tests` on Linux x64 and arm64. - A build of this branch against an engine whose Bun side is not on `main` does not work. With the preview of `780dc90982` and `main` before #47129, the build stopped at `src/jsc/bindings/BunCompiledModules.cpp:756` (`too few arguments to function call`, `JSC::AOT::tryReservePagesForNewThread`), and with that call changed every `bun build --compile --aot` ended with `IdOutOfRange`. 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 `e22cf6a525` now. On top of `3688162c4c` it 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 `main` up to #47129 and the preview of `35b64c4afb`. Three things failed that do not pass on a retry. `3688162c4c` answers each: | Test | Failure | Answer | |---|---|---| | `test/aot/engine/ir-1`, `ir-3`, `ir-5`, `ir-6` (nine `.ir` files, Linux x64) | `lower-to-b3: output line 7 does not match: Int64 b@22 = Load(b@10, offset = 8264, ..); nearest: .. offset = 8256 ..` | The offsets are written anew (see "The engine tests") | | `test/aot/parallel/arrays/searches-folds-and-flat-maps-of-a-list-bring-in-only-the-functions-that-do-them.js` | `ImageFunctionsEmitted <= 40, but the build counted 42` | The bound is 48. **A maintainer has to agree** | | `test/bundler/compile-aot-size.test.ts` | hello world with `--trim` maps 25,777,292 bytes, and the bound is 25,700,000 | The bound is 25,880,000. **A maintainer has to agree** | Eight 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 of `main` and 42 here. - Upstream's `Array.from` (WebKit/WebKit@37aa2b5bd94d) steps an iterator by a call of its `next` and closes it by a call of its `return`. The old text was a `for-of` loop. - One function of the library runs for every call of `Array.from`, so the compiler keeps what that call of `next` can reach by name. The 18 more functions are the two helpers `iteratorGenericNext` and `iteratorGenericClose`, one part of `Array.from` that is moved out of line, and the `next`, `return` and `throw` of array iterators, generators, iterator helpers and wrapped iterators. - A one-line `console.log(Array.from([1, 2, 3], x => x + 1).join())` holds 22 functions where `main` holds 6. Its bound is 24. - #47316 expands the two helpers in line in the front end (its engine half is oven-sh/WebKit#934). A release build of it keeps 25 functions for this program and 7 for the one-line program, so the bound of 40 holds again once that pull request is on `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: | hello world | canary of `main` (`081ace731d`) | build 135015 | bound | |---|---|---|---| | `--aot` | 68,138,180 | 68,305,988 | 68,440,000 | | `--aot --trim` | 25,584,836 | 25,752,644 | 25,700,000, now 25,880,000 | Both grow by 167,808 bytes. `.text` of `jsc` grows 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 of `main`. 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: - A stack frame after `{ ...fn }`. Bun names a frame by the own property `name` of the callee first, and by `displayName` after it. A copy that looks every key up makes `name` a property of a function. Upstream WebKit/WebKit@e04a6f9faecf copies from a function by its Structure and leaves `name` alone, 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 (`780dc90982` of oven-sh/WebKit#923). With a local debug build of this branch, `errors/frames-functions-display-name-statement.js`, `errors/frames-functions-given-display-name-far.mjs` and `errors/names-frames-new-function-objects-names.mjs` print the same compiled and plain. The cost: `{ ...fn }` does not get upstream's speedup (160 ms against 50 ms on `JSTests/microbenchmarks/object-spread-function.js`). - `Array.from` in a compiled program held 441 functions. The flow analysis took the call of `next` inside the helper `iteratorGenericNext` for a call of a value nobody knows. oven-sh/WebKit#930 changed that rule, and 22 functions are left (above). Build 134164 also showed a crash under collector stress (`SIGSEGV` at address 0 in `WTF::findAtomBeforeAdding`). Its cause was on `main` too: `AOT::nameOfBuiltin()` makes an atom while a collection ends, where `Heap::pruneDeadReferences()` has set the atom table of the thread to null. #### The engine tests `test/aot/engine-tests` has the IR text tests of the engine that need entries of Bun's table of builtins (1,601 files since #47129). - A test names a builtin that is written in JavaScript by its runtime function number. Upstream WebKit/WebKit@37aa2b5bd94d deleted `defaultAsyncFromAsyncIteratorWithNext`, which was number 23. Every number from 24 on is one lower: 2,648 numbers in 371 files. `every` is 30 (was 31), `find` 34, `from` 46, `map` 64 and `some` 88. 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. - The instance of a compiled program holds one word for every link-time constant of the engine, and the deleted builtin was one. Every field behind that list is eight bytes lower. Nine tests check the B3 of a function line by line and had such offsets in 19 lines (8040, 8168, 8192, 8216, 8264). `test/aot/tools/update-ir-tests.ts` wrote them anew with a release `testaot` on Linux x64, and nothing else in those files changed. - With a release `testaot` and `jsc` built from this branch, `testaot run test/aot/engine-tests` passes: 1,599 files, 2 todo. - oven-sh/WebKit#923 makes the same change of numbers in the engine's own tests. #### The new test file `test/js/bun/jsc/webkit-upgrade-e8f704815e.test.ts` has 17 cases. Four of them fail on Bun 1.4.3-canary, because the engine changes there: | Case | Old engine | New engine | |---|---|---| | `Math.sumPrecise([-1])` | `-1.0000000000000002` | `-1` | | Own keys of the revoke function of `Proxy.revocable`, after `length` is deleted and defined again, against those of an arrow function after the same steps | another order (`name`, `length`) | the same order (`length`, `name`) | | `Error.stack` of an async function that awaits its own promise through `Promise.all` | the frame repeats | one frame | | `[x, y].sort(boundComparator)` when the comparator leaves optimized code (the program of oven-sh/WebKit#885) | the caller gets `Array.prototype.sort` itself | the caller gets the sorted array | The 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.groupBy` and the iterator helpers, `Array.fromAsync`, `Array.prototype.join`, `JSON.parse` of objects with the same keys (also `-0`, invalid input and a reviver), `Bun.JSONL.parseChunk` cut at every position, loops that end in a null test or a negated comparison, and an anchored RegExp and a `switch` on a substring. #### The bytecode snapshots `test/bundler/bundler_bytecode_portable.test.ts` compares a hash of the serialized bytecode. 22 entries come from a local debug build with the merged engine. The entry `bun build --bytecode libraries.js` comes 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 `main` at 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 of `RegExp.lastMatch`, `RegExp.$1` or 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::getBackref` read through a null pointer. Upstream WebKit/WebKit@191803bb2304, which is in this range, throws a `RangeError` there. ```sh BUN_JSC_maxRegExpStackSize=65536 bun -e ' const re = new RegExp("^" + "(z)?".repeat(8) + "(?:a|b)+$"); console.log(re.test(Buffer.alloc(100000, "a").toString())); console.log(RegExp.lastMatch.length);' ``` - Bun 1.4.3-canary: `true`, then `panic(main thread): Segmentation fault at address 0x4`. - A debug build of this branch: `true`, then `RangeError: Out of memory`, also for `RegExp.$1`, `RegExp.$9`, `RegExp["$&"]` and `RegExp.lastParen`. `test/js/bun/jsc/regexp-legacy-static-properties.test.ts` runs the program of upstream's stress test in a child with `BUN_JSC_maxRegExpStackSize=65536` and compares every line that the child prints: `matched: true` for the first `test()`, a `RangeError` for each read and for an assignment to `RegExp.input`, and the values of the properties after the next match. `USE_SYSTEM_BUN=1 bun test` fails it with the panic, and `bun bd test` passes it. The test comes from #47160, which had the upstream commit alone (oven-sh/WebKit#929, closed now). #### What ran locally - With the pin of the merge commit, a debug build with ASAN: `webkit-upgrade-e8f704815e.test.ts` passes 17 of 17, and `regexp-legacy-static-properties.test.ts` passes. - `bun run build:local` against the merged WebKit (Debug, no ASAN). `-p '42'` prints `42`. - `test/js/bun/jsc`: 215 pass. Two `domjit.test.ts` cases pass their 20 s limit in this Debug build. The same two take 42 s on a debug build of `main`. - `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.rs` needs no change. #### The three assertion commits WebKit/WebKit@0bf94cf0c1, WebKit/WebKit@4bc9ad4d7f and WebKit/WebKit@cf89f1571e check the bits of `Heap::m_worldState` with `RELEASE_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`](WebKit/WebKit@f59345e) (2026-10-22) .. [`e8f704815e94`](WebKit/WebKit@e8f7048) (2026-10-27). **59** of the 360 upstream commits touch `Source/JavaScriptCore`, `Source/WTF` or `Source/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.parse` reads the keys it already knows in a loop of their own** ([`6f5f583b55`](WebKit/WebKit@6f5f583b55)). A key found in `JSONCache`'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. - **Object spread and rest of a function take the fast path** ([`e04a6f9fae`](WebKit/WebKit@e04a6f9fae)): `{ ...fn }` and `let { a, ...rest } = fn` are 5x faster. PostCSS does this once per `LazyResult`. - **`Array.from`, `%TypedArray%.from`, `Object.groupBy`, `Map.groupBy` and `Iterator.prototype.flatMap/some/every/find` drive the iterator themselves** ([`37aa2b5bd9`](WebKit/WebKit@37aa2b5bd9)). They no longer build a wrapper object for a `for-of` loop: 1.1x to 1.6x on the `Array.from` microbenchmarks. - **`Proxy.revocable` is 2.9x faster** ([`fad04e2527`](WebKit/WebKit@fad04e2527)). The revoke function is a `JSFunctionWithFields` with a cached executable, and the result object has a cached Structure. The class `ProxyRevoke` is gone. - **Loop conditions are one instruction more often** ([`bd50166362`](WebKit/WebKit@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. - **The RegExp first-character filter reads substring ropes in place** ([`b92d6a6bea`](WebKit/WebKit@b92d6a6bea)), and `String#match` with a constant anchored RegExp uses the filter in the DFG. The same commit makes DFG/FTL `switch` on a substring rope read the width of the base string, not the bit cached in the rope. - **Two DFG/FTL and Wasm miscompile fixes**: an OSR exit in a bound `Array#sort` comparator returned past the `sort` call ([`f274ef4c03`](WebKit/WebKit@f274ef4c03)), and a cross-instance Wasm tail call copied its frame from one `restoreFrameSize` too low ([`0927910cf9`](WebKit/WebKit@0927910cf9)). - **The GC asserts its stop-the-world protocol in release builds** ([`0bf94cf0c1`](WebKit/WebKit@0bf94cf0c1), [`4bc9ad4d7f`](WebKit/WebKit@4bc9ad4d7f), [`cf89f1571e`](WebKit/WebKit@cf89f1571e)). A mutator that takes or gives up heap access in a state the protocol does not allow crashes now. - **`Math.sumPrecise` is correct for negative sums** ([`8ee560d748`](WebKit/WebKit@8ee560d748)): `Math.sumPrecise([-1])` was `-1.0000000000000002`. ### Runtime & builtins - [`e04a6f9fae`](WebKit/WebKit@e04a6f9fae) ([328286](https://bugs.webkit.org/show_bug.cgi?id=328286)): `@copyDataProperties` and `@cloneObject` accept a `JSFunction` source on the path that reads the Structure, through the new `JSFunction::canPerformFastEnumerablePropertyEnumeration(VM&)`. It needs an unmodified `name` and `length`, no accessors and no own `__proto__`. object-spread-function 4.99x, object-rest-function 5.54x. - [`37aa2b5bd9`](WebKit/WebKit@37aa2b5bd9) ([328563](https://bugs.webkit.org/show_bug.cgi?id=328563)): Five builtin files call `@iteratorGenericNext` in a `for (;;)` loop and close the iterator with `@ifAbruptCloseIterator`. The link-time constant `defaultAsyncFromAsyncIteratorWithNext` is removed, and `defaultAsyncFromAsyncIterator` has its body now. - [`fad04e2527`](WebKit/WebKit@fad04e2527) ([328635](https://bugs.webkit.org/show_bug.cgi?id=328635)): `Proxy.revocable`: see Highlights. Removed: `ProxyRevoke.{h,cpp}`, `ProxyRevokeInlines.h`, `proxyRevokeSpace`, `JSGlobalObject::proxyRevokeStructure()`. Added: `proxyRevocableResultStructure()`, `VM::proxyRevokeExecutable()`, `JSFunctionWithFields::Field::RevocableProxy`, the identifiers `proxy` and `revoke`. Observable: the own keys of the revoke function list `length` and `name` first, like any function. - [`e81441a5ec`](WebKit/WebKit@e81441a5ec) ([328769](https://bugs.webkit.org/show_bug.cgi?id=328769)): `JSOnlyStringsAndInt32sJoiner` is renamed `JSExactLengthJoiner`. `Array#join` keeps its exact-length path for arrays that also hold booleans, `undefined` or `null`. - [`8ee560d748`](WebKit/WebKit@8ee560d748) ([315450](https://bugs.webkit.org/show_bug.cgi?id=315450)): `WTF::Xsum::XsumSmall::compute()` rounded a negative sum away from zero when it must not. `Math.sumPrecise([-Number.MAX_VALUE])` was `-Infinity`. - [`071ce01fcb`](WebKit/WebKit@071ce01fcb) ([328147](https://bugs.webkit.org/show_bug.cgi?id=328147)): `Interpreter::getAsyncStackTrace` stops at the second visit of a promise combinator. An async function that awaits its own promise through `Promise.all` no longer repeats its frame up to `Error.stackTraceLimit`, or hangs. - [`be583048f3`](WebKit/WebKit@be583048f3) ([328788](https://bugs.webkit.org/show_bug.cgi?id=328788)): `Identifier::add` no longer does one atomic ref and one deref of the `AtomStringImpl` it returns. - [`ca48e0119c`](WebKit/WebKit@ca48e0119c) ([328786](https://bugs.webkit.org/show_bug.cgi?id=328786)): The last two `USE(BIGINT32)` blocks are deleted. Dead code. ### Parser / bytecode generator - [`bd50166362`](WebKit/WebKit@bd50166362) ([328623](https://bugs.webkit.org/show_bug.cgi?id=328623)): `emitJumpIfTrue` and `emitJumpIfFalse` no longer require a forward target for their fusions. `while (node != null)` and `do {} while (!(a < b))` end in one fused jump. The subject names only the null tests. The diff also covers the ten negated compares. - [`4e5e850636`](WebKit/WebKit@4e5e850636) ([328770](https://bugs.webkit.org/show_bug.cgi?id=328770)): `BytecodeGeneratorBase<Traits>` is folded into `BytecodeGenerator`. `GenericLabel` and `GenericBoundLabel` are the plain classes `Label` and `BoundLabel`, and `Label::bind` takes the instruction writer. `BytecodeGeneratorBase.h` is deleted and `BytecodeGeneratorBaseInlines.h` is renamed `BytecodeGeneratorInlines.h`. `BytecodeList.rb` loses the unused type `:WasmBoundLabel`, and no opcode. ### DFG / FTL - [`f274ef4c03`](WebKit/WebKit@f274ef4c03) ([327983](https://bugs.webkit.org/show_bug.cgi?id=327983)): An inlined bound function keeps the call kind of its caller. `InlineCallFrame::BoundFunctionCall` and `BoundFunctionTailCall` are removed. A bound comparator inlined into `Array#sort` is an `ArraySortComparatorCall`, so an OSR exit inside it restarts the `sort`. A recursive tail call through a bound function can become a jump in the FTL. - [`b92d6a6bea`](WebKit/WebKit@b92d6a6bea) ([328389](https://bugs.webkit.org/show_bug.cgi?id=328389)): See Highlights. `compileRegExpMatchFast` (DFG) returns `null` without a call when the first byte cannot start a match. ### RegExp - [`59e81f3e12`](WebKit/WebKit@59e81f3e12) ([328828](https://bugs.webkit.org/show_bug.cgi?id=328828)): A match array gets `index`, `input`, `groups` and `indices` written into its butterfly before the array cell exists. `tryCreateUninitializedRegExpMatchesArray` has a fifth parameter, and `JSArray::tryCreateUninitializedRestrictedButterfly` is new. - [`1984003fd9`](WebKit/WebKit@1984003fd9) ([328895](https://bugs.webkit.org/show_bug.cgi?id=328895)): On x86_64 the Yarr JIT copies fewer than 16 `ParenContext` frame slots with straight-line code, and eight per loop iteration above that. regexp-parencontext-frame-slots 1.80x. - [`191803bb23`](WebKit/WebKit@191803bb23) ([328417](https://bugs.webkit.org/show_bug.cgi?id=328417)): `RegExp.lastMatch`, `RegExp.$1` and the other legacy properties throw a `RangeError` when the lazy re-match fails. Before, they read a null array. ### JSON - [`6f5f583b55`](WebKit/WebKit@6f5f583b55) ([328615](https://bugs.webkit.org/show_bug.cgi?id=328615)): See Highlights. The object branch of `LiteralParser::parseRecursively` is one loop with the lambdas `parseValue`, `putWithTransition` and `finishObject`. `Lexer::skipWhitespaceBeforeKey()` is removed, `Lexer::setPtr()` and `end()` are new, and `numberOfDigitsForSafeInt32` moves to `ParseInt.h`. - [`2dff3f1dbf`](WebKit/WebKit@2dff3f1dbf) ([329046](https://bugs.webkit.org/show_bug.cgi?id=329046)): Compile fix for the commit above with clang 20: three lambdas capture `vm` by name. ### GC / heap - [`0bf94cf0c1`](WebKit/WebKit@0bf94cf0c1) ([328987](https://bugs.webkit.org/show_bug.cgi?id=328987)): `Heap::stopTheMutator` asserts that no mutator holds the conn, where it had a branch that returned false. - [`4bc9ad4d7f`](WebKit/WebKit@4bc9ad4d7f) ([329005](https://bugs.webkit.org/show_bug.cgi?id=329005)): `Heap::resumeTheMutator` asserts that the mutator is stopped, has no heap access and no conn. It returned early when the mutator was not stopped. - [`cf89f1571e`](WebKit/WebKit@cf89f1571e) ([329038](https://bugs.webkit.org/show_bug.cgi?id=329038)): Release asserts on `Heap::m_worldState` in `acquireAccessSlow`, `releaseAccessSlow`, `setNeedCollectionEpilogue`, `setMutatorWaiting`, `clearMutatorWaiting`, `Collector::beginCollectionInEachHeap`, `finishChangingPhase` and `stopThePeriphery`. `Collector::requestCollection` gets two debug asserts. `Heap::needCollectionEpilogue()` is new. ### WebAssembly - [`0927910cf9`](WebKit/WebKit@0927910cf9) ([329002](https://bugs.webkit.org/show_bug.cgi?id=329002)): `Wasm::emitRestoreInstanceFrameIfNeeded` starts its copy at the stack pointer from before the adjustment. ### WTF - [`45f193ae80`](WebKit/WebKit@45f193ae80) ([328940](https://bugs.webkit.org/show_bug.cgi?id=328940)): `Thread::tryCreate()` returns null when the thread cannot be created. `Thread::create()` calls it and still crashes. `$.agent.start` in the `jsc` shell throws. - [`e8f704815e`](WebKit/WebKit@e8f704815e) ([329066](https://bugs.webkit.org/show_bug.cgi?id=329066)): The defaults of `LOG_DISABLED`, `ASSERT_MSG_DISABLED`, `ASSERT_ARG_DISABLED`, `BACKTRACE_DISABLED`, `FATAL_DISABLED` and `ERROR_DISABLED` move from `Assertions.h` to `PlatformEnable.h`. - [`bbfbc41dc9`](WebKit/WebKit@bbfbc41dc9) ([327419](https://bugs.webkit.org/show_bug.cgi?id=327419)): The `RELEASE_LOG*` macros are defined once, on top of a `WTF_RELEASE_LOG_SEND` per backend. `LOGF`, `SD_JOURNAL_SEND` and `LOG_ANDROID_SEND` are removed. - [`3757158274`](WebKit/WebKit@3757158274) ([328861](https://bugs.webkit.org/show_bug.cgi?id=328861)): `allowCompactPointers<T>()` looks at the `AllowCompactPointers<T*>` specialization first. `WTF_ALLOW_COMPACT_POINTERS_TO_INCOMPLETE_TYPE(JSC::JSCell)` moves from `MicrotaskQueue.h` to `JSCJSValue.h`. - [`2b85a5e547`](WebKit/WebKit@2b85a5e547) ([328859](https://bugs.webkit.org/show_bug.cgi?id=328859)): `printInternal(PrintStream&, String&)` is defined in `PrintStream.cpp`, not inline. - [`38418ba096`](WebKit/WebKit@38418ba096) ([328643](https://bugs.webkit.org/show_bug.cgi?id=328643)): `NeverDestroyed` and `LazyNeverDestroyed` read their storage through `std::launder`. - [`701620c269`](WebKit/WebKit@701620c269) ([328791](https://bugs.webkit.org/show_bug.cgi?id=328791)): `Vector::appendRange(Range&&)` for a sized range. The rest of the commit is WebCore. - [`272972fe8c`](WebKit/WebKit@272972fe8c) ([328652](https://bugs.webkit.org/show_bug.cgi?id=328652)): `WTF::initializeObjectIdentifierDomain()`. Only WebKit's GPU process calls it. - Fixes in headers that nothing in JavaScriptCore uses: [`961981e9e8`](WebKit/WebKit@961981e9e8) (`MediaTime` ordering), [`2c813011e9`](WebKit/WebKit@2c813011e9) (`WeakListHashSet` const iterator), [`3e90cc907c`](WebKit/WebKit@3e90cc907c) (`LoggingHashMap`), [`474bb3fa62`](WebKit/WebKit@474bb3fa62) (`BitSet::setEachNthBit` asserts `n`). ### bmalloc / libpas Bun's JavaScriptCore allocates through mimalloc, and the ASAN builds through the system allocator, so none of these changes what a shipped `bun` does. - [`c8ce68fbaa`](WebKit/WebKit@c8ce68fbaa) ([328247](https://bugs.webkit.org/show_bug.cgi?id=328247)): Each page config of a heap has its own minimum of objects per page. `PAS_MIN_OBJECTS_PER_PAGE` is renamed `PAS_DEFAULT_MIN_OBJECTS_PER_PAGE`, and `PAS_MAX_OBJECT_SIZE` takes the minimum as an argument. - [`37e9021372`](WebKit/WebKit@37e9021372) ([328674](https://bugs.webkit.org/show_bug.cgi?id=328674)): Medium segregated pages take objects up to 18432 bytes (from 11776). - [`ad3ad2c6ea`](WebKit/WebKit@ad3ad2c6ea) ([328277](https://bugs.webkit.org/show_bug.cgi?id=328277)): Free small segregated pages stay committed 450 ms longer (900 ms on macOS). - [`1ae8574624`](WebKit/WebKit@1ae8574624) ([328282](https://bugs.webkit.org/show_bug.cgi?id=328282)): Four more size classes in the designated intrinsic heap: 112, 144, 272 and 384 bytes. ### Build system - [`9c5e8c5fc1`](WebKit/WebKit@9c5e8c5fc1) ([328481](https://bugs.webkit.org/show_bug.cgi?id=328481)): CMake Debug builds compile bmalloc and `FastMalloc.cpp` with `-O3`, except with MSVC and clang-cl. - [`3c41f3fb2f`](WebKit/WebKit@3c41f3fb2f) ([329015](https://bugs.webkit.org/show_bug.cgi?id=329015)): Symbols that only offlineasm output references get `REFERENCED_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. </details> <!-- robobun:evidence:begin --> --- **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 <!-- robobun:evidence:end -->
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.
I believe this might have been what was causing some people to face segfaults with FFI. I sadly didn't catch this one in #793