Consolidate runtime helpers (X86Base, Interlocked, Buffer) across CoreCLR and NativeAOT#122791
Consolidate runtime helpers (X86Base, Interlocked, Buffer) across CoreCLR and NativeAOT#122791
Conversation
|
Tagging subscribers to this area: @agocke, @MichalStrehovsky, @jkotas |
Co-authored-by: jkotas <[email protected]>
…NativeAOT Co-authored-by: jkotas <[email protected]>
|
@copilot This looks great! Could you please move the QCall that implements Interlocked.MemoryBarrierProcessWide to src\coreclr\runtiem as well? The shared implementation should be called |
Co-authored-by: jkotas <[email protected]>
|
@copilot Let's also move |
src/libraries/System.Private.CoreLib/src/System/Runtime/Intrinsics/X86/X86Base.cs
Outdated
Show resolved
Hide resolved
…emMove to shared MiscNativeHelpers - Added Interlocked_MemoryBarrierProcessWide, Buffer_Clear, and Buffer_MemMove to MiscNativeHelpers.h/cpp - Removed old implementations from VM comutilnative.cpp/h and NativeAOT MiscHelpers.cpp - Updated managed code to use shared QCalls (Interlocked.cs and Buffer.NativeAot.cs) - Removed RhFlushProcessWriteBuffers from NativeAOT RuntimeImports.cs - Defined QCALLTYPE in MiscNativeHelpers.h to ensure compatibility with both VM and NativeAOT - Fixed Buffer_Clear to use direct arithmetic instead of ALIGN_UP/ALIGN_DOWN macros for portability Co-authored-by: jkotas <[email protected]>
Done in 06bba12. Moved Interlocked_MemoryBarrierProcessWide to shared MiscNativeHelpers and removed RhFlushProcessWriteBuffers and VM implementation.
Done in 06bba12. Moved Buffer_Clear and Buffer_MemMove to shared MiscNativeHelpers following the same pattern. |
…rBlock - Added (int) cast to return statement in RhpGetNumThunkBlocksPerMapping - Added (int) cast to return statement in RhpGetNumThunksPerBlock - Fixes build breaks caused by size_t to int conversion warnings - Ensures proper return type matching for functions declared as returning int Co-authored-by: jkotas <[email protected]>
- Added size_t thunksMapSize = THUNKS_MAP_SIZE at start of RhAllocateThunksMapping - Replaced all THUNKS_MAP_SIZE usages in the function with thunksMapSize local - Improves performance by avoiding multiple evaluations of the max() macro - Macro involves OS_PAGE_SIZE which could be a non-trivial computation Co-authored-by: jkotas <[email protected]>
|
@copilot Add more casts to fix build breaks |
- Cast OS_PAGE_SIZE to (int) in RhpGetThunkBlockSize return statement - Cast expression to (uint32_t) in thunk address calculation at line 177 - Fixes C4267 warnings about conversion from size_t to int/uint32_t - Ensures proper type matching for return values and assignments Co-authored-by: jkotas <[email protected]>
|
@copilot More build breaks - add casts: |
- Moved ICALL_TYPE(SPANHELPERS) from after System.Buffer to after System.RuntimeTypeHandle - ICALL_TYPE entries must be sorted alphabetically by full type name - System.SpanHelpers now correctly positioned between System.RuntimeTypeHandle and System.String - Maintains proper alphabetical ordering in icall-def.h Co-authored-by: jkotas <[email protected]>
- Cast expression to (uint32_t) in ARM64 thunk generation code - Fixes C4267 warning about conversion from size_t to uint32_t at line 236 - Expression involves OS_PAGE_SIZE calculation for thunk offset - Ensures proper type matching for uint32_t pointer assignment Co-authored-by: jkotas <[email protected]>
src/libraries/System.Private.CoreLib/src/System/SpanHelpers.ByteMemOps.cs
Outdated
Show resolved
Hide resolved
src/libraries/System.Private.CoreLib/src/System/SpanHelpers.ByteMemOps.cs
Outdated
Show resolved
Hide resolved
- Changed alignedEnd calculation from ~(nuint)16 to ~(nuint)(16 - 1) for clarity - Both alignment masks now use consistent (16 - 1) pattern - Removed (int32_t) cast from ASSERT in allocheap.cpp to fix gcc build break - ASSERT now directly compares alignment <= OS_PAGE_SIZE without cast - Both are size_t types so no cast needed Co-authored-by: jkotas <[email protected]>
src/libraries/System.Private.CoreLib/src/System/Runtime/Intrinsics/X86/X86Base.cs
Show resolved
Hide resolved
|
@MichalStrehovsky @jkoritzinsky This is introducing sharing of QCALLs between NAOT and non-NAOT |
There was a problem hiding this comment.
Pull request overview
This PR consolidates duplicate runtime helper implementations (X86Base, Interlocked, Buffer operations) across CoreCLR, NativeAOT, and Mono into shared locations, maximizing code reuse while minimizing conditional compilation. The changes create new shared QCall implementations in src/coreclr/runtime/ and unify managed code with minimal #if MONO directives.
Key Changes:
- Moved X86Base.CpuId and Interlocked.MemoryBarrierProcessWide to shared QCall implementations in
MiscNativeHelpers.cpp - Replaced Buffer QCalls with direct CRT memset/memmove calls via LibraryImport
- Eliminated all platform-specific partial classes for X86Base (CoreCLR.cs, NativeAot.cs, Mono.cs deleted)
- Removed OS_PAGE_SIZE abstraction layer and Range.h utility class from NativeAOT
- Fixed type conversions and include ordering in NativeAOT Runtime
Reviewed changes
Copilot reviewed 43 out of 43 changed files in this pull request and generated no comments.
Show a summary per file
| File | Description |
|---|---|
| src/coreclr/runtime/MiscNativeHelpers.cpp/h | New shared QCall implementations for X86Base_CpuId and Interlocked_MemoryBarrierProcessWide |
| src/coreclr/nativeaot/Runtime/common.h | New header defining QCALLTYPE for NativeAOT to support shared QCalls |
| src/libraries/System.Private.CoreLib/src/System/Runtime/Intrinsics/X86/X86Base.cs | Unified CpuId implementation with conditional InternalCall (Mono) vs LibraryImport (CoreCLR/NativeAOT) |
| src/libraries/System.Private.CoreLib/src/System/Threading/Interlocked.cs | Consolidated MemoryBarrierProcessWide for CoreCLR/NativeAOT (Mono has separate icall) |
| src/libraries/System.Private.CoreLib/src/System/SpanHelpers.ByteMemOps.cs | Replaced Buffer QCalls with direct memset/memmove calls; added x86/AMD64 alignment optimization |
| src/libraries/System.Private.CoreLib/src/System/Buffer.cs | Removed QCall wrapper methods (MemmoveInternal, ZeroMemoryInternal) |
| src/coreclr/vm/comutilnative.cpp/h | Removed old X86BaseCpuId, Buffer_Clear, Buffer_MemMove, and Interlocked_MemoryBarrierProcessWide QCalls |
| src/coreclr/vm/qcallentrypoints.cpp | Updated QCall entry points to use shared implementations (memset, memmove, X86Base_CpuId) |
| src/coreclr/nativeaot/Runtime/MiscHelpers.cpp | Removed NativeAOT-specific RhCpuIdEx and RhFlushProcessWriteBuffers implementations |
| src/coreclr/nativeaot/Runtime/RuntimeImports.cs | Removed NativeAOT-specific imports for RhCpuIdEx, RhFlushProcessWriteBuffers, memset, and memmove |
| src/coreclr/nativeaot/System.Private.CoreLib/src/System/Buffer.NativeAot.cs | Removed NativeAOT-specific MemmoveInternal and ZeroMemoryInternal wrappers |
| src/coreclr/nativeaot/System.Private.CoreLib/src/System/Threading/Interlocked.cs | Removed NativeAOT-specific MemoryBarrierProcessWide implementation |
| src/coreclr/System.Private.CoreLib/src/System/Buffer.CoreCLR.cs | Removed CoreCLR-specific QCall imports for Buffer_Clear and Buffer_MemMove |
| src/coreclr/System.Private.CoreLib/src/System/Threading/Interlocked.CoreCLR.cs | Removed CoreCLR-specific MemoryBarrierProcessWide (moved to shared file) |
| src/coreclr/System.Private.CoreLib/src/System/Runtime/Intrinsics/X86/X86Base.CoreCLR.cs | Deleted entire file (functionality moved to shared X86Base.cs) |
| src/coreclr/nativeaot/System.Private.CoreLib/src/System/Runtime/Intrinsics/X86/X86Base.NativeAot.cs | Deleted entire file (functionality moved to shared X86Base.cs) |
| src/mono/System.Private.CoreLib/src/System/Runtime/Intrinsics/X86/X86Base.Mono.cs | Deleted entire file (functionality moved to shared X86Base.cs) |
| src/mono/System.Private.CoreLib/src/System/Buffer.Mono.cs | Removed MemmoveInternal and ZeroMemoryInternal icall declarations (moved to SpanHelpers) |
| src/mono/mono/metadata/icall.c | Renamed and updated signatures for ves_icall_System_SpanHelpers_memmove and memset |
| src/mono/mono/metadata/icall-def.h | Updated icall definitions; added SPANHELPERS type; removed Buffer icalls; renamed X86Base.__cpuidex to CpuId |
| src/mono/mono/metadata/icall-decl.h | Updated icall declarations to use SpanHelpers namespace and new signatures |
| src/mono/mono/mini/simd-intrinsics.c | Renamed ves_icall_System_Runtime_Intrinsics_X86_X86Base___cpuidex to CpuId |
| src/coreclr/nativeaot/Runtime/CommonMacros.h | Fixed ZeroMemory macro parameter names; removed INLINE macro and OS_PAGE_SIZE definition |
| src/coreclr/nativeaot/Runtime/allocheap.h | Refactored BlockListElem to remove dependency on Range.h |
| src/coreclr/nativeaot/Runtime/allocheap.cpp | Removed AllocHeap::Contains method and Range usage; fixed type cast in ASSERT |
| src/coreclr/nativeaot/Runtime/ThunksMapping.cpp | Added explicit size_t to int/uint32_t casts; cached THUNKS_MAP_SIZE in local variable |
| src/coreclr/nativeaot/Runtime/Range.h | Deleted entire file (Range and MemRange utility classes no longer needed) |
| src/coreclr/nativeaot/Runtime/unix/PalUnix.cpp | Removed InitializeOsPageSize and PalGetOsPageSize functions |
| src/coreclr/nativeaot/Runtime/unix/PalInline.h | Removed PalOsPageSize inline function |
| src/coreclr/nativeaot/Runtime/windows/PalInline.h | Removed PalOsPageSize inline function |
| src/coreclr/nativeaot/Runtime/Pal.h | Removed PalGetOsPageSize declaration |
| src/coreclr/nativeaot/Runtime/unix/UnixSignals.cpp | Added common.h include at top |
| src/coreclr/nativeaot/Runtime/unix/HardwareExceptions.cpp | Added common.h include at top |
| src/coreclr/nativeaot/Runtime/disabledruntimeeventinternal.cpp | Added common.h include at top |
| src/coreclr/nativeaot/Runtime/disabledeventpipeinternal.cpp | Added common.h include at top |
| src/coreclr/nativeaot/Runtime/CachedInterfaceDispatchPal.h | Removed Range.h include |
| src/coreclr/vm/CMakeLists.txt | Added MiscNativeHelpers.cpp to build |
| src/coreclr/nativeaot/Runtime/CMakeLists.txt | Added MiscNativeHelpers.cpp to build |
| *.csproj files | Removed references to deleted platform-specific partial class files |
Description
Consolidates duplicate implementations from NativeAOT, CoreCLR, and Mono into shared locations, enabling maximum code sharing across all three runtimes. Creates new shared native implementations in
src/coreclr/runtime/MiscNativeHelpers.cpp/hfor QCalls and consolidates managed code in shared System.Private.CoreLib files with minimal conditional compilation.Changes Made
Shared QCall Implementations
X86Base_CpuId - CPUID instruction wrapper
RhCpuIdEx(NativeAOT) andX86BaseCpuId(CoreCLR VM)src/coreclr/runtime/MiscNativeHelpers.cppX86Base.cswith#if MONOconditional compilationX86Base.CoreCLR.cs,X86Base.NativeAot.cs, andX86Base.Mono.cs__cpuidextoCpuIdacross all runtimesInterlocked_MemoryBarrierProcessWide - Process-wide memory barrier
RhFlushProcessWriteBuffers(NativeAOT) and old CoreCLR VM implementationsrc/coreclr/runtime/MiscNativeHelpers.cppBuffer Operations Refactoring
Buffer_ClearandBuffer_MemMoveQCall implementations entirelymemsetandmemmoveinSpanHelpers.ByteMemOps.csSpanHelpers.ByteMemOps.cswith conditional compilation:#if MONO: InternalCall implementations withvoid*pointer types namedmemmoveandmemset#else: LibraryImport QCall implementations for CoreCLR/NativeAOT withvoid*pointer typesBuffer.Mono.csUnsafe.WriteUnalignedwithBlock16for better code generationves_icall_System_SpanHelpers_memmoveandves_icall_System_SpanHelpers_memsetvoid*pointer types matching standard C library conventionsInfrastructure Updates
src/coreclr/runtime/MiscNativeHelpers.h/cppfor shared QCall implementationssrc/coreclr/nativeaot/Runtime/common.hwithQCALLTYPEdefinition for NativeAOTZeroMemorymacro definition in CommonMacros.h to use proper parameter namesINLINEmacro definition that was causing build conflicts(16 - 1)pattern for clarityCode Sharing Achievement
#if MONO/#elseblocks where runtime-specific behavior is requiredvoid*pointer types for memset/memmove, matching C library conventionsCustomer Impact
None. Internal refactoring only - no functional changes or public API modifications.
Regression
No. This is code consolidation and optimization, not a bug fix.
Testing
Risk
Low. Code consolidation with careful attention to maintaining identical behavior:
Original prompt
This pull request was created from Copilot chat.
✨ Let Copilot coding agent set things up for you — coding agent works faster and does higher quality work when set up for your repo.