diff --git a/docs/release-notes/.FSharp.Compiler.Service/11.0.100.md b/docs/release-notes/.FSharp.Compiler.Service/11.0.100.md index ab65df29a6e..879be45c437 100644 --- a/docs/release-notes/.FSharp.Compiler.Service/11.0.100.md +++ b/docs/release-notes/.FSharp.Compiler.Service/11.0.100.md @@ -130,6 +130,7 @@ * Fix dot-completion after indexed expressions (`a.[0].Data.`, `a[0].Data.`, `[1;2].Length.`) returning unrelated global completions instead of expression-typings members. ([Issue #4966](https://github.com/dotnet/fsharp/issues/4966), [PR #19934](https://github.com/dotnet/fsharp/pull/19934)) * Quotations of `match s with "" -> _` no longer leak the `s <> null && s.Length = 0` lowering; the empty-string optimization moved from pattern-match compilation to the optimizer so quoted expressions keep `op_Equality(s, "")`. ([Issue #19873](https://github.com/dotnet/fsharp/issues/19873)) * Fix #5795: Allow attributes defined in a `module rec` / `namespace rec` scope to be used on union cases, record fields, and generic type parameters of types in the same recursive scope. ([Issue #5795](https://github.com/dotnet/fsharp/issues/5795), [PR #19744](https://github.com/dotnet/fsharp/pull/19744)) +* Avoid per-instance lock object in InterruptibleLazy and DelayInitArrayMap (PR [#20088](https://github.com/dotnet/fsharp/pull/20088)) ### Added diff --git a/src/Compiler/Utilities/illib.fs b/src/Compiler/Utilities/illib.fs index 87434b07720..0b8d51be0a3 100644 --- a/src/Compiler/Utilities/illib.fs +++ b/src/Compiler/Utilities/illib.fs @@ -15,8 +15,6 @@ open FSharp.Compiler.Caches [] type InterruptibleLazy<'T> private (value, valueFactory: unit -> 'T) = - let syncObj = obj () - [] // TODO nullness - this is boxed to obj because of an attribute targets bug fixed in main, but not yet shipped (needs shipped 8.0.400) let mutable valueFactory: objnull = valueFactory @@ -34,7 +32,7 @@ type InterruptibleLazy<'T> private (value, valueFactory: unit -> 'T) = match valueFactory with | null -> value | _ -> - Monitor.Enter(syncObj) + Monitor.Enter(this) try match valueFactory with @@ -44,7 +42,7 @@ type InterruptibleLazy<'T> private (value, valueFactory: unit -> 'T) = value <- (valueFactory |> unbox 'T>) () valueFactory <- Unchecked.defaultof<_> finally - Monitor.Exit(syncObj) + Monitor.Exit(this) value @@ -151,8 +149,6 @@ module internal PervasiveAutoOpens = [] type DelayInitArrayMap<'T, 'TDictKey, 'TDictValue>(f: unit -> 'T[]) = - let syncObj = obj () - let mutable arrayStore: (_ array | null) = null let mutable dictStore: (_ | null) = null @@ -162,7 +158,7 @@ type DelayInitArrayMap<'T, 'TDictKey, 'TDictValue>(f: unit -> 'T[]) = match arrayStore with | NonNull value -> value | _ -> - Monitor.Enter(syncObj) + Monitor.Enter(this) try match arrayStore with @@ -174,14 +170,14 @@ type DelayInitArrayMap<'T, 'TDictKey, 'TDictValue>(f: unit -> 'T[]) = func <- Unchecked.defaultof<_> freshArray finally - Monitor.Exit(syncObj) + Monitor.Exit(this) member this.GetDictionary() = match dictStore with | NonNull value -> value | _ -> let array = this.GetArray() - Monitor.Enter(syncObj) + Monitor.Enter(this) try match dictStore with @@ -191,7 +187,7 @@ type DelayInitArrayMap<'T, 'TDictKey, 'TDictValue>(f: unit -> 'T[]) = dictStore <- dict dict finally - Monitor.Exit(syncObj) + Monitor.Exit(this) abstract CreateDictionary: 'T[] -> IDictionary<'TDictKey, 'TDictValue>