Skip to content

Commit 93e7fd3

Browse files
committed
Make owningState a weak reference
`owningState` of `TypeVar` was still a source of memory leaks even though we null it out when a TypeVar gets instantiated. The problem is that uninstantiated TypeVars can sit as parts of types in caches.
1 parent d1486a5 commit 93e7fd3

File tree

2 files changed

+6
-5
lines changed

2 files changed

+6
-5
lines changed

compiler/src/dotty/tools/dotc/core/TyperState.scala

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ import printing.{Showable, Printer}
1111
import printing.Texts._
1212
import config.Config
1313
import collection.mutable
14+
import java.lang.ref.WeakReference
1415

1516
class TyperState(r: Reporter) extends DotClass with Showable {
1617

@@ -143,8 +144,7 @@ extends TyperState(r) {
143144
if (targetState.constraint eq previousConstraint) constraint
144145
else targetState.constraint & constraint
145146
constraint foreachTypeVar { tvar =>
146-
if (tvar.owningState eq this)
147-
tvar.owningState = targetState
147+
if (tvar.owningState.get eq this) tvar.owningState = new WeakReference(targetState)
148148
}
149149
targetState.ephemeral |= ephemeral
150150
targetState.gc()
@@ -157,7 +157,7 @@ extends TyperState(r) {
157157
constraint foreachTypeVar { tvar =>
158158
if (!tvar.inst.exists) {
159159
val inst = instType(tvar)
160-
if (inst.exists && (tvar.owningState eq this)) {
160+
if (inst.exists && (tvar.owningState.get eq this)) {
161161
tvar.inst = inst
162162
val lam = tvar.origin.binder
163163
if (constraint.isRemovable(lam)) toCollect += lam

compiler/src/dotty/tools/dotc/core/Types.scala

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ import Flags.FlagSet
3636
import language.implicitConversions
3737
import scala.util.hashing.{ MurmurHash3 => hashing }
3838
import config.Printers.{core, typr, cyclicErrors}
39+
import java.lang.ref.WeakReference
3940

4041
object Types {
4142

@@ -3186,7 +3187,7 @@ object Types {
31863187
/** The state owning the variable. This is at first `creatorState`, but it can
31873188
* be changed to an enclosing state on a commit.
31883189
*/
3189-
private[core] var owningState = creatorState
3190+
private[core] var owningState = new WeakReference(creatorState)
31903191

31913192
/** The instance type of this variable, or NoType if the variable is currently
31923193
* uninstantiated
@@ -3204,7 +3205,7 @@ object Types {
32043205
private def instantiateWith(tp: Type)(implicit ctx: Context): Type = {
32053206
assert(tp ne this, s"self instantiation of ${tp.show}, constraint = ${ctx.typerState.constraint.show}")
32063207
typr.println(s"instantiating ${this.show} with ${tp.show}")
3207-
if ((ctx.typerState eq owningState) && !ctx.typeComparer.subtypeCheckInProgress)
3208+
if ((ctx.typerState eq owningState.get) && !ctx.typeComparer.subtypeCheckInProgress)
32083209
inst = tp
32093210
ctx.typerState.constraint = ctx.typerState.constraint.replace(origin, tp)
32103211
tp

0 commit comments

Comments
 (0)