Uh oh!
There was an error while loading. Please reload this page.
Add preemptive-only cooperative GC transition holder - #133276
Open
davidwrighton wants to merge 1 commit into
Open
Add preemptive-only cooperative GC transition holder#133276davidwrighton wants to merge 1 commit into
davidwrighton wants to merge 1 commit into
Conversation
Introduce GCX_COOP_FROM_PREEMP for call sites that are known to enter in preemptive mode, avoiding conditional mode restoration on normal and exceptional exits. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Copilot-Session: 7c53d414-704b-43fe-86cd-a4f5e0dc0446
|
Azure Pipelines: Successfully started running 3 pipeline(s). 13 pipeline(s) were filtered out due to trigger conditions. There may be pipelines that require an authorized user to comment /azp run to run. |
Contributor
Tagging subscribers to this area: @agocke |
Contributor
There was a problem hiding this comment.
🔵 Needs a closer look
It changes GC mode transition semantics across a large number of VM/QCall sites, so the regression blast radius is high and needs focused human validation of the “always-enter-preemptive” assumption per call site category.
Pull request overview
This PR introduces a new GC mode transition holder, GCX_COOP_FROM_PREEMP(), intended for call sites that are guaranteed to enter in preemptive mode, and updates a large set of existing GCX_COOP() usages to use the new holder where that precondition is believed to hold.
Changes:
- Add
GCX_COOP_FROM_PREEMP()macro +GCCoopFromPreempholder to provide a smaller preemptive→cooperative scope and an unconditional return to preemptive mode. - Update many QCall and VM sites that previously used
GCX_COOP()to useGCX_COOP_FROM_PREEMP()under the assumption they always enter preemptive. - Keep
GCX_COOP()at sites where the incoming mode is not guaranteed (per PR description).
File summaries
| File | Description |
|---|---|
| src/coreclr/vm/weakreferencenative.cpp | Switch select COM interop QCall regions to GCX_COOP_FROM_PREEMP(). |
| src/coreclr/vm/varargsnative.cpp | Switch ArgIterator QCalls to GCX_COOP_FROM_PREEMP(). |
| src/coreclr/vm/util.hpp | Add GCX_COOP_FROM_PREEMP() macro and document usage. |
| src/coreclr/vm/threads.h | Add GCCoopFromPreemp holder + internal enter/pop helpers for the new transition pattern. |
| src/coreclr/vm/threads.cpp | Switch arg-buffer swap to GCX_COOP_FROM_PREEMP(). |
| src/coreclr/vm/stubhelpers.cpp | Switch multiple interop QCall bodies to GCX_COOP_FROM_PREEMP(). |
| src/coreclr/vm/stdinterfaces.cpp | Switch COM type info helper scope to GCX_COOP_FROM_PREEMP(). |
| src/coreclr/vm/runtimehandles.cpp | Switch multiple reflection/runtime-handle QCall scopes to GCX_COOP_FROM_PREEMP(). |
| src/coreclr/vm/reflectioninvocation.cpp | Switch reflection invocation QCall scopes to GCX_COOP_FROM_PREEMP(). |
| src/coreclr/vm/qcall.cpp | Switch QCall handle helpers to GCX_COOP_FROM_PREEMP(). |
| src/coreclr/vm/prestub.cpp | Switch debug/slow-path GC-triggering regions to GCX_COOP_FROM_PREEMP(). |
| src/coreclr/vm/olevariant.cpp | Switch VARIANT conversion QCall scope to GCX_COOP_FROM_PREEMP(). |
| src/coreclr/vm/nativelibrary.cpp | Switch ALC resolve/managed callback scopes to GCX_COOP_FROM_PREEMP(). |
| src/coreclr/vm/mlinfo.cpp | Switch marshaling metadata/handle scopes to GCX_COOP_FROM_PREEMP(). |
| src/coreclr/vm/methodtable.cpp | Switch interface method-table resolution scopes to GCX_COOP_FROM_PREEMP(). |
| src/coreclr/vm/marshalnative.cpp | Switch many marshal/COM QCall scopes to GCX_COOP_FROM_PREEMP(). |
| src/coreclr/vm/managedmdimport.cpp | Switch managed metadata import array allocation scope to GCX_COOP_FROM_PREEMP(). |
| src/coreclr/vm/loaderallocator.cpp | Switch loader allocator GC/suspend + tracking setup scopes to GCX_COOP_FROM_PREEMP(). |
| src/coreclr/vm/jitinterface.cpp | Switch various JIT-EE helper scopes to GCX_COOP_FROM_PREEMP(). |
| src/coreclr/vm/jithelpers.cpp | Switch selected helper QCalls to GCX_COOP_FROM_PREEMP(). |
| src/coreclr/vm/interoplibinterface_objc.cpp | Switch ObjC reference tracking handle operations to GCX_COOP_FROM_PREEMP(). |
| src/coreclr/vm/interoplibinterface_java.cpp | Switch Java bridge initialization/handle operations to GCX_COOP_FROM_PREEMP(). |
| src/coreclr/vm/interoplibinterface_comwrappers.cpp | Switch ComWrappers handle/cache setup to GCX_COOP_FROM_PREEMP(). |
| src/coreclr/vm/ilstubresolver.cpp | Switch IL stub string literal construction scope to GCX_COOP_FROM_PREEMP(). |
| src/coreclr/vm/ilmarshalers.cpp | Switch SafeArray marshaling QCall scopes to GCX_COOP_FROM_PREEMP(). |
| src/coreclr/vm/finalizerthread.cpp | Switch browser/WASI finalizer iteration KickOff scope to GCX_COOP_FROM_PREEMP(). |
| src/coreclr/vm/exceptionhandling.cpp | Switch filter/stackwalk-related QCalls to GCX_COOP_FROM_PREEMP(). |
| src/coreclr/vm/dynamicmethod.cpp | Switch multiple LCG resolver scopes to GCX_COOP_FROM_PREEMP(). |
| src/coreclr/vm/dwbucketmanager.hpp | Switch exception-name retrieval scope to GCX_COOP_FROM_PREEMP(). |
| src/coreclr/vm/dispatchinfo.cpp | Switch managed view synchronization scope to GCX_COOP_FROM_PREEMP(). |
| src/coreclr/vm/debugdebugger.cpp | Switch debugger-related QCalls to GCX_COOP_FROM_PREEMP(). |
| src/coreclr/vm/custommarshalerinfo.cpp | Switch marshaler object setup scope to GCX_COOP_FROM_PREEMP(). |
| src/coreclr/vm/customattribute.cpp | Switch custom attribute instantiation/data creation scopes to GCX_COOP_FROM_PREEMP(). |
| src/coreclr/vm/crst.cpp | Switch debugger suspend-forbid holder scope to GCX_COOP_FROM_PREEMP(). |
| src/coreclr/vm/comutilnative.cpp | Switch numerous core QCalls (GC interface, failfast, etc.) to GCX_COOP_FROM_PREEMP(). |
| src/coreclr/vm/comsynchronizable.cpp | Switch thread/lock object QCalls to GCX_COOP_FROM_PREEMP(). |
| src/coreclr/vm/commodule.cpp | Switch reflection module RVAs/types QCalls to GCX_COOP_FROM_PREEMP(). |
| src/coreclr/vm/comdynamic.cpp | Switch dynamic type creation scope to GCX_COOP_FROM_PREEMP(). |
| src/coreclr/vm/comdependenthandle.cpp | Switch dependent handle alloc/free QCalls to GCX_COOP_FROM_PREEMP(). |
| src/coreclr/vm/comdelegate.cpp | Switch delegate init/reflection helper QCalls to GCX_COOP_FROM_PREEMP(). |
| src/coreclr/vm/comconnectionpoints.cpp | Switch connection enumeration scope to GCX_COOP_FROM_PREEMP(). |
| src/coreclr/vm/class.cpp | Switch EnC static field creation scope to GCX_COOP_FROM_PREEMP(). |
| src/coreclr/vm/ceeload.cpp | Switch module init/profiler callback + stringref resolution scopes to GCX_COOP_FROM_PREEMP(). |
| src/coreclr/vm/assemblynative.cpp | Switch many assembly QCalls to GCX_COOP_FROM_PREEMP(). |
| src/coreclr/vm/assembly.cpp | Switch loader-allocator association + profiler callback scopes to GCX_COOP_FROM_PREEMP(). |
| src/coreclr/vm/arraynative.cpp | Switch array allocation/ctor QCalls to GCX_COOP_FROM_PREEMP(). |
| src/coreclr/vm/appdomainnative.cpp | Switch dynamic assembly + intern QCalls to GCX_COOP_FROM_PREEMP(). |
Review details
- Files reviewed: 47/47 changed files
- Comments generated: 0
- Review effort level: Lite
jkotas
approved these changes
Sep 5, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for freeto join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
GCX_COOP_FROM_PREEMP(), a cooperative-mode holder for sites that are guaranteed to enter in preemptive modeGCX_COOP()at 132 sites where the incoming mode is not guaranteed or unwind behavior requires its defensive restorationThe new holder uses the existing non-nestable assertions in
DisablePreemptiveGC()andEnablePreemptiveGC()to detect invalid use in Checked and Debug builds.Size impact
Measured using
build.cmd clr -os browser -c releaseagainst a baseline build from the same checkout:corerun.wasmAs a representative example, the Browser WASM body for the
AppDomain_CreateDynamicAssemblyQCall decreased from 721 bytes to 611 bytes, a reduction of 110 bytes or 15.257%.Validation
build.cmd -subset clr -configuration Checkedbuild.cmd clr -os browser -c releaseNote
This pull request description was generated with GitHub Copilot.