From 38e707849c1f8fad4bf662ea66a2922fb67c635f Mon Sep 17 00:00:00 2001 From: Iulian Dragos Date: Mon, 23 Aug 2010 08:52:50 +0000 Subject: More robust icode loading and fixed an issue wh... More robust icode loading and fixed an issue when dead-code eliminating closures that have live static fields. --- .../scala/tools/nsc/backend/icode/BasicBlocks.scala | 2 +- .../scala/tools/nsc/backend/icode/Repository.scala | 19 +++++++++++++------ .../tools/nsc/backend/opt/ClosureElimination.scala | 2 +- .../tools/nsc/backend/opt/DeadCodeElimination.scala | 9 +++++++++ .../scala/tools/nsc/backend/opt/Inliners.scala | 2 +- .../tools/nsc/symtab/classfile/ClassfileParser.scala | 1 + .../tools/nsc/symtab/classfile/ICodeReader.scala | 2 +- 7 files changed, 27 insertions(+), 10 deletions(-) (limited to 'src') diff --git a/src/compiler/scala/tools/nsc/backend/icode/BasicBlocks.scala b/src/compiler/scala/tools/nsc/backend/icode/BasicBlocks.scala index 91e1b4eb8a..9b0e52ffac 100644 --- a/src/compiler/scala/tools/nsc/backend/icode/BasicBlocks.scala +++ b/src/compiler/scala/tools/nsc/backend/icode/BasicBlocks.scala @@ -385,7 +385,7 @@ trait BasicBlocks { /** Close the block */ def close { - assert(!closed) + assert(!closed || ignore) assert(instructionList.length > 0, "Empty block.") closed = true setFlag(DIRTYSUCCS) diff --git a/src/compiler/scala/tools/nsc/backend/icode/Repository.scala b/src/compiler/scala/tools/nsc/backend/icode/Repository.scala index 78a47e129c..fe1a514094 100644 --- a/src/compiler/scala/tools/nsc/backend/icode/Repository.scala +++ b/src/compiler/scala/tools/nsc/backend/icode/Repository.scala @@ -42,11 +42,18 @@ trait Repository { } /** Load bytecode for given symbol. */ - private def load(sym: Symbol) { - val (c1, c2) = icodeReader.readClass(sym) - - assert(c1.symbol == sym || c2.symbol == sym) - loaded += (c1.symbol -> c1) - loaded += (c2.symbol -> c2) + def load(sym: Symbol) { + try { + val (c1, c2) = icodeReader.readClass(sym) + + assert(c1.symbol == sym || c2.symbol == sym, "c1.symbol = %s, c2.symbol = %s, sym = %s".format(c1.symbol, c2.symbol, sym)) + loaded += (c1.symbol -> c1) + loaded += (c2.symbol -> c2) + } catch { + case e: MissingRequirementError => + log("Failed to load %s. [%s]".format(sym.fullName, e.getMessage)) + if (settings.debug.value) + e.printStackTrace + } } } diff --git a/src/compiler/scala/tools/nsc/backend/opt/ClosureElimination.scala b/src/compiler/scala/tools/nsc/backend/opt/ClosureElimination.scala index bbb84430c4..fc824bb8cd 100644 --- a/src/compiler/scala/tools/nsc/backend/opt/ClosureElimination.scala +++ b/src/compiler/scala/tools/nsc/backend/opt/ClosureElimination.scala @@ -48,7 +48,7 @@ abstract class ClosureElimination extends SubComponent { idx -= 1 } if (!liveOut(x)) { - println("removing dead store/load " + x) + log("removing dead store/load " + x) Some(Nil) } else None } else diff --git a/src/compiler/scala/tools/nsc/backend/opt/DeadCodeElimination.scala b/src/compiler/scala/tools/nsc/backend/opt/DeadCodeElimination.scala index 589425298f..4149ef2ab6 100644 --- a/src/compiler/scala/tools/nsc/backend/opt/DeadCodeElimination.scala +++ b/src/compiler/scala/tools/nsc/backend/opt/DeadCodeElimination.scala @@ -160,6 +160,15 @@ abstract class DeadCodeElimination extends SubComponent { if (inliner.isClosureClass(sym)) { liveClosures += sym } + + // it may be better to move static initializers from closures to + // the enclosing class, to allow the optimizer to remove more closures. + // right now, the only static fields in closures are created when caching + // 'symbol literals. + case LOAD_FIELD(sym, true) if inliner.isClosureClass(sym.owner) => + log("added closure class for field " + sym) + liveClosures += sym.owner + case LOAD_EXCEPTION() => () diff --git a/src/compiler/scala/tools/nsc/backend/opt/Inliners.scala b/src/compiler/scala/tools/nsc/backend/opt/Inliners.scala index c0146bcd0c..f662a40a26 100644 --- a/src/compiler/scala/tools/nsc/backend/opt/Inliners.scala +++ b/src/compiler/scala/tools/nsc/backend/opt/Inliners.scala @@ -142,7 +142,7 @@ abstract class Inliners extends SubComponent { } if (shouldLoadImplFor(concreteMethod, receiver)) - icodes.icode(concreteMethod.enclClass, true) + icodes.load(concreteMethod.enclClass) def isAvailable = icodes available concreteMethod.enclClass def isCandidate = isClosureClass(receiver) || concreteMethod.isEffectivelyFinal || receiver.isFinal diff --git a/src/compiler/scala/tools/nsc/symtab/classfile/ClassfileParser.scala b/src/compiler/scala/tools/nsc/symtab/classfile/ClassfileParser.scala index 244df8179a..5a9b3f57cc 100644 --- a/src/compiler/scala/tools/nsc/symtab/classfile/ClassfileParser.scala +++ b/src/compiler/scala/tools/nsc/symtab/classfile/ClassfileParser.scala @@ -82,6 +82,7 @@ abstract class ClassfileParser { println("Skipping class: " + root + ": " + root.getClass) } */ + log("parsing " + file.name) this.in = new AbstractFileReader(file) if (root.isModule) { this.clazz = root.companionClass diff --git a/src/compiler/scala/tools/nsc/symtab/classfile/ICodeReader.scala b/src/compiler/scala/tools/nsc/symtab/classfile/ICodeReader.scala index 0a6f208f54..95a0c2b53d 100644 --- a/src/compiler/scala/tools/nsc/symtab/classfile/ICodeReader.scala +++ b/src/compiler/scala/tools/nsc/symtab/classfile/ICodeReader.scala @@ -51,7 +51,7 @@ abstract class ICodeReader extends ClassfileParser { classPath.findSourceFile(name) match { case Some(classFile) => parse(classFile, sym) - case _ => log("Could not find: " + cls) + case _ => throw new MissingRequirementError("Could not find bytecode for " + cls) } (staticCode, instanceCode) -- cgit v1.2.3