Skip to content

Commit 0e3c70f

Browse files
oderskyAdriaan Moors
authored and
Adriaan Moors
committed
Attempt #3 to optimize findMember
Fixed fingerPrinting scheme to work with rehashes, also added finger prints to typedIdent searches.
1 parent 41f4497 commit 0e3c70f

File tree

4 files changed

+23
-8
lines changed

4 files changed

+23
-8
lines changed

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

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4510,6 +4510,8 @@ trait Typers extends Modes with Adaptations with Tags {
45104510
assert(errorContainer == null, "Cannot set ambiguous error twice for identifier")
45114511
errorContainer = tree
45124512
}
4513+
4514+
val fingerPrint: Long = name.fingerPrint
45134515

45144516
var defSym: Symbol = tree.symbol // the directly found symbol
45154517
var pre: Type = NoPrefix // the prefix type of defSym, if a class member
@@ -4548,7 +4550,10 @@ trait Typers extends Modes with Adaptations with Tags {
45484550
var cx = startingIdentContext
45494551
while (defSym == NoSymbol && cx != NoContext && (cx.scope ne null)) { // cx.scope eq null arises during FixInvalidSyms in Duplicators
45504552
pre = cx.enclClass.prefix
4551-
defEntry = cx.scope.lookupEntry(name)
4553+
defEntry = {
4554+
val scope = cx.scope
4555+
if ((fingerPrint & scope.fingerPrints) != 0) scope.lookupEntry(name) else null
4556+
}
45524557
if ((defEntry ne null) && qualifies(defEntry.sym)) {
45534558
// Right here is where SI-1987, overloading in package objects, can be
45544559
// seen to go wrong. There is an overloaded symbol, but when referring

src/reflect/scala/reflect/internal/Names.scala

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -414,6 +414,9 @@ trait Names extends api.Names {
414414
}
415415
else toString
416416
}
417+
418+
@inline
419+
final def fingerPrint: Long = (1L << start)
417420

418421
/** TODO - find some efficiency. */
419422
def append(ch: Char) = newName("" + this + ch)

src/reflect/scala/reflect/internal/Scopes.scala

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -41,15 +41,15 @@ trait Scopes extends api.Scopes { self: SymbolTable =>
4141
* This is necessary because when run from reflection every scope needs to have a
4242
* SynchronizedScope as mixin.
4343
*/
44-
class Scope protected[Scopes] (initElems: ScopeEntry = null) extends Iterable[Symbol] {
44+
class Scope protected[Scopes] (initElems: ScopeEntry = null, initFingerPrints: Long = 0L) extends Iterable[Symbol] {
4545

4646
/** A bitset containing the last 6 bits of the start value of every name
4747
* stored in this scope.
4848
*/
49-
var fingerPrints: Long = 0L
49+
var fingerPrints: Long = initFingerPrints
5050

5151
protected[Scopes] def this(base: Scope) = {
52-
this(base.elems)
52+
this(base.elems, base.fingerPrints)
5353
nestinglevel = base.nestinglevel + 1
5454
}
5555

@@ -119,7 +119,7 @@ trait Scopes extends api.Scopes { self: SymbolTable =>
119119
* @param sym ...
120120
*/
121121
def enter[T <: Symbol](sym: T): T = {
122-
fingerPrints |= (1L << sym.name.start)
122+
fingerPrints |= sym.name.fingerPrint
123123
enterEntry(newScopeEntry(sym, this))
124124
sym
125125
}
@@ -156,6 +156,7 @@ trait Scopes extends api.Scopes { self: SymbolTable =>
156156
}
157157

158158
def rehash(sym: Symbol, newname: Name) {
159+
fingerPrints |= newname.fingerPrint
159160
if (hashtable ne null) {
160161
val index = sym.name.start & HASHMASK
161162
var e1 = hashtable(index)

src/reflect/scala/reflect/internal/Types.scala

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1045,7 +1045,7 @@ trait Types extends api.Types { self: SymbolTable =>
10451045
var continue = true
10461046
var self: Type = null
10471047
var membertpe: Type = null
1048-
val fingerPrint: Long = (1L << name.start)
1048+
val fingerPrint: Long = name.fingerPrint
10491049
while (continue) {
10501050
continue = false
10511051
val bcs0 = baseClasses
@@ -1612,8 +1612,13 @@ trait Types extends api.Types { self: SymbolTable =>
16121612
if (period != currentPeriod) {
16131613
tpe.baseClassesPeriod = currentPeriod
16141614
if (!isValidForBaseClasses(period)) {
1615-
tpe.baseClassesCache = null
1616-
tpe.baseClassesCache = tpe.memo(computeBaseClasses)(tpe.typeSymbol :: _.baseClasses.tail)
1615+
val start = Statistics.pushTimer(typeOpsStack, baseClassesNanos)
1616+
try {
1617+
tpe.baseClassesCache = null
1618+
tpe.baseClassesCache = tpe.memo(computeBaseClasses)(tpe.typeSymbol :: _.baseClasses.tail)
1619+
} finally {
1620+
Statistics.popTimer(typeOpsStack, start)
1621+
}
16171622
}
16181623
}
16191624
if (tpe.baseClassesCache eq null)
@@ -6909,6 +6914,7 @@ object TypesStats {
69096914
val findMemberNanos = Statistics.newStackableTimer("time spent in findmember", typerNanos)
69106915
val asSeenFromNanos = Statistics.newStackableTimer("time spent in asSeenFrom", typerNanos)
69116916
val baseTypeSeqNanos = Statistics.newStackableTimer("time spent in baseTypeSeq", typerNanos)
6917+
val baseClassesNanos = Statistics.newStackableTimer("time spent in baseClasses", typerNanos)
69126918
val compoundBaseTypeSeqCount = Statistics.newSubCounter(" of which for compound types", baseTypeSeqCount)
69136919
val typerefBaseTypeSeqCount = Statistics.newSubCounter(" of which for typerefs", baseTypeSeqCount)
69146920
val singletonBaseTypeSeqCount = Statistics.newSubCounter(" of which for singletons", baseTypeSeqCount)

0 commit comments

Comments
 (0)