aboutsummaryrefslogtreecommitdiff
path: root/src/dotty/tools/dotc/core/Annotations.scala
diff options
context:
space:
mode:
authorMartin Odersky <odersky@gmail.com>2014-02-24 15:37:14 +0100
committerMartin Odersky <odersky@gmail.com>2014-02-24 18:56:48 +0100
commited7755b781bd1b444d38329cb22eacaa3fc1c005 (patch)
tree2eb43f71741310e77248111f5fa5c39203e33c8d /src/dotty/tools/dotc/core/Annotations.scala
parentcdeafeafd252b20a0df5440e0420211af95e0cdc (diff)
downloaddotty-ed7755b781bd1b444d38329cb22eacaa3fc1c005.tar.gz
dotty-ed7755b781bd1b444d38329cb22eacaa3fc1c005.tar.bz2
dotty-ed7755b781bd1b444d38329cb22eacaa3fc1c005.zip
Avoid memory leaks on repeated compilation.
Several measures: 1. Invalidate classOfId and superIdOfClass in ContextBase after each run. These contain local classes that should become inaccessible. 2. Also clear implicitScope cache that maps types to their implicit scopes after each run. (not sure whether this is needed; it did show up in paths from root, but on second thought this might have been a gc-able cycle. 3. Avoid capturing contexts in lazy annotations. 4. Avoid capturing contexts in functions that compute souceModule and moduleClass 5. Avoid capturing contexts in Unpickler's postReadOp hook.
Diffstat (limited to 'src/dotty/tools/dotc/core/Annotations.scala')
-rw-r--r--src/dotty/tools/dotc/core/Annotations.scala22
1 files changed, 12 insertions, 10 deletions
diff --git a/src/dotty/tools/dotc/core/Annotations.scala b/src/dotty/tools/dotc/core/Annotations.scala
index 562974c48..947593ca4 100644
--- a/src/dotty/tools/dotc/core/Annotations.scala
+++ b/src/dotty/tools/dotc/core/Annotations.scala
@@ -6,22 +6,24 @@ import Symbols._, Types._, util.Positions._, Contexts._, Constants._, ast.tpd._
object Annotations {
abstract class Annotation {
- def tree: Tree
+ def tree(implicit ctx: Context): Tree
def symbol(implicit ctx: Context): Symbol = tree.tpe.typeSymbol
def matches(cls: Symbol)(implicit ctx: Context): Boolean = symbol.derivesFrom(cls)
def appliesToModule: Boolean = true // for now; see remark in SymDenotations
- def derivedAnnotation(tree: Tree) =
+ def derivedAnnotation(tree: Tree)(implicit ctx: Context) =
if (tree eq this.tree) this else Annotation(tree)
}
- case class ConcreteAnnotation(val tree: Tree) extends Annotation
+ case class ConcreteAnnotation(t: Tree) extends Annotation {
+ def tree(implicit ctx: Context): Tree = t
+ }
- case class LazyAnnotation(sym: Symbol)(treeFn: => Tree) extends Annotation {
- private var _tree: Tree = null
- def tree = {
- if (_tree == null) _tree = treeFn
- _tree
+ case class LazyAnnotation(sym: Symbol)(treeFn: Context => Tree) extends Annotation {
+ private var myTree: Tree = null
+ def tree(implicit ctx: Context) = {
+ if (myTree == null) myTree = treeFn(ctx)
+ myTree
}
override def symbol(implicit ctx: Context): Symbol = sym
}
@@ -48,11 +50,11 @@ object Annotations {
def apply(atp: Type, args: List[Tree])(implicit ctx: Context): Annotation =
apply(New(atp, args))
- def deferred(sym: Symbol, treeFn: => Tree): Annotation =
+ def deferred(sym: Symbol, treeFn: Context => Tree)(implicit ctx: Context): Annotation =
new LazyAnnotation(sym)(treeFn)
def deferred(atp: Type, args: List[Tree])(implicit ctx: Context): Annotation =
- deferred(atp.classSymbol, New(atp, args))
+ deferred(atp.classSymbol, implicit ctx => New(atp, args))
def makeAlias(sym: TermSymbol)(implicit ctx: Context) =
apply(defn.AliasAnnot, List(Ident(TermRef.withSig(sym.owner.thisType, sym.name, sym.signature, sym))))