diff options
author | Iulian Dragos <jaguarul@gmail.com> | 2010-08-23 08:52:50 +0000 |
---|---|---|
committer | Iulian Dragos <jaguarul@gmail.com> | 2010-08-23 08:52:50 +0000 |
commit | 38e707849c1f8fad4bf662ea66a2922fb67c635f (patch) | |
tree | 5884f7d8c4dd3f097b9c9b32372b9ff22fcdb66c | |
parent | 081b8388975e12c232e296358235747e33e88168 (diff) | |
download | scala-38e707849c1f8fad4bf662ea66a2922fb67c635f.tar.gz scala-38e707849c1f8fad4bf662ea66a2922fb67c635f.tar.bz2 scala-38e707849c1f8fad4bf662ea66a2922fb67c635f.zip |
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.
7 files changed, 27 insertions, 10 deletions
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) |