diff --git a/RELEASE_NOTES.md b/RELEASE_NOTES.md index fdb656f4..aab68835 100644 --- a/RELEASE_NOTES.md +++ b/RELEASE_NOTES.md @@ -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 diff --git a/build/Program.fs b/build/Program.fs index 1e7206cc..ac5a01f5 100644 --- a/build/Program.fs +++ b/build/Program.fs @@ -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" diff --git a/paket.lock b/paket.lock index 7a20605b..9a2bb8c5 100644 --- a/paket.lock +++ b/paket.lock @@ -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) diff --git a/release/package.json b/release/package.json index 5bbbb771..fada11d9 100644 --- a/release/package.json +++ b/release/package.json @@ -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" ] @@ -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.", diff --git a/src/Core/LanguageService.fs b/src/Core/LanguageService.fs index b0a5a1cf..bcfa75fc 100644 --- a/src/Core/LanguageService.fs +++ b/src/Core/LanguageService.fs @@ -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 @@ -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