Skip to content

Commit d894be6

Browse files
committed
Make isCOmpanion test cheaper
As explained in the comment, a scalacLinkedClass must also be a true companion unless the original symbol is a root. This avoids us to drop the (potentially large) unpickled map and save some memory.
1 parent 1b4ca37 commit d894be6

File tree

1 file changed

+27
-6
lines changed

1 file changed

+27
-6
lines changed

src/dotty/tools/dotc/core/tasty/TreeUnpickler.scala

Lines changed: 27 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -41,23 +41,36 @@ class TreeUnpickler(reader: TastyReader, tastyName: TastyName.Table) {
4141
this.positions = positions
4242
}
4343

44+
/** A map from addresses of definition entries to the symbols they define */
4445
private val symAtAddr = new mutable.HashMap[Addr, Symbol]
45-
private val unpickledSyms = new mutable.HashSet[Symbol]
46+
47+
/** A temporary map from addresses of definition entries to the trees they define.
48+
* Used to remember trees of symbols that are created by a completion. Emptied
49+
* once the tree is inlined into a larger tree.
50+
*/
4651
private val treeAtAddr = new mutable.HashMap[Addr, Tree]
47-
private val typeAtAddr = new mutable.HashMap[Addr, Type] // currently populated only for types that are known to be SHAREd.
52+
53+
/** A map from addresses of type entries to the types they define.
54+
* Currently only populated for types that might be recursively referenced
55+
* from within themselves (i.e. RefinedTypes, PolyTypes, MethodTypes).
56+
*/
57+
private val typeAtAddr = new mutable.HashMap[Addr, Type]
4858

4959
/** The root symbol denotation which are defined by the Tasty file associated with this
5060
* TreeUnpickler. Set by `enterTopLevel`.
5161
*/
5262
private var roots: Set[SymDenotation] = null
5363

64+
/** The root symbols that are defined in this Tasty file. This
65+
* is a subset of `roots.map(_.symbol)`.
66+
*/
67+
private var seenRoots: Set[Symbol] = Set()
68+
5469
/** The root owner tree. See `OwnerTree` class definition. Set by `enterTopLevel`. */
5570
private var ownerTree: OwnerTree = _
5671

57-
private def registerSym(addr: Addr, sym: Symbol) = {
72+
private def registerSym(addr: Addr, sym: Symbol) =
5873
symAtAddr(addr) = sym
59-
unpickledSyms += sym
60-
}
6174

6275
/** Enter all toplevel classes and objects into their scopes
6376
* @param roots a set of SymDenotations that should be overwritten by unpickling
@@ -466,6 +479,7 @@ class TreeUnpickler(reader: TastyReader, tastyName: TastyName.Table) {
466479
new Completer(ctx.owner, subReader(start, end)) with SymbolLoaders.SecondCompleter)
467480
rootd.flags = flags &~ Touched // allow one more completion
468481
rootd.privateWithin = privateWithin
482+
seenRoots += rootd.symbol
469483
rootd.symbol
470484
case _ =>
471485
val completer = adjustIfModule(new Completer(ctx.owner, subReader(start, end)))
@@ -675,7 +689,14 @@ class TreeUnpickler(reader: TastyReader, tastyName: TastyName.Table) {
675689
case TYPEDEF | TYPEPARAM =>
676690
if (sym.isClass) {
677691
val companion = sym.scalacLinkedClass
678-
if (companion != NoSymbol && unpickledSyms.contains(companion)) {
692+
693+
// Is the companion defined in the same Tasty file as `sym`?
694+
// The only case top check here is if `sym` is a root. In this case
695+
// `companion` might have been entered by the environment but it might
696+
// been missing from the Tasty file. So we check explicitly for that.
697+
def isCodefined =
698+
roots.contains(companion.denot) == seenRoots.contains(companion)
699+
if (companion.exists && isCodefined) {
679700
import transform.SymUtils._
680701
if (sym is Flags.ModuleClass) sym.registerCompanionMethod(nme.COMPANION_CLASS_METHOD, companion)
681702
else sym.registerCompanionMethod(nme.COMPANION_MODULE_METHOD, companion)

0 commit comments

Comments
 (0)