-
Notifications
You must be signed in to change notification settings - Fork 2.6k
Allow ArrayPool.Shared devirtualization (redux) #20637
Conversation
@@ -19,6 +19,10 @@ namespace System.Buffers | |||
/// </remarks> | |||
public abstract class ArrayPool<T> | |||
{ | |||
// Store the shared ArrayPool in a field of its derived sealed type so the Jit can "see" the exact type | |||
// when the Shared property is inlined which will allow it to devirtualize calls made on it. | |||
private static TlsOverPerCoreLockedStacksArrayPool<T> s_shared = new TlsOverPerCoreLockedStacksArrayPool<T>(); |
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.
This should be also readonly. (The JIT does not take advantage of readonly for object references right now, but it can in future.)
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.
Note we will need jit changes (not yet PR'd, but coming very soon) to light this up.
@@ -33,7 +37,7 @@ public abstract class ArrayPool<T> | |||
/// optimized for very fast access speeds, at the expense of more memory consumption. | |||
/// The shared pool instance is created lazily on first access. | |||
/// </remarks> | |||
public static ArrayPool<T> Shared { get; } = new TlsOverPerCoreLockedStacksArrayPool<T>(); | |||
public static ArrayPool<T> Shared { get; } = s_shared; |
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.
Does this need to be just public static ArrayPool<T> Shared => s_shared;
?
I expect that Shared { get; } =
will create a hidden backing field of the wrong type.
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.
Ha! Definately
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.
Yes...
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.
Thanks
@@ -19,6 +19,10 @@ namespace System.Buffers | |||
/// </remarks> | |||
public abstract class ArrayPool<T> | |||
{ | |||
// Store the shared ArrayPool in a field of its derived sealed type so the Jit can "see" the exact type | |||
// when the Shared property is inlined which will allow it to devirtualize calls made on it. | |||
private readonly static TlsOverPerCoreLockedStacksArrayPool<T> s_shared = new TlsOverPerCoreLockedStacksArrayPool<T>(); |
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.
In the case of a reference type (or more generally where no boxing or conversion is needed), it seems like the C# compiler could be improved here slightly to work better with devirtualization to make the automatic backing field be of the type of the expression on the RHS rather than the type of the property, e.g.
public class C
{
public static A Shared { get; } = new B();
}
public abstract class A { }
public sealed class B : A { }
produces
private static readonly A <Shared>k__BackingField = new B();
public static A Shared => <Shared>k__BackingField;
but it could instead do:
private static readonly B <Shared>k__BackingField = new B();
public static A Shared => <Shared>k__BackingField;
cc: @jaredpar
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.
I think that could only be done when there was an identity preserving conversion. This couldn't be done for instance when the conversion from B to A was boxing, user defined, etc ... Otherwise that change would be quite observable.
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.
Yes. (I tried to note that in my description but maybe I used the wrong words :))
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.
It's Friday, my brain is mush. I didn't read your description carefully enough 😦
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.
Capturing link back from proposal dotnet/roslyn#30797
This change, on top of #20533, is enough to enable devirtualization. The jit change I have in the works isn't needed. However it improves code size so I'll go ahead and PR that too. PMI diffs show a modest number of hits ...
|
Ubuntu failure is the recently-common xunit assembly load issue (#20392)
Has anyone tried tracking this down? |
Signed-off-by: dotnet-bot <dotnet-bot@microsoft.com>
Signed-off-by: dotnet-bot <dotnet-bot@microsoft.com>
Signed-off-by: dotnet-bot <dotnet-bot@microsoft.com>
Signed-off-by: dotnet-bot <dotnet-bot@microsoft.com>
Follow up to #20503