Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
71 changes: 32 additions & 39 deletions src/Compiler/AbstractIL/il.fs
Original file line number Diff line number Diff line change
Expand Up @@ -2142,39 +2142,35 @@ type ILMethodDef
type MethodDefMap = Map<string, ILMethodDef list>

[<Sealed>]
type ILMethodDefs(f: unit -> ILMethodDef[]) =
type ILMethodDefs(f) =
inherit DelayInitArrayMap<ILMethodDef, string, ILMethodDef list>(f)

let mutable array = InlineDelayInit<_>(f)
override this.CreateDictionary(arr) =
let t = Dictionary(arr.Length)

let mutable dict =
InlineDelayInit<_>(fun () ->
let arr = array.Value
let t = Dictionary<_, _>()
for i = arr.Length - 1 downto 0 do
let y = arr[i]
let key = y.Name

for i = arr.Length - 1 downto 0 do
let y = arr[i]
let key = y.Name
match t.TryGetValue key with
| true, m -> t[key] <- y :: m
| _ -> t[key] <- [ y ]

match t.TryGetValue key with
| true, m -> t[key] <- y :: m
| _ -> t[key] <- [ y ]

t)
t

interface IEnumerable with
member x.GetEnumerator() =
((x :> IEnumerable<ILMethodDef>).GetEnumerator() :> IEnumerator)

interface IEnumerable<ILMethodDef> with
member x.GetEnumerator() =
(array.Value :> IEnumerable<ILMethodDef>).GetEnumerator()

member x.AsArray() = array.Value
(x.GetArray() :> IEnumerable<ILMethodDef>).GetEnumerator()

member x.AsList() = array.Value |> Array.toList
member x.AsArray() = x.GetArray()
member x.AsList() = x.GetArray() |> Array.toList

member x.FindByName nm =
match dict.Value.TryGetValue nm with
match x.GetDictionary().TryGetValue nm with
| true, m -> m
| _ -> []

Expand Down Expand Up @@ -2830,43 +2826,40 @@ type ILTypeDef
override x.ToString() = "type " + x.Name

and [<Sealed>] ILTypeDefs(f: unit -> ILPreTypeDef[]) =
inherit DelayInitArrayMap<ILPreTypeDef, string list * string, ILPreTypeDef>(f)

let mutable array = InlineDelayInit<_>(f)
override this.CreateDictionary(arr) =
let t = Dictionary(arr.Length, HashIdentity.Structural)

let mutable dict =
InlineDelayInit<_>(fun () ->
let arr = array.Value
let t = Dictionary<_, _>(HashIdentity.Structural)
for pre in arr do
let key = pre.Namespace, pre.Name
t[key] <- pre

for pre in arr do
let key = pre.Namespace, pre.Name
t[key] <- pre
ReadOnlyDictionary t

ReadOnlyDictionary t)
member x.AsArray() =
[| for pre in x.GetArray() -> pre.GetTypeDef() |]

member _.AsArray() =
[| for pre in array.Value -> pre.GetTypeDef() |]

member _.AsList() =
[ for pre in array.Value -> pre.GetTypeDef() ]
member x.AsList() =
[ for pre in x.GetArray() -> pre.GetTypeDef() ]

interface IEnumerable with
member x.GetEnumerator() =
((x :> IEnumerable<ILTypeDef>).GetEnumerator() :> IEnumerator)

interface IEnumerable<ILTypeDef> with
member x.GetEnumerator() =
(seq { for pre in array.Value -> pre.GetTypeDef() }).GetEnumerator()
(seq { for pre in x.GetArray() -> pre.GetTypeDef() }).GetEnumerator()

member _.AsArrayOfPreTypeDefs() = array.Value
member x.AsArrayOfPreTypeDefs() = x.GetArray()

member _.FindByName nm =
member x.FindByName nm =
let ns, n = splitILTypeName nm
dict.Value[ (ns, n) ].GetTypeDef()
x.GetDictionary().[(ns, n)].GetTypeDef()

member _.ExistsByName nm =
member x.ExistsByName nm =
let ns, n = splitILTypeName nm
dict.Value.ContainsKey((ns, n))
x.GetDictionary().ContainsKey((ns, n))

