summaryrefslogtreecommitdiff
path: root/src/compiler/scala/tools/nsc/backend/icode/Members.scala
diff options
context:
space:
mode:
Diffstat (limited to 'src/compiler/scala/tools/nsc/backend/icode/Members.scala')
-rw-r--r--src/compiler/scala/tools/nsc/backend/icode/Members.scala95
1 files changed, 36 insertions, 59 deletions
diff --git a/src/compiler/scala/tools/nsc/backend/icode/Members.scala b/src/compiler/scala/tools/nsc/backend/icode/Members.scala
index b74770f051..4389afb2b7 100644
--- a/src/compiler/scala/tools/nsc/backend/icode/Members.scala
+++ b/src/compiler/scala/tools/nsc/backend/icode/Members.scala
@@ -3,14 +3,13 @@
* @author Martin Odersky
*/
-package scala.tools.nsc
+package scala
+package tools.nsc
package backend
package icode
-import java.io.PrintWriter
import scala.collection.{ mutable, immutable }
import scala.reflect.internal.util.{ SourceFile, NoSourceFile }
-import symtab.Flags.{ DEFERRED }
trait ReferenceEquality {
override def hashCode = System.identityHashCode(this)
@@ -48,27 +47,33 @@ trait Members {
def touched = _touched
def touched_=(b: Boolean): Unit = {
- if (b)
- blocks foreach (_.touched = true)
+ @annotation.tailrec def loop(xs: List[BasicBlock]) {
+ xs match {
+ case Nil =>
+ case x :: xs => x.touched = true ; loop(xs)
+ }
+ }
+ if (b) loop(blocks.toList)
_touched = b
}
// Constructor code
- startBlock = newBlock
+ startBlock = newBlock()
def removeBlock(b: BasicBlock) {
- if (settings.debug.value) {
- assert(blocks forall (p => !(p.successors contains b)),
- "Removing block that is still referenced in method code " + b + "preds: " + b.predecessors
- )
- assert(b != startBlock || b.successors.length == 1,
- "Removing start block with more than one successor."
- )
+ if (settings.debug) {
+ // only do this sanity check when debug is turned on because it's moderately expensive
+ val referers = blocks filter (_.successors contains b)
+ assert(referers.isEmpty, s"Trying to removing block $b (with preds ${b.predecessors.mkString}) but it is still refered to from block(s) ${referers.mkString}")
}
- if (b == startBlock)
+ if (b == startBlock) {
+ assert(b.successors.length == 1,
+ s"Removing start block ${b} with ${b.successors.length} successors (${b.successors.mkString})."
+ )
startBlock = b.successors.head
+ }
blocks -= b
assert(!blocks.contains(b))
@@ -77,7 +82,7 @@ trait Members {
}
/** This methods returns a string representation of the ICode */
- override def toString = "ICode '" + name + "'";
+ override def toString = "ICode '" + name + "'"
/* Compute a unique new label */
def nextLabel: Int = {
@@ -89,8 +94,8 @@ trait Members {
*/
def newBlock(): BasicBlock = {
touched = true
- val block = new BasicBlock(nextLabel, method);
- blocks += block;
+ val block = new BasicBlock(nextLabel, method)
+ blocks += block
block
}
}
@@ -112,25 +117,23 @@ trait Members {
var cunit: CompilationUnit = _
def addField(f: IField): this.type = {
- fields = f :: fields;
+ fields = f :: fields
this
}
def addMethod(m: IMethod): this.type = {
- methods = m :: methods;
+ methods = m :: methods
this
}
def setCompilationUnit(unit: CompilationUnit): this.type = {
- this.cunit = unit;
+ this.cunit = unit
this
}
override def toString() = symbol.fullName
- def lookupField(s: Symbol) = fields find (_.symbol == s)
def lookupMethod(s: Symbol) = methods find (_.symbol == s)
- def lookupMethod(s: Name) = methods find (_.symbol.name == s)
/* returns this methods static ctor if it has one. */
def lookupStaticCtor: Option[IMethod] = methods find (_.symbol.isStaticConstructor)
@@ -154,14 +157,13 @@ trait Members {
class IMethod(val symbol: Symbol) extends IMember {
var code: Code = NoCode
- def newBlock() = code.newBlock
+ def newBlock() = code.newBlock()
def startBlock = code.startBlock
def lastBlock = { assert(blocks.nonEmpty, symbol); blocks.last }
def blocks = code.blocksList
def linearizedBlocks(lin: Linearizer = self.linearizer): List[BasicBlock] = lin linearize this
def foreachBlock[U](f: BasicBlock => U): Unit = blocks foreach f
- def foreachInstr[U](f: Instruction => U): Unit = foreachBlock(_.toList foreach f)
var native = false
@@ -181,7 +183,7 @@ trait Members {
def hasCode = code ne NoCode
def setCode(code: Code): IMethod = {
- this.code = code;
+ this.code = code
this
}
@@ -195,7 +197,6 @@ trait Members {
}
def addLocals(ls: List[Local]) = ls foreach addLocal
- def addParams(as: List[Local]) = as foreach addParam
def lookupLocal(n: Name): Option[Local] = locals find (_.sym.name == n)
def lookupLocal(sym: Symbol): Option[Local] = locals find (_.sym == sym)
@@ -210,28 +211,7 @@ trait Members {
override def toString() = symbol.fullName
- def matchesSignature(other: IMethod) = {
- (symbol.name == other.symbol.name) &&
- (params corresponds other.params)(_.kind == _.kind) &&
- (returnType == other.returnType)
- }
-
import opcodes._
- def checkLocals(): Unit = {
- def localsSet = (code.blocks flatMap { bb =>
- bb.iterator collect {
- case LOAD_LOCAL(l) => l
- case STORE_LOCAL(l) => l
- }
- }).toSet
-
- if (hasCode) {
- log("[checking locals of " + this + "]")
- locals filterNot localsSet foreach { l =>
- log("Local " + l + " is not declared in " + this)
- }
- }
- }
/** Merge together blocks that have a single successor which has a
* single predecessor. Exception handlers are taken into account (they
@@ -243,10 +223,10 @@ trait Members {
val nextBlock: mutable.Map[BasicBlock, BasicBlock] = mutable.HashMap.empty
for (b <- code.blocks.toList
if b.successors.length == 1;
- succ = b.successors.head;
- if succ ne b;
- if succ.predecessors.length == 1;
- if succ.predecessors.head eq b;
+ succ = b.successors.head
+ if succ ne b
+ if succ.predecessors.length == 1
+ if succ.predecessors.head eq b
if !(exh.exists { (e: ExceptionHandler) =>
(e.covers(succ) && !e.covers(b)) || (e.covers(b) && !e.covers(succ)) })) {
nextBlock(b) = succ
@@ -255,10 +235,10 @@ trait Members {
var bb = code.startBlock
while (!nextBlock.isEmpty) {
if (nextBlock.isDefinedAt(bb)) {
- bb.open
+ bb.open()
var succ = bb
do {
- succ = nextBlock(succ);
+ succ = nextBlock(succ)
val lastInstr = bb.lastInstruction
/* Ticket SI-5672
* Besides removing the control-flow instruction at the end of `bb` (usually a JUMP), we have to pop any values it pushes.
@@ -269,7 +249,7 @@ trait Members {
val oldTKs = lastInstr.consumedTypes
assert(lastInstr.consumed == oldTKs.size, "Someone forgot to override consumedTypes() in " + lastInstr)
- bb.removeLastInstruction
+ bb.removeLastInstruction()
for(tk <- oldTKs.reverse) { bb.emit(DROP(tk), lastInstr.pos) }
succ.toList foreach { i => bb.emit(i, i.pos) }
code.removeBlock(succ)
@@ -277,9 +257,9 @@ trait Members {
nextBlock -= bb
} while (nextBlock.isDefinedAt(succ))
- bb.close
+ bb.close()
} else
- bb = nextBlock.keysIterator.next
+ bb = nextBlock.keysIterator.next()
}
checkValid(this)
}
@@ -297,9 +277,6 @@ trait Members {
/** Starting PC for this local's visibility range. */
var start: Int = _
- /** Ending PC for this local's visibility range. */
- var end: Int = _
-
/** PC-based ranges for this local variable's visibility */
var ranges: List[(Int, Int)] = Nil