mirror of
https://github.com/oven-sh/bun
synced 2026-02-25 19:17:20 +01:00
# JavaScriptCore Upstream Changes: 1b6f54d1c872..upstream/main **Date range**: Feb 5 -- Feb 11, 2026 **Total JSC commits**: 38 --- ## 1. New Features ### WebAssembly JSPI (JavaScript Promise Integration) **Commit**: `53e97afd3421` -- [JSC] JSPI Implementation **Files changed**: 59 files, +3879/-148 lines Full implementation of the [WebAssembly JSPI proposal](https://github.com/WebAssembly/js-promise-integration). Adds two new APIs: - `WebAssembly.promising(wasmFun)` -- wraps a wasm function so it returns a Promise - `new WebAssembly.Suspending(jsFun)` -- wraps a JS function so wasm can suspend on its result Controlled by `useJSPI` feature flag (disabled by default). This is a large change that introduces: - New classes: `EvacuatedStack`, `PinballCompletion`, `JSPIContext`, `WebAssemblySuspending`, `WebAssemblyPromising`, `JSWebAssemblySuspendError` - New `JSPIContext` struct added to `VM` (field `topJSPIContext`) - New `pinballCompletionStructure` in VM - New `WebAssemblySuspendError` and `WebAssemblySuspending` lazy class structures in JSGlobalObject - New methods on VM: `addEvacuatedStackSlice`, `removeEvacuatedStackSlice`, `gatherEvacuatedStackRoots` - New iso subspace: `pinballCompletionSpace` **Follow-up**: `f67441012b90` -- JSPI cages should only generate JIT code when JITCage is enabled ### WebAssembly Memory64 in BBQ Tier **Commit**: `7b98e4b17594` -- Add support for Memory64 in BBQ Tier Extends Memory64 support from the interpreter to the BBQ JIT tier, allowing wasm modules to address >4GB of memory. ### WebAssembly Multi-Memory (instantiation only) **Commit**: `bdf26416947e` -- Support instantiating multiple wasm memories Adds support for instantiating multiple memories in wasm modules (but not executing instructions that use memories other than index 0). Gated behind `useWasmMultiMemory` flag. ### LOL (Lightweight Optimizing Language) JIT -- New Tier (In Progress) A new JIT compilation tier "LOL" is being built incrementally across multiple commits: - `dd56e0f5b991` -- Add get_argument/argument_count bytecodes - `fb43184a0a77` -- Add to_primitive-like bytecodes - `f52fa4a30c76` -- Add switch/throw bytecodes - `7fd04c82d291` -- Add support for this/prototype bytecodes - `11127b8a61e0` -- Add support for op_ret These commits add new files under `Source/JavaScriptCore/lol/` (LOLJIT.cpp, LOLJIT.h, LOLRegisterAllocator.h). This appears to be a new lightweight JIT tier between Baseline and DFG. --- ## 2. Performance Improvements ### Deep Rope String Slicing -- 168x faster **Commit**: `93f2fd68619b` -- [JSC] Limit rope traversal depth in `tryJSSubstringImpl` Limits rope traversal depth to 16 in `tryJSSubstringImpl`. Deep rope strings from repeated concatenation (`s += 'A'`) previously caused O(n^2) behavior. When the depth limit is exceeded, it falls back to `resolveRope` to flatten the string. This directly addresses a performance issue reported against Bun where it was significantly slower than Node.js. ### String#endsWith DFG/FTL Optimization -- up to 10.5x faster **Commit**: `901865149859` -- [JSC] Optimize `String#endsWith` in DFG/FTL Adds a new DFG/FTL intrinsic `StringPrototypeEndsWithIntrinsic` for `String.prototype.endsWith`. Constant folding case is 10.5x faster; general case is 1.45x faster. ### RegExp Flag Getters in DFG/FTL and IC -- 1.6x faster **Commit**: `1fe86a244d00` -- [JSC] Handle RegExp flag getters in DFG/FTL and IC Adds DFG/FTL and inline cache support for RegExp flag property getters (`.global`, `.ignoreCase`, `.multiline`, `.dotAll`, `.sticky`, `.unicode`, `.unicodeSets`, `.hasIndices`). ### String#@@iterator as NewInternalFieldObject in DFG/FTL **Commit**: `44cba41d8eef` -- [JSC] Handle `String#@@iterator` as `NewInternalFieldObject` in DFG/FTL Optimizes string iterator creation in DFG/FTL by treating it as a `NewInternalFieldObject`, enabling allocation sinking. ### ArithMod(Int52) in DFG/FTL **Commit**: `49a21e7ff327` -- [JSC] Add ArithMod(Int52Use, Int52Use) in DFG / FTL **Follow-ups**: `f96be6066671` (constant folding fix), `c8f283248f3f` (NaNOrInfinity fix) Adds Int52 modulo support in DFG/FTL, avoiding expensive `fmod` double operations when inputs are integer-like doubles. ### ArithDiv(Int52) in DFG/FTL -- REVERTED **Commit**: `582cb0306b7c` -- [JSC] Add ArithDiv(Int52Use, Int52Use) in DFG / FTL **Revert**: `2e967edd1dc0` -- Reverted due to JetStream3 regressions ### Intl formatToParts Pre-built Structure -- up to 1.15x faster **Commit**: `a5dd9753d23c` -- [JSC] Optimize Intl formatToParts methods with pre-built Structure Optimizes Intl's `formatToParts` methods by using pre-built Structures for the returned part objects. ### JSBigInt Inline Storage **Commit**: `dbc50284d4cf` -- [JSC] Inline storage into JSBigInt **Related**: `304cf0713b9d` -- Remove JSBigInt::rightTrim and JSBigInt::tryRightTrim Major structural change to JSBigInt: digits are now stored inline (trailing storage) instead of via a separate `CagedBarrierPtr`. This eliminates the separate allocation and pointer indirection. `tryRightTrim` and `rightTrim` removed; `createFrom` renamed to `tryCreateFrom` with span-based API. ### WYHash Always Enabled for Strings **Commit**: `14ba1421ca08` -- [JSC] Always use WYHash for strings Previously, WYHash had a threshold (disabled for short strings on weak devices). Now it's enabled regardless of string size. ### JIT Worklist Thread Count: 3 -> 4 **Commit**: `453c578cadf6` -- [JSC] Bump JIT worklist thread number from 3 to 4 ### Greedy Register Allocator Improvements **Commit**: `b642ae17aade` -- [JSC] Proactively coalesce spill slots during register allocation **Commit**: `a78705db7c08` -- [JSC] GreedyRegAlloc: amortize cost of clearing the visited set in the evict loop --- ## 3. Bug Fixes ### RegExp (YARR) Fixes - `dea6808af40e` -- **Fix stale captures in FixedCount groups in MatchOnly mode**: `.test()` was not clearing captures between FixedCount iterations, causing stale values visible to backreferences. - `437e137889ea` -- **Fix infinite loop in JIT for non-greedy backreference to zero-width capture**: A non-greedy backreference like `\1*?` could loop forever when the referenced capture was undefined or empty. - `d4f884d21c0e` -- **Fix backtracking in NestedAlternativeEnd**: Wrong jump target was used when backtracking from NestedAlternativeEnd. ### ARM64 Cached Immediate Fix **Commit**: `8396ad321ad0` -- [JSC] Fix edge case issue of cached imm in ARM64 TrustedImm32(-1) was not zero-extended when cached, causing wrong reuse when followed by TrustedImm64(-1). ### Wasm Fixes - `cea8513d43ef` -- **Fix RefCast/RefTest folding in B3**: The condition was inverted, causing wrong cast results. - `629632da96e1` -- **Fix debugger races with idle and active VMs in stop-the-world** - `e5391ad90f47` -- **Stack check on IPInt->BBQ loop OSR entry** - `fd15e0d70ab1` -- **Use FrameTracer in wasm table_init operations** ### Structure Heap Alignment Assert Fix **Commit**: `47b52526fd42` -- [JSC] Fix startOfStructureHeap alignment RELEASE_ASSERT --- ## 4. Bun-side Changes - Updated `WEBKIT_VERSION` to `f03492d0636f` - Updated `SerializedScriptValue.cpp`: replaced removed `JSBigInt::tryRightTrim` with `JSBigInt::tryCreateFrom` span-based API - Fixed `CloneSerializer`/`CloneDeserializer` inheritance (`private` -> `public CloneBase`) - Explicitly disabled `ENABLE_MEDIA_SOURCE`, `ENABLE_MEDIA_STREAM`, `ENABLE_WEB_RTC` in `build.ts` and `SetupWebKit.cmake` for JSCOnly port --- ## 5. Summary by Component | Component | Commits | Key Changes | |-----------|---------|-------------| | **WASM** | 9 | JSPI implementation, Memory64 BBQ, multi-memory, RefCast fix, stack checks, debugger races | | **DFG/FTL** | 6 | String#endsWith opt, RegExp flags opt, String@@iterator opt, ArithMod(Int52) | | **YARR (RegExp)** | 3 | Stale captures fix, infinite loop fix, NestedAlternativeEnd backtracking fix | | **B3/Air** | 3 | Spill slot coalescing, generational set for eviction, RefCast/RefTest fix | | **LOL JIT** | 5 | New JIT tier being built incrementally | | **Runtime** | 6 | BigInt inline storage, WYHash always-on, Intl formatToParts opt, ARM64 imm fix, rope depth limit | --------- Co-authored-by: Sosuke Suzuki <sosuke@bun.com>
npm install
bun run ffi
bun run log
bun run gzip
bun run async
bun run sqlite
# to use custom version of bun/deno/node binary
BUN=path/to/bun bun run ffi
# or edit .env file