and [<NoEquality; NoComparison>] ILPreTypeDef =
abstract Namespace: string list
Expand Down
8 changes: 6 additions & 2 deletions src/Compiler/AbstractIL/il.fsi
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ module rec FSharp.Compiler.AbstractIL.IL
open FSharp.Compiler.IO
open System.Collections.Generic
open System.Reflection
open Internal.Utilities.Library

/// Represents the target primary assembly
[<RequireQualifiedAccess>]
Expand Down Expand Up @@ -1179,8 +1180,9 @@ type ILMethodDef =
/// Tables of methods. Logically equivalent to a list of methods but
/// the table is kept in a form optimized for looking up methods by
/// name and arity.
[<NoEquality; NoComparison; Sealed>]
[<NoEquality; NoComparison; Class; Sealed>]
type ILMethodDefs =
inherit DelayInitArrayMap<ILMethodDef, string, ILMethodDef list>

interface IEnumerable<ILMethodDef>

Expand Down Expand Up @@ -1458,8 +1460,10 @@ type ILTypeDefKind =
| Delegate

/// Tables of named type definitions.
[<NoEquality; NoComparison; Sealed>]
[<NoEquality; NoComparison; Class; Sealed>]
type ILTypeDefs =
inherit DelayInitArrayMap<ILPreTypeDef, string list * string, ILPreTypeDef>

interface IEnumerable<ILTypeDef>

member internal AsArray: unit -> ILTypeDef[]
Expand Down
58 changes: 42 additions & 16 deletions src/Compiler/Utilities/illib.fs
Original file line number Diff line number Diff line change
Expand Up @@ -118,25 +118,51 @@ module internal PervasiveAutoOpens =

task.Result

/// An efficient lazy for inline storage in a class type. Results in fewer thunks.
[<Struct>]
type InlineDelayInit<'T when 'T: not struct> =
new(f: unit -> 'T) =
{
store = Unchecked.defaultof<'T>
func = Func<_>(f)
}
[<AbstractClass>]
type DelayInitArrayMap<'T, 'TDictKey, 'TDictValue>(f: unit -> 'T[]) =
let syncObj = obj ()

let mutable arrayStore = null
let mutable dictStore = null

let mutable func = f

member this.GetArray() =
match arrayStore with
| NonNull value -> value
| _ ->
Monitor.Enter(syncObj)

try
match arrayStore with
| NonNull value -> value
| _ ->

arrayStore <- func ()

val mutable store: 'T
val mutable func: Func<'T> MaybeNull
func <- Unchecked.defaultof<_>
arrayStore
finally
Monitor.Exit(syncObj)

member x.Value =
match x.func with
| null -> x.store
member this.GetDictionary() =
match dictStore with
| NonNull value -> value
| _ ->
let res = LazyInitializer.EnsureInitialized(&x.store, x.func)
x.func <- null
res
let array = this.GetArray()
Monitor.Enter(syncObj)

try
match dictStore with
| NonNull value -> value
| _ ->

dictStore <- this.CreateDictionary(array)
dictStore
finally
Monitor.Exit(syncObj)

abstract CreateDictionary: 'T[] -> IDictionary<'TDictKey, 'TDictValue>

//-------------------------------------------------------------------------
// Library: projections
Expand Down
13 changes: 7 additions & 6 deletions src/Compiler/Utilities/illib.fsi
Original file line number Diff line number Diff line change
Expand Up @@ -70,13 +70,14 @@ module internal PervasiveAutoOpens =

val notFound: unit -> 'a

