-
Notifications
You must be signed in to change notification settings - Fork 5k
Remove all explicit GC Poll calls in unmanaged code. #113715
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Remove all explicit GC Poll calls in unmanaged code. #113715
Conversation
@EgorBot -windows_x64 -arm64 using System;
using System.Runtime.CompilerServices;
using BenchmarkDotNet.Attributes;
public unsafe class Bench
{
private F _f;
private byte[] _source;
private byte[] _dest;
private delegate* <ref byte, ref byte, nuint, void> _method;
class F
{
~F() { }
}
public Bench()
{
_f = new F();
_source = new byte[10 * 1024];
_dest = new byte[_source.Length];
Random random = new Random();
random.NextBytes(array);
var method = typeof(Buffer).GetMethod("BulkMoveWithWriteBarrier", BindingFlags.NonPublic | BindingFlags.Static);
_method = (delegate* <ref byte, ref byte, nuint, void>)method.MethodHandle.GetFunctionPointer();
}
[Benchmark]
public void BenchmarkBulkMoveWithWriteBarrier()
{
_method(ref _dest[0], ref _source[0], (nuint)dest.Length);
}
[Benchmark]
public void BenchmarkSuppressFinalize()
{
GC.SuppressFinalize(_f);
}
} |
src/coreclr/System.Private.CoreLib/src/System/Buffer.CoreCLR.cs
Outdated
Show resolved
Hide resolved
@EgorBot -intel -arm using System;
using System.Reflection;
using System.Runtime.CompilerServices;
using BenchmarkDotNet.Attributes;
public unsafe class Bench
{
private F _f;
private byte[] _source;
private byte[] _dest;
private delegate* <ref byte, ref byte, nuint, void> _method;
class F
{
~F() { }
}
public Bench()
{
_f = new F();
_source = new byte[10 * 1024];
_dest = new byte[_source.Length];
Random random = new Random();
random.NextBytes(_source);
var method = typeof(Buffer).GetMethod("BulkMoveWithWriteBarrier", BindingFlags.NonPublic | BindingFlags.Static)!;
_method = (delegate* <ref byte, ref byte, nuint, void>)method.MethodHandle.GetFunctionPointer();
}
[Benchmark]
public void BenchmarkBulkMoveWithWriteBarrier()
{
_method(ref _dest[0], ref _source[0], (nuint)_dest.Length);
}
[Benchmark]
public void BenchmarkSuppressFinalize()
{
GC.SuppressFinalize(_f);
}
} |
src/coreclr/System.Private.CoreLib/src/System/Buffer.CoreCLR.cs
Outdated
Show resolved
Hide resolved
@EgorBot -intel -arm using System;
using System.Reflection;
using System.Runtime.CompilerServices;
using BenchmarkDotNet.Attributes;
public unsafe class Bench
{
private object[] _source;
private object[] _dest;
public Bench()
{
_source = new object[10];
_dest = new object[_source.Length];
}
[Benchmark]
public void BenchmarkBulkMoveWithWriteBarrier()
{
_source.AsSpan().CopyTo(_dest.AsSpan());
}
} |
The kind of benchmark to run for |
...coreclr/System.Private.CoreLib/src/System/Runtime/CompilerServices/RuntimeHelpers.CoreCLR.cs
Outdated
Show resolved
Hide resolved
src/coreclr/System.Private.CoreLib/src/System/Buffer.CoreCLR.cs
Outdated
Show resolved
Hide resolved
/cc @dotnet/jit-contrib |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pull Request Overview
This pull request removes unnecessary explicit GC Poll calls in unmanaged code and moves this logic to managed code while also converting certain FCall methods to managed implementations.
- In GC.CoreCLR.cs, the SuppressFinalize method is modified to only call _SuppressFinalize if the object has a finalizer.
- In Thread.CoreCLR.cs, the unmanaged ThreadNative_PollGC call is replaced by a managed PollGCInternal wrapped by an inline PollGCWorker function.
- In Buffer.CoreCLR.cs, an additional using directive for System.Threading is added.
Reviewed Changes
Copilot reviewed 5 out of 22 changed files in this pull request and generated 1 comment.
File | Description |
---|---|
src/coreclr/System.Private.CoreLib/src/System/GC.CoreCLR.cs | Updates SuppressFinalize with a finalizer check to avoid unnecessary calls. |
src/coreclr/System.Private.CoreLib/src/System/Threading/Thread.CoreCLR.cs | Renames and wraps the GC poll call to move its implementation to managed code. |
src/coreclr/System.Private.CoreLib/src/System/Buffer.CoreCLR.cs | Adds a using directive for System.Threading to support related changes. |
Files not reviewed (17)
- src/coreclr/classlibnative/bcltype/objectnative.cpp: Language not supported
- src/coreclr/jit/compiler.h: Language not supported
- src/coreclr/jit/compiler.hpp: Language not supported
- src/coreclr/jit/flowgraph.cpp: Language not supported
- src/coreclr/jit/gentree.cpp: Language not supported
- src/coreclr/jit/gtlist.h: Language not supported
- src/coreclr/jit/ifconversion.cpp: Language not supported
- src/coreclr/jit/importercalls.cpp: Language not supported
- src/coreclr/jit/liveness.cpp: Language not supported
- src/coreclr/jit/namedintrinsiclist.h: Language not supported
- src/coreclr/jit/optcse.cpp: Language not supported
- src/coreclr/jit/rationalize.cpp: Language not supported
- src/coreclr/jit/valuenum.cpp: Language not supported
- src/coreclr/vm/comutilnative.cpp: Language not supported
- src/coreclr/vm/comutilnative.h: Language not supported
- src/coreclr/vm/fcall.cpp: Language not supported
- src/coreclr/vm/fcall.h: Language not supported
Comments suppressed due to low confidence (1)
src/coreclr/System.Private.CoreLib/src/System/Threading/Thread.CoreCLR.cs:509
- [nitpick] The local function 'PollGCWorker' could be renamed to better reflect that it is a simple wrapper for PollGCInternal; consider a more descriptive name if it improves clarity.
static void PollGCWorker() => PollGCInternal();
7e7c605
to
80e8250
Compare
The fix LGTM assuming that the CI passes. |
@am11 Thanks. I've applied it and that does indeed "fix" the issue. |
Reported upstream for a proper fix DotNetAnalyzers/StyleCopAnalyzers#3922 :) |
Remove explicit GC Poll from
GC.SuppressFinalize()
.Remove GC Poll from FCall and move it to managed,
Buffer.__BulkMoveWithWriteBarrier()
.Remove unneccessary explicit
FC_GC_POLL()
calls.Remove unneccessary explicit
FC_GC_POLL_RET()
calls.Remove unmanaged
GCPoll
implementation.Implement JIT intrinsic for GC Poll,
Thread.FastGCPoll
.Fixes #113807