diff --git a/docs/release-notes/.FSharp.Compiler.Service/9.0.200.md b/docs/release-notes/.FSharp.Compiler.Service/9.0.200.md index f282c6ae800..c7d7b11d770 100644 --- a/docs/release-notes/.FSharp.Compiler.Service/9.0.200.md +++ b/docs/release-notes/.FSharp.Compiler.Service/9.0.200.md @@ -2,7 +2,8 @@ * Fix internal error when calling 'AddSingleton' and other overloads only differing in generic arity ([PR #17804](https://github.com/dotnet/fsharp/pull/17804)) * Fix extension methods support for non-reference system assemblies ([PR #17799](https://github.com/dotnet/fsharp/pull/17799)) -* Ensure `frameworkTcImportsCache` mutations are threadsafe. ([PR #17795](https://github.com/dotnet/fsharp/pull/17795)) +* Ensure `frameworkTcImportsCache` mutations are thread-safe. ([PR #17795](https://github.com/dotnet/fsharp/pull/17795)) +* Fix concurrency issue in `ILPreTypeDefImpl` ([PR #17812](https://github.com/dotnet/fsharp/pull/17812)) ### Added diff --git a/src/Compiler/AbstractIL/il.fs b/src/Compiler/AbstractIL/il.fs index 3c70f5eb93f..82faea51c5e 100644 --- a/src/Compiler/AbstractIL/il.fs +++ b/src/Compiler/AbstractIL/il.fs @@ -2913,35 +2913,17 @@ and [] ILPreTypeDef = /// This is a memory-critical class. Very many of these objects get allocated and held to represent the contents of .NET assemblies. and [] ILPreTypeDefImpl(nameSpace: string list, name: string, metadataIndex: int32, storage: ILTypeDefStored) = - let mutable store: ILTypeDef = Unchecked.defaultof<_> - let mutable storage = storage + let stored = + lazy + match storage with + | ILTypeDefStored.Given td -> td + | ILTypeDefStored.Computed f -> f () + | ILTypeDefStored.Reader f -> f metadataIndex interface ILPreTypeDef with member _.Namespace = nameSpace member _.Name = name - - member x.GetTypeDef() = - match box store with - | null -> - let syncObj = storage - Monitor.Enter(syncObj) - - try - match box store with - | null -> - let value = - match storage with - | ILTypeDefStored.Given td -> td - | ILTypeDefStored.Computed f -> f () - | ILTypeDefStored.Reader f -> f metadataIndex - - store <- value - storage <- Unchecked.defaultof<_> - value - | _ -> store - finally - Monitor.Exit(syncObj) - | _ -> store + member x.GetTypeDef() = stored.Value and ILTypeDefStored = | Given of ILTypeDef