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
6 changes: 6 additions & 0 deletions RELEASE_NOTES.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,9 @@
### 7.22.0 - 24.11.2024

* Update to FSAC 0.75.0. This release adds support for F# 9 language features and .NET 9 SDKs and tooling.
* Removes support for .NET 6 and .NET 7 SDKs and tooling.
* Added new configuration for using the DATAS Server GC Mode via the "FSharp.fsac.gc.useDatas" setting. This mode is enabled by default in .NET 9, disabled by default in .NET 8, and mutually exclusive with the pre-existing "Fsharp.fsac.gc.noAffinitize" and "Fsharp.fsac.gc.heapCount" settings.

### 7.21.2 - 21.09.2024

* FIXED: [Fix Find References in CodeLens](https://github.com/ionide/ionide-vscode-fsharp/pull/2042) from @PaigeM80
Expand Down
2 changes: 1 addition & 1 deletion build/Program.fs
Original file line number Diff line number Diff line change
Expand Up @@ -309,7 +309,7 @@ let initTargets () =


Target.create "CopyFSACNetcore" (fun _ ->
let tfms = [ "net6.0"; "net7.0"; "net8.0" ]
let tfms = [ "net8.0"; "net9.0" ]

for tfm in tfms do
let fsacBinNetcore = $"packages/fsac/fsautocomplete/tools/{tfm}/any"
Expand Down
2 changes: 1 addition & 1 deletion paket.lock
Original file line number Diff line number Diff line change
Expand Up @@ -241,4 +241,4 @@ STORAGE: PACKAGES
RESTRICTION: == netstandard2.0
NUGET
remote: https://api.nuget.org/v3/index.json
fsautocomplete (0.74.1)
fsautocomplete (0.75)
13 changes: 9 additions & 4 deletions release/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -585,17 +585,15 @@
"maximum": 9
},
"FSharp.fsac.gc.heapCount": {
"default": 2,
"markdownDescription": "Limits the number of [heaps](https://learn.microsoft.com/en-us/dotnet/standard/garbage-collection/fundamentals#the-managed-heap) created by the garbage collector. Applies to server garbage collection only. See [Middle Ground between Server and Workstation GC](https://devblogs.microsoft.com/dotnet/middle-ground-between-server-and-workstation-gc/) for more details. This can allow FSAC to still benefit from Server garbage collection while still limiting the number of heaps. [Only available on .NET 7 or higher](https://github.com/ionide/ionide-vscode-fsharp/issues/1899#issuecomment-1649009462). Requires restart.",
"markdownDescription": "Limits the number of [heaps](https://learn.microsoft.com/en-us/dotnet/standard/garbage-collection/fundamentals#the-managed-heap) created by the garbage collector. Applies to server garbage collection only. See [Middle Ground between Server and Workstation GC](https://devblogs.microsoft.com/dotnet/middle-ground-between-server-and-workstation-gc/) for more details. This can allow FSAC to still benefit from Server garbage collection while still limiting the number of heaps. [Only available on .NET 7 or higher](https://github.com/ionide/ionide-vscode-fsharp/issues/1899#issuecomment-1649009462). Requires restart. If FSAC is run on .NET 8 runtimes, this will be set to 2 by default to prevent inflated memory use. On .NET 9 with DATAS enabled, this will not be set. ",
"type": "integer",
"required": [
"FSharp.fsac.gc.server"
]
},
"Fsharp.fsac.gc.noAffinitize": {
"default": true,
"type": "boolean",
"markdownDescription": "Specifies whether to [affinitize](https://learn.microsoft.com/en-us/dotnet/core/runtime-config/garbage-collector#affinitize) garbage collection threads with processors. To affinitize a GC thread means that it can only run on its specific CPU.. Applies to server garbage collection only. See [GCNoAffinitize](https://learn.microsoft.com/en-us/dotnet/framework/configure-apps/file-schema/runtime/gcnoaffinitize-element#remarks) for more details. [Only available on .NET 7 or higher](https://github.com/ionide/ionide-vscode-fsharp/issues/1899#issuecomment-1649009462). Requires restart.",
"markdownDescription": "Specifies whether to [affinitize](https://learn.microsoft.com/en-us/dotnet/core/runtime-config/garbage-collector#affinitize) garbage collection threads with processors. To affinitize a GC thread means that it can only run on its specific CPU.. Applies to server garbage collection only. See [GCNoAffinitize](https://learn.microsoft.com/en-us/dotnet/framework/configure-apps/file-schema/runtime/gcnoaffinitize-element#remarks) for more details. [Only available on .NET 7 or higher](https://github.com/ionide/ionide-vscode-fsharp/issues/1899#issuecomment-1649009462). Requires restart. If FSAC is run on .NET 8 runtimes, this will be set by default. On .NET 9 with DATAS enabled, this will not be set.",
"required": [
"FSharp.fsac.gc.server"
]
Expand All @@ -605,6 +603,13 @@
"markdownDescription": "Configures whether the application uses workstation garbage collection or server garbage collection. See [Workstation vs Server Garbage Collection](https://devblogs.microsoft.com/premier-developer/understanding-different-gc-modes-with-concurrency-visualizer/#workstation-gc-vs-server-gc) for more details. Workstation will use less memory but Server will have more throughput. Requires restart.",
"type": "boolean"
},
"FSharp.fsac.gc.useDatas": {
"markdownDescription": "Configures whether the application uses the DATAS(dynamic adaptation to application sizes) server garbage collection mode. See [DATAS](https://learn.microsoft.com/dotnet/core/runtime-config/garbage-collector#dynamic-adaptation-to-application-sizes-datas) for more details. Requires restart. When FSAC is run on .NET 8 runtimes, this will be set to false by default. On .NET 9 runtimes, this will be set to true by default.",
"type": "boolean",
"required": [
"FSharp.fsac.gc.server"
]
},
"FSharp.fsac.netCoreDllPath": {
"default": "",
"description": "The path to the \u0027fsautocomplete.dll\u0027, a directory containing TFM-specific versions of fsautocomplete.dll, or a directory containing fsautocomplete.dll. Useful for debugging a self-built FSAC. If a DLL is specified, uses it directly. If a directory is specified and it contains TFM-specific folders (net6.0, net7.0, etc) then that directory will be probed for the best TFM to use for the current runtime. This is useful when working with a local copy of FSAC, you can point directly to the bin/Debug or bin/Release folder and it\u0027ll Just Work. Finally, if a directory is specified and there are no TFM paths, then fsautocomplete.dll from that directory is used. Requires restart.",
Expand Down
46 changes: 39 additions & 7 deletions src/Core/LanguageService.fs
Original file line number Diff line number Diff line change
Expand Up @@ -705,11 +705,17 @@ Consider:
| None, Some true -> 9
| None, _ -> 0

let gcHeapCount = "FSharp.fsac.gc.heapCount" |> Configuration.get 2

let gcServer = "FSharp.fsac.gc.server" |> Configuration.get true

let gcNoAffinitize = "Fsharp.fsac.gc.noAffinitize" |> Configuration.get true
let gcServerUseDatas: bool option =
"FSharp.fsac.gc.useDatas" |> Configuration.tryGet |> Option.bind tryBool

let gcNoAffinitize =
"Fsharp.fsac.gc.noAffinitize" |> Configuration.tryGet |> Option.bind tryBool

let gcHeapCount =
"FSharp.fsac.gc.heapCount" |> Configuration.tryGet |> Option.bind tryInt

let parallelReferenceResolution =
"FSharp.fsac.parallelReferenceResolution" |> Configuration.get false
Expand Down Expand Up @@ -866,17 +872,43 @@ Consider:
// Only set DOTNET_GCHeapCount if we're on .NET 7 or higher
// .NET 6 has some issues with this env var on linux
// https://github.com/ionide/ionide-vscode-fsharp/issues/1899
let versionSupportingEnvVars = (semver.parse (Some(U2.Case1 "7.0.0"))).Value

let isNet7orHigher =
semver.cmp (U2.Case2 sdkVersion, Operator.GTE, U2.Case2 versionSupportingEnvVars)
let versionSupportingDATASGCMode = (semver.parse (Some(U2.Case1 "9.0.0"))).Value
let isdotnet8 = sdkVersion.major = 8

let isNet9orHigher =
semver.cmp (U2.Case2 sdkVersion, Operator.GTE, U2.Case2 versionSupportingDATASGCMode)

// datas is on by 9
let useDatas =
match gcServerUseDatas with
| Some b -> b
| None -> isNet9orHigher

let gcNoAffinitize =
match gcNoAffinitize with
| Some b -> b
| None -> isdotnet8 || not useDatas // no need to affinitize on 9 because Datas

let gcHeapCount =
match gcHeapCount with
| Some i -> Some i
| None -> if isdotnet8 then Some 2 else None

let fsacEnvVars =
[ yield! fsacEnvVars
if isNet7orHigher then

if useDatas then
// DATAS and affinitization/heap management seem to be mutually exclusive, so we enforce that here.
yield "DOTNET_GCDynamicAdaptationMode", box (boolToInt useDatas) // https://learn.microsoft.com/en-us/dotnet/core/runtime-config/garbage-collector#dynamic-adaptation-to-application-sizes-datas
else
// it doesn't really make sense to set GCNoAffinitize without setting GCHeapCount
yield "DOTNET_GCNoAffinitize", box (boolToInt gcNoAffinitize) // https://learn.microsoft.com/en-us/dotnet/core/runtime-config/garbage-collector#affinitize
yield "DOTNET_GCHeapCount", box (gcHeapCount.ToString("X")) // Requires hexadecimal value https://learn.microsoft.com/en-us/dotnet/core/runtime-config/garbage-collector#heap-count

yield!
gcHeapCount
|> Option.map (fun hc -> "DOTNET_GCHeapCount", box (hc.ToString("X")))
|> Option.toList // Requires hexadecimal value https://learn.microsoft.com/en-us/dotnet/core/runtime-config/garbage-collector#heap-count

yield "DOTNET_GCConserveMemory", box gcConserveMemory //https://learn.microsoft.com/en-us/dotnet/core/runtime-config/garbage-collector#conserve-memory
yield "DOTNET_GCServer", box (boolToInt gcServer) // https://learn.microsoft.com/en-us/dotnet/core/runtime-config/garbage-collector#workstation-vs-server
Expand Down
Loading