Skip to content

Commit 811e2fa

Browse files
author
extempore
committed
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. git-svn-id: http://lampsvn.epfl.ch/svn-repos/scala/scala/trunk@25164 5e8d7ff9-d8ef-0310-90f0-a4852d11357a
1 parent 4cfe16b commit 811e2fa

File tree

1 file changed

+10
-6
lines changed

1 file changed

+10
-6
lines changed

src/compiler/scala/tools/nsc/typechecker/RefChecks.scala

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ package scala.tools.nsc
77
package typechecker
88

99
import symtab.Flags._
10-
import collection.mutable.{HashSet, HashMap}
10+
import collection.{ mutable, immutable }
1111
import transform.InfoTransform
1212
import scala.collection.mutable.ListBuffer
1313

@@ -658,11 +658,13 @@ abstract class RefChecks extends InfoTransform {
658658
* </ol>
659659
*/
660660
private def validateBaseTypes(clazz: Symbol) {
661+
val seenParents = mutable.HashSet[Type]()
661662
val seenTypes = new Array[List[Type]](clazz.info.baseTypeSeq.length)
662-
for (i <- 0 until seenTypes.length) seenTypes(i) = Nil
663+
for (i <- 0 until seenTypes.length)
664+
seenTypes(i) = Nil
663665

664666
/** validate all base types of a class in reverse linear order. */
665-
def register(tp: Type) {
667+
def register(tp: Type): Unit = {
666668
// if (clazz.fullName.endsWith("Collection.Projection"))
667669
// println("validate base type "+tp)
668670
val baseClass = tp.typeSymbol
@@ -674,7 +676,9 @@ abstract class RefChecks extends InfoTransform {
674676
tp :: (seenTypes(index) filter (tp1 => !(tp <:< tp1)))
675677
}
676678
}
677-
tp.parents foreach register
679+
val remaining = tp.parents filterNot seenParents
680+
seenParents ++= remaining
681+
remaining foreach register
678682
}
679683
register(clazz.tpe)
680684
for (i <- 0 until seenTypes.length) {
@@ -701,7 +705,7 @@ abstract class RefChecks extends InfoTransform {
701705
private val CoVariance = 1
702706
private val AnyVariance = 2
703707

704-
private val escapedPrivateLocals = new HashSet[Symbol]
708+
private val escapedPrivateLocals = new mutable.HashSet[Symbol]
705709

706710
val varianceValidator = new Traverser {
707711

@@ -851,7 +855,7 @@ abstract class RefChecks extends InfoTransform {
851855
}
852856

853857
private var currentLevel: LevelInfo = null
854-
private val symIndex = new HashMap[Symbol, Int]
858+
private val symIndex = new mutable.HashMap[Symbol, Int]
855859

856860
private def pushLevel() {
857861
currentLevel = new LevelInfo(currentLevel)

0 commit comments

Comments
 (0)