Skip to content

Commit

Permalink
Attempt scala#9 to opimize findMember.
Browse files Browse the repository at this point in the history
Also avoid recomputation of memberType in findMembers
  • Loading branch information
odersky authored and adriaanm committed Jul 14, 2012
1 parent 71d2ceb commit fcb0c01
Showing 1 changed file with 43 additions and 24 deletions.
67 changes: 43 additions & 24 deletions src/reflect/scala/reflect/internal/Types.scala
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import Flags._
import scala.util.control.ControlThrowable
import scala.annotation.tailrec
import util.Statistics
import scala.runtime.ObjectRef

/* A standard type pattern match:
case ErrorType =>
Expand Down Expand Up @@ -1031,9 +1032,21 @@ trait Types extends api.Types { self: SymbolTable =>

//Console.println("find member " + name.decode + " in " + this + ":" + this.baseClasses)//DEBUG
var members: Scope = null
var membertpes: mutable.Map[Symbol, Type] = null
var required = requiredFlags
var excluded = excludedFlags | DEFERRED
var continue = true
var self: Type = null

def getMtpe(cache: mutable.Map[Symbol, Type], sym: Symbol): Type = cache get sym match {
case Some(tpe) if tpe ne null =>
tpe
case _ =>
val result = self memberType sym
cache(sym) = result
result
}

while (continue) {
continue = false
val bcs0 = baseClasses
Expand All @@ -1044,29 +1057,31 @@ trait Types extends api.Types { self: SymbolTable =>
while (entry ne null) {
val sym = entry.sym
val flags = sym.flags
if ((flags & requiredFlags) == requiredFlags) {
if ((flags & required) == required) {
val excl = flags & excluded
if (excl == 0L &&
(// omit PRIVATE LOCALS unless selector class is contained in class owning the def.
(bcs eq bcs0) ||
(flags & PrivateLocal) != PrivateLocal ||
(bcs0.head.hasTransOwner(bcs.head)))) {
if (members eq null) members = newScope
var prevEntry = members.lookupEntry(sym.name)
var symtpe: Type = null
while ((prevEntry ne null) &&
!((prevEntry.sym eq sym) ||
(prevEntry.sym.owner ne sym.owner) &&
!sym.hasFlag(PRIVATE) && {
if (self eq null) self = this.narrow
if (symtpe eq null) symtpe = self.memberType(sym)
self.memberType(prevEntry.sym) matches symtpe
})) {
prevEntry = members lookupNextEntry prevEntry
if (members eq null) {
members = newScope
membertpes = new mutable.HashMap
}
if (prevEntry eq null) {
members enter sym
var others: ScopeEntry = members.lookupEntry(sym.name)
var symtpe: Type = null
while ((others ne null) && {
val other = others.sym
(other ne sym) &&
((other.owner eq sym.owner) ||
(flags & PRIVATE) != 0 || {
if (self eq null) self = this.narrow
if (symtpe eq null) symtpe = self.memberType(sym)
!(getMtpe(membertpes, other) matches symtpe)
})}) {
others = members lookupNextEntry others
}
if (others eq null) members enter sym
} else if (excl == DEFERRED) {
continue = true
}
Expand All @@ -1076,6 +1091,7 @@ trait Types extends api.Types { self: SymbolTable =>
// excluded = excluded | LOCAL
bcs = bcs.tail
} // while (!bcs.isEmpty)
required |= DEFERRED
excluded = excludedFlags
} // while (continue)
Statistics.popTimer(typeOpsStack, start)
Expand Down Expand Up @@ -1116,20 +1132,23 @@ trait Types extends api.Types { self: SymbolTable =>
var self: Type = null
val fingerPrint: Long = name.fingerPrint

def getMtpe(sym: Symbol, idx: Int): Type = {
def getMtpe(idx: Int, sym: Symbol): Type = {
var result = membertpes(idx)
if (result eq null) { result = self memberType sym; membertpes(idx) = result }
if (result eq null) {
result = self memberType sym
membertpes(idx) = result
}
result
}

def addMtpe(xs: Array[Type], tpe: Type, idx: Int): Array[Type] =
if (idx < xs.length ) {
def addMtpe(xs: Array[Type], idx: Int, tpe: Type): Array[Type] =
if (idx < xs.length) {
xs(idx) = tpe
xs
} else {
val ys = new Array[Type](xs.length * 2)
Array.copy(xs, 0, ys, 0, xs.length)
addMtpe(ys, tpe, idx)
addMtpe(ys, idx, tpe)
}

while (continue) {
Expand Down Expand Up @@ -1173,7 +1192,7 @@ trait Types extends api.Types { self: SymbolTable =>
membertpes(1) = symtpe
}
} else {
var others = members
var others: List[Symbol] = members
var idx = 0
var symtpe: Type = null
while ((others ne null) && {
Expand All @@ -1183,7 +1202,7 @@ trait Types extends api.Types { self: SymbolTable =>
(flags & PRIVATE) != 0 || {
if (self eq null) self = this.narrow
if (symtpe eq null) symtpe = self.memberType(sym)
!(getMtpe(other, idx) matches symtpe)
!(getMtpe(idx, other) matches symtpe)
})}) {
others = others.tail
idx += 1
Expand All @@ -1192,7 +1211,7 @@ trait Types extends api.Types { self: SymbolTable =>
val lastM1 = new ::(sym, null)
lastM.tl = lastM1
lastM = lastM1
membertpes = addMtpe(membertpes, symtpe, idx)
membertpes = addMtpe(membertpes, idx, symtpe)
}
}
} else if (excl == DEFERRED) {
Expand All @@ -1205,8 +1224,8 @@ trait Types extends api.Types { self: SymbolTable =>
// excluded = excluded | LOCAL
bcs = if (name == nme.CONSTRUCTOR) Nil else bcs.tail
} // while (!bcs.isEmpty)
excluded = excludedFlags
required |= DEFERRED
excluded = excludedFlags
} // while (continue)
Statistics.popTimer(typeOpsStack, start)
if (suspension ne null) suspension foreach (_.suspended = false)
Expand Down

0 comments on commit fcb0c01

Please sign in to comment.