diff options
author | Iulian Dragos <jaguarul@gmail.com> | 2008-10-27 16:25:50 +0000 |
---|---|---|
committer | Iulian Dragos <jaguarul@gmail.com> | 2008-10-27 16:25:50 +0000 |
commit | d1bf566ad6bc231ebcb43a59b736497e35ba4b97 (patch) | |
tree | fa59cfdb2fcbaad3c77e454522176eb059d5b2b7 /src/compiler | |
parent | cc97afe49feb585819abf0b5ae6fc25c34e349df (diff) | |
download | scala-d1bf566ad6bc231ebcb43a59b736497e35ba4b97.tar.gz scala-d1bf566ad6bc231ebcb43a59b736497e35ba4b97.tar.bz2 scala-d1bf566ad6bc231ebcb43a59b736497e35ba4b97.zip |
Fixed optimization phases (#1379).
Diffstat (limited to 'src/compiler')
6 files changed, 36 insertions, 15 deletions
diff --git a/src/compiler/scala/tools/nsc/backend/icode/BasicBlocks.scala b/src/compiler/scala/tools/nsc/backend/icode/BasicBlocks.scala index b50bb8aebc..d3ea32d8bc 100644 --- a/src/compiler/scala/tools/nsc/backend/icode/BasicBlocks.scala +++ b/src/compiler/scala/tools/nsc/backend/icode/BasicBlocks.scala @@ -412,7 +412,23 @@ trait BasicBlocks { method.exh.foreach { e: ExceptionHandler => if (e.covers(this)) res = e.startBlock :: res } - res + res ++ exceptionalSucc(this, res) + } + + /** Return a list of successors for 'b' that come from exception handlers + * covering b's (non-exceptional) successors. These exception handlers + * might not cover 'b' itself. This situation corresponds to an + * exception being thrown as the first thing of one of b's successors. + */ + private def exceptionalSucc(b: BasicBlock, succs: List[BasicBlock]): List[BasicBlock] = { + def findSucc(s: BasicBlock): List[BasicBlock] = { + val ss = method.exh flatMap { h => + if (h.covers(s)) List(h.startBlock) else Nil + } + ss ++ (ss flatMap findSucc) + } + + succs.flatMap(findSucc).removeDuplicates } /** Returns the precessors of this block, in the current 'code' chunk. @@ -468,6 +484,6 @@ object BBFlags { /** This block is closed. No new instructions can be added. */ final val CLOSED = 0x00000008 - /** This block has been changed, chached results are recomputed. */ + /** This block has been changed, cached results are recomputed. */ final val TOUCHED = 0x00000010 } diff --git a/src/compiler/scala/tools/nsc/backend/icode/Checkers.scala b/src/compiler/scala/tools/nsc/backend/icode/Checkers.scala index 23cc47f06a..dc435bd2e9 100644 --- a/src/compiler/scala/tools/nsc/backend/icode/Checkers.scala +++ b/src/compiler/scala/tools/nsc/backend/icode/Checkers.scala @@ -67,11 +67,11 @@ abstract class Checkers { val STRING = REFERENCE(definitions.StringClass) val SCALA_ALL = REFERENCE(definitions.NothingClass) val SCALA_ALL_REF = REFERENCE(definitions.NullClass) -// val CASE_CLASS = REFERENCE(definitions.getClass("scala.CaseClass")) + val THROWABLE = REFERENCE(definitions.ThrowableClass) def checkICodes: Unit = { if (settings.verbose.value) - Console.println("[[consistency check at the beginning of phase " + globalPhase.name + "]]") + println("[[consistency check at the beginning of phase " + globalPhase.name + "]]") classes.values foreach check } @@ -555,6 +555,12 @@ abstract class Checkers { stack.pop stack.push(kind) + case LOAD_EXCEPTION() => + stack.push(THROWABLE) + + case SCOPE_ENTER(_) | SCOPE_EXIT(_) => + () + case _ => abort("Unknown instruction: " + instr) } diff --git a/src/compiler/scala/tools/nsc/backend/icode/ExceptionHandlers.scala b/src/compiler/scala/tools/nsc/backend/icode/ExceptionHandlers.scala index 8c6d9a4490..94db998bff 100644 --- a/src/compiler/scala/tools/nsc/backend/icode/ExceptionHandlers.scala +++ b/src/compiler/scala/tools/nsc/backend/icode/ExceptionHandlers.scala @@ -7,8 +7,7 @@ package scala.tools.nsc.backend.icode; -import scala.collection.mutable.HashMap; -import scala.collection.mutable.HashSet; +import scala.collection._ /** * Exception handlers are pieces of code that `handle' exceptions on @@ -34,15 +33,15 @@ trait ExceptionHandlers { self: ICodes => def startBlock = _startBlock; /** The list of blocks that are covered by this exception handler */ - var covered: List[BasicBlock] = Nil; + var covered: immutable.Set[BasicBlock] = immutable.HashSet.empty[BasicBlock] def addCoveredBlock(b: BasicBlock): ExceptionHandler = { - covered = b :: covered; + covered = covered + b this } /** Is `b' covered by this exception handler? */ - def covers(b: BasicBlock): Boolean = covered.contains(b); + def covers(b: BasicBlock): Boolean = covered(b); /** The body of this exception handler. May contain 'dead' blocks (which will not * make it into generated code because linearizers may not include them) */ diff --git a/src/compiler/scala/tools/nsc/backend/icode/Members.scala b/src/compiler/scala/tools/nsc/backend/icode/Members.scala index 5dcebe7ecf..a1fd3c7ae5 100644 --- a/src/compiler/scala/tools/nsc/backend/icode/Members.scala +++ b/src/compiler/scala/tools/nsc/backend/icode/Members.scala @@ -269,7 +269,7 @@ trait Members { self: ICodes => succ.toList foreach { i => bb.emit(i, i.pos) } code.removeBlock(succ) nextBlock -= bb - exh foreach { e => e.covered = e.covered.remove { b1 => b1 == succ } } + exh foreach { e => e.covered = e.covered - succ } } while (nextBlock.isDefinedAt(succ)) bb.close } else diff --git a/src/compiler/scala/tools/nsc/backend/jvm/GenJVM.scala b/src/compiler/scala/tools/nsc/backend/jvm/GenJVM.scala index 5d6351d24b..708971a35a 100644 --- a/src/compiler/scala/tools/nsc/backend/jvm/GenJVM.scala +++ b/src/compiler/scala/tools/nsc/backend/jvm/GenJVM.scala @@ -817,7 +817,7 @@ abstract class GenJVM extends SubComponent { start = labels(b).getAnchor() end = endPC(b) } - covered = covered remove b.== + covered = covered - b } }); diff --git a/src/compiler/scala/tools/nsc/backend/msil/GenMSIL.scala b/src/compiler/scala/tools/nsc/backend/msil/GenMSIL.scala index 4db90c9c3a..dbabae1387 100644 --- a/src/compiler/scala/tools/nsc/backend/msil/GenMSIL.scala +++ b/src/compiler/scala/tools/nsc/backend/msil/GenMSIL.scala @@ -991,8 +991,8 @@ abstract class GenMSIL extends SubComponent { }) // shorter try-catch-finally last (the ones contained in another) - affectedHandlers = affectedHandlers.sort({(h1, h2) => h1.covered.length > h2.covered.length}) - affectedHandlers = affectedHandlers.filter(h => {h.covered.length == affectedHandlers(0).covered.length}) + affectedHandlers = affectedHandlers.sort({(h1, h2) => h1.covered.size > h2.covered.size}) + affectedHandlers = affectedHandlers.filter(h => {h.covered.size == affectedHandlers(0).covered.size}) untreatedHandlers = untreatedHandlers -- affectedHandlers // more than one catch produces more than one exh, but we only need one @@ -1018,7 +1018,7 @@ abstract class GenMSIL extends SubComponent { val excBlock = currentBlock.addExceptionBlock(singleAffectedHandler) exceptionBlock = Some(excBlock) - val (tryBlocks, newBlock) = adaptBlocks(blocksToPut.intersect(singleAffectedHandler.covered), singleAffectedHandler) + val (tryBlocks, newBlock) = adaptBlocks(blocksToPut.intersect(singleAffectedHandler.covered.toList), singleAffectedHandler) newBlock match { case Some(block) => @@ -1068,7 +1068,7 @@ abstract class GenMSIL extends SubComponent { // some blocks may have been removed by linearization untreatedHandlers.foreach(h => { h.blocks = h.blocks.intersect(blocksToPut) - h.covered = h.covered.intersect(blocksToPut) + h.covered = h.covered.intersect(collection.immutable.HashSet.empty ++ blocksToPut) if (h.finalizer != null && h.finalizer != NoFinalizer) h.finalizer.blocks = h.finalizer.blocks.intersect(blocksToPut) }) |