Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
35 commits
Select commit Hold shift + click to select a range
5233567
add cache
majocha Apr 24, 2025
df70074
enable typeSubsumptionCache in IDE
majocha Apr 24, 2025
460f592
add some monitoring
majocha Apr 24, 2025
e94a9e5
Merge branch 'main' into compiler-cache
majocha Apr 24, 2025
b2a130a
yeet LFU
majocha Apr 24, 2025
4c7e044
flesh out the comparer
majocha Apr 24, 2025
a269b6a
fix sources
majocha Apr 24, 2025
874d9c1
try to deal with CI memory overload
majocha Apr 24, 2025
c266706
Merge branch 'main' into compiler-cache
majocha Apr 24, 2025
4bca2df
replace singleton with CWT again
majocha Apr 25, 2025
9ba405d
remove sketchy logic
majocha Apr 25, 2025
5c6a500
cache of caches
majocha Apr 25, 2025
605c967
Merge branch 'main' into compiler-cache
majocha Apr 25, 2025
3046f88
ilver
majocha Apr 25, 2025
80dc554
events -> counters
majocha Apr 25, 2025
6926f97
precompute hash
majocha Apr 25, 2025
ec8fab4
no metrics in ci
majocha Apr 26, 2025
59cb94e
simplify
majocha Apr 26, 2025
b8ba293
simplify
majocha Apr 26, 2025
13cded8
clean up
majocha Apr 26, 2025
365ae5b
cut unnecessary stuff
majocha Apr 26, 2025
96fa966
add name
majocha Apr 27, 2025
2743a4d
naming
majocha Apr 27, 2025
8b2b986
basic tests
majocha Apr 28, 2025
8e4f662
Merge branch 'main' into compiler-cache
majocha Apr 28, 2025
bf17afa
rn
majocha Apr 28, 2025
d49e276
fix tests
majocha Apr 28, 2025
f7f766e
Merge branch 'main' into compiler-cache
majocha Apr 28, 2025
aa76a84
ilver
majocha Apr 28, 2025
a182b36
use MailboxProcessor for lock-free eviction handling
majocha Apr 29, 2025
d6b3ac9
ilverify
majocha Apr 29, 2025
523fea3
return
majocha Apr 29, 2025
9c70966
restore cts
majocha Apr 29, 2025
4ae54c0
Merge branch 'main' into compiler-cache
majocha Apr 30, 2025
95b8115
Merge branch 'main' into compiler-cache
majocha Apr 30, 2025
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
7 changes: 5 additions & 2 deletions src/Compiler/Checking/import.fs
Original file line number Diff line number Diff line change
Expand Up @@ -108,7 +108,9 @@ let createTypeSubsumptionCache (g: TcGlobals) =
MaximumCapacity = 4 * 32768 }
Cache.Create<TTypeCacheKey, bool>(options)

let typeSubsumptionCaches = ConditionalWeakTable<TcGlobals, Cache<TTypeCacheKey, bool>>()
let typeSubsumptionCaches = Cache.Create<TcGlobals, Cache<TTypeCacheKey, bool>>({ CacheOptions.Default with MaximumCapacity = 16 })

do typeSubsumptionCaches.ValueEvicted.Add <| _.Dispose()

//-------------------------------------------------------------------------
// Import an IL types as F# types.
Expand All @@ -132,7 +134,8 @@ type ImportMap(g: TcGlobals, assemblyLoader: AssemblyLoader) =

member _.ILTypeRefToTyconRefCache = typeRefToTyconRefCache

member val TypeSubsumptionCache: Cache<TTypeCacheKey, bool> = typeSubsumptionCaches.GetValue(g, createTypeSubsumptionCache)
member val TypeSubsumptionCache: Cache<TTypeCacheKey, bool> =
typeSubsumptionCaches.GetOrCreate(g, createTypeSubsumptionCache)

let CanImportILScopeRef (env: ImportMap) m scoref =

