Bun добавил поддержку потоков с общей памятью в JavaScriptCore
В рамках открытого PR в репозитории WebKit реализованы общие‑heap потоки для JavaScriptCore: новые API, тестовый набор, TSAN‑сборка без гонок и ряд оптимизаций, готовых к использованию в Bun.
Bun получил возможность запускать JavaScript‑код в нескольких потоках, используя общую кучу в движке JavaScriptCore (JSC). Это первый шаг к полноценной многопоточности в среде, где до этого всё исполнялось в едином потоке, и открывает путь к значительным ускорениям серверных приложений.
Как реализованы общие‑heap потоки?
В PR описаны детали архитектуры: отдельный heap‑сервер, аллокаторы per‑thread, общий VM‑state, а также новые типы «TID/SW‑tagged» и сегментированные «butterflies». Для синхронизации добавлен набор API Thread/Lock/Condition/ThreadLocal и поддержка атомиков на свойствах объектов, включаемый флагом --useThreads. Все функции работают через «semantic oracle» – глобальный JSLock, который сериализует доступ к общей памяти.
Что изменилось в тестовой инфраструктуре?
- Добавлен набор из 39 тестов, проверяющих корректность работы многопоточного кода.
- Встроена сборка без JIT, совместимая с TSAN; при простое она не генерирует ни одной гонки данных.
- В тестовом раннере появились тайм‑ауты, позволяющие фиксировать зависания как падения.
- Показатели прохождения: 81 из 85 тестов успешно завершились, оставшиеся два – тайм‑ауты, а остальные – фиксированы в последующих патчах.
Какие оптимизации JIT‑компилятора включены?
- Тiers‑based JIT теперь учитывает TID/SW‑теги, позволяя выполнять быстрые проверки в FTL и использовать epoch‑based сборку CodeBlock.
- Введён «per‑thread fresh‑block cache», который уменьшил нагрузку на глобальный аллокатор до 0.33 % всех выделений.
- Переписаны пути доступа к «butterfly»‑структурам: теперь при конфликте используется быстрый «slow‑path», а в обычных случаях – прямой доступ без сегментации.
Какой эффект на производительность?
- По результатам измерений 99.67 % из 70.9 млн ячеек уже попадают в «interval‑bump», а оставшиеся 0.33 % требуют лишь ~250 мс дополнительного времени на трёхшаговый поиск аллокатора.
- Сокращение «tax» в JIT‑слое с 1912 мс до 1214 мс (≈ 36 % улучшения) достигается за счёт устранения лишних проверок в GC и оптимизации доступа к структурам.
- В тестах с
String.fromCharCodeнаблюдалось до 15‑кратное ускорение после исправления ранних гонок при первом обращении из воркера.
Какие баги и регрессии устранены?
- Исправлен порядок линковки статической библиотеки ICU в модуле WTF.
- Устранены два сбоя сборки без JIT, связанные с неправильными зависимостями.
- Сняты гонки в
LocalAllocatorиHeapпри работе в режиме shared‑mode, а также исправлены проблемы сwaiter listиcondition wakeup. - Добавлены проверки в DFG‑байткод‑парсер, предотвращающие бесконечные OSR‑выходы при первом доступе к lazy‑статическим свойствам из воркера.
Что это значит для бизнеса?
Благодаря поддержке многопоточности в Bun можно разместить тяжёлые серверные задачи (например, генерацию PDF, обработку изображений или парсинг больших JSON‑файлов) в отдельных потоках без риска гонок. На практике это сокращает время отклика типичного API‑запроса на 30‑40 % и позволяет более эффективно использовать многоядерные серверы, экономя до 25 % расходов на инфраструктуру.