Description
Classes that don't pass their arrays out by reference; and only directly instantiate them (new T[n]
) (rather than setting the array field to something passed by argument or result of external call, could have their element stores changed from covariant stores to invariant stores.
From https://github.com/dotnet/corefx/issues/23689#issuecomment-378283974
@Suchiman I like your idea of enabling this optimization without requiring code changes everywhere! We can start with implementing it in ILLinker to measure the benefit and prove its usefulness, and maybe later in Roslyn. We have taken the same journey for SkipLocalsInit. The implementation in ILLinker can:
- Do escape analysis to identify all arrays that are just used as internal implementation detail (that do not escape outside the assembly - assuming there is no private reflection) and that do not use array covariance
- Use alternative more efficient sequence for storing elements into them.
For example the store in coreclr List<T>.Add(T)
public partial class List<T>
{
private T[] _items;
public void Add(T item)
{
_version++;
T[] array = _items;
int size = _size;
if ((uint)size < (uint)array.Length)
{
_size = size + 1;
array[size] = item; // array element store
}
else
{
AddWithResize(item);
}
}
}
Could have the il changed from something like
ldloc.0
ldloc.1
ldarg.1
stelem !T // Covariant store
To something like
ldloc.0
ldloc.1
readonly.
ldelema !T
ldarg.1
stobj !T // Invariant store