diff --git a/compiler/src/dotty/tools/dotc/config/Config.scala b/compiler/src/dotty/tools/dotc/config/Config.scala index d7980b55f36a..2e778a9db81a 100644 --- a/compiler/src/dotty/tools/dotc/config/Config.scala +++ b/compiler/src/dotty/tools/dotc/config/Config.scala @@ -147,8 +147,10 @@ object Config { /** Initial size of superId table */ final val InitialSuperIdsSize = 4096 - /** Initial capacity of uniques HashMap */ - final val initialUniquesCapacity = 40000 + /** Initial capacity of uniques HashMap. + * Note: This MUST BE a power of two to work with util.HashSet + */ + final val initialUniquesCapacity = 65536 /** How many recursive calls to NamedType#underlying are performed before logging starts. */ final val LogPendingUnderlyingThreshold = 50 diff --git a/compiler/src/dotty/tools/dotc/core/TypeOps.scala b/compiler/src/dotty/tools/dotc/core/TypeOps.scala index ba3b049d6f18..2b0be7e6e19e 100644 --- a/compiler/src/dotty/tools/dotc/core/TypeOps.scala +++ b/compiler/src/dotty/tools/dotc/core/TypeOps.scala @@ -131,7 +131,7 @@ trait TypeOps { this: Context => // TODO: Make standalone object. /** a faster version of cs1 intersect cs2 */ def intersect(cs1: List[ClassSymbol], cs2: List[ClassSymbol]): List[ClassSymbol] = { - val cs2AsSet = new util.HashSet[ClassSymbol](100) + val cs2AsSet = new util.HashSet[ClassSymbol](128) cs2.foreach(cs2AsSet.addEntry) cs1.filter(cs2AsSet.contains) } diff --git a/compiler/src/dotty/tools/dotc/transform/TreeTransform.scala b/compiler/src/dotty/tools/dotc/transform/TreeTransform.scala index e1e3edb7380c..768a51cf4e47 100644 --- a/compiler/src/dotty/tools/dotc/transform/TreeTransform.scala +++ b/compiler/src/dotty/tools/dotc/transform/TreeTransform.scala @@ -210,9 +210,16 @@ object TreeTransforms { */ class NXTransformations { - private def hasRedefinedMethod(cls: Class[_], name: String): Boolean = - if (cls.getDeclaredMethods.exists(_.getName == name)) cls != classOf[TreeTransform] - else hasRedefinedMethod(cls.getSuperclass, name) + private def hasRedefinedMethod(cls: Class[_], name: String): Boolean = { + val clsMethods = cls.getDeclaredMethods + var i = clsMethods.length - 1 + while (i >= 0) { + if (clsMethods(i).getName == name) + return cls != classOf[TreeTransform] + i -= 1 + } + hasRedefinedMethod(cls.getSuperclass, name) + } /** Create an index array `next` of size one larger than the size of `transforms` such that * for each index i, `next(i)` is the smallest index j such that diff --git a/compiler/src/dotty/tools/dotc/util/HashSet.scala b/compiler/src/dotty/tools/dotc/util/HashSet.scala index ff470ef5dc26..c6fa4c9e84cc 100644 --- a/compiler/src/dotty/tools/dotc/util/HashSet.scala +++ b/compiler/src/dotty/tools/dotc/util/HashSet.scala @@ -2,7 +2,7 @@ package dotty.tools.dotc.util /** A hash set that allows some privileged protected access to its internals */ -class HashSet[T >: Null <: AnyRef](initialCapacity: Int, loadFactor: Float = 0.25f) extends Set[T] { +class HashSet[T >: Null <: AnyRef](powerOfTwoInitialCapacity: Int, loadFactor: Float = 0.25f) extends Set[T] { private var used: Int = _ private var limit: Int = _ private var table: Array[AnyRef] = _ @@ -20,11 +20,11 @@ class HashSet[T >: Null <: AnyRef](initialCapacity: Int, loadFactor: Float = 0.2 /** Remove all elements from this set and set back to initial configuration */ def clear(): Unit = { used = 0 - allocate(initialCapacity) + allocate(powerOfTwoInitialCapacity) } - /** Turn hashode `x` into a table index */ - private def index(x: Int): Int = math.abs(x % table.length) + /** Turn hashcode `x` into a table index */ + private def index(x: Int): Int = x & (table.length - 1) /** Hashcode, can be overridden */ def hash(x: T): Int = x.hashCode diff --git a/compiler/src/dotty/tools/dotc/util/Stats.scala b/compiler/src/dotty/tools/dotc/util/Stats.scala index 970b44248d70..bb2f2dff8063 100644 --- a/compiler/src/dotty/tools/dotc/util/Stats.scala +++ b/compiler/src/dotty/tools/dotc/util/Stats.scala @@ -21,7 +21,7 @@ import collection.mutable } @inline - def record(fn: String, n: Int = 1) = + def record(fn: => String, n: => Int = 1) = if (enabled) doRecord(fn, n) private def doRecord(fn: String, n: Int) =