Skip to content

Commit e045ba3

Browse files
committed
Attempt #3 to optimize findMember
Fixed fingerPrinting scheme to work with rehashes, also added finger prints to typedIdent searches.
1 parent 231d8ea commit e045ba3

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
@@ -4509,6 +4509,8 @@ trait Typers extends Modes with Adaptations with Tags {
45094509
assert(errorContainer == null, "Cannot set ambiguous error twice for identifier")
45104510
errorContainer = tree
45114511
}
4512+
4513+
val fingerPrint: Long = name.fingerPrint
45124514

45134515
var defSym: Symbol = tree.symbol // the directly found symbol
45144516
var pre: Type = NoPrefix // the prefix type of defSym, if a class member
@@ -4547,7 +4549,10 @@ trait Typers extends Modes with Adaptations with Tags {
45474549
var cx = startingIdentContext
45484550
while (defSym == NoSymbol && cx != NoContext && (cx.scope ne null)) { // cx.scope eq null arises during FixInvalidSyms in Duplicators
45494551
pre = cx.enclClass.prefix
4550-
defEntry = cx.scope.lookupEntry(name)
4552+
defEntry = {
4553+
val scope = cx.scope
4554+
if ((fingerPrint & scope.fingerPrints) != 0) scope.lookupEntry(name) else null
4555+
}
45514556
if ((defEntry ne null) && qualifies(defEntry.sym)) {
45524557
// Right here is where SI-1987, overloading in package objects, can be
45534558
// 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
@@ -1046,7 +1046,7 @@ trait Types extends api.Types { self: SymbolTable =>
10461046
var continue = true
10471047
var self: Type = null
10481048
var membertpe: Type = null
1049-
val fingerPrint: Long = (1L << name.start)
1049+
val fingerPrint: Long = name.fingerPrint
10501050
while (continue) {
10511051
continue = false
10521052
val bcs0 = baseClasses
@@ -1613,8 +1613,13 @@ trait Types extends api.Types { self: SymbolTable =>
16131613
if (period != currentPeriod) {
16141614
tpe.baseClassesPeriod = currentPeriod
16151615
if (!isValidForBaseClasses(period)) {
1616-
tpe.baseClassesCache = null
1617-
tpe.baseClassesCache = tpe.memo(computeBaseClasses)(tpe.typeSymbol :: _.baseClasses.tail)
1616+
val start = Statistics.pushTimer(typeOpsStack, baseClassesNanos)
1617+
try {
1618+
tpe.baseClassesCache = null
1619+
tpe.baseClassesCache = tpe.memo(computeBaseClasses)(tpe.typeSymbol :: _.baseClasses.tail)
1620+
} finally {
1621+
Statistics.popTimer(typeOpsStack, start)
1622+
}
16181623
}
16191624
}
16201625
if (tpe.baseClassesCache eq null)
@@ -6920,6 +6925,7 @@ object TypesStats {
69206925
val findMemberNanos = Statistics.newStackableTimer("time spent in findmember", typerNanos)
69216926
val asSeenFromNanos = Statistics.newStackableTimer("time spent in asSeenFrom", typerNanos)
69226927
val baseTypeSeqNanos = Statistics.newStackableTimer("time spent in baseTypeSeq", typerNanos)
6928+
val baseClassesNanos = Statistics.newStackableTimer("time spent in baseClasses", typerNanos)
69236929
val compoundBaseTypeSeqCount = Statistics.newSubCounter(" of which for compound types", baseTypeSeqCount)
69246930
val typerefBaseTypeSeqCount = Statistics.newSubCounter(" of which for typerefs", baseTypeSeqCount)
69256931
val singletonBaseTypeSeqCount = Statistics.newSubCounter(" of which for singletons", baseTypeSeqCount)

0 commit comments

Comments
 (0)