Skip to content

Commit e22f124

Browse files
committed
memoize only stable structures
1 parent 73c80ff commit e22f124

File tree

2 files changed

+35
-14
lines changed

2 files changed

+35
-14
lines changed

src/Compiler/Checking/TypeRelations.fs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,8 @@ type TTypeCacheKey =
3131
static member TryGetFromStrippedTypes(ty1, ty2, canCoerce) =
3232
let tryGetTypeStructure ty =
3333
match ty with
34-
| TType_app _ -> tryGetTypeStructureOfStrippedType ty
34+
| TType_app _ ->
35+
tryGetTypeStructureOfStrippedType ty
3536
| _ -> ValueNone
3637

3738
(tryGetTypeStructure ty1, tryGetTypeStructure ty2)

src/Compiler/Utilities/TypeHashing.fs

Lines changed: 33 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -385,6 +385,7 @@ module HashTastMemberOrVals =
385385
///
386386
/// </summary>
387387
module StructuralUtilities =
388+
open Internal.Utilities.Library.Extras
388389

389390
[<Struct; NoComparison; RequireQualifiedAccess>]
390391
type TypeToken =
@@ -399,17 +400,23 @@ module StructuralUtilities =
399400
| Unsolved of int
400401
| Rigid of int
401402

402-
type TypeStructure = TypeStructure of TypeToken[]
403+
type TypeStructure =
404+
| Stable of TypeToken[]
405+
| Unstable of TypeToken[]
406+
| PossiblyInfinite
403407

404408
type private EmitContext =
405409
{
406410
typarMap: System.Collections.Generic.Dictionary<Stamp, int>
411+
mutable stable: bool
407412
}
408413

409-
let inline emitNullness (n: Nullness) =
414+
let private emitNullness env (n: Nullness) =
410415
match n.TryEvaluate() with
411416
| ValueSome k -> TypeToken.Nullness k
412-
| ValueNone -> TypeToken.NullnessUnsolved
417+
| ValueNone ->
418+
env.stable <- false
419+
TypeToken.NullnessUnsolved
413420

414421
let rec private emitMeasure (m: Measure) =
415422
seq {
@@ -438,7 +445,7 @@ module StructuralUtilities =
438445

439446
| TType_app(tcref, tinst, n) ->
440447
TypeToken.Stamp tcref.Stamp
441-
emitNullness n
448+
emitNullness env n
442449

443450
for arg in tinst do
444451
yield! emitTType env arg
@@ -466,10 +473,10 @@ module StructuralUtilities =
466473
| TType_fun(d, r, n) ->
467474
yield! emitTType env d
468475
yield! emitTType env r
469-
emitNullness n
476+
emitNullness env n
470477

471478
| TType_var(r, n) ->
472-
emitNullness n
479+
emitNullness env n
473480

474481
let typarId =
475482
match env.typarMap.TryGetValue r.Stamp with
@@ -480,21 +487,22 @@ module StructuralUtilities =
480487
idx
481488

482489
match r.Solution with
483-
| Some ty ->
484-
yield! emitTType env ty
490+
| Some ty -> yield! emitTType env ty
485491
| None ->
486492
if r.Rigidity = TyparRigidity.Rigid then
487493
TypeToken.Rigid typarId
488494
else
495+
env.stable <- false
489496
TypeToken.Unsolved typarId
490497
| TType_measure m -> yield! emitMeasure m
491498
}
492499

493-
let tryGetTypeStructureOfStrippedType (ty: TType) =
500+
let private getTypeStructureOfStrippedType (ty: TType) =
494501

495502
let env =
496503
{
497504
typarMap = System.Collections.Generic.Dictionary<Stamp, int>()
505+
stable = true
498506
}
499507

500508
let tokens =
@@ -504,7 +512,19 @@ module StructuralUtilities =
504512
|> Seq.toArray
505513

506514
// If the sequence got too long, just drop it, we could be dealing with an infinite type.
507-
if tokens.Length = 256 then
508-
ValueNone
509-
else
510-
ValueSome(TypeStructure tokens)
515+
if tokens.Length = 256 then PossiblyInfinite
516+
elif not env.stable then Unstable tokens
517+
else Stable tokens
518+
519+
let tryGetTypeStructureOfStrippedType ty =
520+
// Speed up repeated calls by memoizing results for types that yield a stable structure.
521+
let memoize =
522+
WeakMap.cacheConditionally
523+
(function
524+
| Stable _ -> true
525+
| _ -> false)
526+
getTypeStructureOfStrippedType
527+
528+
match memoize ty with
529+
| PossiblyInfinite -> ValueNone
530+
| ts -> ValueSome ts

0 commit comments

Comments
 (0)