diff --git a/src/absil/ilread.fs b/src/absil/ilread.fs index bec39d9b800..3d523de4f27 100644 --- a/src/absil/ilread.fs +++ b/src/absil/ilread.fs @@ -10,7 +10,6 @@ module FSharp.Compiler.AbstractIL.ILBinaryReader #nowarn "42" // This construct is deprecated: it is only for use in the F# library open System -open System.Collections.Concurrent open System.Collections.Generic open System.Diagnostics open System.IO @@ -3606,11 +3605,11 @@ let openMetadataReader (fileName, mdfile: BinaryFile, metadataPhysLoc, peinfo, p let inbase = Filename.fileNameOfPath fileName + ": " // All the caches. The sizes are guesstimates for the rough sharing-density of the assembly - let cacheAssemblyRef = mkCacheInt32 false inbase "ILAssemblyRef" (getNumRows TableNames.AssemblyRef) + let cacheAssemblyRef = mkCacheInt32 reduceMemoryUsage inbase "ILAssemblyRef" (getNumRows TableNames.AssemblyRef) let cacheMethodSpecAsMethodData = mkCacheGeneric reduceMemoryUsage inbase "MethodSpecAsMethodData" (getNumRows TableNames.MethodSpec / 20 + 1) let cacheMemberRefAsMemberData = mkCacheGeneric reduceMemoryUsage inbase "MemberRefAsMemberData" (getNumRows TableNames.MemberRef / 20 + 1) let cacheCustomAttr = mkCacheGeneric reduceMemoryUsage inbase "CustomAttr" (getNumRows TableNames.CustomAttribute / 50 + 1) - let cacheTypeRef = mkCacheInt32 false inbase "ILTypeRef" (getNumRows TableNames.TypeRef / 20 + 1) + let cacheTypeRef = mkCacheInt32 reduceMemoryUsage inbase "ILTypeRef" (getNumRows TableNames.TypeRef / 20 + 1) let cacheTypeRefAsType = mkCacheGeneric reduceMemoryUsage inbase "TypeRefAsType" (getNumRows TableNames.TypeRef / 20 + 1) let cacheBlobHeapAsPropertySig = mkCacheGeneric reduceMemoryUsage inbase "BlobHeapAsPropertySig" (getNumRows TableNames.Property / 20 + 1) let cacheBlobHeapAsFieldSig = mkCacheGeneric reduceMemoryUsage inbase "BlobHeapAsFieldSig" (getNumRows TableNames.Field / 20 + 1) @@ -3969,19 +3968,10 @@ type ILModuleReaderImpl(ilModule: ILModuleDef, ilAssemblyRefs: Lazy - (stronglyHeldReaderCacheSize, - keepMax=stronglyHeldReaderCacheSize, // only strong entries - areSimilar=(fun (x, y) -> x = y)) -let ilModuleReaderCache1Lock = Lock() - -// // Cache to reuse readers that have already been created and are not yet GC'd -let ilModuleReaderCache2 = new ConcurrentDictionary>(HashIdentity.Structural) +let ilModuleReaderCache = new AgedLookup(stronglyHeldReaderCacheSize, areSimilar=(fun (x, y) -> x = y)) +let ilModuleReaderCacheLock = Lock() let stableFileHeuristicApplies fileName = not noStableFileHeuristic && try FileSystem.IsStableFileHeuristic fileName with _ -> false @@ -4032,29 +4022,17 @@ let OpenILModuleReader fileName opts = let fakeKey = ILModuleReaderCacheKey(fileName, System.DateTime.UtcNow, ILScopeRef.Local, false, ReduceMemoryFlag.Yes, MetadataOnlyFlag.Yes) fakeKey, false - let cacheResult1 = - // can't used a cached entry when reading PDBs, since it makes the returned object IDisposable - if keyOk && opts.pdbDirPath.IsNone then - ilModuleReaderCache1Lock.AcquireLock (fun ltok -> ilModuleReaderCache1.TryGet(ltok, key)) + let cacheResult = + if keyOk then + if opts.pdbDirPath.IsSome then None // can't used a cached entry when reading PDBs, since it makes the returned object IDisposable + else ilModuleReaderCacheLock.AcquireLock (fun ltok -> ilModuleReaderCache.TryGet(ltok, key)) else None - - match cacheResult1 with + + match cacheResult with | Some ilModuleReader -> ilModuleReader | None -> - let cacheResult2 = - // can't used a cached entry when reading PDBs, since it makes the returned object IDisposable - if keyOk && opts.pdbDirPath.IsNone then - ilModuleReaderCache2.TryGetValue(key) - else - false, Unchecked.defaultof<_> - - let mutable res = Unchecked.defaultof<_> - match cacheResult2 with - | true, weak when weak.TryGetTarget(&res) -> res - | _ -> - let reduceMemoryUsage = (opts.reduceMemoryUsage = ReduceMemoryFlag.Yes) let metadataOnly = (opts.metadataOnly = MetadataOnlyFlag.Yes) @@ -4093,12 +4071,10 @@ let OpenILModuleReader fileName opts = let ilModule, ilAssemblyRefs, _pdb = openPE (fullPath, pefile, None, reduceMemoryUsage, opts.ilGlobals, false) new ILModuleReaderImpl(ilModule, ilAssemblyRefs, ignore) - let ilModuleReader = ilModuleReader :> ILModuleReader if keyOk then - ilModuleReaderCache1Lock.AcquireLock (fun ltok -> ilModuleReaderCache1.Put(ltok, key, ilModuleReader)) - ilModuleReaderCache2.[key] <- System.WeakReference<_>(ilModuleReader) - ilModuleReader - + ilModuleReaderCacheLock.AcquireLock (fun ltok -> ilModuleReaderCache.Put(ltok, key, ilModuleReader)) + + ilModuleReader :> ILModuleReader else // This case is primarily used in fsc.exe. @@ -4122,14 +4098,11 @@ let OpenILModuleReader fileName opts = let ilModule, ilAssemblyRefs, pdb = openPE (fullPath, pefile, opts.pdbDirPath, reduceMemoryUsage, opts.ilGlobals, false) let ilModuleReader = new ILModuleReaderImpl(ilModule, ilAssemblyRefs, (fun () -> ClosePdbReader pdb)) - let ilModuleReader = ilModuleReader :> ILModuleReader - // Readers with PDB reader disposal logic don't go in the cache. Note the PDB reader is only used in static linking. if keyOk && opts.pdbDirPath.IsNone then - ilModuleReaderCache1Lock.AcquireLock (fun ltok -> ilModuleReaderCache1.Put(ltok, key, ilModuleReader)) - ilModuleReaderCache2.[key] <- WeakReference<_>(ilModuleReader) + ilModuleReaderCacheLock.AcquireLock (fun ltok -> ilModuleReaderCache.Put(ltok, key, ilModuleReader)) - ilModuleReader + ilModuleReader :> ILModuleReader [] module Shim =