Skip to content
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

Enable RuntimeType.GenericCache to hold multiple types of cache entries #102034

Merged
merged 17 commits into from
May 31, 2024
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -662,17 +662,14 @@ internal sealed unsafe partial class ArrayInitializeCache : RuntimeType.IGeneric
[LibraryImport(RuntimeHelpers.QCall, EntryPoint = "Array_GetElementConstructorEntrypoint")]
private static partial delegate*<ref byte, void> GetElementConstructorEntrypoint(QCallTypeHandle arrayType);

static RuntimeType.IGenericCacheEntry.GenericCacheKind RuntimeType.IGenericCacheEntry<ArrayInitializeCache>.Kind => RuntimeType.IGenericCacheEntry.GenericCacheKind.ArrayInitialize;

private ArrayInitializeCache(delegate*<ref byte, void> constructorEntrypoint)
{
ConstructorEntrypoint = constructorEntrypoint;
}

public static ArrayInitializeCache Create(RuntimeType arrayType)
{
return new(GetElementConstructorEntrypoint(new QCallTypeHandle(ref arrayType)));
}
public static ArrayInitializeCache Create(RuntimeType arrayType) => new(GetElementConstructorEntrypoint(new QCallTypeHandle(ref arrayType)));
public void InitializeCompositeCache(RuntimeType.CompositeCacheEntry compositeEntry) => compositeEntry._arrayInitializeCache = this;
public static ref ArrayInitializeCache? GetStorageRef(RuntimeType.CompositeCacheEntry compositeEntry) => ref compositeEntry._arrayInitializeCache;
}
}

Expand Down
12 changes: 7 additions & 5 deletions src/coreclr/System.Private.CoreLib/src/System/Enum.CoreCLR.cs
Original file line number Diff line number Diff line change
Expand Up @@ -98,16 +98,13 @@ static EnumInfo<TStorage> InitializeEnumInfo(RuntimeType enumType, bool getNames
// force that copy into the cache even if we already have a cache entry without names
// so we don't have to recompute the names if asked again.
return getNames
? enumType.OverwriteCacheEntry(EnumInfo<TStorage>.CreateWithNames(enumType))
? enumType.ReplaceCacheEntry(EnumInfo<TStorage>.CreateWithNames(enumType))
jkoritzinsky marked this conversation as resolved.
Show resolved Hide resolved
: enumType.GetOrCreateCacheEntry<EnumInfo<TStorage>>();
}
}

