[browser][coreclr] WASM-specific GC OS layer; no mmap/decommit - #127328

Merged
pavelsavara merged 47 commits into
dotnet:mainfrom
pavelsavara:browser_no_mmap
May 7, 2026
Merged

[browser][coreclr] WASM-specific GC OS layer; no mmap/decommit#127328
pavelsavara merged 47 commits into
dotnet:mainfrom
pavelsavara:browser_no_mmap

Conversation

@pavelsavara

@pavelsavarapavelsavara commented Apr 23, 2026

Copy link
Copy Markdown
Member

Fixes#121036
Fixes#117813
Fixes#118943

Summary

This PR adds a dedicated WASM implementation of the GC's OS abstraction layer
(GCToOSInterface) and updates the GC and PAL to handle the fact that on WASM
there is no virtual memory: pages cannot be reserved without committing,
partial unmaps don't return memory to the engine, and MAP_FIXED / madvise
are not supported.

The previous approach reused gcenv.unix.cpp with #ifdef TARGET_WASM patches
and overloaded use_large_pages_p to mean "decommit is a no-op". This change
splits those concerns:

  • A new gc/wasm/gcenv.cpp replaces gc/unix/gcenv.unix.cpp on WASM and
    implements VirtualReserve / VirtualCommit / VirtualDecommit /
    VirtualRelease on top of posix_memalign / free. WASM-specific patches
    in gcenv.unix.cpp are removed.
  • A new GC flag never_decommit_p replaces every "is decommit a no-op" check
    that was previously expressed as use_large_pages_p. It is set on WASM
    unconditionally and on other platforms whenever use_large_pages_p is set.
  • gc/CMakeLists.txt now selects gc/wasm for WASM targets while still
    including unix/configure.cmake to generate config.gc.h.
  • The PAL's virtual.cpp is similarly cleaned up to use posix_memalign /
    free on WASM and to zero memory on MEM_DECOMMIT, so the next
    VirtualCommit (a no-op on WASM) sees zeroed memory.
  • A new minipal_getpagesize abstraction is introduced. On WASM it returns a
    compile-time constant of 16 KB (the GC's page granularity, distinct from the
    64 KB memory.grow granularity that getpagesize() reports). On Windows it
    returns the 4 KB constant inline. On other POSIX systems it caches
    getpagesize() once per process. CoreCLR PAL callers are updated to use it.

Why a separate never_decommit_p

On large pages, decommit is a no-op because the OS pre-commits the entire
range. On WASM, decommit is a no-op because there is no way to give linear
memory back to the engine. The two cases share the same set of GC code paths
that must be skipped or modified (decommit_ephemeral_segment_pages,
decommit_step, decommit_region, decommit_heap_segment_pages,
decommit_heap_segment, distribute_free_regions tail-decommit,
reset_memory, virtual_commit, virtual_decommit assert), but they have
nothing else in common. Reusing use_large_pages_p on WASM was misleading and
made it easy to forget large-pages-only behavior (e.g., pre-touch). The new
flag captures only the "decommit is a no-op" semantics; non-WASM behavior is
unchanged because never_decommit_p == use_large_pages_p everywhere except
WASM.

Why minipal_getpagesize

The GC needs the OS page size to be a compile-time constant on WASM (16 KB)
so that alignment math folds. getpagesize() on emscripten returns 64 KB
(the memory.grow granularity), which is too coarse for GC alignment and
thresholds. Centralizing this in minipal lets PAL and GC agree on a single
value and avoids #ifdefs at every call site.

Notes

  • VirtualReserveAndCommitLargePages on WASM falls through to the regular
    reserve/commit path; the GC does not request large pages on WASM.
  • posix_memalign may return either freshly grown linear memory (zeroed by
    the WASM spec) or a recycled block from emscripten's allocator free list.
    We always memset to zero on reserve and on decommit so callers can rely
    on the standard "memory starts zeroed" contract.
  • VirtualReset returns false on WASM, forcing the GC to use the
    decommit+commit fallback (memset to zero) rather than relying on
    madvise, which is a no-op on emscripten.

@pavelsavarapavelsavara added this to the 11.0.0 milestone Apr 23, 2026
@pavelsavarapavelsavara self-assigned this Apr 23, 2026
CopilotAI review requested due to automatic review settings April 23, 2026 16:55
@pavelsavarapavelsavara added arch-wasm WebAssembly architecture area-GC-coreclr labels Apr 23, 2026
@dotnet-policy-service

Copy link
Copy Markdown
Contributor

Tagging subscribers to this area: @JulieLeeMSFT, @dotnet/gc
See info in area-owners.md if you want to be subscribed.

CopilotAI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR separates WebAssembly-specific GC OS interface behavior from the shared Unix implementation by introducing a dedicated gcenv.wasm.cpp, and adjusts the PAL virtual memory implementation on WASM to avoid relying on Emscripten’s incomplete mmap/munmap support.

Changes:

  • Added a dedicated WASM GCToOSInterface implementation (gcenv.wasm.cpp) and CMake wiring for building it.
  • Routed WASM GC builds to the new gc/wasm directory and removed WASM-specific #ifdef paths from gcenv.unix.cpp.
  • Updated PAL virtual memory reserve/release on WASM to use posix_memalign/free instead of mmap/munmap.

Reviewed changes

Copilot reviewed 5 out of 5 changed files in this pull request and generated 4 comments.

Show a summary per file
FileDescription
src/coreclr/pal/src/map/virtual.cppSwitches WASM reserve/release behavior to posix_memalign/free and adjusts related error/cleanup paths.
src/coreclr/gc/wasm/gcenv.wasm.cppNew WASM-specific GC OS interface implementation (virtual memory, CPU/NUMA stubs, memory stats).
src/coreclr/gc/wasm/CMakeLists.txtAdds build definition for the WASM GC PAL object library.
src/coreclr/gc/unix/gcenv.unix.cppRemoves WASM-specific branches and fixes nanosleep EINTR retry logic.
src/coreclr/gc/CMakeLists.txtRoutes WASM builds to gc/wasm instead of gc/unix.

Comment threadsrc/coreclr/pal/src/map/virtual.cpp
Comment threadsrc/coreclr/pal/src/map/virtual.cpp Outdated
Comment threadsrc/coreclr/gc/wasm/gcenv.wasm.cpp Outdated
Comment threadsrc/coreclr/gc/wasm/gcenv.wasm.cpp Outdated
@pavelsavarapavelsavara changed the title [wasm][coreclr] Extract WASM-specific GC memory management into dedicated file[browser/wasi] Dedicated WASM GC PAL — replace mmap with posix_memalign and optimize memory operationsApr 23, 2026
@pavelsavarapavelsavara changed the title [browser/wasi] Dedicated WASM GC PAL — replace mmap with posix_memalign and optimize memory operations[browser/wasi][coreCLR] Dedicated WASM GC PAL — replace mmap with posix_memalign and optimize memory operationsApr 24, 2026
CopilotAI review requested due to automatic review settings April 24, 2026 08:20

CopilotAI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 7 out of 7 changed files in this pull request and generated 7 comments.

Comment threadsrc/coreclr/gc/wasm/gcenv.wasm.cpp Outdated
Comment threadsrc/coreclr/gc/wasm/gcenv.wasm.cpp Outdated
Comment threadsrc/coreclr/gc/wasm/gcenv.wasm.cpp Outdated
Comment threadsrc/coreclr/gc/wasm/gcenv.wasm.cpp Outdated
Comment threadsrc/coreclr/pal/src/map/virtual.cpp Outdated
Comment threadsrc/coreclr/pal/src/map/virtual.cpp Outdated
Comment threadsrc/coreclr/pal/src/map/virtual.cpp Outdated
CopilotAI review requested due to automatic review settings April 24, 2026 11:37
@pavelsavara
pavelsavara marked this pull request as ready for review April 24, 2026 11:43

CopilotAI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 7 out of 7 changed files in this pull request and generated 7 comments.

Comment threadsrc/coreclr/gc/wasm/gcenv.cpp
Comment threadsrc/coreclr/gc/wasm/CMakeLists.txt
Comment threadsrc/coreclr/gc/wasm/gcenv.cpp
Comment threadsrc/coreclr/pal/src/map/virtual.cpp Outdated
Comment threadsrc/coreclr/gc/wasm/gcenv.wasm.cpp Outdated
Comment threadsrc/coreclr/gc/wasm/gcenv.cpp
Comment threadsrc/coreclr/gc/wasm/gcenv.cpp

CopilotAI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 7 out of 7 changed files in this pull request and generated 1 comment.

Comment threadsrc/coreclr/gc/wasm/gcenv.cpp
Comment threadsrc/native/minipal/wasm.h Outdated
CopilotAI review requested due to automatic review settings May 6, 2026 07:36

CopilotAI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 17 out of 17 changed files in this pull request and generated no new comments.

@pavelsavara
pavelsavara requested a review from janvorliMay 6, 2026 12:59
Comment threadsrc/coreclr/gc/regions_segments.cpp Outdated
Comment threadsrc/coreclr/pal/src/map/virtual.cpp Outdated
Comment threadsrc/coreclr/gc/wasm/CMakeLists.txt

@janvorlijanvorli left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM, thank you!

@pavelsavara

Copy link
Copy Markdown
MemberAuthor

/ba-g unrelated CI fail

@pavelsavara
pavelsavara merged commit 5dd24c0 into dotnet:mainMay 7, 2026
176 of 178 checks passed
@pavelsavara
pavelsavara deleted the browser_no_mmap branch May 7, 2026 06:15
@BenVBenV mentioned this pull request May 11, 2026
lewing added a commit to lewing/runtime that referenced this pull request May 22, 2026
PR dotnet#127328 introduced a dedicated src/coreclr/gc/wasm/gcenv.cpp that
replaces gcenv.unix.cpp when targeting WebAssembly (browser or WASI).
The CMake selector in src/coreclr/gc/CMakeLists.txt now reads:
if(CLR_CMAKE_TARGET_ARCH_WASM)
add_subdirectory(wasm)
elseif(CLR_CMAKE_HOST_UNIX)
add_subdirectory(unix)
so the original PR's three changes to gcenv.unix.cpp are no longer
compiled for WASI:
- _WASI_EMULATED_MMAN guard on the <sys/mman.h> include
- exclusion of __wasi__ from the ReadMemAvailable() guard
- __wasi__ branch in GetAvailablePhysicalMemory()
The wasm-specific implementation in gc/wasm/gcenv.cpp already implements
equivalent available-memory logic using __builtin_wasm_memory_size, so
nothing of value is lost by reverting these hunks to match upstream.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@github-actionsgithub-actionsBot locked and limited conversation to collaborators Jun 6, 2026
Sign up for freeto subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

arch-wasmWebAssembly architecturearea-GC-coreclr

Projects

None yet

6 participants

