Skip to content

Commit 11ec7a1

Browse files
committed
Cache also private members
This means we have to do extra work for a nonPrivateMember that hits a private member. But that's probably not a very common case. On the other hand, every find member operation needs one less scope lookup this way.
1 parent d90f8cd commit 11ec7a1

File tree

4 files changed

+52
-70
lines changed

4 files changed

+52
-70
lines changed

compiler/src/dotty/tools/dotc/core/Denotations.scala

Lines changed: 6 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1022,7 +1022,12 @@ object Denotations {
10221022
def filterDisjoint(denots: PreDenotation)(using Context): SingleDenotation =
10231023
if (denots.exists && denots.matches(this)) NoDenotation else this
10241024
def filterWithFlags(required: FlagSet, excluded: FlagSet)(using Context): SingleDenotation =
1025-
if (required.isEmpty && excluded.isEmpty || compatibleWith(required, excluded)) this else NoDenotation
1025+
def symd: SymDenotation = this match
1026+
case symd: SymDenotation => symd
1027+
case _ => symbol.denot
1028+
if !required.isEmpty && !symd.isAllOf(required)
1029+
|| !excluded.isEmpty && symd.isOneOf(excluded) then NoDenotation
1030+
else this
10261031
def aggregate[T](f: SingleDenotation => T, g: (T, T) => T): T = f(this)
10271032

10281033
type AsSeenFromResult = SingleDenotation
@@ -1056,16 +1061,6 @@ object Denotations {
10561061
if (!owner.membersNeedAsSeenFrom(pre) || symbol.is(NonMember)) this
10571062
else derived(symbol.info)
10581063
}
1059-
1060-
/** Does this denotation have all the `required` flags but none of the `excluded` flags?
1061-
*/
1062-
private def compatibleWith(required: FlagSet, excluded: FlagSet)(using Context): Boolean = {
1063-
val symd: SymDenotation = this match {
1064-
case symd: SymDenotation => symd
1065-
case _ => symbol.denot
1066-
}
1067-
symd.isAllOf(required) && !symd.isOneOf(excluded)
1068-
}
10691064
}
10701065