Expand Down
28 changes: 20 additions & 8 deletions src/Compiler/Utilities/Caches.fs
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,12 @@ open System
open System.Collections.Generic
open System.Collections.Concurrent
open System.Threading
open System.Threading.Tasks
open System.Diagnostics
open System.Diagnostics.Metrics

open FSharp.Compiler.Diagnostics

[<Struct; RequireQualifiedAccess; NoComparison>]
type EvictionMethod =
| Background
Expand Down Expand Up @@ -154,7 +157,7 @@ type Cache<'Key, 'Value when 'Key: not null and 'Key: equality> internal (option

let cacheHit = Event<unit>()
let cacheMiss = Event<unit>()
let eviction = Event<unit>()
let eviction = Event<'Value>()
let evictionFail = Event<unit>()
let overCapacity = Event<unit>()

Expand All @@ -181,7 +184,7 @@ type Cache<'Key, 'Value when 'Key: not null and 'Key: equality> internal (option
| true, removed ->
evictionQueue.Remove(removed)
pool.Reclaim(removed)
eviction.Trigger()
eviction.Trigger(removed.Value)
| _ ->
failwith "eviction fail"
evictionFail.Trigger()
Expand Down Expand Up @@ -230,6 +233,17 @@ type Cache<'Key, 'Value when 'Key: not null and 'Key: equality> internal (option
pool.Reclaim(cachedEntity)
false

member this.GetOrCreate(key: 'Key, valueFactory: 'Key -> 'Value) =
match this.TryGetValue(key) with
| true, value -> value
| _ ->
let value = valueFactory key
this.TryAdd(key, value) |> ignore
value

[<CLIEvent>]
member val ValueEvicted = eviction.Publish

interface ICacheEvents with

[<CLIEvent>]
Expand All @@ -239,7 +253,7 @@ type Cache<'Key, 'Value when 'Key: not null and 'Key: equality> internal (option
member val CacheMiss = cacheMiss.Publish

[<CLIEvent>]
member val Eviction = eviction.Publish
member val Eviction = eviction.Publish |> Event.map ignore

[<CLIEvent>]
member val EvictionFail = evictionFail.Publish
Expand All @@ -249,14 +263,12 @@ type Cache<'Key, 'Value when 'Key: not null and 'Key: equality> internal (option

interface IDisposable with
member this.Dispose() =
store.Clear()
cts.Cancel()
CacheInstrumentation.RemoveInstrumentation(this)
GC.SuppressFinalize(this)

member this.Dispose() = (this :> IDisposable).Dispose()

override this.Finalize() : unit = this.Dispose()

member this.GetStats() = CacheInstrumentation.GetStats(this)

and CacheInstrumentation(cache: ICacheEvents) =
Expand Down Expand Up @@ -367,8 +379,8 @@ module Cache =

let options =
match Environment.GetEnvironmentVariable(overrideVariable) with
| null -> options
| _ -> { options with MaximumCapacity = 1024 }
| NonNull _ when options.MaximumCapacity > 1024 -> { options with MaximumCapacity = 1024 }
| _ -> options

// Increase expected capacity by the percentage to evict, since we want to not resize the dictionary.
let capacity =
Expand Down
6 changes: 5 additions & 1 deletion src/Compiler/Utilities/Caches.fsi
Original file line number Diff line number Diff line change
Expand Up @@ -58,8 +58,12 @@ type internal Cache<'Key, 'Value when 'Key: not null and 'Key: equality> =
new: options: CacheOptions * capacity: int * cts: CancellationTokenSource -> Cache<'Key, 'Value>
member TryGetValue: key: 'Key * value: outref<'Value> -> bool
member TryAdd: key: 'Key * value: 'Value -> bool
member Dispose: unit -> unit
member GetOrCreate: key: 'Key * valueFactory: ('Key -> 'Value) -> 'Value
member GetStats: unit -> string
member Dispose: unit -> unit

[<CLIEvent>]
member ValueEvicted: IEvent<'Value>

interface ICacheEvents
interface IDisposable
Expand Down
Loading