| File: Internal\Runtime\TypeLoader\TypeSystemContextFactory.cs | Web Access |
| Project: src\runtime\src\coreclr\nativeaot\System.Private.TypeLoader\src\System.Private.TypeLoader.csproj (System.Private.TypeLoader) |
// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. using System; using System.Collections.Generic; using System.Runtime.InteropServices; using System.Text; using System.Threading; using Internal.TypeSystem; namespace Internal.Runtime.TypeLoader { public static class TypeSystemContextFactory { // Cache the most recent instance of TypeSystemContext in a weak handle, and reuse it if possible // This allows us to avoid recreating the type resolution context again and again, but still allows it to go away once the types are no longer being built private static WeakGCHandle<TypeSystemContext?> s_cachedContext = new WeakGCHandle<TypeSystemContext?>(null); private static readonly Lock s_lock = new Lock(useTrivialWaits: true); public static TypeSystemContext Create() { using (s_lock.EnterScope()) { if (s_cachedContext.TryGetTarget(out TypeSystemContext? context)) { s_cachedContext.SetTarget(null); return context; } } return new TypeLoaderTypeSystemContext(new TargetDetails( #if TARGET_ARM TargetArchitecture.ARM, #elif TARGET_ARM64 TargetArchitecture.ARM64, #elif TARGET_X86 TargetArchitecture.X86, #elif TARGET_AMD64 TargetArchitecture.X64, #elif TARGET_WASM TargetArchitecture.Wasm32, #elif TARGET_LOONGARCH64 TargetArchitecture.LoongArch64, #elif TARGET_RISCV64 TargetArchitecture.RiscV64, #else #error Unknown architecture #endif TargetOS.Windows, TargetAbi.Unknown)); } public static void Recycle(TypeSystemContext context) { // Only cache a reasonably small context that is still in Gen0 if (context.LoadFactor > 200 || GC.GetGeneration(context) > 0) return; // Flush the type system context from all types being recycled context.FlushTypeBuilderStates(); // No lock needed here - the reference assignment is atomic s_cachedContext.SetTarget(context); } } }