Skip to content

Commit 00f53bc

Browse files
committed
reduce memory use
1 parent 9c70966 commit 00f53bc

File tree

8 files changed

+60
-30
lines changed

8 files changed

+60
-30
lines changed

eng/build.sh

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -226,7 +226,7 @@ function Test() {
226226
projectname="${projectname%.*}"
227227
testlogpath="$artifacts_dir/TestResults/$configuration/${projectname}_$targetframework.xml"
228228
args="test \"$testproject\" --no-restore --no-build -c $configuration -f $targetframework --test-adapter-path . --logger \"xunit;LogFilePath=$testlogpath\" --blame-hang-timeout 5minutes --results-directory $artifacts_dir/TestResults/$configuration -p:vstestusemsbuildoutput=false"
229-
args+=" -- xUnit.MaxParallelThreads=1"
229+
230230
"$DOTNET_INSTALL_DIR/dotnet" $args || exit $?
231231
}
232232

src/Compiler/Utilities/Caches.fs

Lines changed: 17 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -20,8 +20,8 @@ type CacheOptions =
2020

2121
static member Default =
2222
{
23-
TotalCapacity = 128
24-
HeadroomPercentage = 50
23+
TotalCapacity = 256
24+
HeadroomPercentage = 10
2525
}
2626

2727
// It is important that this is not a struct, because LinkedListNode holds a reference to it,
@@ -172,10 +172,14 @@ module Cache =
172172
let OverrideCapacityForTesting () =
173173
Environment.SetEnvironmentVariable(overrideVariable, "true", EnvironmentVariableTarget.Process)
174174

175-
let applyOverride (capacity: int) =
175+
let applyOverride (options: CacheOptions) =
176176
match Environment.GetEnvironmentVariable(overrideVariable) with
177-
| NonNull _ when capacity > 4096 -> 4096
178-
| _ -> capacity
177+
| NonNull _ when options.TotalCapacity > 64 * 1024 ->
178+
{
179+
CacheOptions.TotalCapacity = 64 * 1024
180+
CacheOptions.HeadroomPercentage = 80
181+
}
182+
| _ -> options
179183