@pavelsavara@am11@jkotas@janvorli@SingleAccretion
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Add copy buttons to all
 blocks\n(function() {\n function addCopyButtons() {\n document.querySelectorAll('pre code').forEach(function(codeBlock) {\n if (codeBlock.parentElement.hasAttribute('data-copy-added')) return;\n codeBlock.parentElement.setAttribute('data-copy-added', 'true');\n \n var btn = document.createElement('button');\n btn.textContent = 'Copy';\n btn.style.cssText = 'position:absolute;top:4px;right:4px;padding:2px 8px;font-size:11px;background:#4ecdc4;border:none;border-radius:4px;color:#1a1a2e;cursor:pointer;opacity:0.7;transition:opacity 0.2s;';\n btn.onmouseover = function() { this.style.opacity = '1'; };\n btn.onmouseout = function() { this.style.opacity = '0.7'; };\n btn.onclick = function() {\n navigator.clipboard.writeText(codeBlock.textContent).then(function() {\n btn.textContent = 'Copied!';\n setTimeout(function() { btn.textContent = 'Copy'; }, 1500);\n });\n };\n codeBlock.parentElement.style.position = 'relative';\n codeBlock.parentElement.appendChild(btn);\n });\n }\n \n addCopyButtons();\n \n // Re-run on dynamic content\n var observer = new MutationObserver(addCopyButtons);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Add Copy Buttons to Code Blocks");
}
} catch(__e) { console.warn('[Userscript:Add Copy Buttons to Code Blocks]', __e); }
})();
(function(){
try {
var __m = "github.com";
var __re = new RegExp('^' + "github\\.com" + '
Skip to content

[browser][coreclr] WASM-specific GC OS layer; no mmap/decommit - #127328

Merged
pavelsavara merged 47 commits into
dotnet:mainfrom
pavelsavara:browser_no_mmap
May 7, 2026
Merged

[browser][coreclr] WASM-specific GC OS layer; no mmap/decommit#127328
pavelsavara merged 47 commits into
dotnet:mainfrom
pavelsavara:browser_no_mmap

Conversation

@pavelsavara

@pavelsavarapavelsavara commented Apr 23, 2026

Copy link
Copy Markdown
Member

Fixes#121036
Fixes#117813
Fixes#118943

Summary

This PR adds a dedicated WASM implementation of the GC's OS abstraction layer
(GCToOSInterface) and updates the GC and PAL to handle the fact that on WASM
there is no virtual memory: pages cannot be reserved without committing,
partial unmaps don't return memory to the engine, and MAP_FIXED / madvise
are not supported.

The previous approach reused gcenv.unix.cpp with #ifdef TARGET_WASM patches
and overloaded use_large_pages_p to mean "decommit is a no-op". This change
splits those concerns:

  • A new gc/wasm/gcenv.cpp replaces gc/unix/gcenv.unix.cpp on WASM and
    implements VirtualReserve / VirtualCommit / VirtualDecommit /
    VirtualRelease on top of posix_memalign / free. WASM-specific patches
    in gcenv.unix.cpp are removed.
  • A new GC flag never_decommit_p replaces every "is decommit a no-op" check
    that was previously expressed as use_large_pages_p. It is set on WASM
    unconditionally and on other platforms whenever use_large_pages_p is set.
  • gc/CMakeLists.txt now selects gc/wasm for WASM targets while still
    including unix/configure.cmake to generate config.gc.h.
  • The PAL's virtual.cpp is similarly cleaned up to use posix_memalign /
    free on WASM and to zero memory on MEM_DECOMMIT, so the next
    VirtualCommit (a no-op on WASM) sees zeroed memory.
  • A new minipal_getpagesize abstraction is introduced. On WASM it returns a
    compile-time constant of 16 KB (the GC's page granularity, distinct from the
    64 KB memory.grow granularity that getpagesize() reports). On Windows it
    returns the 4 KB constant inline. On other POSIX systems it caches
    getpagesize() once per process. CoreCLR PAL callers are updated to use it.

Why a separate never_decommit_p

On large pages, decommit is a no-op because the OS pre-commits the entire
range. On WASM, decommit is a no-op because there is no way to give linear
memory back to the engine. The two cases share the same set of GC code paths
that must be skipped or modified (decommit_ephemeral_segment_pages,
decommit_step, decommit_region, decommit_heap_segment_pages,
decommit_heap_segment, distribute_free_regions tail-decommit,
reset_memory, virtual_commit, virtual_decommit assert), but they have
nothing else in common. Reusing use_large_pages_p on WASM was misleading and
made it easy to forget large-pages-only behavior (e.g., pre-touch). The new
flag captures only the "decommit is a no-op" semantics; non-WASM behavior is
unchanged because never_decommit_p == use_large_pages_p everywhere except
WASM.

Why minipal_getpagesize

The GC needs the OS page size to be a compile-time constant on WASM (16 KB)
so that alignment math folds. getpagesize() on emscripten returns 64 KB
(the memory.grow granularity), which is too coarse for GC alignment and
thresholds. Centralizing this in minipal lets PAL and GC agree on a single
value and avoids #ifdefs at every call site.

Notes

  • VirtualReserveAndCommitLargePages on WASM falls through to the regular
    reserve/commit path; the GC does not request large pages on WASM.
  • posix_memalign may return either freshly grown linear memory (zeroed by
    the WASM spec) or a recycled block from emscripten's allocator free list.
    We always memset to zero on reserve and on decommit so callers can rely
    on the standard "memory starts zeroed" contract.
  • VirtualReset returns false on WASM, forcing the GC to use the
    decommit+commit fallback (memset to zero) rather than relying on
    madvise, which is a no-op on emscripten.

@pavelsavarapavelsavara added this to the 11.0.0 milestone Apr 23, 2026
@pavelsavarapavelsavara self-assigned this Apr 23, 2026
CopilotAI review requested due to automatic review settings April 23, 2026 16:55
@pavelsavarapavelsavara added arch-wasm WebAssembly architecture area-GC-coreclr labels Apr 23, 2026
@dotnet-policy-service

Copy link
Copy Markdown
Contributor

Tagging subscribers to this area: @JulieLeeMSFT, @dotnet/gc
See info in area-owners.md if you want to be subscribed.

CopilotAI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR separates WebAssembly-specific GC OS interface behavior from the shared Unix implementation by introducing a dedicated gcenv.wasm.cpp, and adjusts the PAL virtual memory implementation on WASM to avoid relying on Emscripten’s incomplete mmap/munmap support.

Changes:

  • Added a dedicated WASM GCToOSInterface implementation (gcenv.wasm.cpp) and CMake wiring for building it.
  • Routed WASM GC builds to the new gc/wasm directory and removed WASM-specific #ifdef paths from gcenv.unix.cpp.
  • Updated PAL virtual memory reserve/release on WASM to use posix_memalign/free instead of mmap/munmap.

Reviewed changes

Copilot reviewed 5 out of 5 changed files in this pull request and generated 4 comments.

Show a summary per file
FileDescription
src/coreclr/pal/src/map/virtual.cppSwitches WASM reserve/release behavior to posix_memalign/free and adjusts related error/cleanup paths.
src/coreclr/gc/wasm/gcenv.wasm.cppNew WASM-specific GC OS interface implementation (virtual memory, CPU/NUMA stubs, memory stats).
src/coreclr/gc/wasm/CMakeLists.txtAdds build definition for the WASM GC PAL object library.
src/coreclr/gc/unix/gcenv.unix.cppRemoves WASM-specific branches and fixes nanosleep EINTR retry logic.
src/coreclr/gc/CMakeLists.txtRoutes WASM builds to gc/wasm instead of gc/unix.

Comment threadsrc/coreclr/pal/src/map/virtual.cpp
Comment threadsrc/coreclr/pal/src/map/virtual.cpp Outdated
Comment threadsrc/coreclr/gc/wasm/gcenv.wasm.cpp Outdated
Comment threadsrc/coreclr/gc/wasm/gcenv.wasm.cpp Outdated
@pavelsavarapavelsavara changed the title [wasm][coreclr] Extract WASM-specific GC memory management into dedicated file[browser/wasi] Dedicated WASM GC PAL — replace mmap with posix_memalign and optimize memory operationsApr 23, 2026
@pavelsavarapavelsavara changed the title [browser/wasi] Dedicated WASM GC PAL — replace mmap with posix_memalign and optimize memory operations[browser/wasi][coreCLR] Dedicated WASM GC PAL — replace mmap with posix_memalign and optimize memory operationsApr 24, 2026
CopilotAI review requested due to automatic review settings April 24, 2026 08:20

CopilotAI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 7 out of 7 changed files in this pull request and generated 7 comments.

Comment threadsrc/coreclr/gc/wasm/gcenv.wasm.cpp Outdated
Comment threadsrc/coreclr/gc/wasm/gcenv.wasm.cpp Outdated
Comment threadsrc/coreclr/gc/wasm/gcenv.wasm.cpp Outdated
Comment threadsrc/coreclr/gc/wasm/gcenv.wasm.cpp Outdated
Comment threadsrc/coreclr/pal/src/map/virtual.cpp Outdated
Comment threadsrc/coreclr/pal/src/map/virtual.cpp Outdated
Comment threadsrc/coreclr/pal/src/map/virtual.cpp Outdated
CopilotAI review requested due to automatic review settings April 24, 2026 11:37
@pavelsavara
pavelsavara marked this pull request as ready for review April 24, 2026 11:43

CopilotAI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 7 out of 7 changed files in this pull request and generated 7 comments.

Comment threadsrc/coreclr/gc/wasm/gcenv.cpp
Comment threadsrc/coreclr/gc/wasm/CMakeLists.txt
Comment threadsrc/coreclr/gc/wasm/gcenv.cpp
Comment threadsrc/coreclr/pal/src/map/virtual.cpp Outdated
Comment threadsrc/coreclr/gc/wasm/gcenv.wasm.cpp Outdated
Comment threadsrc/coreclr/gc/wasm/gcenv.cpp
Comment threadsrc/coreclr/gc/wasm/gcenv.cpp

CopilotAI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 7 out of 7 changed files in this pull request and generated 1 comment.

Comment threadsrc/coreclr/gc/wasm/gcenv.cpp
Comment threadsrc/native/minipal/wasm.h Outdated
CopilotAI review requested due to automatic review settings May 6, 2026 07:36

CopilotAI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 17 out of 17 changed files in this pull request and generated no new comments.

@pavelsavara
pavelsavara requested a review from janvorliMay 6, 2026 12:59
Comment threadsrc/coreclr/gc/regions_segments.cpp Outdated
Comment threadsrc/coreclr/pal/src/map/virtual.cpp Outdated
Comment threadsrc/coreclr/gc/wasm/CMakeLists.txt

@janvorlijanvorli left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM, thank you!

@pavelsavara

Copy link
Copy Markdown
MemberAuthor

/ba-g unrelated CI fail

@pavelsavara
pavelsavara merged commit 5dd24c0 into dotnet:mainMay 7, 2026
176 of 178 checks passed
@pavelsavara
pavelsavara deleted the browser_no_mmap branch May 7, 2026 06:15
@BenVBenV mentioned this pull request May 11, 2026
lewing added a commit to lewing/runtime that referenced this pull request May 22, 2026
PR dotnet#127328 introduced a dedicated src/coreclr/gc/wasm/gcenv.cpp that
replaces gcenv.unix.cpp when targeting WebAssembly (browser or WASI).
The CMake selector in src/coreclr/gc/CMakeLists.txt now reads:
if(CLR_CMAKE_TARGET_ARCH_WASM)
add_subdirectory(wasm)
elseif(CLR_CMAKE_HOST_UNIX)
add_subdirectory(unix)
so the original PR's three changes to gcenv.unix.cpp are no longer
compiled for WASI:
- _WASI_EMULATED_MMAN guard on the <sys/mman.h> include
- exclusion of __wasi__ from the ReadMemAvailable() guard
- __wasi__ branch in GetAvailablePhysicalMemory()
The wasm-specific implementation in gc/wasm/gcenv.cpp already implements
equivalent available-memory logic using __builtin_wasm_memory_size, so
nothing of value is lost by reverting these hunks to match upstream.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@github-actionsgithub-actionsBot locked and limited conversation to collaborators Jun 6, 2026
Sign up for freeto subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

arch-wasmWebAssembly architecturearea-GC-coreclr

Projects

None yet

6 participants

@pavelsavara@am11@jkotas@janvorli@SingleAccretion
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Force GitHub README to respect dark mode\n(function() {\n var style = document.createElement('style');\n style.textContent = '\n .markdown-body {\n color-scheme: dark light;\n }\n .markdown-body pre { background: #161b22 !important; }\n .markdown-body code { background: rgba(110, 118, 129, 0.4) !important; }\n .markdown-body table th, .markdown-body table td { border-color: #30363d !important; }\n .markdown-body img { background: #0d1117; }\n .markdown-body blockquote { border-left-color: #8b949e; }\n .markdown-body hr { border-color: #30363d; }\n ';\n document.head.appendChild(style);\n})();", "GitHub Dark Mode README Fix"); } } catch(__e) { console.warn('[Userscript:GitHub Dark Mode README Fix]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

[browser][coreclr] WASM-specific GC OS layer; no mmap/decommit - #127328

Merged
pavelsavara merged 47 commits into
dotnet:mainfrom
pavelsavara:browser_no_mmap
May 7, 2026
Merged

[browser][coreclr] WASM-specific GC OS layer; no mmap/decommit#127328
pavelsavara merged 47 commits into
dotnet:mainfrom
pavelsavara:browser_no_mmap

Conversation

@pavelsavara

@pavelsavarapavelsavara commented Apr 23, 2026

Copy link
Copy Markdown
Member

Fixes#121036
Fixes#117813
Fixes#118943

Summary

This PR adds a dedicated WASM implementation of the GC's OS abstraction layer
(GCToOSInterface) and updates the GC and PAL to handle the fact that on WASM
there is no virtual memory: pages cannot be reserved without committing,
partial unmaps don't return memory to the engine, and MAP_FIXED / madvise
are not supported.

The previous approach reused gcenv.unix.cpp with #ifdef TARGET_WASM patches
and overloaded use_large_pages_p to mean "decommit is a no-op". This change
splits those concerns:

  • A new gc/wasm/gcenv.cpp replaces gc/unix/gcenv.unix.cpp on WASM and
    implements VirtualReserve / VirtualCommit / VirtualDecommit /
    VirtualRelease on top of posix_memalign / free. WASM-specific patches
    in gcenv.unix.cpp are removed.
  • A new GC flag never_decommit_p replaces every "is decommit a no-op" check
    that was previously expressed as use_large_pages_p. It is set on WASM
    unconditionally and on other platforms whenever use_large_pages_p is set.
  • gc/CMakeLists.txt now selects gc/wasm for WASM targets while still
    including unix/configure.cmake to generate config.gc.h.
  • The PAL's virtual.cpp is similarly cleaned up to use posix_memalign /
    free on WASM and to zero memory on MEM_DECOMMIT, so the next
    VirtualCommit (a no-op on WASM) sees zeroed memory.
  • A new minipal_getpagesize abstraction is introduced. On WASM it returns a
    compile-time constant of 16 KB (the GC's page granularity, distinct from the
    64 KB memory.grow granularity that getpagesize() reports). On Windows it
    returns the 4 KB constant inline. On other POSIX systems it caches
    getpagesize() once per process. CoreCLR PAL callers are updated to use it.

Why a separate never_decommit_p

On large pages, decommit is a no-op because the OS pre-commits the entire
range. On WASM, decommit is a no-op because there is no way to give linear
memory back to the engine. The two cases share the same set of GC code paths
that must be skipped or modified (decommit_ephemeral_segment_pages,
decommit_step, decommit_region, decommit_heap_segment_pages,
decommit_heap_segment, distribute_free_regions tail-decommit,
reset_memory, virtual_commit, virtual_decommit assert), but they have
nothing else in common. Reusing use_large_pages_p on WASM was misleading and
made it easy to forget large-pages-only behavior (e.g., pre-touch). The new
flag captures only the "decommit is a no-op" semantics; non-WASM behavior is
unchanged because never_decommit_p == use_large_pages_p everywhere except
WASM.

Why minipal_getpagesize

The GC needs the OS page size to be a compile-time constant on WASM (16 KB)
so that alignment math folds. getpagesize() on emscripten returns 64 KB
(the memory.grow granularity), which is too coarse for GC alignment and
thresholds. Centralizing this in minipal lets PAL and GC agree on a single
value and avoids #ifdefs at every call site.

Notes

  • VirtualReserveAndCommitLargePages on WASM falls through to the regular
    reserve/commit path; the GC does not request large pages on WASM.
  • posix_memalign may return either freshly grown linear memory (zeroed by
    the WASM spec) or a recycled block from emscripten's allocator free list.
    We always memset to zero on reserve and on decommit so callers can rely
    on the standard "memory starts zeroed" contract.
  • VirtualReset returns false on WASM, forcing the GC to use the
    decommit+commit fallback (memset to zero) rather than relying on
    madvise, which is a no-op on emscripten.

@pavelsavarapavelsavara added this to the 11.0.0 milestone Apr 23, 2026
@pavelsavarapavelsavara self-assigned this Apr 23, 2026
CopilotAI review requested due to automatic review settings April 23, 2026 16:55
@pavelsavarapavelsavara added arch-wasm WebAssembly architecture area-GC-coreclr labels Apr 23, 2026
@dotnet-policy-service

Copy link
Copy Markdown
Contributor

Tagging subscribers to this area: @JulieLeeMSFT, @dotnet/gc
See info in area-owners.md if you want to be subscribed.

CopilotAI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR separates WebAssembly-specific GC OS interface behavior from the shared Unix implementation by introducing a dedicated gcenv.wasm.cpp, and adjusts the PAL virtual memory implementation on WASM to avoid relying on Emscripten’s incomplete mmap/munmap support.

Changes:

  • Added a dedicated WASM GCToOSInterface implementation (gcenv.wasm.cpp) and CMake wiring for building it.
  • Routed WASM GC builds to the new gc/wasm directory and removed WASM-specific #ifdef paths from gcenv.unix.cpp.
  • Updated PAL virtual memory reserve/release on WASM to use posix_memalign/free instead of mmap/munmap.

Reviewed changes

Copilot reviewed 5 out of 5 changed files in this pull request and generated 4 comments.

Show a summary per file
FileDescription
src/coreclr/pal/src/map/virtual.cppSwitches WASM reserve/release behavior to posix_memalign/free and adjusts related error/cleanup paths.
src/coreclr/gc/wasm/gcenv.wasm.cppNew WASM-specific GC OS interface implementation (virtual memory, CPU/NUMA stubs, memory stats).
src/coreclr/gc/wasm/CMakeLists.txtAdds build definition for the WASM GC PAL object library.
src/coreclr/gc/unix/gcenv.unix.cppRemoves WASM-specific branches and fixes nanosleep EINTR retry logic.
src/coreclr/gc/CMakeLists.txtRoutes WASM builds to gc/wasm instead of gc/unix.

Comment threadsrc/coreclr/pal/src/map/virtual.cpp
Comment threadsrc/coreclr/pal/src/map/virtual.cpp Outdated
Comment threadsrc/coreclr/gc/wasm/gcenv.wasm.cpp Outdated
Comment threadsrc/coreclr/gc/wasm/gcenv.wasm.cpp Outdated
@pavelsavarapavelsavara changed the title [wasm][coreclr] Extract WASM-specific GC memory management into dedicated file[browser/wasi] Dedicated WASM GC PAL — replace mmap with posix_memalign and optimize memory operationsApr 23, 2026
@pavelsavarapavelsavara changed the title [browser/wasi] Dedicated WASM GC PAL — replace mmap with posix_memalign and optimize memory operations[browser/wasi][coreCLR] Dedicated WASM GC PAL — replace mmap with posix_memalign and optimize memory operationsApr 24, 2026
CopilotAI review requested due to automatic review settings April 24, 2026 08:20

CopilotAI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 7 out of 7 changed files in this pull request and generated 7 comments.

Comment threadsrc/coreclr/gc/wasm/gcenv.wasm.cpp Outdated
Comment threadsrc/coreclr/gc/wasm/gcenv.wasm.cpp Outdated
Comment threadsrc/coreclr/gc/wasm/gcenv.wasm.cpp Outdated
Comment threadsrc/coreclr/gc/wasm/gcenv.wasm.cpp Outdated
Comment threadsrc/coreclr/pal/src/map/virtual.cpp Outdated
Comment threadsrc/coreclr/pal/src/map/virtual.cpp Outdated
Comment threadsrc/coreclr/pal/src/map/virtual.cpp Outdated
CopilotAI review requested due to automatic review settings April 24, 2026 11:37
@pavelsavara
pavelsavara marked this pull request as ready for review April 24, 2026 11:43

CopilotAI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 7 out of 7 changed files in this pull request and generated 7 comments.

Comment threadsrc/coreclr/gc/wasm/gcenv.cpp
Comment threadsrc/coreclr/gc/wasm/CMakeLists.txt
Comment threadsrc/coreclr/gc/wasm/gcenv.cpp
Comment threadsrc/coreclr/pal/src/map/virtual.cpp Outdated
Comment threadsrc/coreclr/gc/wasm/gcenv.wasm.cpp Outdated
Comment threadsrc/coreclr/gc/wasm/gcenv.cpp
Comment threadsrc/coreclr/gc/wasm/gcenv.cpp

CopilotAI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 7 out of 7 changed files in this pull request and generated 1 comment.

Comment threadsrc/coreclr/gc/wasm/gcenv.cpp
Comment threadsrc/native/minipal/wasm.h Outdated
CopilotAI review requested due to automatic review settings May 6, 2026 07:36

CopilotAI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 17 out of 17 changed files in this pull request and generated no new comments.

@pavelsavara
pavelsavara requested a review from janvorliMay 6, 2026 12:59
Comment threadsrc/coreclr/gc/regions_segments.cpp Outdated
Comment threadsrc/coreclr/pal/src/map/virtual.cpp Outdated
Comment threadsrc/coreclr/gc/wasm/CMakeLists.txt

@janvorlijanvorli left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM, thank you!

@pavelsavara

Copy link
Copy Markdown
MemberAuthor

/ba-g unrelated CI fail

@pavelsavara
pavelsavara merged commit 5dd24c0 into dotnet:mainMay 7, 2026
176 of 178 checks passed
@pavelsavara
pavelsavara deleted the browser_no_mmap branch May 7, 2026 06:15
@BenVBenV mentioned this pull request May 11, 2026
lewing added a commit to lewing/runtime that referenced this pull request May 22, 2026
PR dotnet#127328 introduced a dedicated src/coreclr/gc/wasm/gcenv.cpp that
replaces gcenv.unix.cpp when targeting WebAssembly (browser or WASI).
The CMake selector in src/coreclr/gc/CMakeLists.txt now reads:
if(CLR_CMAKE_TARGET_ARCH_WASM)
add_subdirectory(wasm)
elseif(CLR_CMAKE_HOST_UNIX)
add_subdirectory(unix)
so the original PR's three changes to gcenv.unix.cpp are no longer
compiled for WASI:
- _WASI_EMULATED_MMAN guard on the <sys/mman.h> include
- exclusion of __wasi__ from the ReadMemAvailable() guard
- __wasi__ branch in GetAvailablePhysicalMemory()
The wasm-specific implementation in gc/wasm/gcenv.cpp already implements
equivalent available-memory logic using __builtin_wasm_memory_size, so
nothing of value is lost by reverting these hunks to match upstream.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@github-actionsgithub-actionsBot locked and limited conversation to collaborators Jun 6, 2026
Sign up for freeto subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

arch-wasmWebAssembly architecturearea-GC-coreclr

Projects

None yet

6 participants

@pavelsavara@am11@jkotas@janvorli@SingleAccretion
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Highlight search terms from Google/DuckDuckGo/Bing referrer\n(function() {\n var ref = document.referrer;\n var terms = [];\n \n if (ref.includes('google.com') || ref.includes('duckduckgo.com') || ref.includes('bing.com')) {\n var url = new URL(ref);\n var q = url.searchParams.get('q') || url.searchParams.get('p');\n if (q) {\n terms = q.split(/\\s+/).filter(function(t) { return t.length > 2; });\n }\n }\n \n if (terms.length === 0) return;\n \n var style = document.createElement('style');\n style.textContent = '.userscript-highlight { background: #fbbf24; color: #1a1a2e; padding: 1px 3px; border-radius: 2px; }';\n document.head.appendChild(style);\n \n function highlight(node) {\n if (node.nodeType === 3) { // text node\n var text = node.textContent;\n var found = false;\n terms.forEach(function(term) {\n var regex = new RegExp('(' + term.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\') + ')', 'gi');\n if (regex.test(text)) {\n found = true;\n var frag = document.createDocumentFragment();\n var parts = text.split(regex);\n parts.forEach(function(part, i) {\n if (i % 2 === 0) {\n frag.appendChild(document.createTextNode(part));\n } else {\n var span = document.createElement('span');\n span.className = 'userscript-highlight';\n span.textContent = part;\n frag.appendChild(span);\n }\n });\n node.parentNode.replaceChild(frag, node);\n }\n });\n } else if (node.nodeType === 1 && node.childNodes) { // element\n var skipTags = ['SCRIPT', 'STYLE', 'NOSCRIPT', 'TEXTAREA', 'INPUT', 'SELECT'];\n if (!skipTags.includes(node.tagName)) {\n Array.from(node.childNodes).forEach(highlight);\n }\n }\n }\n \n highlight(document.body);\n \n // Re-highlight on dynamic content\n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1 || node.nodeType === 3) highlight(node);\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Highlight Search Terms"); } } catch(__e) { console.warn('[Userscript:Highlight Search Terms]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

[browser][coreclr] WASM-specific GC OS layer; no mmap/decommit - #127328

Merged
pavelsavara merged 47 commits into
dotnet:mainfrom
pavelsavara:browser_no_mmap
May 7, 2026
Merged

[browser][coreclr] WASM-specific GC OS layer; no mmap/decommit#127328
pavelsavara merged 47 commits into
dotnet:mainfrom
pavelsavara:browser_no_mmap

Conversation

@pavelsavara

@pavelsavarapavelsavara commented Apr 23, 2026

Copy link
Copy Markdown
Member

Fixes#121036
Fixes#117813
Fixes#118943

Summary

This PR adds a dedicated WASM implementation of the GC's OS abstraction layer
(GCToOSInterface) and updates the GC and PAL to handle the fact that on WASM
there is no virtual memory: pages cannot be reserved without committing,
partial unmaps don't return memory to the engine, and MAP_FIXED / madvise
are not supported.

The previous approach reused gcenv.unix.cpp with #ifdef TARGET_WASM patches
and overloaded use_large_pages_p to mean "decommit is a no-op". This change
splits those concerns:

  • A new gc/wasm/gcenv.cpp replaces gc/unix/gcenv.unix.cpp on WASM and
    implements VirtualReserve / VirtualCommit / VirtualDecommit /
    VirtualRelease on top of posix_memalign / free. WASM-specific patches
    in gcenv.unix.cpp are removed.
  • A new GC flag never_decommit_p replaces every "is decommit a no-op" check
    that was previously expressed as use_large_pages_p. It is set on WASM
    unconditionally and on other platforms whenever use_large_pages_p is set.
  • gc/CMakeLists.txt now selects gc/wasm for WASM targets while still
    including unix/configure.cmake to generate config.gc.h.
  • The PAL's virtual.cpp is similarly cleaned up to use posix_memalign /
    free on WASM and to zero memory on MEM_DECOMMIT, so the next
    VirtualCommit (a no-op on WASM) sees zeroed memory.
  • A new minipal_getpagesize abstraction is introduced. On WASM it returns a
    compile-time constant of 16 KB (the GC's page granularity, distinct from the
    64 KB memory.grow granularity that getpagesize() reports). On Windows it
    returns the 4 KB constant inline. On other POSIX systems it caches
    getpagesize() once per process. CoreCLR PAL callers are updated to use it.

Why a separate never_decommit_p

On large pages, decommit is a no-op because the OS pre-commits the entire
range. On WASM, decommit is a no-op because there is no way to give linear
memory back to the engine. The two cases share the same set of GC code paths
that must be skipped or modified (decommit_ephemeral_segment_pages,
decommit_step, decommit_region, decommit_heap_segment_pages,
decommit_heap_segment, distribute_free_regions tail-decommit,
reset_memory, virtual_commit, virtual_decommit assert), but they have
nothing else in common. Reusing use_large_pages_p on WASM was misleading and
made it easy to forget large-pages-only behavior (e.g., pre-touch). The new
flag captures only the "decommit is a no-op" semantics; non-WASM behavior is
unchanged because never_decommit_p == use_large_pages_p everywhere except
WASM.

Why minipal_getpagesize

The GC needs the OS page size to be a compile-time constant on WASM (16 KB)
so that alignment math folds. getpagesize() on emscripten returns 64 KB
(the memory.grow granularity), which is too coarse for GC alignment and
thresholds. Centralizing this in minipal lets PAL and GC agree on a single
value and avoids #ifdefs at every call site.

Notes

  • VirtualReserveAndCommitLargePages on WASM falls through to the regular
    reserve/commit path; the GC does not request large pages on WASM.
  • posix_memalign may return either freshly grown linear memory (zeroed by
    the WASM spec) or a recycled block from emscripten's allocator free list.
    We always memset to zero on reserve and on decommit so callers can rely
    on the standard "memory starts zeroed" contract.
  • VirtualReset returns false on WASM, forcing the GC to use the
    decommit+commit fallback (memset to zero) rather than relying on
    madvise, which is a no-op on emscripten.

@pavelsavarapavelsavara added this to the 11.0.0 milestone Apr 23, 2026
@pavelsavarapavelsavara self-assigned this Apr 23, 2026
CopilotAI review requested due to automatic review settings April 23, 2026 16:55
@pavelsavarapavelsavara added arch-wasm WebAssembly architecture area-GC-coreclr labels Apr 23, 2026
@dotnet-policy-service

Copy link
Copy Markdown
Contributor

Tagging subscribers to this area: @JulieLeeMSFT, @dotnet/gc
See info in area-owners.md if you want to be subscribed.

CopilotAI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR separates WebAssembly-specific GC OS interface behavior from the shared Unix implementation by introducing a dedicated gcenv.wasm.cpp, and adjusts the PAL virtual memory implementation on WASM to avoid relying on Emscripten’s incomplete mmap/munmap support.

Changes:

  • Added a dedicated WASM GCToOSInterface implementation (gcenv.wasm.cpp) and CMake wiring for building it.
  • Routed WASM GC builds to the new gc/wasm directory and removed WASM-specific #ifdef paths from gcenv.unix.cpp.
  • Updated PAL virtual memory reserve/release on WASM to use posix_memalign/free instead of mmap/munmap.

Reviewed changes

Copilot reviewed 5 out of 5 changed files in this pull request and generated 4 comments.

Show a summary per file
FileDescription
src/coreclr/pal/src/map/virtual.cppSwitches WASM reserve/release behavior to posix_memalign/free and adjusts related error/cleanup paths.
src/coreclr/gc/wasm/gcenv.wasm.cppNew WASM-specific GC OS interface implementation (virtual memory, CPU/NUMA stubs, memory stats).
src/coreclr/gc/wasm/CMakeLists.txtAdds build definition for the WASM GC PAL object library.
src/coreclr/gc/unix/gcenv.unix.cppRemoves WASM-specific branches and fixes nanosleep EINTR retry logic.
src/coreclr/gc/CMakeLists.txtRoutes WASM builds to gc/wasm instead of gc/unix.

Comment threadsrc/coreclr/pal/src/map/virtual.cpp
Comment threadsrc/coreclr/pal/src/map/virtual.cpp Outdated
Comment threadsrc/coreclr/gc/wasm/gcenv.wasm.cpp Outdated
Comment threadsrc/coreclr/gc/wasm/gcenv.wasm.cpp Outdated
@pavelsavarapavelsavara changed the title [wasm][coreclr] Extract WASM-specific GC memory management into dedicated file[browser/wasi] Dedicated WASM GC PAL — replace mmap with posix_memalign and optimize memory operationsApr 23, 2026
@pavelsavarapavelsavara changed the title [browser/wasi] Dedicated WASM GC PAL — replace mmap with posix_memalign and optimize memory operations[browser/wasi][coreCLR] Dedicated WASM GC PAL — replace mmap with posix_memalign and optimize memory operationsApr 24, 2026
CopilotAI review requested due to automatic review settings April 24, 2026 08:20

CopilotAI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 7 out of 7 changed files in this pull request and generated 7 comments.

Comment threadsrc/coreclr/gc/wasm/gcenv.wasm.cpp Outdated
Comment threadsrc/coreclr/gc/wasm/gcenv.wasm.cpp Outdated
Comment threadsrc/coreclr/gc/wasm/gcenv.wasm.cpp Outdated
Comment threadsrc/coreclr/gc/wasm/gcenv.wasm.cpp Outdated
Comment threadsrc/coreclr/pal/src/map/virtual.cpp Outdated
Comment threadsrc/coreclr/pal/src/map/virtual.cpp Outdated
Comment threadsrc/coreclr/pal/src/map/virtual.cpp Outdated
CopilotAI review requested due to automatic review settings April 24, 2026 11:37
@pavelsavara
pavelsavara marked this pull request as ready for review April 24, 2026 11:43

CopilotAI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 7 out of 7 changed files in this pull request and generated 7 comments.

Comment threadsrc/coreclr/gc/wasm/gcenv.cpp
Comment threadsrc/coreclr/gc/wasm/CMakeLists.txt
Comment threadsrc/coreclr/gc/wasm/gcenv.cpp
Comment threadsrc/coreclr/pal/src/map/virtual.cpp Outdated
Comment threadsrc/coreclr/gc/wasm/gcenv.wasm.cpp Outdated
Comment threadsrc/coreclr/gc/wasm/gcenv.cpp
Comment threadsrc/coreclr/gc/wasm/gcenv.cpp

CopilotAI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 7 out of 7 changed files in this pull request and generated 1 comment.

Comment threadsrc/coreclr/gc/wasm/gcenv.cpp
Comment threadsrc/native/minipal/wasm.h Outdated
CopilotAI review requested due to automatic review settings May 6, 2026 07:36

CopilotAI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 17 out of 17 changed files in this pull request and generated no new comments.

@pavelsavara
pavelsavara requested a review from janvorliMay 6, 2026 12:59
Comment threadsrc/coreclr/gc/regions_segments.cpp Outdated
Comment threadsrc/coreclr/pal/src/map/virtual.cpp Outdated
Comment threadsrc/coreclr/gc/wasm/CMakeLists.txt

@janvorlijanvorli left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM, thank you!

@pavelsavara

Copy link
Copy Markdown
MemberAuthor

/ba-g unrelated CI fail

@pavelsavara
pavelsavara merged commit 5dd24c0 into dotnet:mainMay 7, 2026
176 of 178 checks passed
@pavelsavara
pavelsavara deleted the browser_no_mmap branch May 7, 2026 06:15
@BenVBenV mentioned this pull request May 11, 2026
lewing added a commit to lewing/runtime that referenced this pull request May 22, 2026
PR dotnet#127328 introduced a dedicated src/coreclr/gc/wasm/gcenv.cpp that
replaces gcenv.unix.cpp when targeting WebAssembly (browser or WASI).
The CMake selector in src/coreclr/gc/CMakeLists.txt now reads:
if(CLR_CMAKE_TARGET_ARCH_WASM)
add_subdirectory(wasm)
elseif(CLR_CMAKE_HOST_UNIX)
add_subdirectory(unix)
so the original PR's three changes to gcenv.unix.cpp are no longer
compiled for WASI:
- _WASI_EMULATED_MMAN guard on the <sys/mman.h> include
- exclusion of __wasi__ from the ReadMemAvailable() guard
- __wasi__ branch in GetAvailablePhysicalMemory()
The wasm-specific implementation in gc/wasm/gcenv.cpp already implements
equivalent available-memory logic using __builtin_wasm_memory_size, so
nothing of value is lost by reverting these hunks to match upstream.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@github-actionsgithub-actionsBot locked and limited conversation to collaborators Jun 6, 2026
Sign up for freeto subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

arch-wasmWebAssembly architecturearea-GC-coreclr

Projects

None yet

6 participants

@pavelsavara@am11@jkotas@janvorli@SingleAccretion
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Strip utm_, fbclid, gclid, etc. from all links on page\n(function() {\n var trackingParams = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content',\n 'fbclid', 'gclid', 'dclid', 'msclkid', 'yclid',\n 'ref', 'ref_src', 'source', 'medium', 'campaign'];\n \n function cleanUrl(url) {\n try {\n var u = new URL(url, window.location.origin);\n var changed = false;\n trackingParams.forEach(function(p) {\n if (u.searchParams.has(p)) {\n u.searchParams.delete(p);\n changed = true;\n }\n });\n return changed ? u.toString() : url;\n } catch (e) {\n return url;\n }\n }\n \n function cleanLinks() {\n document.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n \n cleanLinks();\n \n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1) {\n if (node.tagName === 'A') cleanLinks();\n node.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Remove Tracking Parameters from Links"); } } catch(__e) { console.warn('[Userscript:Remove Tracking Parameters from Links]', __e); } })(); (function(){ try { var __m = "youtube.com"; var __re = new RegExp('^' + "youtube\\.com" + '
Skip to content

[browser][coreclr] WASM-specific GC OS layer; no mmap/decommit - #127328

Merged
pavelsavara merged 47 commits into
dotnet:mainfrom
pavelsavara:browser_no_mmap
May 7, 2026
Merged

[browser][coreclr] WASM-specific GC OS layer; no mmap/decommit#127328
pavelsavara merged 47 commits into
dotnet:mainfrom
pavelsavara:browser_no_mmap

Conversation

@pavelsavara

@pavelsavarapavelsavara commented Apr 23, 2026

Copy link
Copy Markdown
Member

Fixes#121036
Fixes#117813
Fixes#118943

Summary

This PR adds a dedicated WASM implementation of the GC's OS abstraction layer
(GCToOSInterface) and updates the GC and PAL to handle the fact that on WASM
there is no virtual memory: pages cannot be reserved without committing,
partial unmaps don't return memory to the engine, and MAP_FIXED / madvise
are not supported.

The previous approach reused gcenv.unix.cpp with #ifdef TARGET_WASM patches
and overloaded use_large_pages_p to mean "decommit is a no-op". This change
splits those concerns:

  • A new gc/wasm/gcenv.cpp replaces gc/unix/gcenv.unix.cpp on WASM and
    implements VirtualReserve / VirtualCommit / VirtualDecommit /
    VirtualRelease on top of posix_memalign / free. WASM-specific patches
    in gcenv.unix.cpp are removed.
  • A new GC flag never_decommit_p replaces every "is decommit a no-op" check
    that was previously expressed as use_large_pages_p. It is set on WASM
    unconditionally and on other platforms whenever use_large_pages_p is set.
  • gc/CMakeLists.txt now selects gc/wasm for WASM targets while still
    including unix/configure.cmake to generate config.gc.h.
  • The PAL's virtual.cpp is similarly cleaned up to use posix_memalign /
    free on WASM and to zero memory on MEM_DECOMMIT, so the next
    VirtualCommit (a no-op on WASM) sees zeroed memory.
  • A new minipal_getpagesize abstraction is introduced. On WASM it returns a
    compile-time constant of 16 KB (the GC's page granularity, distinct from the
    64 KB memory.grow granularity that getpagesize() reports). On Windows it
    returns the 4 KB constant inline. On other POSIX systems it caches
    getpagesize() once per process. CoreCLR PAL callers are updated to use it.

Why a separate never_decommit_p

On large pages, decommit is a no-op because the OS pre-commits the entire
range. On WASM, decommit is a no-op because there is no way to give linear
memory back to the engine. The two cases share the same set of GC code paths
that must be skipped or modified (decommit_ephemeral_segment_pages,
decommit_step, decommit_region, decommit_heap_segment_pages,
decommit_heap_segment, distribute_free_regions tail-decommit,
reset_memory, virtual_commit, virtual_decommit assert), but they have
nothing else in common. Reusing use_large_pages_p on WASM was misleading and
made it easy to forget large-pages-only behavior (e.g., pre-touch). The new
flag captures only the "decommit is a no-op" semantics; non-WASM behavior is
unchanged because never_decommit_p == use_large_pages_p everywhere except
WASM.

Why minipal_getpagesize

The GC needs the OS page size to be a compile-time constant on WASM (16 KB)
so that alignment math folds. getpagesize() on emscripten returns 64 KB
(the memory.grow granularity), which is too coarse for GC alignment and
thresholds. Centralizing this in minipal lets PAL and GC agree on a single
value and avoids #ifdefs at every call site.

Notes

  • VirtualReserveAndCommitLargePages on WASM falls through to the regular
    reserve/commit path; the GC does not request large pages on WASM.
  • posix_memalign may return either freshly grown linear memory (zeroed by
    the WASM spec) or a recycled block from emscripten's allocator free list.
    We always memset to zero on reserve and on decommit so callers can rely
    on the standard "memory starts zeroed" contract.
  • VirtualReset returns false on WASM, forcing the GC to use the
    decommit+commit fallback (memset to zero) rather than relying on
    madvise, which is a no-op on emscripten.

@pavelsavarapavelsavara added this to the 11.0.0 milestone Apr 23, 2026
@pavelsavarapavelsavara self-assigned this Apr 23, 2026
CopilotAI review requested due to automatic review settings April 23, 2026 16:55
@pavelsavarapavelsavara added arch-wasm WebAssembly architecture area-GC-coreclr labels Apr 23, 2026
@dotnet-policy-service

Copy link
Copy Markdown
Contributor

Tagging subscribers to this area: @JulieLeeMSFT, @dotnet/gc
See info in area-owners.md if you want to be subscribed.

CopilotAI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR separates WebAssembly-specific GC OS interface behavior from the shared Unix implementation by introducing a dedicated gcenv.wasm.cpp, and adjusts the PAL virtual memory implementation on WASM to avoid relying on Emscripten’s incomplete mmap/munmap support.

Changes:

  • Added a dedicated WASM GCToOSInterface implementation (gcenv.wasm.cpp) and CMake wiring for building it.
  • Routed WASM GC builds to the new gc/wasm directory and removed WASM-specific #ifdef paths from gcenv.unix.cpp.
  • Updated PAL virtual memory reserve/release on WASM to use posix_memalign/free instead of mmap/munmap.

Reviewed changes

Copilot reviewed 5 out of 5 changed files in this pull request and generated 4 comments.

Show a summary per file
FileDescription
src/coreclr/pal/src/map/virtual.cppSwitches WASM reserve/release behavior to posix_memalign/free and adjusts related error/cleanup paths.
src/coreclr/gc/wasm/gcenv.wasm.cppNew WASM-specific GC OS interface implementation (virtual memory, CPU/NUMA stubs, memory stats).
src/coreclr/gc/wasm/CMakeLists.txtAdds build definition for the WASM GC PAL object library.
src/coreclr/gc/unix/gcenv.unix.cppRemoves WASM-specific branches and fixes nanosleep EINTR retry logic.
src/coreclr/gc/CMakeLists.txtRoutes WASM builds to gc/wasm instead of gc/unix.

Comment threadsrc/coreclr/pal/src/map/virtual.cpp
Comment threadsrc/coreclr/pal/src/map/virtual.cpp Outdated
Comment threadsrc/coreclr/gc/wasm/gcenv.wasm.cpp Outdated
Comment threadsrc/coreclr/gc/wasm/gcenv.wasm.cpp Outdated
@pavelsavarapavelsavara changed the title [wasm][coreclr] Extract WASM-specific GC memory management into dedicated file[browser/wasi] Dedicated WASM GC PAL — replace mmap with posix_memalign and optimize memory operationsApr 23, 2026
@pavelsavarapavelsavara changed the title [browser/wasi] Dedicated WASM GC PAL — replace mmap with posix_memalign and optimize memory operations[browser/wasi][coreCLR] Dedicated WASM GC PAL — replace mmap with posix_memalign and optimize memory operationsApr 24, 2026
CopilotAI review requested due to automatic review settings April 24, 2026 08:20

CopilotAI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 7 out of 7 changed files in this pull request and generated 7 comments.

Comment threadsrc/coreclr/gc/wasm/gcenv.wasm.cpp Outdated
Comment threadsrc/coreclr/gc/wasm/gcenv.wasm.cpp Outdated
Comment threadsrc/coreclr/gc/wasm/gcenv.wasm.cpp Outdated
Comment threadsrc/coreclr/gc/wasm/gcenv.wasm.cpp Outdated
Comment threadsrc/coreclr/pal/src/map/virtual.cpp Outdated
Comment threadsrc/coreclr/pal/src/map/virtual.cpp Outdated
Comment threadsrc/coreclr/pal/src/map/virtual.cpp Outdated
CopilotAI review requested due to automatic review settings April 24, 2026 11:37
@pavelsavara
pavelsavara marked this pull request as ready for review April 24, 2026 11:43

CopilotAI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 7 out of 7 changed files in this pull request and generated 7 comments.

Comment threadsrc/coreclr/gc/wasm/gcenv.cpp
Comment threadsrc/coreclr/gc/wasm/CMakeLists.txt
Comment threadsrc/coreclr/gc/wasm/gcenv.cpp
Comment threadsrc/coreclr/pal/src/map/virtual.cpp Outdated
Comment threadsrc/coreclr/gc/wasm/gcenv.wasm.cpp Outdated
Comment threadsrc/coreclr/gc/wasm/gcenv.cpp
Comment threadsrc/coreclr/gc/wasm/gcenv.cpp

CopilotAI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 7 out of 7 changed files in this pull request and generated 1 comment.

Comment threadsrc/coreclr/gc/wasm/gcenv.cpp
Comment threadsrc/native/minipal/wasm.h Outdated
CopilotAI review requested due to automatic review settings May 6, 2026 07:36

CopilotAI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 17 out of 17 changed files in this pull request and generated no new comments.

@pavelsavara
pavelsavara requested a review from janvorliMay 6, 2026 12:59
Comment threadsrc/coreclr/gc/regions_segments.cpp Outdated
Comment threadsrc/coreclr/pal/src/map/virtual.cpp Outdated
Comment threadsrc/coreclr/gc/wasm/CMakeLists.txt

@janvorlijanvorli left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM, thank you!

@pavelsavara

Copy link
Copy Markdown
MemberAuthor

/ba-g unrelated CI fail

@pavelsavara
pavelsavara merged commit 5dd24c0 into dotnet:mainMay 7, 2026
176 of 178 checks passed
@pavelsavara
pavelsavara deleted the browser_no_mmap branch May 7, 2026 06:15
@BenVBenV mentioned this pull request May 11, 2026
lewing added a commit to lewing/runtime that referenced this pull request May 22, 2026
PR dotnet#127328 introduced a dedicated src/coreclr/gc/wasm/gcenv.cpp that
replaces gcenv.unix.cpp when targeting WebAssembly (browser or WASI).
The CMake selector in src/coreclr/gc/CMakeLists.txt now reads:
if(CLR_CMAKE_TARGET_ARCH_WASM)
add_subdirectory(wasm)
elseif(CLR_CMAKE_HOST_UNIX)
add_subdirectory(unix)
so the original PR's three changes to gcenv.unix.cpp are no longer
compiled for WASI:
- _WASI_EMULATED_MMAN guard on the <sys/mman.h> include
- exclusion of __wasi__ from the ReadMemAvailable() guard
- __wasi__ branch in GetAvailablePhysicalMemory()
The wasm-specific implementation in gc/wasm/gcenv.cpp already implements
equivalent available-memory logic using __builtin_wasm_memory_size, so
nothing of value is lost by reverting these hunks to match upstream.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@github-actionsgithub-actionsBot locked and limited conversation to collaborators Jun 6, 2026
Sign up for freeto subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

arch-wasmWebAssembly architecturearea-GC-coreclr

Projects

None yet

6 participants

@pavelsavara@am11@jkotas@janvorli@SingleAccretion
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Auto-enable theater mode on YouTube\n(function() {\n function tryTheater() {\n var btn = document.querySelector('button[aria-label=\"Theater mode\"], ytd-player #player button[title=\"Theater mode\"]');\n if (btn && !btn.classList.contains('activated')) {\n btn.click();\n }\n }\n \n // Try immediately\n tryTheater();\n \n // Try after navigation (SPA)\n var lastUrl = location.href;\n setInterval(function() {\n if (location.href !== lastUrl) {\n lastUrl = location.href;\n setTimeout(tryTheater, 500);\n }\n }, 1000);\n \n // Also try on player load\n var observer = new MutationObserver(tryTheater);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "YouTube Theater Mode Default"); } } catch(__e) { console.warn('[Userscript:YouTube Theater Mode Default]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

[browser][coreclr] WASM-specific GC OS layer; no mmap/decommit - #127328

Merged
pavelsavara merged 47 commits into
dotnet:mainfrom
pavelsavara:browser_no_mmap
May 7, 2026
Merged

[browser][coreclr] WASM-specific GC OS layer; no mmap/decommit#127328
pavelsavara merged 47 commits into
dotnet:mainfrom
pavelsavara:browser_no_mmap

Conversation

@pavelsavara

@pavelsavarapavelsavara commented Apr 23, 2026

Copy link
Copy Markdown
Member

Fixes#121036
Fixes#117813
Fixes#118943

Summary

This PR adds a dedicated WASM implementation of the GC's OS abstraction layer
(GCToOSInterface) and updates the GC and PAL to handle the fact that on WASM
there is no virtual memory: pages cannot be reserved without committing,
partial unmaps don't return memory to the engine, and MAP_FIXED / madvise
are not supported.

The previous approach reused gcenv.unix.cpp with #ifdef TARGET_WASM patches
and overloaded use_large_pages_p to mean "decommit is a no-op". This change
splits those concerns:

  • A new gc/wasm/gcenv.cpp replaces gc/unix/gcenv.unix.cpp on WASM and
    implements VirtualReserve / VirtualCommit / VirtualDecommit /
    VirtualRelease on top of posix_memalign / free. WASM-specific patches
    in gcenv.unix.cpp are removed.
  • A new GC flag never_decommit_p replaces every "is decommit a no-op" check
    that was previously expressed as use_large_pages_p. It is set on WASM
    unconditionally and on other platforms whenever use_large_pages_p is set.
  • gc/CMakeLists.txt now selects gc/wasm for WASM targets while still
    including unix/configure.cmake to generate config.gc.h.
  • The PAL's virtual.cpp is similarly cleaned up to use posix_memalign /
    free on WASM and to zero memory on MEM_DECOMMIT, so the next
    VirtualCommit (a no-op on WASM) sees zeroed memory.
  • A new minipal_getpagesize abstraction is introduced. On WASM it returns a
    compile-time constant of 16 KB (the GC's page granularity, distinct from the
    64 KB memory.grow granularity that getpagesize() reports). On Windows it
    returns the 4 KB constant inline. On other POSIX systems it caches
    getpagesize() once per process. CoreCLR PAL callers are updated to use it.

Why a separate never_decommit_p

On large pages, decommit is a no-op because the OS pre-commits the entire
range. On WASM, decommit is a no-op because there is no way to give linear
memory back to the engine. The two cases share the same set of GC code paths
that must be skipped or modified (decommit_ephemeral_segment_pages,
decommit_step, decommit_region, decommit_heap_segment_pages,
decommit_heap_segment, distribute_free_regions tail-decommit,
reset_memory, virtual_commit, virtual_decommit assert), but they have
nothing else in common. Reusing use_large_pages_p on WASM was misleading and
made it easy to forget large-pages-only behavior (e.g., pre-touch). The new
flag captures only the "decommit is a no-op" semantics; non-WASM behavior is
unchanged because never_decommit_p == use_large_pages_p everywhere except
WASM.

Why minipal_getpagesize

The GC needs the OS page size to be a compile-time constant on WASM (16 KB)
so that alignment math folds. getpagesize() on emscripten returns 64 KB
(the memory.grow granularity), which is too coarse for GC alignment and
thresholds. Centralizing this in minipal lets PAL and GC agree on a single
value and avoids #ifdefs at every call site.

Notes

  • VirtualReserveAndCommitLargePages on WASM falls through to the regular
    reserve/commit path; the GC does not request large pages on WASM.
  • posix_memalign may return either freshly grown linear memory (zeroed by
    the WASM spec) or a recycled block from emscripten's allocator free list.
    We always memset to zero on reserve and on decommit so callers can rely
    on the standard "memory starts zeroed" contract.
  • VirtualReset returns false on WASM, forcing the GC to use the
    decommit+commit fallback (memset to zero) rather than relying on
    madvise, which is a no-op on emscripten.

@pavelsavarapavelsavara added this to the 11.0.0 milestone Apr 23, 2026
@pavelsavarapavelsavara self-assigned this Apr 23, 2026
CopilotAI review requested due to automatic review settings April 23, 2026 16:55
@pavelsavarapavelsavara added arch-wasm WebAssembly architecture area-GC-coreclr labels Apr 23, 2026
@dotnet-policy-service

Copy link
Copy Markdown
Contributor

Tagging subscribers to this area: @JulieLeeMSFT, @dotnet/gc
See info in area-owners.md if you want to be subscribed.

CopilotAI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR separates WebAssembly-specific GC OS interface behavior from the shared Unix implementation by introducing a dedicated gcenv.wasm.cpp, and adjusts the PAL virtual memory implementation on WASM to avoid relying on Emscripten’s incomplete mmap/munmap support.

Changes:

  • Added a dedicated WASM GCToOSInterface implementation (gcenv.wasm.cpp) and CMake wiring for building it.
  • Routed WASM GC builds to the new gc/wasm directory and removed WASM-specific #ifdef paths from gcenv.unix.cpp.
  • Updated PAL virtual memory reserve/release on WASM to use posix_memalign/free instead of mmap/munmap.

Reviewed changes

Copilot reviewed 5 out of 5 changed files in this pull request and generated 4 comments.

Show a summary per file
FileDescription
src/coreclr/pal/src/map/virtual.cppSwitches WASM reserve/release behavior to posix_memalign/free and adjusts related error/cleanup paths.
src/coreclr/gc/wasm/gcenv.wasm.cppNew WASM-specific GC OS interface implementation (virtual memory, CPU/NUMA stubs, memory stats).
src/coreclr/gc/wasm/CMakeLists.txtAdds build definition for the WASM GC PAL object library.
src/coreclr/gc/unix/gcenv.unix.cppRemoves WASM-specific branches and fixes nanosleep EINTR retry logic.
src/coreclr/gc/CMakeLists.txtRoutes WASM builds to gc/wasm instead of gc/unix.

Comment threadsrc/coreclr/pal/src/map/virtual.cpp
Comment threadsrc/coreclr/pal/src/map/virtual.cpp Outdated
Comment threadsrc/coreclr/gc/wasm/gcenv.wasm.cpp Outdated
Comment threadsrc/coreclr/gc/wasm/gcenv.wasm.cpp Outdated
@pavelsavarapavelsavara changed the title [wasm][coreclr] Extract WASM-specific GC memory management into dedicated file[browser/wasi] Dedicated WASM GC PAL — replace mmap with posix_memalign and optimize memory operationsApr 23, 2026
@pavelsavarapavelsavara changed the title [browser/wasi] Dedicated WASM GC PAL — replace mmap with posix_memalign and optimize memory operations[browser/wasi][coreCLR] Dedicated WASM GC PAL — replace mmap with posix_memalign and optimize memory operationsApr 24, 2026
CopilotAI review requested due to automatic review settings April 24, 2026 08:20

CopilotAI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 7 out of 7 changed files in this pull request and generated 7 comments.

Comment threadsrc/coreclr/gc/wasm/gcenv.wasm.cpp Outdated
Comment threadsrc/coreclr/gc/wasm/gcenv.wasm.cpp Outdated
Comment threadsrc/coreclr/gc/wasm/gcenv.wasm.cpp Outdated
Comment threadsrc/coreclr/gc/wasm/gcenv.wasm.cpp Outdated
Comment threadsrc/coreclr/pal/src/map/virtual.cpp Outdated
Comment threadsrc/coreclr/pal/src/map/virtual.cpp Outdated
Comment threadsrc/coreclr/pal/src/map/virtual.cpp Outdated
CopilotAI review requested due to automatic review settings April 24, 2026 11:37
@pavelsavara
pavelsavara marked this pull request as ready for review April 24, 2026 11:43

CopilotAI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 7 out of 7 changed files in this pull request and generated 7 comments.

Comment threadsrc/coreclr/gc/wasm/gcenv.cpp
Comment threadsrc/coreclr/gc/wasm/CMakeLists.txt
Comment threadsrc/coreclr/gc/wasm/gcenv.cpp
Comment threadsrc/coreclr/pal/src/map/virtual.cpp Outdated
Comment threadsrc/coreclr/gc/wasm/gcenv.wasm.cpp Outdated
Comment threadsrc/coreclr/gc/wasm/gcenv.cpp
Comment threadsrc/coreclr/gc/wasm/gcenv.cpp

CopilotAI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 7 out of 7 changed files in this pull request and generated 1 comment.

Comment threadsrc/coreclr/gc/wasm/gcenv.cpp
Comment threadsrc/native/minipal/wasm.h Outdated
CopilotAI review requested due to automatic review settings May 6, 2026 07:36

CopilotAI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 17 out of 17 changed files in this pull request and generated no new comments.

@pavelsavara
pavelsavara requested a review from janvorliMay 6, 2026 12:59
Comment threadsrc/coreclr/gc/regions_segments.cpp Outdated
Comment threadsrc/coreclr/pal/src/map/virtual.cpp Outdated
Comment threadsrc/coreclr/gc/wasm/CMakeLists.txt

@janvorlijanvorli left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM, thank you!

@pavelsavara

Copy link
Copy Markdown
MemberAuthor

/ba-g unrelated CI fail

@pavelsavara
pavelsavara merged commit 5dd24c0 into dotnet:mainMay 7, 2026
176 of 178 checks passed
@pavelsavara
pavelsavara deleted the browser_no_mmap branch May 7, 2026 06:15
@BenVBenV mentioned this pull request May 11, 2026
lewing added a commit to lewing/runtime that referenced this pull request May 22, 2026
PR dotnet#127328 introduced a dedicated src/coreclr/gc/wasm/gcenv.cpp that
replaces gcenv.unix.cpp when targeting WebAssembly (browser or WASI).
The CMake selector in src/coreclr/gc/CMakeLists.txt now reads:
if(CLR_CMAKE_TARGET_ARCH_WASM)
add_subdirectory(wasm)
elseif(CLR_CMAKE_HOST_UNIX)
add_subdirectory(unix)
so the original PR's three changes to gcenv.unix.cpp are no longer
compiled for WASI:
- _WASI_EMULATED_MMAN guard on the <sys/mman.h> include
- exclusion of __wasi__ from the ReadMemAvailable() guard
- __wasi__ branch in GetAvailablePhysicalMemory()
The wasm-specific implementation in gc/wasm/gcenv.cpp already implements
equivalent available-memory logic using __builtin_wasm_memory_size, so
nothing of value is lost by reverting these hunks to match upstream.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@github-actionsgithub-actionsBot locked and limited conversation to collaborators Jun 6, 2026
Sign up for freeto subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

arch-wasmWebAssembly architecturearea-GC-coreclr

Projects

None yet

6 participants

@pavelsavara@am11@jkotas@janvorli@SingleAccretion
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Remove or un-stick sticky/fixed headers that block content\n(function() {\n function unstick() {\n document.querySelectorAll('header, nav, [role=\"banner\"], .header, .navbar, .sticky, .fixed-top, [style*=\"position: fixed\"], [style*=\"position:sticky\"]').forEach(function(el) {\n if (el.style.position === 'fixed' || el.style.position === 'sticky' || \n getComputedStyle(el).position === 'fixed' || getComputedStyle(el).position === 'sticky') {\n el.style.position = 'static';\n el.style.top = 'auto';\n el.style.zIndex = 'auto';\n }\n });\n }\n \n unstick();\n \n var observer = new MutationObserver(unstick);\n observer.observe(document.body, { childList: true, subtree: true, attributes: true, attributeFilter: ['style', 'class'] });\n})();", "Kill Sticky Headers"); } } catch(__e) { console.warn('[Userscript:Kill Sticky Headers]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

[browser][coreclr] WASM-specific GC OS layer; no mmap/decommit - #127328

Merged
pavelsavara merged 47 commits into
dotnet:mainfrom
pavelsavara:browser_no_mmap
May 7, 2026
Merged

[browser][coreclr] WASM-specific GC OS layer; no mmap/decommit#127328
pavelsavara merged 47 commits into
dotnet:mainfrom
pavelsavara:browser_no_mmap

Conversation

@pavelsavara

@pavelsavarapavelsavara commented Apr 23, 2026

Copy link
Copy Markdown
Member

Fixes#121036
Fixes#117813
Fixes#118943

Summary

This PR adds a dedicated WASM implementation of the GC's OS abstraction layer
(GCToOSInterface) and updates the GC and PAL to handle the fact that on WASM
there is no virtual memory: pages cannot be reserved without committing,
partial unmaps don't return memory to the engine, and MAP_FIXED / madvise
are not supported.

The previous approach reused gcenv.unix.cpp with #ifdef TARGET_WASM patches
and overloaded use_large_pages_p to mean "decommit is a no-op". This change
splits those concerns:

  • A new gc/wasm/gcenv.cpp replaces gc/unix/gcenv.unix.cpp on WASM and
    implements VirtualReserve / VirtualCommit / VirtualDecommit /
    VirtualRelease on top of posix_memalign / free. WASM-specific patches
    in gcenv.unix.cpp are removed.
  • A new GC flag never_decommit_p replaces every "is decommit a no-op" check
    that was previously expressed as use_large_pages_p. It is set on WASM
    unconditionally and on other platforms whenever use_large_pages_p is set.
  • gc/CMakeLists.txt now selects gc/wasm for WASM targets while still
    including unix/configure.cmake to generate config.gc.h.
  • The PAL's virtual.cpp is similarly cleaned up to use posix_memalign /
    free on WASM and to zero memory on MEM_DECOMMIT, so the next
    VirtualCommit (a no-op on WASM) sees zeroed memory.
  • A new minipal_getpagesize abstraction is introduced. On WASM it returns a
    compile-time constant of 16 KB (the GC's page granularity, distinct from the
    64 KB memory.grow granularity that getpagesize() reports). On Windows it
    returns the 4 KB constant inline. On other POSIX systems it caches
    getpagesize() once per process. CoreCLR PAL callers are updated to use it.

Why a separate never_decommit_p

On large pages, decommit is a no-op because the OS pre-commits the entire
range. On WASM, decommit is a no-op because there is no way to give linear
memory back to the engine. The two cases share the same set of GC code paths
that must be skipped or modified (decommit_ephemeral_segment_pages,
decommit_step, decommit_region, decommit_heap_segment_pages,
decommit_heap_segment, distribute_free_regions tail-decommit,
reset_memory, virtual_commit, virtual_decommit assert), but they have
nothing else in common. Reusing use_large_pages_p on WASM was misleading and
made it easy to forget large-pages-only behavior (e.g., pre-touch). The new
flag captures only the "decommit is a no-op" semantics; non-WASM behavior is
unchanged because never_decommit_p == use_large_pages_p everywhere except
WASM.

Why minipal_getpagesize

The GC needs the OS page size to be a compile-time constant on WASM (16 KB)
so that alignment math folds. getpagesize() on emscripten returns 64 KB
(the memory.grow granularity), which is too coarse for GC alignment and
thresholds. Centralizing this in minipal lets PAL and GC agree on a single
value and avoids #ifdefs at every call site.

Notes

  • VirtualReserveAndCommitLargePages on WASM falls through to the regular
    reserve/commit path; the GC does not request large pages on WASM.
  • posix_memalign may return either freshly grown linear memory (zeroed by
    the WASM spec) or a recycled block from emscripten's allocator free list.
    We always memset to zero on reserve and on decommit so callers can rely
    on the standard "memory starts zeroed" contract.
  • VirtualReset returns false on WASM, forcing the GC to use the
    decommit+commit fallback (memset to zero) rather than relying on
    madvise, which is a no-op on emscripten.

@pavelsavarapavelsavara added this to the 11.0.0 milestone Apr 23, 2026
@pavelsavarapavelsavara self-assigned this Apr 23, 2026
CopilotAI review requested due to automatic review settings April 23, 2026 16:55
@pavelsavarapavelsavara added arch-wasm WebAssembly architecture area-GC-coreclr labels Apr 23, 2026
@dotnet-policy-service

Copy link
Copy Markdown
Contributor

Tagging subscribers to this area: @JulieLeeMSFT, @dotnet/gc
See info in area-owners.md if you want to be subscribed.

CopilotAI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR separates WebAssembly-specific GC OS interface behavior from the shared Unix implementation by introducing a dedicated gcenv.wasm.cpp, and adjusts the PAL virtual memory implementation on WASM to avoid relying on Emscripten’s incomplete mmap/munmap support.

Changes:

  • Added a dedicated WASM GCToOSInterface implementation (gcenv.wasm.cpp) and CMake wiring for building it.
  • Routed WASM GC builds to the new gc/wasm directory and removed WASM-specific #ifdef paths from gcenv.unix.cpp.
  • Updated PAL virtual memory reserve/release on WASM to use posix_memalign/free instead of mmap/munmap.

Reviewed changes

Copilot reviewed 5 out of 5 changed files in this pull request and generated 4 comments.

Show a summary per file
FileDescription
src/coreclr/pal/src/map/virtual.cppSwitches WASM reserve/release behavior to posix_memalign/free and adjusts related error/cleanup paths.
src/coreclr/gc/wasm/gcenv.wasm.cppNew WASM-specific GC OS interface implementation (virtual memory, CPU/NUMA stubs, memory stats).
src/coreclr/gc/wasm/CMakeLists.txtAdds build definition for the WASM GC PAL object library.
src/coreclr/gc/unix/gcenv.unix.cppRemoves WASM-specific branches and fixes nanosleep EINTR retry logic.
src/coreclr/gc/CMakeLists.txtRoutes WASM builds to gc/wasm instead of gc/unix.

Comment threadsrc/coreclr/pal/src/map/virtual.cpp
Comment threadsrc/coreclr/pal/src/map/virtual.cpp Outdated
Comment threadsrc/coreclr/gc/wasm/gcenv.wasm.cpp Outdated
Comment threadsrc/coreclr/gc/wasm/gcenv.wasm.cpp Outdated
@pavelsavarapavelsavara changed the title [wasm][coreclr] Extract WASM-specific GC memory management into dedicated file[browser/wasi] Dedicated WASM GC PAL — replace mmap with posix_memalign and optimize memory operationsApr 23, 2026
@pavelsavarapavelsavara changed the title [browser/wasi] Dedicated WASM GC PAL — replace mmap with posix_memalign and optimize memory operations[browser/wasi][coreCLR] Dedicated WASM GC PAL — replace mmap with posix_memalign and optimize memory operationsApr 24, 2026
CopilotAI review requested due to automatic review settings April 24, 2026 08:20

CopilotAI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 7 out of 7 changed files in this pull request and generated 7 comments.

Comment threadsrc/coreclr/gc/wasm/gcenv.wasm.cpp Outdated
Comment threadsrc/coreclr/gc/wasm/gcenv.wasm.cpp Outdated
Comment threadsrc/coreclr/gc/wasm/gcenv.wasm.cpp Outdated
Comment threadsrc/coreclr/gc/wasm/gcenv.wasm.cpp Outdated
Comment threadsrc/coreclr/pal/src/map/virtual.cpp Outdated
Comment threadsrc/coreclr/pal/src/map/virtual.cpp Outdated
Comment threadsrc/coreclr/pal/src/map/virtual.cpp Outdated
CopilotAI review requested due to automatic review settings April 24, 2026 11:37
@pavelsavara
pavelsavara marked this pull request as ready for review April 24, 2026 11:43

CopilotAI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 7 out of 7 changed files in this pull request and generated 7 comments.

Comment threadsrc/coreclr/gc/wasm/gcenv.cpp
Comment threadsrc/coreclr/gc/wasm/CMakeLists.txt
Comment threadsrc/coreclr/gc/wasm/gcenv.cpp
Comment threadsrc/coreclr/pal/src/map/virtual.cpp Outdated
Comment threadsrc/coreclr/gc/wasm/gcenv.wasm.cpp Outdated
Comment threadsrc/coreclr/gc/wasm/gcenv.cpp
Comment threadsrc/coreclr/gc/wasm/gcenv.cpp

CopilotAI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 7 out of 7 changed files in this pull request and generated 1 comment.

Comment threadsrc/coreclr/gc/wasm/gcenv.cpp
Comment threadsrc/native/minipal/wasm.h Outdated
CopilotAI review requested due to automatic review settings May 6, 2026 07:36

CopilotAI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 17 out of 17 changed files in this pull request and generated no new comments.

@pavelsavara
pavelsavara requested a review from janvorliMay 6, 2026 12:59
Comment threadsrc/coreclr/gc/regions_segments.cpp Outdated
Comment threadsrc/coreclr/pal/src/map/virtual.cpp Outdated
Comment threadsrc/coreclr/gc/wasm/CMakeLists.txt

@janvorlijanvorli left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM, thank you!

@pavelsavara

Copy link
Copy Markdown
MemberAuthor

/ba-g unrelated CI fail

@pavelsavara
pavelsavara merged commit 5dd24c0 into dotnet:mainMay 7, 2026
176 of 178 checks passed
@pavelsavara
pavelsavara deleted the browser_no_mmap branch May 7, 2026 06:15
@BenVBenV mentioned this pull request May 11, 2026
lewing added a commit to lewing/runtime that referenced this pull request May 22, 2026
PR dotnet#127328 introduced a dedicated src/coreclr/gc/wasm/gcenv.cpp that
replaces gcenv.unix.cpp when targeting WebAssembly (browser or WASI).
The CMake selector in src/coreclr/gc/CMakeLists.txt now reads:
if(CLR_CMAKE_TARGET_ARCH_WASM)
add_subdirectory(wasm)
elseif(CLR_CMAKE_HOST_UNIX)
add_subdirectory(unix)
so the original PR's three changes to gcenv.unix.cpp are no longer
compiled for WASI:
- _WASI_EMULATED_MMAN guard on the <sys/mman.h> include
- exclusion of __wasi__ from the ReadMemAvailable() guard
- __wasi__ branch in GetAvailablePhysicalMemory()
The wasm-specific implementation in gc/wasm/gcenv.cpp already implements
equivalent available-memory logic using __builtin_wasm_memory_size, so
nothing of value is lost by reverting these hunks to match upstream.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@github-actionsgithub-actionsBot locked and limited conversation to collaborators Jun 6, 2026
Sign up for freeto subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

arch-wasmWebAssembly architecturearea-GC-coreclr

Projects

None yet

6 participants

@pavelsavara@am11@jkotas@janvorli@SingleAccretion
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Universal Dark Mode - works on any site\n(function() {\n var enabled = true;\n \n function applyDarkMode() {\n if (!enabled) return;\n \n // Create style element if it doesn't exist\n var style = document.getElementById('universal-dark-mode-style');\n if (!style) {\n style = document.createElement('style');\n style.id = 'universal-dark-mode-style';\n document.head.appendChild(style);\n }\n \n // Dark mode CSS - inverts colors but preserves images/video\n style.textContent = '\n /* Invert everything except media */\n html {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #1a1a2e !important;\n }\n \n /* Restore images, videos, iframes, canvas */\n img, video, iframe, canvas, svg, picture, [style*=\"background-image\"] {\n filter: invert(1) hue-rotate(180deg) !important;\n }\n \n /* Preserve specific elements that should not be inverted */\n .no-dark-mode, .no-dark-mode *,\n [data-theme=\"light\"], [data-theme=\"light\"],\n .ace_editor, .ace_editor *,\n .CodeMirror, .CodeMirror *,\n .monaco-editor, .monaco-editor *,\n .markdown-body pre, .markdown-body pre *,\n .highlight, .highlight *,\n pre code, pre code * {\n filter: none !important;\n }\n \n /* Fix common UI elements */\n .modal, .popup, .dropdown-menu, .tooltip, .popover {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #2d2d44 !important;\n border-color: #444 !important;\n }\n \n /* Scrollbars */\n ::-webkit-scrollbar { background: #1a1a2e !important; }\n ::-webkit-scrollbar-thumb { background: #444 !important; }\n ::-webkit-scrollbar-thumb:hover { background: #555 !important; }\n \n /* Selection */\n ::selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ::-moz-selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ';\n }\n \n function removeDarkMode() {\n var style = document.getElementById('universal-dark-mode-style');\n if (style) style.remove();\n }\n \n // Toggle with Alt+Shift+D\n document.addEventListener('keydown', function(e) {\n if (e.altKey && e.shiftKey && e.key === 'D') {\n e.preventDefault();\n enabled = !enabled;\n if (enabled) {\n applyDarkMode();\n console.log('[Universal Dark Mode] Enabled');\n } else {\n removeDarkMode();\n console.log('[Universal Dark Mode] Disabled');\n }\n }\n });\n \n // Apply on load\n applyDarkMode();\n \n // Re-apply on dynamic content\n var observer = new MutationObserver(function(mutations) {\n if (enabled && !document.getElementById('universal-dark-mode-style')) {\n applyDarkMode();\n }\n });\n observer.observe(document.head, { childList: true });\n \n console.log('[Universal Dark Mode] Loaded - Press Alt+Shift+D to toggle');\n})();", "Universal Dark Mode"); } } catch(__e) { console.warn('[Userscript:Universal Dark Mode]', __e); } })(); })();
Skip to content

[browser][coreclr] WASM-specific GC OS layer; no mmap/decommit - #127328

Merged
pavelsavara merged 47 commits into
dotnet:mainfrom
pavelsavara:browser_no_mmap
May 7, 2026
Merged

[browser][coreclr] WASM-specific GC OS layer; no mmap/decommit#127328
pavelsavara merged 47 commits into
dotnet:mainfrom
pavelsavara:browser_no_mmap

Conversation

@pavelsavara

@pavelsavarapavelsavara commented Apr 23, 2026

Copy link
Copy Markdown
Member

Fixes#121036
Fixes#117813
Fixes#118943

Summary

This PR adds a dedicated WASM implementation of the GC's OS abstraction layer
(GCToOSInterface) and updates the GC and PAL to handle the fact that on WASM
there is no virtual memory: pages cannot be reserved without committing,
partial unmaps don't return memory to the engine, and MAP_FIXED / madvise
are not supported.

The previous approach reused gcenv.unix.cpp with #ifdef TARGET_WASM patches
and overloaded use_large_pages_p to mean "decommit is a no-op". This change
splits those concerns:

  • A new gc/wasm/gcenv.cpp replaces gc/unix/gcenv.unix.cpp on WASM and
    implements VirtualReserve / VirtualCommit / VirtualDecommit /
    VirtualRelease on top of posix_memalign / free. WASM-specific patches
    in gcenv.unix.cpp are removed.
  • A new GC flag never_decommit_p replaces every "is decommit a no-op" check
    that was previously expressed as use_large_pages_p. It is set on WASM
    unconditionally and on other platforms whenever use_large_pages_p is set.
  • gc/CMakeLists.txt now selects gc/wasm for WASM targets while still
    including unix/configure.cmake to generate config.gc.h.
  • The PAL's virtual.cpp is similarly cleaned up to use posix_memalign /
    free on WASM and to zero memory on MEM_DECOMMIT, so the next
    VirtualCommit (a no-op on WASM) sees zeroed memory.
  • A new minipal_getpagesize abstraction is introduced. On WASM it returns a
    compile-time constant of 16 KB (the GC's page granularity, distinct from the
    64 KB memory.grow granularity that getpagesize() reports). On Windows it
    returns the 4 KB constant inline. On other POSIX systems it caches
    getpagesize() once per process. CoreCLR PAL callers are updated to use it.

Why a separate never_decommit_p

On large pages, decommit is a no-op because the OS pre-commits the entire
range. On WASM, decommit is a no-op because there is no way to give linear
memory back to the engine. The two cases share the same set of GC code paths
that must be skipped or modified (decommit_ephemeral_segment_pages,
decommit_step, decommit_region, decommit_heap_segment_pages,
decommit_heap_segment, distribute_free_regions tail-decommit,
reset_memory, virtual_commit, virtual_decommit assert), but they have
nothing else in common. Reusing use_large_pages_p on WASM was misleading and
made it easy to forget large-pages-only behavior (e.g., pre-touch). The new
flag captures only the "decommit is a no-op" semantics; non-WASM behavior is
unchanged because never_decommit_p == use_large_pages_p everywhere except
WASM.

Why minipal_getpagesize

The GC needs the OS page size to be a compile-time constant on WASM (16 KB)
so that alignment math folds. getpagesize() on emscripten returns 64 KB
(the memory.grow granularity), which is too coarse for GC alignment and
thresholds. Centralizing this in minipal lets PAL and GC agree on a single
value and avoids #ifdefs at every call site.

Notes

  • VirtualReserveAndCommitLargePages on WASM falls through to the regular
    reserve/commit path; the GC does not request large pages on WASM.
  • posix_memalign may return either freshly grown linear memory (zeroed by
    the WASM spec) or a recycled block from emscripten's allocator free list.
    We always memset to zero on reserve and on decommit so callers can rely
    on the standard "memory starts zeroed" contract.
  • VirtualReset returns false on WASM, forcing the GC to use the
    decommit+commit fallback (memset to zero) rather than relying on
    madvise, which is a no-op on emscripten.

@pavelsavarapavelsavara added this to the 11.0.0 milestone Apr 23, 2026
@pavelsavarapavelsavara self-assigned this Apr 23, 2026
CopilotAI review requested due to automatic review settings April 23, 2026 16:55
@pavelsavarapavelsavara added arch-wasm WebAssembly architecture area-GC-coreclr labels Apr 23, 2026
@dotnet-policy-service

Copy link
Copy Markdown
Contributor

Tagging subscribers to this area: @JulieLeeMSFT, @dotnet/gc
See info in area-owners.md if you want to be subscribed.

CopilotAI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR separates WebAssembly-specific GC OS interface behavior from the shared Unix implementation by introducing a dedicated gcenv.wasm.cpp, and adjusts the PAL virtual memory implementation on WASM to avoid relying on Emscripten’s incomplete mmap/munmap support.

Changes:

  • Added a dedicated WASM GCToOSInterface implementation (gcenv.wasm.cpp) and CMake wiring for building it.
  • Routed WASM GC builds to the new gc/wasm directory and removed WASM-specific #ifdef paths from gcenv.unix.cpp.
  • Updated PAL virtual memory reserve/release on WASM to use posix_memalign/free instead of mmap/munmap.

Reviewed changes

Copilot reviewed 5 out of 5 changed files in this pull request and generated 4 comments.

Show a summary per file
FileDescription
src/coreclr/pal/src/map/virtual.cppSwitches WASM reserve/release behavior to posix_memalign/free and adjusts related error/cleanup paths.
src/coreclr/gc/wasm/gcenv.wasm.cppNew WASM-specific GC OS interface implementation (virtual memory, CPU/NUMA stubs, memory stats).
src/coreclr/gc/wasm/CMakeLists.txtAdds build definition for the WASM GC PAL object library.
src/coreclr/gc/unix/gcenv.unix.cppRemoves WASM-specific branches and fixes nanosleep EINTR retry logic.
src/coreclr/gc/CMakeLists.txtRoutes WASM builds to gc/wasm instead of gc/unix.

Comment threadsrc/coreclr/pal/src/map/virtual.cpp
Comment threadsrc/coreclr/pal/src/map/virtual.cpp Outdated
Comment threadsrc/coreclr/gc/wasm/gcenv.wasm.cpp Outdated
Comment threadsrc/coreclr/gc/wasm/gcenv.wasm.cpp Outdated
@pavelsavarapavelsavara changed the title [wasm][coreclr] Extract WASM-specific GC memory management into dedicated file[browser/wasi] Dedicated WASM GC PAL — replace mmap with posix_memalign and optimize memory operationsApr 23, 2026
@pavelsavarapavelsavara changed the title [browser/wasi] Dedicated WASM GC PAL — replace mmap with posix_memalign and optimize memory operations[browser/wasi][coreCLR] Dedicated WASM GC PAL — replace mmap with posix_memalign and optimize memory operationsApr 24, 2026
CopilotAI review requested due to automatic review settings April 24, 2026 08:20

CopilotAI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 7 out of 7 changed files in this pull request and generated 7 comments.

Comment threadsrc/coreclr/gc/wasm/gcenv.wasm.cpp Outdated
Comment threadsrc/coreclr/gc/wasm/gcenv.wasm.cpp Outdated
Comment threadsrc/coreclr/gc/wasm/gcenv.wasm.cpp Outdated
Comment threadsrc/coreclr/gc/wasm/gcenv.wasm.cpp Outdated
Comment threadsrc/coreclr/pal/src/map/virtual.cpp Outdated
Comment threadsrc/coreclr/pal/src/map/virtual.cpp Outdated
Comment threadsrc/coreclr/pal/src/map/virtual.cpp Outdated
CopilotAI review requested due to automatic review settings April 24, 2026 11:37
@pavelsavara
pavelsavara marked this pull request as ready for review April 24, 2026 11:43

CopilotAI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 7 out of 7 changed files in this pull request and generated 7 comments.

Comment threadsrc/coreclr/gc/wasm/gcenv.cpp
Comment threadsrc/coreclr/gc/wasm/CMakeLists.txt
Comment threadsrc/coreclr/gc/wasm/gcenv.cpp
Comment threadsrc/coreclr/pal/src/map/virtual.cpp Outdated
Comment threadsrc/coreclr/gc/wasm/gcenv.wasm.cpp Outdated
Comment threadsrc/coreclr/gc/wasm/gcenv.cpp
Comment threadsrc/coreclr/gc/wasm/gcenv.cpp

CopilotAI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 7 out of 7 changed files in this pull request and generated 1 comment.

Comment threadsrc/coreclr/gc/wasm/gcenv.cpp
Comment threadsrc/native/minipal/wasm.h Outdated
CopilotAI review requested due to automatic review settings May 6, 2026 07:36

CopilotAI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 17 out of 17 changed files in this pull request and generated no new comments.

@pavelsavara
pavelsavara requested a review from janvorliMay 6, 2026 12:59
Comment threadsrc/coreclr/gc/regions_segments.cpp Outdated
Comment threadsrc/coreclr/pal/src/map/virtual.cpp Outdated
Comment threadsrc/coreclr/gc/wasm/CMakeLists.txt

@janvorlijanvorli left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM, thank you!

@pavelsavara

Copy link
Copy Markdown
MemberAuthor

/ba-g unrelated CI fail

@pavelsavara
pavelsavara merged commit 5dd24c0 into dotnet:mainMay 7, 2026
176 of 178 checks passed
@pavelsavara
pavelsavara deleted the browser_no_mmap branch May 7, 2026 06:15
@BenVBenV mentioned this pull request May 11, 2026
lewing added a commit to lewing/runtime that referenced this pull request May 22, 2026
PR dotnet#127328 introduced a dedicated src/coreclr/gc/wasm/gcenv.cpp that
replaces gcenv.unix.cpp when targeting WebAssembly (browser or WASI).
The CMake selector in src/coreclr/gc/CMakeLists.txt now reads:
if(CLR_CMAKE_TARGET_ARCH_WASM)
add_subdirectory(wasm)
elseif(CLR_CMAKE_HOST_UNIX)
add_subdirectory(unix)
so the original PR's three changes to gcenv.unix.cpp are no longer
compiled for WASI:
- _WASI_EMULATED_MMAN guard on the <sys/mman.h> include
- exclusion of __wasi__ from the ReadMemAvailable() guard
- __wasi__ branch in GetAvailablePhysicalMemory()
The wasm-specific implementation in gc/wasm/gcenv.cpp already implements
equivalent available-memory logic using __builtin_wasm_memory_size, so
nothing of value is lost by reverting these hunks to match upstream.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@github-actionsgithub-actionsBot locked and limited conversation to collaborators Jun 6, 2026
Sign up for freeto subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

arch-wasmWebAssembly architecturearea-GC-coreclr

Projects

None yet

6 participants

@pavelsavara@am11@jkotas@janvorli@SingleAccretion