Skip to content

Commit

Permalink
Avoid memory leaks in InlineAccessors
Browse files Browse the repository at this point in the history
Make sure that `AccessProxies.accessedBy` can be GCed.
  • Loading branch information
nicolasstucki committed Sep 9, 2021
1 parent bd83faf commit 1c0bf3f
Show file tree
Hide file tree
Showing 6 changed files with 19 additions and 7 deletions.
3 changes: 0 additions & 3 deletions compiler/src/dotty/tools/dotc/CompilationUnit.scala
Original file line number Diff line number Diff line change
Expand Up @@ -56,9 +56,6 @@ class CompilationUnit protected (val source: SourceFile) {
*/
var needsQuotePickling: Boolean = false

/** A structure containing a temporary map for generating inline accessors */
val inlineAccessors: InlineAccessors = new InlineAccessors

var suspended: Boolean = false
var suspendedAtInliningPhase: Boolean = false

Expand Down
1 change: 1 addition & 0 deletions compiler/src/dotty/tools/dotc/transform/Inlining.scala
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import SymUtils._
import NameKinds._
import dotty.tools.dotc.ast.tpd
import typer.Implicits.SearchFailureType
import typer.PrepareInlineable

import scala.collection.mutable
import dotty.tools.dotc.core.Annotations._
Expand Down
15 changes: 14 additions & 1 deletion compiler/src/dotty/tools/dotc/typer/PrepareInlineable.scala
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,19 @@ import dotty.tools.dotc.transform.TreeMapWithStages._
object PrepareInlineable {
import tpd._

private val InlineAccessorsKey = new Property.Key[InlineAccessors]

def initContext(ctx: Context): Context =
ctx.fresh.setProperty(InlineAccessorsKey, new InlineAccessors)

def makeInlineable(tree: Tree)(using Context): Tree =
ctx.property(InlineAccessorsKey).get.makeInlineable(tree)

def addAccessorDefs(cls: Symbol, body: List[Tree])(using Context): List[Tree] =
ctx.property(InlineAccessorsKey) match
case Some(inlineAccessors) => inlineAccessors.addAccessorDefs(cls, body)
case _ => body

class InlineAccessors extends AccessProxies {

/** If an inline accessor name wraps a unique inline name, this is taken as indication
Expand Down Expand Up @@ -251,7 +264,7 @@ object PrepareInlineable {
if inlined.isInlineMethod then
inlinedBody = dropInlineIfError(inlined,
checkInlineMethod(inlined,
ctx.compilationUnit.inlineAccessors.makeInlineable(inlinedBody)))
PrepareInlineable.makeInlineable(inlinedBody)))
inlining.println(i"Body to inline for $inlined: $inlinedBody")
inlinedBody
})
Expand Down
2 changes: 1 addition & 1 deletion compiler/src/dotty/tools/dotc/typer/QuotesAndSplices.scala
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ trait QuotesAndSplices {
}

private def makeInlineable(tree: Tree)(using Context): Tree =
ctx.compilationUnit.inlineAccessors.makeInlineable(tree)
PrepareInlineable.makeInlineable(tree)

/** Translate `${ t: Expr[T] }` into expression `t.splice` while tracking the quotation level in the context */
def typedSplice(tree: untpd.Splice, pt: Type)(using Context): Tree = {
Expand Down
2 changes: 1 addition & 1 deletion compiler/src/dotty/tools/dotc/typer/Typer.scala
Original file line number Diff line number Diff line change
Expand Up @@ -2461,7 +2461,7 @@ class Typer extends Namer
// 4. Polymorphic type defs override nothing.

protected def addAccessorDefs(cls: Symbol, body: List[Tree])(using Context): List[Tree] =
ctx.compilationUnit.inlineAccessors.addAccessorDefs(cls, body)
PrepareInlineable.addAccessorDefs(cls, body)

/** If this is a real class, make sure its first parent is a
* constructor call. Cannot simply use a type. Overridden in ReTyper.
Expand Down
3 changes: 2 additions & 1 deletion compiler/src/dotty/tools/dotc/typer/TyperPhase.scala
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,8 @@ class TyperPhase(addRootImports: Boolean = true) extends Phase {
override def runOn(units: List[CompilationUnit])(using Context): List[CompilationUnit] =
val unitContexts =
for unit <- units yield
val newCtx = ctx.fresh.setPhase(this.start).setCompilationUnit(unit)
val newCtx0 = ctx.fresh.setPhase(this.start).setCompilationUnit(unit)
val newCtx = PrepareInlineable.initContext(newCtx0)
report.inform(s"typing ${unit.source}")
if (addRootImports)
newCtx.withRootImports
Expand Down

0 comments on commit 1c0bf3f

Please sign in to comment.