summaryrefslogtreecommitdiff
path: root/src/compiler/scala/tools/nsc/typechecker/RefChecks.scala
diff options
context:
space:
mode:
authorPaul Phillips <paulp@improving.org>2011-06-28 17:47:21 +0000
committerPaul Phillips <paulp@improving.org>2011-06-28 17:47:21 +0000
commit42fb66a2cbcad4fff0634dc935f135494f04be93 (patch)
treec1aad8ed0ae96f968a34164d481d524a4fbcf184 /src/compiler/scala/tools/nsc/typechecker/RefChecks.scala
parentc23c21853a76adfc8694ce752853a5be5d5c8cf3 (diff)
downloadscala-42fb66a2cbcad4fff0634dc935f135494f04be93.tar.gz
scala-42fb66a2cbcad4fff0634dc935f135494f04be93.tar.bz2
scala-42fb66a2cbcad4fff0634dc935f135494f04be93.zip
Continuing to press on RefChecks, discovered wh...
Continuing to press on RefChecks, discovered what seemed a pretty spectacular performance bug, at least at first. I was disappointed to see that the time gain didn't measure up. Still, nanos are nanos. According to YourKit, millis spent in List#foreach on a compilation of src/library broke down like this: | +---LinearSeqOptimized$class.foreach | 173,123 100 % | | +---RefChecks$RefCheckTransformer.register$1 | 117,658 68 % | I think that is largely a profiler lie, but there is enough truth. After adjusting to prune before recursing, the number of invocations of method register in validateBaseTypes drops by 98%. Review by odersky.
Diffstat (limited to 'src/compiler/scala/tools/nsc/typechecker/RefChecks.scala')
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/RefChecks.scala16
1 files changed, 10 insertions, 6 deletions
diff --git a/src/compiler/scala/tools/nsc/typechecker/RefChecks.scala b/src/compiler/scala/tools/nsc/typechecker/RefChecks.scala
index e842a667aa..a434af1175 100644
--- a/src/compiler/scala/tools/nsc/typechecker/RefChecks.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/RefChecks.scala
@@ -7,7 +7,7 @@ package scala.tools.nsc
package typechecker
import symtab.Flags._
-import collection.mutable.{HashSet, HashMap}
+import collection.{ mutable, immutable }
import transform.InfoTransform
import scala.collection.mutable.ListBuffer
@@ -658,11 +658,13 @@ abstract class RefChecks extends InfoTransform {
* </ol>
*/
private def validateBaseTypes(clazz: Symbol) {
+ val seenParents = mutable.HashSet[Type]()
val seenTypes = new Array[List[Type]](clazz.info.baseTypeSeq.length)
- for (i <- 0 until seenTypes.length) seenTypes(i) = Nil
+ for (i <- 0 until seenTypes.length)
+ seenTypes(i) = Nil
/** validate all base types of a class in reverse linear order. */
- def register(tp: Type) {
+ def register(tp: Type): Unit = {
// if (clazz.fullName.endsWith("Collection.Projection"))
// println("validate base type "+tp)
val baseClass = tp.typeSymbol
@@ -674,7 +676,9 @@ abstract class RefChecks extends InfoTransform {
tp :: (seenTypes(index) filter (tp1 => !(tp <:< tp1)))
}
}
- tp.parents foreach register
+ val remaining = tp.parents filterNot seenParents
+ seenParents ++= remaining
+ remaining foreach register
}
register(clazz.tpe)
for (i <- 0 until seenTypes.length) {
@@ -701,7 +705,7 @@ abstract class RefChecks extends InfoTransform {
private val CoVariance = 1
private val AnyVariance = 2
- private val escapedPrivateLocals = new HashSet[Symbol]
+ private val escapedPrivateLocals = new mutable.HashSet[Symbol]
val varianceValidator = new Traverser {
@@ -851,7 +855,7 @@ abstract class RefChecks extends InfoTransform {
}
private var currentLevel: LevelInfo = null
- private val symIndex = new HashMap[Symbol, Int]
+ private val symIndex = new mutable.HashMap[Symbol, Int]
private def pushLevel() {
currentLevel = new LevelInfo(currentLevel)