internal sealed partial class EnumInfo<TStorage> : RuntimeType.IGenericCacheEntry<EnumInfo<TStorage>>
{
static RuntimeType.IGenericCacheEntry.GenericCacheKind RuntimeType.IGenericCacheEntry<EnumInfo<TStorage>>.Kind => RuntimeType.IGenericCacheEntry.GenericCacheKind.EnumInfo;

[MethodImpl(MethodImplOptions.NoInlining)]
public static EnumInfo<TStorage> CreateWithNames(RuntimeType type)
jkoritzinsky marked this conversation as resolved.
Show resolved Hide resolved
{
TStorage[]? values = null;
Expand All @@ -126,7 +123,6 @@ public static EnumInfo<TStorage> CreateWithNames(RuntimeType type)
return new EnumInfo<TStorage>(hasFlagsAttribute, values, names!);
}

[MethodImpl(MethodImplOptions.NoInlining)]
public static EnumInfo<TStorage> Create(RuntimeType type)
jkoritzinsky marked this conversation as resolved.
Show resolved Hide resolved
{
jkoritzinsky marked this conversation as resolved.
Show resolved Hide resolved
TStorage[]? values = null;
Expand All @@ -144,6 +140,12 @@ public static EnumInfo<TStorage> Create(RuntimeType type)

return new EnumInfo<TStorage>(hasFlagsAttribute, values, null!);
}

public void InitializeCompositeCache(RuntimeType.CompositeCacheEntry compositeEntry) => compositeEntry._enumInfo = this;

// This type is the only type that will be stored in the _enumInfo field, so we can use Unsafe.As here.
public static ref EnumInfo<TStorage>? GetStorageRef(RuntimeType.CompositeCacheEntry compositeEntry)
=> ref Unsafe.As<RuntimeType.IGenericCacheEntry?, EnumInfo<TStorage>?>(ref compositeEntry._enumInfo);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ internal sealed partial class RuntimeType
/// A cache which allows optimizing <see cref="Activator.CreateInstance"/>,
/// <see cref="CreateInstanceDefaultCtor"/>, and related APIs.
/// </summary>
private sealed unsafe class ActivatorCache : IGenericCacheEntry<ActivatorCache>
internal sealed unsafe class ActivatorCache : IGenericCacheEntry<ActivatorCache>
{
// The managed calli to the newobj allocator, plus its first argument (MethodTable*).
// In the case of the COM allocator, first arg is ComClassFactory*, not MethodTable*.
Expand All @@ -28,9 +28,9 @@ private sealed unsafe class ActivatorCache : IGenericCacheEntry<ActivatorCache>
private readonly RuntimeType _originalRuntimeType;
#endif

static IGenericCacheEntry.GenericCacheKind IGenericCacheEntry<ActivatorCache>.Kind => IGenericCacheEntry.GenericCacheKind.Activator;

public static ActivatorCache Create(RuntimeType type) => new ActivatorCache(type);
public static ActivatorCache Create(RuntimeType type) => new(type);
public void InitializeCompositeCache(RuntimeType.CompositeCacheEntry compositeEntry) => compositeEntry._activatorCache = this;
public static ref ActivatorCache? GetStorageRef(RuntimeType.CompositeCacheEntry compositeEntry) => ref compositeEntry._activatorCache;

private ActivatorCache(RuntimeType rt)
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1500,10 +1500,8 @@ private MemberInfoCache<T> GetMemberCache<T>(ref MemberInfoCache<T>? m_cache)

internal ref IGenericCacheEntry? GenericCache => ref m_genericCache;

private sealed class FunctionPointerCache : IGenericCacheEntry<FunctionPointerCache>
internal sealed class FunctionPointerCache : IGenericCacheEntry<FunctionPointerCache>
{
static IGenericCacheEntry.GenericCacheKind IGenericCacheEntry<FunctionPointerCache>.Kind => IGenericCacheEntry.GenericCacheKind.FunctionPointer;

public Type[] FunctionPointerReturnAndParameterTypes { get; }

private FunctionPointerCache(Type[] functionPointerReturnAndParameterTypes)
Expand All @@ -1516,6 +1514,8 @@ public static FunctionPointerCache Create(RuntimeType type)
Debug.Assert(type.IsFunctionPointer);
return new(RuntimeTypeHandle.GetArgumentTypesFromFunctionPointer(type));
}
public void InitializeCompositeCache(RuntimeType.CompositeCacheEntry compositeEntry) => compositeEntry._functionPointerCache = this;
public static ref FunctionPointerCache? GetStorageRef(RuntimeType.CompositeCacheEntry compositeEntry) => ref compositeEntry._functionPointerCache;
}

internal Type[] FunctionPointerReturnAndParameterTypes
Expand Down Expand Up @@ -1940,10 +1940,10 @@ internal T GetOrCreateCacheEntry<T>()
return IGenericCacheEntry<T>.Find(this);
}

internal T OverwriteCacheEntry<T>(T entry)
internal T ReplaceCacheEntry<T>(T entry)
where T : class, IGenericCacheEntry<T>
{
IGenericCacheEntry<T>.Overwrite(this, entry);
IGenericCacheEntry<T>.Replace(this, entry);
return entry;
}

Expand Down Expand Up @@ -2060,7 +2060,7 @@ private static void SplitName(string? fullname, out string? name, out string? ns
name = fullname;
}
}
#endregion
#endregion
jkoritzinsky marked this conversation as resolved.
Show resolved Hide resolved

#region Filters
internal static BindingFlags FilterPreCalculate(bool isPublic, bool isInherited, bool isStatic)
Expand Down Expand Up @@ -2387,7 +2387,7 @@ private static bool FilterApplyMethodBase(

#endregion

#endregion
#endregion

#region Private Data Members

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,11 @@ internal sealed partial class RuntimeType
/// <summary>
/// A cache which allows optimizing <see cref="RuntimeHelpers.GetUninitializedObject(Type)"/>.
/// </summary>
private sealed unsafe partial class CreateUninitializedCache : IGenericCacheEntry<CreateUninitializedCache>
internal sealed unsafe partial class CreateUninitializedCache : IGenericCacheEntry<CreateUninitializedCache>
{
static IGenericCacheEntry.GenericCacheKind IGenericCacheEntry<CreateUninitializedCache>.Kind => IGenericCacheEntry.GenericCacheKind.CreateUninitialized;
public static CreateUninitializedCache Create(RuntimeType type) => new CreateUninitializedCache(type);
public static CreateUninitializedCache Create(RuntimeType type) => new(type);
public void InitializeCompositeCache(RuntimeType.CompositeCacheEntry compositeEntry) => compositeEntry._createUninitializedCache = this;
public static ref CreateUninitializedCache? GetStorageRef(RuntimeType.CompositeCacheEntry compositeEntry) => ref compositeEntry._createUninitializedCache;

// The managed calli to the newobj allocator, plus its first argument (MethodTable*).
private readonly delegate*<void*, object> _pfnAllocator;
Expand Down
Loading
Loading