Disable server GC and background GC for CoreCLR WebAssembly builds#127178
Disable server GC and background GC for CoreCLR WebAssembly builds#127178
Conversation
Agent-Logs-Url: https://github.com/dotnet/runtime/sessions/ef405ab1-bc2a-472f-b797-52d49c5d8409 Co-authored-by: davidwrighton <10779849+davidwrighton@users.noreply.github.com>
|
@copilot let's disable the background GC for WASM too. |
|
cc: @radekdoulik FYI |
Agent-Logs-Url: https://github.com/dotnet/runtime/sessions/05b0c780-4d5e-4177-b5ec-c07a31e050a7 Co-authored-by: davidwrighton <10779849+davidwrighton@users.noreply.github.com>
…eLoadedBeforeCodeIsRun, and reportTailCallDecision Agent-Logs-Url: https://github.com/dotnet/runtime/sessions/05b0c780-4d5e-4177-b5ec-c07a31e050a7 Co-authored-by: davidwrighton <10779849+davidwrighton@users.noreply.github.com>
Agent-Logs-Url: https://github.com/dotnet/runtime/sessions/7f661e48-3027-488a-8ca9-5fc83d287082 Co-authored-by: janvorli <10758568+janvorli@users.noreply.github.com>
Done in dc7b9f9. Added Additional savings from disabling background GC: 47,527 bytes raw / 15,680 bytes brotli, bringing the total vs baseline to 93,330 bytes raw (2.2%) / 25,599 bytes brotli (2.0%). |
|
@copilot please undo the changes in the jitinterface.cpp, these are unrelated to the GC changes. |
|
I had similar PR #127222 for it, so closed it and moved the feedback commit here, which disables the server GC on iOS and tvOS. /cc @vitek-karas |
Agent-Logs-Url: https://github.com/dotnet/runtime/sessions/1e26f7c7-3b3e-4cd7-a48d-366fafe10a91 Co-authored-by: davidwrighton <10779849+davidwrighton@users.noreply.github.com>
Agent-Logs-Url: https://github.com/dotnet/runtime/sessions/1e26f7c7-3b3e-4cd7-a48d-366fafe10a91 Co-authored-by: davidwrighton <10779849+davidwrighton@users.noreply.github.com>
Agent-Logs-Url: https://github.com/dotnet/runtime/sessions/1e26f7c7-3b3e-4cd7-a48d-366fafe10a91 Co-authored-by: davidwrighton <10779849+davidwrighton@users.noreply.github.com>
Agent-Logs-Url: https://github.com/dotnet/runtime/sessions/f2b3bc16-9cd9-4a56-a401-ad3a56525764 Co-authored-by: davidwrighton <10779849+davidwrighton@users.noreply.github.com>
|
Tagging subscribers to 'arch-wasm': @lewing, @pavelsavara |
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 9 out of 9 changed files in this pull request and generated 4 comments.
Comments suppressed due to low confidence (2)
src/coreclr/gc/datadescriptor/datadescriptor.inc:25
- The BACKGROUND_GC guard only wraps MarkArray/NextSweepObj/Background* fields, but the SavedSweepEphemeralSeg/Start fields later in this GCHeap type definition are still only guarded by !USE_REGIONS. In datadescriptor.h those SavedSweepEphemeral* offsets are now only defined when BACKGROUND_GC is enabled, so this can lead to referencing missing cdac_data members (and a build break) when BACKGROUND_GC is disabled. Please guard SavedSweepEphemeralSeg/Start here with the same
!USE_REGIONS && BACKGROUND_GCcondition used elsewhere in the descriptor.
#endif // BACKGROUND_GC
CDAC_TYPE_FIELD(GCHeap, T_POINTER, AllocAllocated, cdac_data<GC_NAMESPACE::gc_heap>::AllocAllocated)
CDAC_TYPE_FIELD(GCHeap, T_POINTER, EphemeralHeapSegment, cdac_data<GC_NAMESPACE::gc_heap>::EphemeralHeapSegment)
CDAC_TYPE_FIELD(GCHeap, T_POINTER, CardTable, cdac_data<GC_NAMESPACE::gc_heap>::CardTable)
CDAC_TYPE_FIELD(GCHeap, T_POINTER, FinalizeQueue, cdac_data<GC_NAMESPACE::gc_heap>::FinalizeQueue)
docs/design/datacontracts/GC.md:163
- Several table entries still say "sever builds"; this looks like a typo and should be "server builds".
| `GCHeap` | AllocAllocated | GC | Heap's highest address allocated by Alloc (in sever builds) |
| `GCHeap` | EphemeralHeapSegment | GC | Pointer to the heap's ephemeral heap segment (in sever builds) |
| `GCHeap` | CardTable | GC | Pointer to the heap's bookkeeping GC data structure (in sever builds) |
| `GCHeap` | FinalizeQueue | GC | Pointer to the heap's CFinalize data structure (in sever builds) |
| `GCHeap` | GenerationTable | GC | Pointer to the start of an array containing `"TotalGenerationCount"` `Generation` structures (in sever builds) |
| MarkArray = heap.MarkArray ?? TargetPointer.Null, | ||
| NextSweepObject = heap.NextSweepObj ?? TargetPointer.Null, | ||
| BackGroundSavedMinAddress = heap.BackgroundMinSavedAddr ?? TargetPointer.Null, | ||
| BackGroundSavedMaxAddress = heap.BackgroundMaxSavedAddr ?? TargetPointer.Null, |
There was a problem hiding this comment.
This introduces new behavior where background-GC-related fields can be missing and are defaulted to TargetPointer.Null. There are existing cDAC GC contract unit tests, but they don’t appear to cover the "background GC disabled" shape (globals/fields absent). Please add tests exercising both workstation (missing globals) and server (missing type fields) scenarios to ensure these null-default semantics stay correct.
| | `GCHeap` | MarkArray | GC | Pointer to the heap's MarkArray (only in server builds with background GC) | | ||
| | `GCHeap` | NextSweepObj | GC | Pointer to the heap's NextSweepObj (only in server builds with background GC) | | ||
| | `GCHeap` | BackgroundMinSavedAddr | GC | Heap's background saved lowest address (only in server builds with background GC) | | ||
| | `GCHeap` | BackgroundMaxSavedAddr | GC | Heap's background saved highest address (only in server builds with background GC) | |
There was a problem hiding this comment.
The updated availability notes correctly call out background GC for MarkArray/NextSweepObj/Background* fields. For consistency with the descriptor changes, please also update the SavedSweepEphemeralSeg/SavedSweepEphemeralStart entries later in this table to mention they’re absent when BACKGROUND_GC is disabled as well (not just when segment GC is unavailable).
| | `GCHeapMarkArray` | TargetPointer | GC | Pointer to the static heap's MarkArray (in workstation builds with background GC) | | ||
| | `GCHeapNextSweepObj` | TargetPointer | GC | Pointer to the static heap's NextSweepObj (in workstation builds with background GC) | | ||
| | `GCHeapBackgroundMinSavedAddr` | TargetPointer | GC | Background saved lowest address (in workstation builds with background GC) | | ||
| | `GCHeapBackgroundMaxSavedAddr` | TargetPointer | GC | Background saved highest address (in workstation builds with background GC) | |
There was a problem hiding this comment.
These globals are now documented as only present with background GC, which matches the code changes. Please also update the GCHeapSavedSweepEphemeralSeg/GCHeapSavedSweepEphemeralStart entries later in this globals table to reflect that they’re also absent when BACKGROUND_GC is disabled.
| if (NOT CLR_CMAKE_HOST_ANDROID AND NOT CLR_CMAKE_TARGET_ARCH_WASM AND NOT CLR_CMAKE_TARGET_IOS AND NOT CLR_CMAKE_TARGET_TVOS) | ||
| set(FEATURE_SVR_GC 1) | ||
| add_definitions(-DFEATURE_SVR_GC) | ||
| endif(NOT CLR_CMAKE_HOST_ANDROID) | ||
| endif(NOT CLR_CMAKE_HOST_ANDROID AND NOT CLR_CMAKE_TARGET_ARCH_WASM AND NOT CLR_CMAKE_TARGET_IOS AND NOT CLR_CMAKE_TARGET_TVOS) |
There was a problem hiding this comment.
This change disables FEATURE_SVR_GC not only for WebAssembly but also for iOS and tvOS. That broadens the behavior change beyond what’s described in the PR title/description; if that’s unintentional, drop the iOS/tvOS conditions, and if it’s intentional, please update the PR description to call out the additional platforms affected (and why).
🤖 Copilot Code Review — PR #127178Note This review was generated by Copilot and should be treated as an AI-generated analysis. Findings were cross-validated across multiple model families (Claude Opus 4.6, Claude Sonnet 4.5, GPT-5.3-Codex). Holistic AssessmentMotivation: Well-justified. WASM is single-threaded and has no use for server GC or background GC (which requires WRITE_WATCH and threads). The measured ~93KB (2.2%) raw savings are meaningful for a WASM target. Disabling server GC for iOS/tvOS follows the same rationale as the pre-existing Android exclusion. Approach: Clean and follows established codebase patterns. The cDAC optional-field handling mirrors the existing Summary: Detailed Findings
|
Description
Applies two complementary size optimizations for CoreCLR WebAssembly builds, which use the interpreter instead of the traditional JIT:
Disable server GC —
FEATURE_SVR_GCis suppressed for WebAssembly inclrdefinitions.cmake. WebAssembly is single-threaded and has no use for server GC's multi-heap design.Disable background GC — Background GC (concurrent GC) requires
WRITE_WATCHsupport and background threads, neither of which is available on WebAssembly.BACKGROUND_GCis now suppressed with a#ifndef TARGET_WASMguard ingcpriv.h. Thedatadescriptor.handdatadescriptor.inccDAC descriptor files are updated to guard the fields and globals that only exist whenBACKGROUND_GCis defined.cDAC support for optional background GC fields — The cDAC contract reader (
GCHeapWKS.cs,GCHeapSVR.cs,IGCHeap.cs,GC_1.cs) is updated so thatMarkArray,NextSweepObj,BackgroundMinSavedAddr, andBackgroundMaxSavedAddrare treated as optional fields — absent when background GC is disabled, and defaulted to0. Field presence is determined by whether the fields exist in the data descriptor (no explicit feature flag is emitted). TheGC.mdcontract documentation is updated to describe this optional behavior, following the same pattern as the segment-only fields such asGCHeapSavedSweepEphemeralSeg.Size measurements (
corerun.wasm)