summaryrefslogtreecommitdiff
path: root/src/compiler/scala/tools/nsc/backend/opt/ClosureElimination.scala
diff options
context:
space:
mode:
authorJason Zaugg <jzaugg@gmail.com>2014-05-18 12:01:17 +0200
committerJason Zaugg <jzaugg@gmail.com>2014-05-19 22:27:50 +0200
commitccc5eef051c8588c1fe4029e832d5b6387976aa6 (patch)
tree8bb35044f3f935e82c6db343252f970a3cf8953c /src/compiler/scala/tools/nsc/backend/opt/ClosureElimination.scala
parent5b1d43d8ffda4b5881df7ce6634a7adebbb02f21 (diff)
downloadscala-ccc5eef051c8588c1fe4029e832d5b6387976aa6.tar.gz
scala-ccc5eef051c8588c1fe4029e832d5b6387976aa6.tar.bz2
scala-ccc5eef051c8588c1fe4029e832d5b6387976aa6.zip
SI-8601 Avoid over-eager optimization of LOAD_FIELD
It can NPE or trigger static class initilization, we can't elimiate it without changing semantics. To make sure we don't thwart closure elimination, I've allowed DCE to eliminate a non-static LOAD_FIELD of a member of a closure class. It would be more general to track nullity of the reciever (e.g, `this` or `new Foo` cannot be null), but that would require more infrastructure in this phase. I've added a test for closure inlining based on a a suggestion by @dragos. This actually passes if we remove the (LOAD_FIELD, DROP) peephole optimization for `closelim` altogether. But I chose to adapt that optimization (only allow it for non-static, closure fields), rather then remove it alogether, in the interests of treading lightly.
Diffstat (limited to 'src/compiler/scala/tools/nsc/backend/opt/ClosureElimination.scala')
-rw-r--r--src/compiler/scala/tools/nsc/backend/opt/ClosureElimination.scala7
1 files changed, 2 insertions, 5 deletions
diff --git a/src/compiler/scala/tools/nsc/backend/opt/ClosureElimination.scala b/src/compiler/scala/tools/nsc/backend/opt/ClosureElimination.scala
index c49f23852f..a866173a88 100644
--- a/src/compiler/scala/tools/nsc/backend/opt/ClosureElimination.scala
+++ b/src/compiler/scala/tools/nsc/backend/opt/ClosureElimination.scala
@@ -56,11 +56,8 @@ abstract class ClosureElimination extends SubComponent {
case (BOX(t1), UNBOX(t2)) if (t1 == t2) =>
Some(Nil)
- case (LOAD_FIELD(sym, isStatic), DROP(_)) if !sym.hasAnnotation(definitions.VolatileAttr) =>
- if (isStatic)
- Some(Nil)
- else
- Some(DROP(REFERENCE(definitions.ObjectClass)) :: Nil)
+ case (LOAD_FIELD(sym, /* isStatic */false), DROP(_)) if !sym.hasAnnotation(definitions.VolatileAttr) && inliner.isClosureClass(sym.owner) =>
+ Some(DROP(REFERENCE(definitions.ObjectClass)) :: Nil)
case _ => None
}