summaryrefslogtreecommitdiff
path: root/src/compiler
diff options
context:
space:
mode:
authorPaul Phillips <paulp@improving.org>2011-07-27 00:52:47 +0000
committerPaul Phillips <paulp@improving.org>2011-07-27 00:52:47 +0000
commit401baad565218da34558318ebd1f65edb31b39c8 (patch)
tree6177a99518fe598e51dd3d02aa9666c4fd27bacb /src/compiler
parent68031b3af11a2f79b186607f44d5c327051d19bd (diff)
downloadscala-401baad565218da34558318ebd1f65edb31b39c8.tar.gz
scala-401baad565218da34558318ebd1f65edb31b39c8.tar.bz2
scala-401baad565218da34558318ebd1f65edb31b39c8.zip
Fix/workaround for inliner bug uncovered by fin...
Fix/workaround for inliner bug uncovered by finalizing Option methods. Something in the backend is leaving open but empty blocks in the worklist. Rather than freaking out at the merest mention of an empty block, I quietly remove the empty ones. A proper fix will involve not leaving empty blocks lying around but we're on a schedule here people. Review by dragos.
Diffstat (limited to 'src/compiler')
-rw-r--r--src/compiler/scala/tools/nsc/backend/icode/ICodes.scala19
-rw-r--r--src/compiler/scala/tools/nsc/backend/icode/Linearizers.scala7
2 files changed, 21 insertions, 5 deletions
diff --git a/src/compiler/scala/tools/nsc/backend/icode/ICodes.scala b/src/compiler/scala/tools/nsc/backend/icode/ICodes.scala
index 9553d5cf9b..06c3ee2a9e 100644
--- a/src/compiler/scala/tools/nsc/backend/icode/ICodes.scala
+++ b/src/compiler/scala/tools/nsc/backend/icode/ICodes.scala
@@ -35,7 +35,7 @@ abstract class ICodes extends AnyRef
with Repository
{
val global: Global
- import global.{ definitions, settings, perRunCaches }
+ import global.{ log, definitions, settings, perRunCaches }
/** The ICode representation of classes */
val classes = perRunCaches.newMap[global.Symbol, IClass]()
@@ -72,11 +72,22 @@ abstract class ICodes extends AnyRef
}
def checkValid(m: IMethod) {
- for (b <- m.code.blocks)
- if (!b.closed) {
+ // always dicey to iterate over mutable structures
+ val bs = m.code.blocks.toList
+
+ for (b <- bs ; if !b.closed) {
+ // Something is leaving open/empty blocks around (see SI-4840) so
+ // let's not kill the deal unless it's nonempty.
+ if (b.isEmpty) {
+ log("!!! Found open but empty block while inlining " + m + ": removing from block list.")
+ m.code removeBlock b
+ }
+ else {
+ Console.println("Fatal bug in inliner: found open block when inlining " + m)
m.dump
- global.abort("Open block: " + b + " " + b.flagsString)
+ global.abort("Open block was: " + b + " " + b.flagsString)
}
+ }
}
object liveness extends Liveness {
diff --git a/src/compiler/scala/tools/nsc/backend/icode/Linearizers.scala b/src/compiler/scala/tools/nsc/backend/icode/Linearizers.scala
index 9f22a6de90..8130c99978 100644
--- a/src/compiler/scala/tools/nsc/backend/icode/Linearizers.scala
+++ b/src/compiler/scala/tools/nsc/backend/icode/Linearizers.scala
@@ -14,6 +14,8 @@ import mutable.ListBuffer
trait Linearizers {
self: ICodes =>
+
+ import global.debuglog
import opcodes._
abstract class Linearizer {
@@ -178,11 +180,14 @@ trait Linearizers {
* Prepend b to the list, if not already scheduled.
* @return Returns true if the block was added.
*/
- def add(b: BasicBlock) =
+ def add(b: BasicBlock) = {
+ debuglog("Linearizer adding block " + b.label)
+
if (!added(b.label)) {
added += b.label
blocks = b :: blocks;
}
+ }
}
/** A 'dump' of the blocks in this method, which does not