summaryrefslogtreecommitdiff
path: root/src/compiler
diff options
context:
space:
mode:
authorPaul Phillips <paulp@improving.org>2013-11-04 16:51:20 -0800
committerPaul Phillips <paulp@improving.org>2013-11-04 16:51:20 -0800
commit075f6f260ccfba83b118c308195d1ede2e66ad18 (patch)
tree9b3720df7575e52da14c5a7a0854d4fc1f290e39 /src/compiler
parent05681d4def04f290728e673b7856a57b872c8019 (diff)
downloadscala-075f6f260ccfba83b118c308195d1ede2e66ad18.tar.gz
scala-075f6f260ccfba83b118c308195d1ede2e66ad18.tar.bz2
scala-075f6f260ccfba83b118c308195d1ede2e66ad18.zip
SI-6546 InnerClasses attribute refers to absent class
At issue is that the optimizer would eliminate closure classes completely, then neglect to eliminate those classes from the container's InnerClasses attribute. This breaks tooling which expects those entries to correspond to real classes. The code change is essentially mgarcia's - I minimized it and put the caches in perRunCaches, and added the test case which verifies that after being compiled under -optimise, there are no inner classes. Before/after: 7,8d6 < InnerClasses: < public final #22; //class A_1$$anonfun$f$1 37,45c35,40 < #21 = Utf8 A_1$$anonfun$f$1 < #22 = Class #21 // A_1$$anonfun$f$1 < #23 = Utf8 Code --- > #21 = Utf8 Code
Diffstat (limited to 'src/compiler')
-rw-r--r--src/compiler/scala/tools/nsc/backend/jvm/GenASM.scala4
-rw-r--r--src/compiler/scala/tools/nsc/backend/opt/DeadCodeElimination.scala8
2 files changed, 10 insertions, 2 deletions
diff --git a/src/compiler/scala/tools/nsc/backend/jvm/GenASM.scala b/src/compiler/scala/tools/nsc/backend/jvm/GenASM.scala
index 7c46d648fe..97140aca2e 100644
--- a/src/compiler/scala/tools/nsc/backend/jvm/GenASM.scala
+++ b/src/compiler/scala/tools/nsc/backend/jvm/GenASM.scala
@@ -86,6 +86,7 @@ abstract class GenASM extends SubComponent with BytecodeWriters with GenJVMASM {
if (settings.Xdce.value)
for ((sym, cls) <- icodes.classes if inliner.isClosureClass(sym) && !deadCode.liveClosures(sym)) {
log(s"Optimizer eliminated ${sym.fullNameString}")
+ deadCode.elidedClosures += sym
icodes.classes -= sym
}
@@ -624,7 +625,8 @@ abstract class GenASM extends SubComponent with BytecodeWriters with GenJVMASM {
innerClassBuffer += m
}
- val allInners: List[Symbol] = innerClassBuffer.toList
+ val allInners: List[Symbol] = innerClassBuffer.toList filterNot deadCode.elidedClosures
+
if (allInners.nonEmpty) {
debuglog(csym.fullName('.') + " contains " + allInners.size + " inner classes.")
diff --git a/src/compiler/scala/tools/nsc/backend/opt/DeadCodeElimination.scala b/src/compiler/scala/tools/nsc/backend/opt/DeadCodeElimination.scala
index 1beed3f420..db56f61f16 100644
--- a/src/compiler/scala/tools/nsc/backend/opt/DeadCodeElimination.scala
+++ b/src/compiler/scala/tools/nsc/backend/opt/DeadCodeElimination.scala
@@ -40,7 +40,13 @@ abstract class DeadCodeElimination extends SubComponent {
}
/** closures that are instantiated at least once, after dead code elimination */
- val liveClosures: mutable.Set[Symbol] = new mutable.HashSet()
+ val liveClosures = perRunCaches.newSet[Symbol]()
+
+ /** closures that are eliminated, populated by GenASM.AsmPhase.run()
+ * these class symbols won't have a .class physical file, thus shouldn't be included in InnerClasses JVM attribute,
+ * otherwise some tools get confused or slow (SI-6546)
+ * */
+ val elidedClosures = perRunCaches.newSet[Symbol]()
/** Remove dead code.
*/