summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorIulian Dragos <jaguarul@gmail.com>2008-10-28 17:58:19 +0000
committerIulian Dragos <jaguarul@gmail.com>2008-10-28 17:58:19 +0000
commit4149421661d0b2401312515ac0c4f4e54a83b3c2 (patch)
tree6ff125ca3376fa361c59b6ae80482cc8df98be8b
parent0a14ec63938d84f1750611c3ea1acca2f38a033c (diff)
downloadscala-4149421661d0b2401312515ac0c4f4e54a83b3c2.tar.gz
scala-4149421661d0b2401312515ac0c4f4e54a83b3c2.tar.bz2
scala-4149421661d0b2401312515ac0c4f4e54a83b3c2.zip
Propagated fixes for optimizer (fixed #1402 and...
Propagated fixes for optimizer (fixed #1402 and #1379)
-rw-r--r--src/compiler/scala/tools/nsc/backend/icode/BasicBlocks.scala20
-rw-r--r--src/compiler/scala/tools/nsc/backend/icode/Checkers.scala11
-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.scala24
-rw-r--r--src/compiler/scala/tools/nsc/backend/msil/GenMSIL.scala8
-rw-r--r--src/compiler/scala/tools/nsc/symtab/Definitions.scala9
-rw-r--r--src/compiler/scala/tools/nsc/symtab/classfile/ClassfileParser.scala10
-rw-r--r--src/compiler/scala/tools/nsc/symtab/classfile/ICodeReader.scala12
-rw-r--r--src/compiler/scala/tools/nsc/transform/Mixin.scala10
10 files changed, 78 insertions, 37 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 46b5066e63..dc435bd2e9 100644
--- a/src/compiler/scala/tools/nsc/backend/icode/Checkers.scala
+++ b/src/compiler/scala/tools/nsc/backend/icode/Checkers.scala
@@ -67,10 +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 = {
- Console.println("[[consistency check at beginning of phase " + globalPhase.name + "]]")
+ if (settings.verbose.value)
+ println("[[consistency check at the beginning of phase " + globalPhase.name + "]]")
classes.values foreach check
}
@@ -554,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 e8d7b2a6c9..2bdb1eaa43 100644
--- a/src/compiler/scala/tools/nsc/backend/jvm/GenJVM.scala
+++ b/src/compiler/scala/tools/nsc/backend/jvm/GenJVM.scala
@@ -132,7 +132,7 @@ abstract class GenJVM extends SubComponent {
}
if (!(jclass.getName().endsWith("$") && sym.isModuleClass))
addScalaAttr(if (isTopLevelModule(sym)) sym.sourceModule else sym);
- addInnerClasses
+ addInnerClasses(jclass)
val outfile = getFile(jclass, ".class")
val outstream = new DataOutputStream(outfile.output)
@@ -405,7 +405,7 @@ abstract class GenJVM extends SubComponent {
}
def addGenericSignature(jmember: JMember, sym: Symbol) {
- if (!sym.hasFlag(Flags.PRIVATE | Flags.EXPANDEDNAME | Flags.SYNTHETIC) && settings.target.value == "jvm-1.5") {
+ if (settings.target.value == "jvm-1.5") {
erasure.javaSig(sym) match {
case Some(sig) =>
val index = jmember.getConstantPool().addUtf8(sig).toShort
@@ -465,11 +465,14 @@ abstract class GenJVM extends SubComponent {
jmember.addAttribute(attr)
}
- def addInnerClasses {
+ def addInnerClasses(jclass: JClass) {
+ def addOwnInnerClasses(cls: Symbol) {
+ for (sym <- cls.info.decls.elements if sym.isClass)
+ innerClasses = innerClasses + sym;
+ }
// add inner classes which might not have been referenced yet
atPhase(currentRun.erasurePhase) {
- for (sym <- clasz.symbol.info.decls.elements if sym.isClass)
- innerClasses = innerClasses + sym;
+ addOwnInnerClasses(clasz.symbol)
}
if (!innerClasses.isEmpty) {
@@ -479,13 +482,16 @@ abstract class GenJVM extends SubComponent {
for (innerSym <- innerClasses.toList.sort(_.name.length < _.name.length)) {
var outerName = javaName(innerSym.rawowner)
// remove the trailing '$'
- //if (outerName.endsWith("$"))
- //outerName = outerName.substring(0, outerName.length - 1)
+ if (outerName.endsWith("$"))
+ outerName = outerName.substring(0, outerName.length - 1)
+ var flags = javaFlags(innerSym)
+ if (innerSym.rawowner.hasFlag(Flags.MODULE))
+ flags |= JAccessFlags.ACC_STATIC
innerClassesAttr.addEntry(javaName(innerSym),
outerName,
innerSym.rawname.toString,
- javaFlags(innerSym));
+ flags);
}
}
}
@@ -811,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)
})
diff --git a/src/compiler/scala/tools/nsc/symtab/Definitions.scala b/src/compiler/scala/tools/nsc/symtab/Definitions.scala
index 18fd09e0ba..11c3db13ee 100644
--- a/src/compiler/scala/tools/nsc/symtab/Definitions.scala
+++ b/src/compiler/scala/tools/nsc/symtab/Definitions.scala
@@ -365,10 +365,17 @@ trait Definitions {
private def newCovariantPolyClass(owner: Symbol, name: Name, parent: Symbol => Type): Symbol = {
val clazz = newClass(owner, name, List())
val tparam = newTypeParam(clazz, 0) setFlag COVARIANT
+ val p = parent(tparam)
+/* p.typeSymbol.initialize
+ println(p.typeSymbol + " flags: " + Flags.flagsToString(p.typeSymbol.flags))
+ val parents = /*if (p.typeSymbol.isTrait)
+ List(definitions.AnyRefClass.tpe, p)
+ else*/ List(p)
+ println("creating " + name + " with parents " + parents) */
clazz.setInfo(
PolyType(
List(tparam),
- ClassInfoType(List(parent(tparam)), newClassScope(clazz), clazz)))
+ ClassInfoType(List(p), newClassScope(clazz), clazz)))
}
private def newAlias(owner: Symbol, name: Name, alias: Type): Symbol = {
diff --git a/src/compiler/scala/tools/nsc/symtab/classfile/ClassfileParser.scala b/src/compiler/scala/tools/nsc/symtab/classfile/ClassfileParser.scala
index c52eda360a..80ee38f337 100644
--- a/src/compiler/scala/tools/nsc/symtab/classfile/ClassfileParser.scala
+++ b/src/compiler/scala/tools/nsc/symtab/classfile/ClassfileParser.scala
@@ -204,7 +204,11 @@ abstract class ClassfileParser {
in.buf(start) != CONSTANT_METHODREF &&
in.buf(start) != CONSTANT_INTFMETHODREF) errorBadTag(start)
val ownerTpe = getClassOrArrayType(in.getChar(start + 1))
+ if (settings.debug.value)
+ log("getMemberSymbol(static: " + static + "): owner type: " + ownerTpe + " " + ownerTpe.typeSymbol.originalName)
val (name, tpe) = getNameAndType(in.getChar(start + 3), ownerTpe)
+ if (settings.debug.value)
+ log("getMemberSymbol: name and tpe: " + name + ": " + tpe)
if (name == nme.MODULE_INSTANCE_FIELD) {
val index = in.getChar(start + 1)
val name = getExternalName(in.getChar(starts(index) + 1))
@@ -377,8 +381,10 @@ abstract class ClassfileParser {
val classInfo = ClassInfoType(parents, instanceDefs, clazz)
val staticInfo = ClassInfoType(List(), staticDefs, statics)
- if (!isScala && !isScalaRaw)
+ if (!isScala && !isScalaRaw) {
+ //println("Entering inner classes for " + clazz)
enterOwnInnerClasses
+ }
val curbp = in.bp
skipMembers() // fields
skipMembers() // methods
@@ -386,7 +392,7 @@ abstract class ClassfileParser {
clazz.setFlag(sflags)
setPrivateWithin(clazz, jflags)
setPrivateWithin(staticModule, jflags)
- if (!hasMeta) {
+ if (!hasMeta || isScalaRaw) {
clazz.setInfo(classInfo)
}
statics.setInfo(staticInfo)
diff --git a/src/compiler/scala/tools/nsc/symtab/classfile/ICodeReader.scala b/src/compiler/scala/tools/nsc/symtab/classfile/ICodeReader.scala
index 6606214970..09c2c75ef5 100644
--- a/src/compiler/scala/tools/nsc/symtab/classfile/ICodeReader.scala
+++ b/src/compiler/scala/tools/nsc/symtab/classfile/ICodeReader.scala
@@ -51,13 +51,11 @@ abstract class ICodeReader extends ClassfileParser {
if (entry ne null) {
classFile = entry.classFile
// if (isScalaModule)
- //sym = cls.linkedClassOfModule
+// sym = cls.linkedClassOfModule
assert(classFile ne null, "No classfile for " + cls)
// for (s <- cls.info.members)
// Console.println("" + s + ": " + s.tpe)
- this.instanceCode = new IClass(sym)
- this.staticCode = new IClass(sym.linkedClassOfClass)
parse(classFile, sym)
} else
log("Could not find: " + cls)
@@ -75,13 +73,14 @@ abstract class ICodeReader extends ClassfileParser {
}
override def parseClass() {
+ this.instanceCode = new IClass(clazz)
+ this.staticCode = new IClass(staticModule)
val jflags = in.nextChar
val isAttribute = (jflags & JAVA_ACC_ANNOTATION) != 0
var sflags = transFlags(jflags, true)
if ((sflags & DEFERRED) != 0) sflags = sflags & ~DEFERRED | ABSTRACT
val c = pool.getClassSymbol(in.nextChar)
-// if (c != clazz)
-// throw new IOException("class file '" + in.file + "' contains " + c + "instead of " + clazz)
+
parseInnerClasses()
in.skip(2) // super class
@@ -643,7 +642,8 @@ abstract class ICodeReader extends ClassfileParser {
* There are two possible classes, the static part and the instance part.
*/
def getCode(flags: Int): IClass =
- if ((flags & JAVA_ACC_STATIC) != 0) staticCode else instanceCode
+ if (isScalaModule) staticCode
+ else if ((flags & JAVA_ACC_STATIC) != 0) staticCode else instanceCode
class LinearCode {
var instrs: ListBuffer[(Int, Instruction)] = new ListBuffer
diff --git a/src/compiler/scala/tools/nsc/transform/Mixin.scala b/src/compiler/scala/tools/nsc/transform/Mixin.scala
index ab020716d2..30f2c69372 100644
--- a/src/compiler/scala/tools/nsc/transform/Mixin.scala
+++ b/src/compiler/scala/tools/nsc/transform/Mixin.scala
@@ -677,12 +677,12 @@ abstract class Mixin extends InfoTransform {
&& !sym.isOuterAccessor)
if (settings.debug.value) {
- println("needsInitFlag(" + sym.fullNameString + "): " + res)
- println("\tsym.isGetter: " + sym.isGetter)
- println("\t!isInitializedToDefault: " + !sym.isInitializedToDefault + sym.hasFlag(DEFAULTINIT) + sym.hasFlag(ACCESSOR) + sym.isTerm)
- println("\t!sym.hasFlag(PARAMACCESSOR): " + !sym.hasFlag(PARAMACCESSOR))
+ log("needsInitFlag(" + sym.fullNameString + "): " + res)
+ log("\tsym.isGetter: " + sym.isGetter)
+ log("\t!isInitializedToDefault: " + !sym.isInitializedToDefault + sym.hasFlag(DEFAULTINIT) + sym.hasFlag(ACCESSOR) + sym.isTerm)
+ log("\t!sym.hasFlag(PARAMACCESSOR): " + !sym.hasFlag(PARAMACCESSOR))
//println("\t!sym.accessed.hasFlag(PRESUPER): " + !sym.accessed.hasFlag(PRESUPER))
- println("\t!sym.isOuterAccessor: " + !sym.isOuterAccessor)
+ log("\t!sym.isOuterAccessor: " + !sym.isOuterAccessor)
}
res