diff options
author | Martin Odersky <odersky@gmail.com> | 2012-07-12 13:09:21 +0200 |
---|---|---|
committer | Adriaan Moors <adriaan.moors@epfl.ch> | 2012-07-14 12:09:30 +0200 |
commit | 1a73aa087e9ccd7584d91c653a8b61905da7c904 (patch) | |
tree | 9584abca5c63f980734495478a28f0a2587fdf8b /src | |
parent | 026a70d55591c3b5ee157e22998b62168afee686 (diff) | |
download | scala-1a73aa087e9ccd7584d91c653a8b61905da7c904.tar.gz scala-1a73aa087e9ccd7584d91c653a8b61905da7c904.tar.bz2 scala-1a73aa087e9ccd7584d91c653a8b61905da7c904.zip |
Attempt #1 to optimize findMember
Keeps fingerprints in scopes which are bitsets telling you what the last 6 bits of each hashcode of the names stored in the scope are. findMember will avoid looking in a scope if inferprints do not match.
Diffstat (limited to 'src')
-rw-r--r-- | src/reflect/scala/reflect/internal/Scopes.scala | 15 | ||||
-rw-r--r-- | src/reflect/scala/reflect/internal/Types.scala | 5 |
2 files changed, 16 insertions, 4 deletions
diff --git a/src/reflect/scala/reflect/internal/Scopes.scala b/src/reflect/scala/reflect/internal/Scopes.scala index ceacd2afb0..939cd556a6 100644 --- a/src/reflect/scala/reflect/internal/Scopes.scala +++ b/src/reflect/scala/reflect/internal/Scopes.scala @@ -42,6 +42,11 @@ trait Scopes extends api.Scopes { self: SymbolTable => * SynchronizedScope as mixin. */ class Scope protected[Scopes] (initElems: ScopeEntry = null) extends Iterable[Symbol] { + + /** A bitset containing the last 6 bits of the start value of every name + * stored in this scope. + */ + var fingerPrints: Long = 0L protected[Scopes] def this(base: Scope) = { this(base.elems) @@ -95,7 +100,7 @@ trait Scopes extends api.Scopes { self: SymbolTable => * * @param e ... */ - protected def enter(e: ScopeEntry) { + protected def enterEntry(e: ScopeEntry) { elemsCache = null if (hashtable ne null) enterInHash(e) @@ -113,7 +118,11 @@ trait Scopes extends api.Scopes { self: SymbolTable => * * @param sym ... */ - def enter[T <: Symbol](sym: T): T = { enter(newScopeEntry(sym, this)); sym } + def enter[T <: Symbol](sym: T): T = { + fingerPrints |= (1L << sym.name.start) + enterEntry(newScopeEntry(sym, this)) + sym + } /** enter a symbol, asserting that no symbol with same name exists in scope * @@ -344,7 +353,7 @@ trait Scopes extends api.Scopes { self: SymbolTable => /** The empty scope (immutable). */ object EmptyScope extends Scope { - override def enter(e: ScopeEntry) { + override def enterEntry(e: ScopeEntry) { abort("EmptyScope.enter") } } diff --git a/src/reflect/scala/reflect/internal/Types.scala b/src/reflect/scala/reflect/internal/Types.scala index 56cc265e48..191981efef 100644 --- a/src/reflect/scala/reflect/internal/Types.scala +++ b/src/reflect/scala/reflect/internal/Types.scala @@ -1045,6 +1045,7 @@ trait Types extends api.Types { self: SymbolTable => var continue = true var self: Type = null var membertpe: Type = null + val fingerPrint: Long = (1L << name.start) while (continue) { continue = false val bcs0 = baseClasses @@ -1052,7 +1053,9 @@ trait Types extends api.Types { self: SymbolTable => while (!bcs.isEmpty) { val decls = bcs.head.info.decls var entry = - if (name == nme.ANYNAME) decls.elems else decls.lookupEntry(name) + if (name == nme.ANYNAME) decls.elems + else if ((fingerPrint & decls.fingerPrints) == 0) null + else decls.lookupEntry(name) while (entry ne null) { val sym = entry.sym if (sym hasAllFlags requiredFlags) { |