Add GC.AllocateUninitializedArray<T> polyfill#541
Add GC.AllocateUninitializedArray<T> polyfill#541SimonCropp merged 3 commits intoSimonCropp:mainfrom
Conversation
Add source-compatible polyfill for GC.AllocateUninitializedArray<T>(int, bool) which was introduced in .NET 5.0. On older runtimes the implementation delegates to new T[length] (zero-initialized) for source compliance. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
|
I think silently ignoring it is pretty dangerous. The whole reason people pass pinned: true is to stash a pointer into the buffer and hand it off to native code for later (async I/O, native callbacks, long-running workers). On net5+ that's fine because POH arrays never move. With this polyfill the GC is free to relocate the array on the next compaction and the stored pointer is now aimed at whatever happens to live at that address — heap corruption that usually crashes far away from the actual bug, sometimes hours later. Not fun to debug. Pure managed code and single-call P/Invoke are fine, but those aren't why anyone passes pinned: true in the first place. I think drop the two-arg overload and just polyfill AllocateUninitializedArray(int length) |
|
Because I use it to allocate already pinned but always pin anyway, I never thought some could rely on that. Maybe we should keep the parameter and throw on |
|
@paulomorgado yep, happy with that |
…led with pinned=true On older runtimes, pinned allocations cannot be performed, so the polyfill now throws NotSupportedException instead of silently ignoring the parameter. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
c7383ac to
ddf9469
Compare
Summary
Add source-compatible polyfill for GC.AllocateUninitializedArray(int, bool) which was introduced in .NET 5.0.
On older runtimes the implementation delegates to
ew T[length] (zero-initialized) for source compliance — code that calls this API compiles and runs correctly on all targets, though without the performance benefit of skipping zero-initialization.
Guard
#if !NET5_0_OR_GREATER — the native API exists from .NET 5.0 onward.
Changes