Skip to content

Commit

Permalink
Fix races in the ProvidedTypesContext (#11841)
Browse files Browse the repository at this point in the history
  • Loading branch information
DedSec256 authored Jul 16, 2021
1 parent 4f826ec commit e19155e
Show file tree
Hide file tree
Showing 3 changed files with 12 additions and 11 deletions.
8 changes: 4 additions & 4 deletions src/fsharp/CheckDeclarations.fs
Original file line number Diff line number Diff line change
Expand Up @@ -3484,12 +3484,12 @@ module EstablishTypeDefinitionCores =
tycon.entity_tycon_repr <- repr
// Record the details so we can map System.Type --> TyconRef
let ilOrigRootTypeRef = GetOriginalILTypeRefOfProvidedType (theRootTypeWithRemapping, m)
theRootTypeWithRemapping.PUntaint ((fun st -> ignore(lookupTyconRef.Remove(st)) ; lookupTyconRef.Add(st, tcref)), m)
theRootTypeWithRemapping.PUntaint ((fun st -> ignore(lookupTyconRef.TryRemove(st)) ; ignore(lookupTyconRef.TryAdd(st, tcref))), m)

// Record the details so we can map System.Type --> ILTypeRef, including the relocation if any
if not isSuppressRelocate then
let ilTgtRootTyRef = tycon.CompiledRepresentationForNamedType
theRootTypeWithRemapping.PUntaint ((fun st -> ignore(lookupILTypeRef.Remove(st)) ; lookupILTypeRef.Add(st, ilTgtRootTyRef)), m)
theRootTypeWithRemapping.PUntaint ((fun st -> ignore(lookupILTypeRef.TryRemove(st)) ; ignore(lookupILTypeRef.TryAdd(st, ilTgtRootTyRef))), m)

// Iterate all nested types and force their embedding, to populate the mapping from System.Type --> TyconRef/ILTypeRef.
// This is only needed for generated types, because for other types the System.Type objects self-describe
Expand Down Expand Up @@ -3522,12 +3522,12 @@ module EstablishTypeDefinitionCores =
let ilOrigTypeRef = GetOriginalILTypeRefOfProvidedType (st, m)

// Record the details so we can map System.Type --> TyconRef
st.PUntaint ((fun st -> ignore(lookupTyconRef.Remove(st)) ; lookupTyconRef.Add(st, nestedTyRef)), m)
st.PUntaint ((fun st -> ignore(lookupTyconRef.TryRemove(st)) ; ignore(lookupTyconRef.TryAdd(st, nestedTyRef))), m)

if isGenerated then
let ilTgtTyRef = nestedTycon.CompiledRepresentationForNamedType
// Record the details so we can map System.Type --> ILTypeRef
st.PUntaint ((fun st -> ignore(lookupILTypeRef.Remove(st)) ; lookupILTypeRef.Add(st, ilTgtTyRef)), m)
st.PUntaint ((fun st -> ignore(lookupILTypeRef.TryRemove(st)) ; ignore(lookupILTypeRef.TryAdd(st, ilTgtTyRef))), m)

// Record the details so we can build correct ILTypeDefs during static linking rewriting
if not isSuppressRelocate then
Expand Down
9 changes: 5 additions & 4 deletions src/fsharp/ExtensionTyping.fs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ namespace FSharp.Compiler
#if !NO_EXTENSIONTYPING

open System
open System.Collections.Concurrent
open System.IO
open System.Collections.Generic
open System.Reflection
Expand Down Expand Up @@ -271,7 +272,7 @@ module internal ExtensionTyping =
and ProvidedTypeContext =
| NoEntries
// The dictionaries are safe because the ProvidedType with the ProvidedTypeContext are only accessed one thread at a time during type-checking.
| Entries of Dictionary<ProvidedType, ILTypeRef> * Lazy<Dictionary<ProvidedType, obj>>
| Entries of ConcurrentDictionary<ProvidedType, ILTypeRef> * Lazy<ConcurrentDictionary<ProvidedType, obj>>

static member Empty = NoEntries

Expand All @@ -280,7 +281,7 @@ module internal ExtensionTyping =
member ctxt.GetDictionaries() =
match ctxt with
| NoEntries ->
Dictionary<ProvidedType, ILTypeRef>(ProvidedTypeComparer.Instance), Dictionary<ProvidedType, obj>(ProvidedTypeComparer.Instance)
ConcurrentDictionary<ProvidedType, ILTypeRef>(ProvidedTypeComparer.Instance), ConcurrentDictionary<ProvidedType, obj>(ProvidedTypeComparer.Instance)
| Entries (lookupILTR, lookupILTCR) ->
lookupILTR, lookupILTCR.Force()

Expand All @@ -305,8 +306,8 @@ module internal ExtensionTyping =
match ctxt with
| NoEntries -> NoEntries
| Entries(d1, d2) ->
Entries(d1, lazy (let dict = Dictionary<ProvidedType, obj>(ProvidedTypeComparer.Instance)
for KeyValue (st, tcref) in d2.Force() do dict.Add(st, f tcref)
Entries(d1, lazy (let dict = ConcurrentDictionary<ProvidedType, obj>(ProvidedTypeComparer.Instance)
for KeyValue (st, tcref) in d2.Force() do dict.TryAdd(st, f tcref) |> ignore
dict))

and [<AllowNullLiteral; Sealed>]
Expand Down
6 changes: 3 additions & 3 deletions src/fsharp/ExtensionTyping.fsi
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ namespace FSharp.Compiler
#if !NO_EXTENSIONTYPING

open System
open System.Collections.Generic
open System.Collections.Concurrent
open FSharp.Core.CompilerServices
open FSharp.Compiler.AbstractIL.IL
open FSharp.Compiler.Text
Expand Down Expand Up @@ -78,9 +78,9 @@ module internal ExtensionTyping =

static member Empty : ProvidedTypeContext

static member Create : Dictionary<ProvidedType, ILTypeRef> * Dictionary<ProvidedType, obj (* TyconRef *) > -> ProvidedTypeContext
static member Create : ConcurrentDictionary<ProvidedType, ILTypeRef> * ConcurrentDictionary<ProvidedType, obj (* TyconRef *) > -> ProvidedTypeContext

member GetDictionaries : unit -> Dictionary<ProvidedType, ILTypeRef> * Dictionary<ProvidedType, obj (* TyconRef *) >
member GetDictionaries : unit -> ConcurrentDictionary<ProvidedType, ILTypeRef> * ConcurrentDictionary<ProvidedType, obj (* TyconRef *) >

/// Map the TyconRef objects, if any
member RemapTyconRefs : (obj -> obj) -> ProvidedTypeContext
Expand Down

0 comments on commit e19155e

Please sign in to comment.