Skip to content

libpas(win): release TLC commit charge on scavenge; harden VirtualQuery#185

Open
Jarred-Sumner wants to merge 1 commit intomainfrom
jarred/windows-tlc-decommit-commit-charge
Open

libpas(win): release TLC commit charge on scavenge; harden VirtualQuery#185
Jarred-Sumner wants to merge 1 commit intomainfrom
jarred/windows-tlc-decommit-commit-charge

Conversation

@Jarred-Sumner
Copy link
Copy Markdown
Collaborator

Summary

  • pas_thread_local_cache.c: switch the three TLC commit/decommit sites from the _without_mprotect variants to pas_page_malloc_commit/decommit. On Windows the _without_mprotect decommit uses DiscardVirtualMemory (does not release commit charge) while the matching commit always VirtualAlloc(MEM_COMMIT)s, so per-thread TLC commit charge ratcheted to high-water mark for the life of each thread. The TLC tracks pages_committed and recommits before reuse, so it doesn't need the keep-accessible semantics — VirtualFree(MEM_DECOMMIT) is correct here. POSIX production unchanged (PAS_MPROTECT_DECOMMITTED is PAS_ENABLE_TESTING).
  • pas_page_malloc.c: wrap the three unchecked VirtualQuery calls in the per-region fallback loops with PAS_ASSERT; on failure memInfo was uninitialized stack and the subsequent asserts/calls used garbage.
  • StructureAlignedMemoryAllocator.cpp: null-guard OSAllocator::commit(result, ...) on the Windows/PlayStation libpas path. bmalloc_try_allocate_auxiliary_with_alignment_inline can return null; VirtualAlloc(NULL, 16KB, MEM_COMMIT, ...) would then allocate and leak a fresh region.

Found while investigating oven-sh/bun#29412 (Windows commit-limit exhaustion: 11.26 GB commit / 1.10 GB RSS). The TLC asymmetry is a confirmed contributor; the other two are hardening in the exact code path that crashed.

Test plan

  • macOS debug build passes (bun build.ts debug → 3058/3058, bin/jsc smoke test OK)
  • Multi-threaded TLC create/destroy/scavenge stress via $.agent workers — exercises all three TLC sites, no asserts
  • Windows CI build (the Windows-specific VirtualFree(MEM_DECOMMIT) path is verified by inspection only on this host)

pas_thread_local_cache used the *_without_mprotect commit/decommit
variants. On Windows, decommit_impl(do_mprotect=false) maps to
DiscardVirtualMemory, which frees physical pages but does not release
commit charge, while commit_impl always issues VirtualAlloc(MEM_COMMIT).
The TLC tracks pages_committed and recommits before reuse, so it does not
need pages to stay accessible across the cycle; switch to
pas_page_malloc_commit/decommit so the scavenger actually returns commit
charge via VirtualFree(MEM_DECOMMIT). POSIX production builds are
unchanged (PAS_MPROTECT_DECOMMITTED is testing-only there).

Also:
- Wrap the three unchecked VirtualQuery calls in commit_impl/decommit_impl
  in PAS_ASSERT so failure surfaces instead of operating on stack garbage.
- StructureAlignedMemoryAllocator: guard OSAllocator::commit on Windows/PS
  when bmalloc_try_allocate_auxiliary returns null (would otherwise
  reserve+commit and leak a fresh 16 KB region at a kernel-chosen address).

Refs oven-sh/bun#29412
@coderabbitai
Copy link
Copy Markdown

coderabbitai bot commented Apr 17, 2026

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro

Run ID: 484e52e7-0e03-4a5d-b623-6b341df455e8

📥 Commits

Reviewing files that changed from the base of the PR and between c0eac76 and 309b195.

📒 Files selected for processing (3)
  • Source/JavaScriptCore/heap/StructureAlignedMemoryAllocator.cpp
  • Source/bmalloc/libpas/src/libpas/pas_page_malloc.c
  • Source/bmalloc/libpas/src/libpas/pas_thread_local_cache.c

Walkthrough

Platform-specific memory management improvements across JavaScript Core and libpas allocators. Changes include conditional commit logic on allocation success, strengthened Windows memory query error handling, and migration to standard mprotect-aware memory functions in thread-local cache operations.

Changes

Cohort / File(s) Summary
Allocation Failure Safety
Source/JavaScriptCore/heap/StructureAlignedMemoryAllocator.cpp
Added null-check condition before calling OSAllocator::commit to prevent committing memory regions when allocation fails on Windows/PlayStation LIBPAS builds.
Windows Memory Query Assertions
Source/bmalloc/libpas/src/libpas/pas_page_malloc.c
Wrapped VirtualQuery calls with PAS_ASSERT in Windows-specific commit and decommit paths. Updated comment to clarify decommit behavior is called by pas_expendable_memory.
Thread-Local Cache Memory Functions
Source/bmalloc/libpas/src/libpas/pas_thread_local_cache.c
Replaced _without_mprotect function variants with standard pas_page_malloc_commit and pas_page_malloc_decommit functions in TLC re-commitment, page commitment, and allocator range decommission operations.
🚥 Pre-merge checks | ✅ 1 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Description check ⚠️ Warning The description does not follow the repository template, which requires a Bugzilla bug reference and specific formatting with commit message structure. Add a Bugzilla bug reference link at the top, format as a commit message with 'Reviewed by' line, and follow the required template structure with explicit section markers.
✅ Passed checks (1 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly summarizes the three main changes: TLC commit charge release on Windows scavenging and VirtualQuery hardening.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.


Comment @coderabbitai help to get the list of available commands and usage tips.

@github-actions
Copy link
Copy Markdown

Preview Builds

Commit Release Date
309b1951 autobuild-preview-pr-185-309b1951 2026-04-17 21:48:26 UTC

Jarred-Sumner added a commit to oven-sh/bun that referenced this pull request Apr 17, 2026
Tests oven-sh/WebKit#185 (libpas Windows TLC commit-charge release).
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant