diff --git a/src/Compiler/AbstractIL/il.fs b/src/Compiler/AbstractIL/il.fs index 2c96d10f528..b918bbe9085 100644 --- a/src/Compiler/AbstractIL/il.fs +++ b/src/Compiler/AbstractIL/il.fs @@ -2876,6 +2876,7 @@ 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 interface ILPreTypeDef with member _.Namespace = nameSpace @@ -2884,12 +2885,24 @@ and [] ILPreTypeDefImpl(nameSpace: string list, name: string, metadataIn member x.GetTypeDef() = match box store with | null -> - match storage with - | ILTypeDefStored.Given td -> - store <- td - td - | ILTypeDefStored.Computed f -> LazyInitializer.EnsureInitialized(&store, Func<_>(fun () -> f ())) - | ILTypeDefStored.Reader f -> LazyInitializer.EnsureInitialized(&store, Func<_>(fun () -> f metadataIndex)) + 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 and ILTypeDefStored =