Skip to content

Commit

Permalink
chunkify TcSymbolUSeData
Browse files Browse the repository at this point in the history
  • Loading branch information
baronfel committed Jan 13, 2019
1 parent 631401a commit 031f1a8
Show file tree
Hide file tree
Showing 3 changed files with 41 additions and 7 deletions.
38 changes: 35 additions & 3 deletions src/fsharp/NameResolution.fs
Original file line number Diff line number Diff line change
Expand Up @@ -1212,7 +1212,7 @@ let GetNestedTypesOfType (ad, ncenv:NameResolver, optFilter, staticResInfo, chec
//-------------------------------------------------------------------------

/// Represents the kind of the occurrence when reporting a name in name resolution
[<RequireQualifiedAccess>]
[<RequireQualifiedAccess; Struct>]
type ItemOccurence =
/// This is a binding / declaration of the item
| Binding
Expand Down Expand Up @@ -1498,13 +1498,45 @@ type TcSymbolUseData =
/// are allocated (one per file), but they are large because the allUsesOfAllSymbols array is large.
type TcSymbolUses(g, capturedNameResolutions : ResizeArray<CapturedNameResolution>, formatSpecifierLocations: (range * int)[]) =

let chunks (items: ResizeArray<'t>) chunkSize =
let itemCount = items.Count
let chunksCount =
match itemCount / chunkSize with
| n when itemCount % chunkSize = 0 -> n
| n -> n + 1 // any remainder means we need an additional chunk to store it

[| for index in 0..chunksCount-1 do
let startIndex = index * chunkSize
let takeCount =
if (index + 1) * chunkSize > itemCount
then itemCount - startIndex
else chunkSize
// pre-creating the array and doing a single copy is slightly better than
// two copies via ResizeArray<'t>.GetRange(start, count).ToArray().
let holder = Array.zeroCreate takeCount
items.CopyTo(startIndex, holder, 0, takeCount)
yield holder |]

/// chunk the provided capturedNameResolutions into arrays that are smaller than the LOH limit
/// in order to prevent long-term storage of those values
let chunkedResolutions: CapturedNameResolution [] [] =
let structSizeBytes = sizeof<TcSymbolUseData>
let lohSizeThresholdBytes = 85_000
// rounding down here is good beacuse it ensure we don't go over
let maxArrayItemCount = lohSizeThresholdBytes / structSizeBytes
chunks capturedNameResolutions maxArrayItemCount

// Make sure we only capture the information we really need to report symbol uses
let allUsesOfSymbols = [| for cnr in capturedNameResolutions -> { Item=cnr.Item; ItemOccurence=cnr.ItemOccurence; DisplayEnv=cnr.DisplayEnv; Range=cnr.Range } |]
let allUsesOfSymbols =
[| for capturedNameResolutionsChunk in chunkedResolutions ->
[| for cnr in capturedNameResolutionsChunk ->
{ Item=cnr.Item; ItemOccurence=cnr.ItemOccurence; DisplayEnv=cnr.DisplayEnv; Range=cnr.Range } |] |]
let capturedNameResolutions = ()
do ignore capturedNameResolutions // don't capture this!

member this.GetUsesOfSymbol(item) =
[| for symbolUse in allUsesOfSymbols do
[| for symbolUseChunk in allUsesOfSymbols do
for symbolUse in symbolUseChunk do
if protectAssemblyExploration false (fun () -> ItemsAreEffectivelyEqual g item symbolUse.Item) then
yield symbolUse |]

Expand Down
4 changes: 2 additions & 2 deletions src/fsharp/NameResolution.fsi
Original file line number Diff line number Diff line change
Expand Up @@ -240,7 +240,7 @@ type TypeNameResolutionInfo =
static member ResolveToTypeRefs : TypeNameResolutionStaticArgsInfo -> TypeNameResolutionInfo

/// Represents the kind of the occurrence when reporting a name in name resolution
[<RequireQualifiedAccess>]
[<RequireQualifiedAccess; Struct>]
type internal ItemOccurence =
| Binding
| Use
Expand Down Expand Up @@ -319,7 +319,7 @@ type internal TcSymbolUses =
member GetUsesOfSymbol : Item -> TcSymbolUseData[]

/// All the uses of all items within the file
member AllUsesOfSymbols : TcSymbolUseData[]
member AllUsesOfSymbols : TcSymbolUseData[][]

/// Get the locations of all the printf format specifiers in the file
member GetFormatSpecifierLocationsAndArity : unit -> (range * int)[]
Expand Down
6 changes: 4 additions & 2 deletions src/fsharp/service/service.fs
Original file line number Diff line number Diff line change
Expand Up @@ -1913,7 +1913,8 @@ type FSharpCheckProjectResults(projectFileName:string, tcConfigOption, keepAssem
let cenv = SymbolEnv(tcGlobals, thisCcu, Some ccuSig, tcImports)

[| for r in tcSymbolUses do
for symbolUse in r.AllUsesOfSymbols do
for symbolUseChunk in r.AllUsesOfSymbols do
for symbolUse in symbolUseChunk do
if symbolUse.ItemOccurence <> ItemOccurence.RelatedText then
let symbol = FSharpSymbol.Create(cenv, symbolUse.Item)
yield FSharpSymbolUse(tcGlobals, symbolUse.DisplayEnv, symbol, symbolUse.ItemOccurence, symbolUse.Range) |]
Expand Down Expand Up @@ -2107,7 +2108,8 @@ type FSharpCheckFileResults(filename: string, errors: FSharpErrorInfo[], scopeOp
(fun () -> [| |])
(fun scope ->
let cenv = scope.SymbolEnv
[| for symbolUse in scope.ScopeSymbolUses.AllUsesOfSymbols do
[| for symbolUseChunk in scope.ScopeSymbolUses.AllUsesOfSymbols do
for symbolUse in symbolUseChunk do
if symbolUse.ItemOccurence <> ItemOccurence.RelatedText then
let symbol = FSharpSymbol.Create(cenv, symbolUse.Item)
yield FSharpSymbolUse(scope.TcGlobals, symbolUse.DisplayEnv, symbol, symbolUse.ItemOccurence, symbolUse.Range) |])
Expand Down

0 comments on commit 031f1a8

Please sign in to comment.