10711066
abstract class NonSymSingleDenotation(symbol: Symbol, initInfo: Type, override val prefix: Type) extends SingleDenotation(symbol, initInfo) {

compiler/src/dotty/tools/dotc/core/Scopes.scala

Lines changed: 2 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -148,12 +148,11 @@ object Scopes {
148148
* Symbols occur in the result in reverse order relative to their occurrence
149149
* in `this.toList`.
150150
*/
151-
final def denotsNamed(name: Name, select: SymDenotation => Boolean = selectAll)(using Context): PreDenotation = {
151+
final def denotsNamed(name: Name)(using Context): PreDenotation = {
152152
var syms: PreDenotation = NoDenotation
153153
var e = lookupEntry(name)
154154
while (e != null) {
155-
val d = e.sym.denot
156-
if (select(d)) syms = syms union d
155+
syms = syms union e.sym.denot
157156
e = lookupNextEntry(e)
158157
}
159158
syms
@@ -458,10 +457,6 @@ object Scopes {
458457
*/
459458
def scopeTransform(owner: Symbol)(op: => MutableScope): MutableScope = op
460459

461-
val selectAll: SymDenotation => Boolean = alwaysTrue
462-
val selectPrivate: SymDenotation => Boolean = d => (d.flagsUNSAFE is Flags.Private)
463-
val selectNonPrivate: SymDenotation => Boolean = d => !(d.flagsUNSAFE is Flags.Private)
464-
465460
/** The empty scope (immutable).
466461
*/
467462
object EmptyScope extends Scope {

compiler/src/dotty/tools/dotc/core/SymDenotations.scala

Lines changed: 42 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -1855,61 +1855,53 @@ object SymDenotations {
18551855
* The elements of the returned pre-denotation all
18561856
* have existing symbols.
18571857
*/
1858-
final def membersNamed(name: Name)(using Context): PreDenotation = {
1859-
val privates = info.decls.denotsNamed(name, selectPrivate)
1860-
privates union nonPrivateMembersNamed(name).filterDisjoint(privates)
1861-
}
1862-
1863-
/** All non-private members of this class that have the given name.
1864-
* The elements of the returned pre-denotation all
1865-
* have existing symbols.
1866-
* @param inherited The method is called on a parent class from computeNPMembersNamed
1867-
*/
1868-
final def nonPrivateMembersNamed(name: Name)(using Context): PreDenotation = {
1869-
Stats.record("nonPrivateMembersNamed")
1870-
if (Config.cacheMembersNamed) {
1858+
final def membersNamed(name: Name)(using Context): PreDenotation =
1859+
Stats.record("membersNamed")
1860+
if Config.cacheMembersNamed then
18711861
var denots: PreDenotation = memberCache.lookup(name)
1872-
if (denots == null) {
1873-
denots = computeNPMembersNamed(name)
1862+
if denots == null then
1863+
denots = computeMembersNamed(name)
18741864
memberCache.enter(name, denots)
1875-
}
1876-
else if (Config.checkCacheMembersNamed) {
1877-
val denots1 = computeNPMembersNamed(name)
1865+
else if Config.checkCacheMembersNamed then
1866+
val denots1 = computeMembersNamed(name)
18781867
assert(denots.exists == denots1.exists, s"cache inconsistency: cached: $denots, computed $denots1, name = $name, owner = $this")
1879-
}
18801868
denots
1881-
}
1882-
else computeNPMembersNamed(name)
1883-
}
1869+
else computeMembersNamed(name)
1870+
18841871

1885-
private[core] def computeNPMembersNamed(name: Name)(using Context): PreDenotation = {
1886-
Stats.record("computeNPMembersNamed after fingerprint")
1887-
ensureCompleted()
1888-
val ownDenots = info.decls.denotsNamed(name, selectNonPrivate)
1889-
if (debugTrace) // DEBUG
1872+
/** All non-private members of this class that have the given name.
1873+
* The elements of the returned pre-denotation all have existing symbols.
1874+
*/
1875+
final def nonPrivateMembersNamed(name: Name)(using Context): PreDenotation =
1876+
val mbr = membersNamed(name)
1877+
val nonPrivate = mbr.filterWithFlags(EmptyFlags, Private)
1878+
if nonPrivate eq mbr then mbr
1879+
else addInherited(name, nonPrivate)
1880+
1881+
private[core] def computeMembersNamed(name: Name)(using Context): PreDenotation =
1882+
Stats.record("computeMembersNamed")
1883+
val ownDenots = info.decls.denotsNamed(name)
1884+
if debugTrace then
18901885
println(s"$this.member($name), ownDenots = $ownDenots")
1891-
def collect(denots: PreDenotation, parents: List[Type]): PreDenotation = parents match {
1886+
if name.isConstructorName then ownDenots
1887+
else addInherited(name, ownDenots)
1888+
1889+
private def addInherited(name: Name, ownDenots: PreDenotation)(using Context): PreDenotation =
1890+
def collect(denots: PreDenotation, parents: List[Type]): PreDenotation = parents match
18921891
case p :: ps =>
18931892
val denots1 = collect(denots, ps)
1894-
p.classSymbol.denot match {
1893+
p.classSymbol.denot match
18951894
case parentd: ClassDenotation =>
1896-
denots1.union(
1897-
parentd.nonPrivateMembersNamed(name)
1898-
.mapInherited(ownDenots, denots1, thisType))
1895+
val inherited = parentd.nonPrivateMembersNamed(name)
1896+
denots1.union(inherited.mapInherited(ownDenots, denots1, thisType))
18991897
case _ =>
19001898
denots1
1901-
}
1902-
case nil =>
1903-
denots
1904-
}
1905-
if (name.isConstructorName) ownDenots
1906-
else collect(ownDenots, classParents)
1907-
}
1899+
case nil => denots
1900+
collect(ownDenots, classParents)
19081901

1909-
override final def findMember(name: Name, pre: Type, required: FlagSet, excluded: FlagSet)(using Context): Denotation = {
1910-
val raw = if (excluded.is(Private)) nonPrivateMembersNamed(name) else membersNamed(name)
1902+
override final def findMember(name: Name, pre: Type, required: FlagSet, excluded: FlagSet)(using Context): Denotation =
1903+
val raw = if excluded.is(Private) then nonPrivateMembersNamed(name) else membersNamed(name)
19111904
raw.filterWithFlags(required, excluded).asSeenFrom(pre).toDenot(pre)
1912-
}
19131905

19141906
/** Compute tp.baseType(this) */
19151907
final def baseTypeOf(tp: Type)(using Context): Type = {
@@ -2213,8 +2205,9 @@ object SymDenotations {
22132205
* object that hides a class or object in the scala package of the same name, because
22142206
* the behavior would then be unintuitive for such members.
22152207
*/
2216-
override def computeNPMembersNamed(name: Name)(using Context): PreDenotation = {
2217-
def recur(pobjs: List[ClassDenotation], acc: PreDenotation): PreDenotation = pobjs match {
2208+
override def computeMembersNamed(name: Name)(using Context): PreDenotation =
2209+
2210+
def recur(pobjs: List[ClassDenotation], acc: PreDenotation): PreDenotation = pobjs match
22182211
case pcls :: pobjs1 =>
22192212
if (pcls.isCompleting) recur(pobjs1, acc)
22202213
else
@@ -2225,12 +2218,11 @@ object SymDenotations {
22252218
}
22262219
recur(pobjs1, acc.union(pobjMembers))
22272220
case nil =>
2228-
val directMembers = super.computeNPMembersNamed(name)
2221+
val directMembers = super.computeMembersNamed(name)
22292222
if !acc.exists then directMembers
22302223
else acc.union(directMembers.filterWithPredicate(!_.symbol.isAbsent())) match
22312224
case d: DenotUnion => dropStale(d)
22322225
case d => d
2233-
}
22342226

22352227
def dropStale(multi: DenotUnion): PreDenotation =
22362228
val compiledNow = multi.filterWithPredicate(d =>
@@ -2272,13 +2264,12 @@ object SymDenotations {
22722264
multi.filterWithPredicate(_.symbol.associatedFile == chosen)
22732265
end dropStale
22742266

2275-
if (symbol `eq` defn.ScalaPackageClass) {
2276-
val denots = super.computeNPMembersNamed(name)
2277-
if (denots.exists || name == nme.CONSTRUCTOR) denots
2267+
if symbol eq defn.ScalaPackageClass then
2268+
val denots = super.computeMembersNamed(name)
2269+
if denots.exists || name == nme.CONSTRUCTOR then denots
22782270
else recur(packageObjs, NoDenotation)
2279-
}
22802271
else recur(packageObjs, NoDenotation)
2281-
}
2272+
end computeMembersNamed
22822273

22832274
/** The union of the member names of the package and the package object */
22842275
override def memberNames(keepOnly: NameFilter)(implicit onBehalf: MemberNames, ctx: Context): Set[Name] = {

compiler/src/dotty/tools/dotc/transform/Instrumentation.scala

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,8 @@ class Instrumentation extends MiniPhase { thisPhase =>
3131
private val namesOfInterest = List(
3232
"::", "+=", "toString", "newArray", "box", "toCharArray",
3333
"map", "flatMap", "filter", "withFilter", "collect", "foldLeft", "foldRight", "take",
34-
"reverse", "mapConserve", "mapconserve", "filterConserve", "zip")
34+
"reverse", "mapConserve", "mapconserve", "filterConserve", "zip",
35+
"denotsNamed", "lookup", "lookupEntry", "lookupAll", "toList")
3536
private var namesToRecord: Set[Name] = _
3637

3738
private var consName: TermName = _

0 commit comments

Comments
 (0)