Repository navigation
fix(postconditions): Let collectible types that went through Old or EnsureAssignable be collected - #75
Merged
Conversation
…nsureAssignable be collected SharedTypes, MemberComparison and DeepCopier cached every type in a static ConcurrentDictionary, which kept a collectible type and its assembly alive. A collectible type (Type.IsCollectible, which accounts for generic arguments and array element types) is now cached in a ConditionalWeakTable; other types keep the ConcurrentDictionary. Refs #48
SharedTypes, MemberComparison and DeepCopier each chose between a ConcurrentDictionary and a ConditionalWeakTable by Type.IsCollectible. TypeCache<TValue> holds both tiers once. Refs #48
…le type TypeCache.GetOrAdd captured its factory in a lambda for the ConditionalWeakTable, so every call allocated a closure, also for a non-collectible type. The collectible branch now has a method of its own. Refs #48
…after what it holds
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Closes #48.
Summary
Three static per-type caches held their
Typekeys strongly: the shared-type classification (SharedTypes), the holds-references cache of the deep copy behindOld<T>()(DeepCopier), and the metadata cache ofEnsureAssignable<T>()(MemberComparison). A collectible type that went throughOld<T>()orEnsureAssignable<T>()(a plugin in a collectibleAssemblyLoadContext, aRunAndCollectdynamic assembly) could therefore never be collected. Its load context could never unload either.Changes
TypeCache<TValue>, which has two tiers:ConcurrentDictionaryfor a type whoseType.IsCollectibleis false;ConditionalWeakTable<Type, StrongBox<TValue>>for a collectible type, so the cache does not keep it alive.IsCollectibleis also true for a constructed type that is collectible only through a generic argument or an array element type, such as aList<PluginType>. That type'sAssemblyisSystem.Private.CoreLib, so the tier is not chosen withAssembly.IsCollectible.IsCollectibleis read only on a miss.EnsureAssignablenow names both tiers. ADR-0024 records the decision, the options and the measurements, anddocs/adr/README.mdlists it.CHANGELOG.md[Unreleased]has an entry under Fixed.Not changed: comparison results, copies, exceptions and messages;
PublicAPI.*.txt; trimming annotations.Testing
dotnet test): 1239 of 1239 at the last commit.CollectibleTypeCacheTests: one collection test per cache, each failing before the fix because the type stayed alive. It also covers aList<T>and an array of a collectible type, and checks that the results for collectible and non-collectible types are the same.TypeCacheTests: a hit for a non-collectible type allocates 0 bytes. This test failed at 24 bytes before its fix.refactorcommits.-warnaserror(win-x64). All 107 checks pass with postconditions on. TheDBC_POST=offvariant was left to CI.Left open
IsCollectible. Only the microbenchmark shows them.ConditionalWeakTable.AssemblyLoadContextis not tested. The tests useRunAndCollectassemblies.Related Issues
Closes #48