[<Struct>]
type internal InlineDelayInit<'T when 'T: not struct> =
[<AbstractClass>]
type DelayInitArrayMap<'T, 'TDictKey, 'TDictValue> =
new: f: (unit -> 'T[]) -> DelayInitArrayMap<'T, 'TDictKey, 'TDictValue>

member GetArray: unit -> 'T[]
member GetDictionary: unit -> IDictionary<'TDictKey, 'TDictValue>

new: f: (unit -> 'T) -> InlineDelayInit<'T>
val mutable store: 'T
val mutable func: Func<'T>
member Value: 'T
abstract CreateDictionary: 'T[] -> IDictionary<'TDictKey, 'TDictValue>

module internal Order =

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -799,6 +799,7 @@ FSharp.Compiler.AbstractIL.IL+ILMethodDefs: ILMethodDef[] AsArray()
FSharp.Compiler.AbstractIL.IL+ILMethodDefs: Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.AbstractIL.IL+ILMethodDef] AsList()
FSharp.Compiler.AbstractIL.IL+ILMethodDefs: Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.AbstractIL.IL+ILMethodDef] FindByName(System.String)
FSharp.Compiler.AbstractIL.IL+ILMethodDefs: Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.AbstractIL.IL+ILMethodDef] TryFindInstanceByNameAndCallingSignature(System.String, ILCallingSignature)
FSharp.Compiler.AbstractIL.IL+ILMethodDefs: System.Collections.Generic.IDictionary`2[System.String,Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.AbstractIL.IL+ILMethodDef]] CreateDictionary(ILMethodDef[])
FSharp.Compiler.AbstractIL.IL+ILMethodImplDef: Boolean Equals(ILMethodImplDef)
FSharp.Compiler.AbstractIL.IL+ILMethodImplDef: Boolean Equals(System.Object)
FSharp.Compiler.AbstractIL.IL+ILMethodImplDef: Boolean Equals(System.Object, System.Collections.IEqualityComparer)
Expand Down Expand Up @@ -1619,6 +1620,7 @@ FSharp.Compiler.AbstractIL.IL+ILTypeDefLayout: Int32 GetHashCode(System.Collecti
FSharp.Compiler.AbstractIL.IL+ILTypeDefLayout: Int32 Tag
FSharp.Compiler.AbstractIL.IL+ILTypeDefLayout: Int32 get_Tag()
FSharp.Compiler.AbstractIL.IL+ILTypeDefLayout: System.String ToString()
FSharp.Compiler.AbstractIL.IL+ILTypeDefs: System.Collections.Generic.IDictionary`2[System.Tuple`2[Microsoft.FSharp.Collections.FSharpList`1[System.String],System.String],FSharp.Compiler.AbstractIL.IL+ILPreTypeDef] CreateDictionary(ILPreTypeDef[])
FSharp.Compiler.AbstractIL.IL+ILTypeInit+Tags: Int32 BeforeField
FSharp.Compiler.AbstractIL.IL+ILTypeInit+Tags: Int32 OnAny
FSharp.Compiler.AbstractIL.IL+ILTypeInit: Boolean Equals(ILTypeInit)
Expand Down Expand Up @@ -11707,4 +11709,8 @@ FSharp.Compiler.Xml.XmlDoc: System.String GetXmlText()
FSharp.Compiler.Xml.XmlDoc: System.String[] GetElaboratedXmlLines()
FSharp.Compiler.Xml.XmlDoc: System.String[] UnprocessedLines
FSharp.Compiler.Xml.XmlDoc: System.String[] get_UnprocessedLines()
FSharp.Compiler.Xml.XmlDoc: Void .ctor(System.String[], FSharp.Compiler.Text.Range)
FSharp.Compiler.Xml.XmlDoc: Void .ctor(System.String[], FSharp.Compiler.Text.Range)
Internal.Utilities.Library.DelayInitArrayMap`3[T,TDictKey,TDictValue]: System.Collections.Generic.IDictionary`2[TDictKey,TDictValue] CreateDictionary(T[])
Internal.Utilities.Library.DelayInitArrayMap`3[T,TDictKey,TDictValue]: System.Collections.Generic.IDictionary`2[TDictKey,TDictValue] GetDictionary()
Internal.Utilities.Library.DelayInitArrayMap`3[T,TDictKey,TDictValue]: T[] GetArray()
Internal.Utilities.Library.DelayInitArrayMap`3[T,TDictKey,TDictValue]: Void .ctor(Microsoft.FSharp.Core.FSharpFunc`2[Microsoft.FSharp.Core.Unit,T[]])
Original file line number Diff line number Diff line change
Expand Up @@ -799,6 +799,7 @@ FSharp.Compiler.AbstractIL.IL+ILMethodDefs: ILMethodDef[] AsArray()
FSharp.Compiler.AbstractIL.IL+ILMethodDefs: Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.AbstractIL.IL+ILMethodDef] AsList()
FSharp.Compiler.AbstractIL.IL+ILMethodDefs: Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.AbstractIL.IL+ILMethodDef] FindByName(System.String)
FSharp.Compiler.AbstractIL.IL+ILMethodDefs: Microsoft.FSharp.Core.FSharpOption`1[FSharp.Compiler.AbstractIL.IL+ILMethodDef] TryFindInstanceByNameAndCallingSignature(System.String, ILCallingSignature)
FSharp.Compiler.AbstractIL.IL+ILMethodDefs: System.Collections.Generic.IDictionary`2[System.String,Microsoft.FSharp.Collections.FSharpList`1[FSharp.Compiler.AbstractIL.IL+ILMethodDef]] CreateDictionary(ILMethodDef[])
FSharp.Compiler.AbstractIL.IL+ILMethodImplDef: Boolean Equals(ILMethodImplDef)
FSharp.Compiler.AbstractIL.IL+ILMethodImplDef: Boolean Equals(System.Object)
FSharp.Compiler.AbstractIL.IL+ILMethodImplDef: Boolean Equals(System.Object, System.Collections.IEqualityComparer)
Expand Down Expand Up @@ -1619,6 +1620,7 @@ FSharp.Compiler.AbstractIL.IL+ILTypeDefLayout: Int32 GetHashCode(System.Collecti
FSharp.Compiler.AbstractIL.IL+ILTypeDefLayout: Int32 Tag
FSharp.Compiler.AbstractIL.IL+ILTypeDefLayout: Int32 get_Tag()
FSharp.Compiler.AbstractIL.IL+ILTypeDefLayout: System.String ToString()
FSharp.Compiler.AbstractIL.IL+ILTypeDefs: System.Collections.Generic.IDictionary`2[System.Tuple`2[Microsoft.FSharp.Collections.FSharpList`1[System.String],System.String],FSharp.Compiler.AbstractIL.IL+ILPreTypeDef] CreateDictionary(ILPreTypeDef[])
FSharp.Compiler.AbstractIL.IL+ILTypeInit+Tags: Int32 BeforeField
FSharp.Compiler.AbstractIL.IL+ILTypeInit+Tags: Int32 OnAny
FSharp.Compiler.AbstractIL.IL+ILTypeInit: Boolean Equals(ILTypeInit)
Expand Down Expand Up @@ -11707,4 +11709,8 @@ FSharp.Compiler.Xml.XmlDoc: System.String GetXmlText()
FSharp.Compiler.Xml.XmlDoc: System.String[] GetElaboratedXmlLines()
FSharp.Compiler.Xml.XmlDoc: System.String[] UnprocessedLines
FSharp.Compiler.Xml.XmlDoc: System.String[] get_UnprocessedLines()
FSharp.Compiler.Xml.XmlDoc: Void .ctor(System.String[], FSharp.Compiler.Text.Range)
FSharp.Compiler.Xml.XmlDoc: Void .ctor(System.String[], FSharp.Compiler.Text.Range)
Internal.Utilities.Library.DelayInitArrayMap`3[T,TDictKey,TDictValue]: System.Collections.Generic.IDictionary`2[TDictKey,TDictValue] CreateDictionary(T[])
Internal.Utilities.Library.DelayInitArrayMap`3[T,TDictKey,TDictValue]: System.Collections.Generic.IDictionary`2[TDictKey,TDictValue] GetDictionary()
Internal.Utilities.Library.DelayInitArrayMap`3[T,TDictKey,TDictValue]: T[] GetArray()
Internal.Utilities.Library.DelayInitArrayMap`3[T,TDictKey,TDictValue]: Void .ctor(Microsoft.FSharp.Core.FSharpFunc`2[Microsoft.FSharp.Core.Unit,T[]])