180184
[<Struct>]
181185
type EvictionQueueMessage<'Key, 'Value> =
@@ -298,19 +302,24 @@ type Cache<'Key, 'Value when 'Key: not null and 'Key: equality> internal (totalC
298302

299303
member this.GetStats() = CacheMetrics.GetStats(this.Name)
300304

301-
static member Create<'Key, 'Value>(options: CacheOptions, ?name, ?observeMetrics) =
305+
static member Create<'Key, 'Value>(?options: CacheOptions, ?name, ?observeMetrics) =
306+
let options = defaultArg options CacheOptions.Default
307+
302308
if options.TotalCapacity < 0 then
303309
invalidArg "Capacity" "Capacity must be positive"
304310

305311
if options.HeadroomPercentage < 0 then
306312
invalidArg "HeadroomPercentage" "HeadroomPercentage must be positive"
307313

308-
let totalCapacity = Cache.applyOverride options.TotalCapacity
314+
if options.HeadroomPercentage > 100 then
315+
invalidArg "HeadroomPercentage" "HeadroomPercentage can not be greater than 100"
316+
317+
let options = Cache.applyOverride options
309318
// Determine evictable headroom as the percentage of total capcity, since we want to not resize the dictionary.
310319
let headroom =
311320
int (float options.TotalCapacity * float options.HeadroomPercentage / 100.0)
312321

313322
let cache =
314-
new Cache<_, _>(totalCapacity, headroom, ?name = name, ?observeMetrics = observeMetrics)
323+
new Cache<_, _>(options.TotalCapacity, headroom, ?name = name, ?observeMetrics = observeMetrics)
315324

316325
cache

src/Compiler/Utilities/Caches.fsi

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ type internal Cache<'Key, 'Value when 'Key: not null and 'Key: equality> =
3434
member Evicted: IEvent<unit>
3535

3636
static member Create<'Key, 'Value> :
37-
options: CacheOptions * ?name: string * ?observeMetrics: bool -> Cache<'Key, 'Value>
37+
?options: CacheOptions * ?name: string * ?observeMetrics: bool -> Cache<'Key, 'Value>
3838

3939
[<Class>]
4040
type internal CacheMetrics =

tests/FSharp.Compiler.ComponentTests/CompilerService/Caches.fs

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ open Xunit
99
let ``Create and dispose many`` () =
1010
let caches =
1111
[
12-
for _ in 1 .. 100 do
12+
for _ in 1 .. 10 do
1313
Cache.Create<string, int>(CacheOptions.Default, observeMetrics = true)
1414
]
1515

@@ -19,7 +19,7 @@ let ``Create and dispose many`` () =
1919
let ``Create and dispose many named`` () =
2020
let caches =
2121
[
22-
for i in 1 .. 100 do
22+
for i in 1 .. 10 do
2323
Cache.Create<string, int>(CacheOptions.Default, name = $"testCache{i}", observeMetrics = true)
2424
]
2525

@@ -41,7 +41,8 @@ let ``Basic add and retrieve`` () =
4141

4242
[<Fact>]
4343
let ``Eviction of least recently used`` () =
44-
use cache = Cache.Create<string, int>({ TotalCapacity = 2; HeadroomPercentage = 0 }, observeMetrics = true)
44+
// 50% headroom out of tatal 4 means non-evictable capacity of 2
45+
use cache = Cache.Create<string, int>({ TotalCapacity = 4; HeadroomPercentage = 50 }, observeMetrics = true)
4546

4647
cache.TryAdd("key1", 1) |> ignore
4748
cache.TryAdd("key2", 2) |> ignore
@@ -67,7 +68,7 @@ let ``Eviction of least recently used`` () =
6768

6869
[<Fact>]
6970
let ``Metrics can be retrieved`` () =
70-
use cache = Cache.Create<string, int>({ TotalCapacity = 2; HeadroomPercentage = 0 }, name = "test_metrics", observeMetrics = true)
71+
use cache = Cache.Create<string, int>({ TotalCapacity = 4; HeadroomPercentage = 50 }, name = "test_metrics", observeMetrics = true)
7172

7273
cache.TryAdd("key1", 1) |> ignore
7374
cache.TryAdd("key2", 2) |> ignore

tests/FSharp.Compiler.ComponentTests/Miscellaneous/FsharpSuiteMigrated.fs

Lines changed: 17 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -14,11 +14,18 @@ open FSharp.Test.ScriptHelpers
1414
module Configuration =
1515
let supportedNames = set ["testlib.fsi";"testlib.fs";"test.mli";"test.ml";"test.fsi";"test.fs";"test2.fsi";"test2.fs";"test.fsx";"test2.fsx"]
1616

17+
[<RequireQualifiedAccess>]
18+
type ScriptSessionIsolation = Shared | Isolated
19+
1720
module ScriptRunner =
1821
open Internal.Utilities.Library
1922

20-
let private createEngine(args,version) =
21-
getSessionForEval args version
23+
let private createEngine(args,version) sessionIsolation =
24+
match sessionIsolation with
25+
| ScriptSessionIsolation.Isolated ->
26+
new FSharpScript(args, true, version)
27+
| ScriptSessionIsolation.Shared ->
28+
getSessionForEval args version
2229

2330
let defaultDefines =
2431
[
@@ -27,12 +34,12 @@ module ScriptRunner =
2734
#endif
2835
]
2936

30-
let runScriptFile version (cu:CompilationUnit) =
37+
let runScriptFile version sessionIsolation (cu:CompilationUnit) =
3138
let cu = cu |> withDefines defaultDefines
3239
match cu with
3340
| FS fsSource ->
3441
use capture = new TestConsole.ExecutionCapture()
35-
let engine = createEngine (fsSource.Options |> Array.ofList,version)
42+
let engine = createEngine (fsSource.Options |> Array.ofList,version) sessionIsolation
3643
let res = evalScriptFromDiskInSharedSession engine cu
3744
match res with
3845
| CompilationResult.Failure _ -> res
@@ -88,7 +95,7 @@ module TestFrameworkAdapter =
8895
| LangVersion.SupportsMl -> "5.0", "--mlcompatibility" :: bonusArgs
8996

9097

91-
let singleTestBuildAndRunAuxVersion (folder:string) bonusArgs mode langVersion =
98+
let singleTestBuildAndRunAuxVersion (folder:string) bonusArgs mode langVersion sessionIsolation =
9299
let absFolder = Path.Combine(baseFolder,folder)
93100
let supportedNames, files =
94101
match mode with
@@ -137,17 +144,17 @@ module TestFrameworkAdapter =
137144
cu
138145
|> withDebug
139146
|> withNoOptimize
140-
|> ScriptRunner.runScriptFile langVersion
147+
|> ScriptRunner.runScriptFile langVersion sessionIsolation
141148
|> shouldSucceed
142149
| FSC_OPTIMIZED ->
143150
cu
144151
|> withOptimize
145152
|> withNoDebug
146-
|> ScriptRunner.runScriptFile langVersion
153+
|> ScriptRunner.runScriptFile langVersion sessionIsolation
147154
|> shouldSucceed
148155
| FSI ->
149156
cu
150-
|> ScriptRunner.runScriptFile langVersion
157+
|> ScriptRunner.runScriptFile langVersion sessionIsolation
151158
|> shouldSucceed
152159
| COMPILED_EXE_APP ->
153160
cu
@@ -161,7 +168,8 @@ module TestFrameworkAdapter =
161168

162169
let singleTestBuildAndRunAux folder bonusArgs mode = singleTestBuildAndRunAuxVersion folder bonusArgs mode LangVersion.Latest
163170
let singleTestBuildAndRunVersion folder mode version = singleTestBuildAndRunAuxVersion folder [] mode version
164-
let singleTestBuildAndRun folder mode = singleTestBuildAndRunVersion folder mode LangVersion.Latest
171+
let singleTestBuildAndRun folder mode = singleTestBuildAndRunVersion folder mode LangVersion.Latest ScriptSessionIsolation.Shared
172+
let singleTestBuildAndRunIsolated folder mode = singleTestBuildAndRunVersion folder mode LangVersion.Latest ScriptSessionIsolation.Isolated
165173

166174
let singleVersionedNegTestAux folder bonusArgs version testName =
167175
singleTestBuildAndRunAuxVersion folder bonusArgs (NEG_TEST_BUILD testName) version

tests/FSharp.Compiler.ComponentTests/Miscellaneous/MigratedCoreTests.fs

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -352,13 +352,13 @@ let ``subtype-FSC_OPTIMIZED`` () = singleTestBuildAndRun "core/subtype" FSC_OPTI
352352
let ``subtype-FSI`` () = singleTestBuildAndRun "core/subtype" FSI
353353

354354
[<Fact>]
355-
let ``syntax-FSC_DEBUG`` () = singleTestBuildAndRun "core/syntax" FSC_DEBUG
355+
let ``syntax-FSC_DEBUG`` () = singleTestBuildAndRunIsolated "core/syntax" FSC_DEBUG
356356

357357
[<Fact>]
358-
let ``syntax-FSC_OPTIMIZED`` () = singleTestBuildAndRun "core/syntax" FSC_OPTIMIZED
358+
let ``syntax-FSC_OPTIMIZED`` () = singleTestBuildAndRunIsolated "core/syntax" FSC_OPTIMIZED
359359

360360
[<Fact>]
361-
let ``syntax-FSI`` () = singleTestBuildAndRun "core/syntax" FSI
361+
let ``syntax-FSI`` () = singleTestBuildAndRunIsolated "core/syntax" FSI
362362

363363
[<Fact>]
364364
let ``test int32-FSC_DEBUG`` () = singleTestBuildAndRun "core/int32" FSC_DEBUG
@@ -453,10 +453,10 @@ let ``fsi_load-FSC_OPTIMIZED`` () = singleTestBuildAndRun "core/fsi-load" FSC_OP
453453
let ``fsi_load-FSI`` () = singleTestBuildAndRun "core/fsi-load" FSI
454454

455455
[<Fact>]
456-
let ``reflect-FSC_OPTIMIZED`` () = singleTestBuildAndRun "core/reflect" FSC_OPTIMIZED
456+
let ``reflect-FSC_OPTIMIZED`` () = singleTestBuildAndRunIsolated "core/reflect" FSC_OPTIMIZED
457457

458458
[<Fact>]
459-
let ``reflect-FSI`` () = singleTestBuildAndRun "core/reflect" FSI
459+
let ``reflect-FSI`` () = singleTestBuildAndRunIsolated "core/reflect" FSI
460460

461461
let isWindows = RuntimeInformation.IsOSPlatform(OSPlatform.Windows)
462462

tests/FSharp.Test.Utilities/Compiler.fs

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ open FSharp.Compiler.IO
77
open FSharp.Compiler.Diagnostics
88
open FSharp.Compiler.Symbols
99
open FSharp.Compiler.Text
10+
open FSharp.Compiler.Caches
1011
open FSharp.Test.Assert
1112
open FSharp.Test.Utilities
1213
open FSharp.Test.ScriptHelpers
@@ -1154,7 +1155,16 @@ module rec Compiler =
11541155
evalFSharp fs script
11551156
| _ -> failwith "Script evaluation is only supported for F#."
11561157

1157-
let getSessionForEval args version = new FSharpScript(additionalArgs=args,quiet=true,langVersion=version)
1158+
let internal sessionCache = Cache.Create<Set<string> * LangVersion, FSharpScript>()
1159+
1160+
let getSessionForEval args version =
1161+
let key = Set args, version
1162+
match sessionCache.TryGetValue(key) with
1163+
| true, script -> script
1164+
| _ ->
1165+
let script = new FSharpScript(additionalArgs=args,quiet=true,langVersion=version)
1166+
sessionCache.TryAdd(key, script) |> ignore
1167+
script
11581168

11591169
let evalInSharedSession (script:FSharpScript) (cUnit: CompilationUnit) : CompilationResult =
11601170
match cUnit with

tests/FSharp.Test.Utilities/ScriptHelpers.fs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,9 @@ type FSharpScript(?additionalArgs: string[], ?quiet: bool, ?langVersion: LangVer
6464
Thread.CurrentThread.CurrentCulture <- Option.defaultValue Globalization.CultureInfo.InvariantCulture desiredCulture
6565

6666
let cancellationToken = defaultArg cancellationToken CancellationToken.None
67-
let ch, errors = fsi.EvalInteractionNonThrowing(code, cancellationToken)
67+
let ch, errors =
68+
lock fsi <| fun () ->
69+
fsi.EvalInteractionNonThrowing(code, cancellationToken)
6870

6971
Thread.CurrentThread.CurrentCulture <- originalCulture
7072

0 commit comments

Comments
 (0)