summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorIulian Dragos <jaguarul@gmail.com>2008-10-27 16:25:50 +0000
committerIulian Dragos <jaguarul@gmail.com>2008-10-27 16:25:50 +0000
commitd1bf566ad6bc231ebcb43a59b736497e35ba4b97 (patch)
treefa59cfdb2fcbaad3c77e454522176eb059d5b2b7
parentcc97afe49feb585819abf0b5ae6fc25c34e349df (diff)
downloadscala-d1bf566ad6bc231ebcb43a59b736497e35ba4b97.tar.gz
scala-d1bf566ad6bc231ebcb43a59b736497e35ba4b97.tar.bz2
scala-d1bf566ad6bc231ebcb43a59b736497e35ba4b97.zip
Fixed optimization phases (#1379).
-rw-r--r--src/compiler/scala/tools/nsc/backend/icode/BasicBlocks.scala20
-rw-r--r--src/compiler/scala/tools/nsc/backend/icode/Checkers.scala10
-rw-r--r--src/compiler/scala/tools/nsc/backend/icode/ExceptionHandlers.scala9
-rw-r--r--src/compiler/scala/tools/nsc/backend/icode/Members.scala2
-rw-r--r--src/compiler/scala/tools/nsc/backend/jvm/GenJVM.scala2
-rw-r--r--src/compiler/scala/tools/nsc/backend/msil/GenMSIL.scala8
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)
})