-
Notifications
You must be signed in to change notification settings - Fork 4.8k
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
Optimize out write barriers for fields in ref-like structs #9512
Comments
And does a byref to a ref-like type serve any useful purpose? It seems that it could be converted to an unmanaged pointer because it doesn't need to be reported to the GC. Though it looks like attempting to write an object reference to an unmanaged pointer makes the JIT emit a checked write barrier rather than no barrier, hmm... |
An example containing 2 cases where the GC write barrier could be eliminated if the write location is known to be on the stack: ref struct RefLike
{
public object o;
[MethodImpl(MethodImplOptions.NoInlining)]
public void NotInlined(object o)
{
this.o = o; // GC WB, the JIT currently assumes that `this` can be on the GC heap
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public void Inlined(object o)
{
this.o = o; // No GC WB if the method is inlined and `this` is on the stack.
}
}
public static void Main()
{
RefLike r = new RefLike();
Test(new object(), ref r);
}
[MethodImpl(MethodImplOptions.NoInlining)]
static void Test(object o, ref RefLike ar)
{
RefLike lr = new RefLike();
lr.o = o; // No GC WB
lr.Inlined(o); // No GC WB
lr.NotInlined(o); // GC WB inside NotInlined
ar.o = o; // GC WB, the JIT currently assumes that `ar` can point into the GC heap
} |
I tried a quick and dirty implementation to see what happens. I wasn't expecting to see anything in the jit-diffs but it turns out that there's already a case like this in corelib. A bunch of GC write barriers disappeared from |
Another example - a non ref struct inside a ref struct:
|
|
Thanks for the example, copying structs like |
Yep, copying structs require a bit more hacking. Currently copying a struct like 488D7118 lea rsi, bword ptr [rcx+24]
488D7908 lea rdi, bword ptr [rcx+8]
E8A1316B5F call CORINFO_HELP_ASSIGN_BYREF
48A5 movsq I can change it to 488D7118 lea rsi, bword ptr [rcx+24]
488D7908 lea rdi, bword ptr [rcx+8]
48A5 movsq
48A5 movsq I'm not sure if the use of 2 |
Example dotnet/aspnetcore#7674 resolved via inlining |
Even uses private ref struct ValueSegmentList
{
public BufferSegment Segment00;
public BufferSegment Segment01;
public BufferSegment Segment02;
public BufferSegment Segment03;
public BufferSegment Segment04;
public BufferSegment Segment05;
public BufferSegment Segment06;
public BufferSegment Segment07;
public BufferSegment Segment08;
public BufferSegment Segment09;
public BufferSegment Segment10;
public BufferSegment Segment11;
public BufferSegment Segment12;
public BufferSegment Segment13;
public BufferSegment Segment14;
public BufferSegment Segment15;
} with ValueSegmentList segmentsToReturn = default;
ref var startSegment = ref segmentsToReturn.Segment00;
int count = 0;
do
{
BufferSegment next = from.NextSegment;
Debug.Assert(next != null || toExclusive == null);
from.ResetMemory();
if ((uint)count < (uint)SegmentPoolSize)
{
// Store in temporary list while preforming expensive resets
Unsafe.Add(ref startSegment, count) = from;
count++;
}
from = next;
} while (from != toExclusive); G_M48697_IG02:
lea rcx, bword ptr [rbp-B8H]
vxorps xmm0, xmm0
vmovdqu qword ptr [rcx], xmm0
vmovdqu qword ptr [rcx+16], xmm0
vmovdqu qword ptr [rcx+32], xmm0
vmovdqu qword ptr [rcx+48], xmm0
vmovdqu qword ptr [rcx+64], xmm0
vmovdqu qword ptr [rcx+80], xmm0
vmovdqu qword ptr [rcx+96], xmm0
vmovdqu qword ptr [rcx+112], xmm0
lea r14, bword ptr [rbp-B8H]
xor r15d, r15d
G_M48697_IG03:
mov r12, gword ptr [rsi+40]
mov rcx, rsi
call BufferSegment:ResetMemory():this
cmp r15d, 16
jae SHORT G_M48697_IG04
movsxd rdx, r15d
lea rcx, bword ptr [r14+8*rdx]
mov rdx, rsi
call CORINFO_HELP_CHECKED_ASSIGN_REF ; checked assign
inc r15d
G_M48697_IG04:
mov rsi, r12
cmp rsi, rdi
jne SHORT G_M48697_IG03 |
From dotnet/coreclr#15745 (comment) :
cc @mikedn
category:cq
theme:barriers
skill-level:expert
cost:small
The text was updated successfully, but these errors were encountered: