@@ -18,6 +18,7 @@ import printing.Printer
1818import printing .Texts ._
1919import util .SourceFile
2020import annotation .constructorOnly
21+ import collection .mutable
2122
2223object TreePickler {
2324
@@ -44,6 +45,15 @@ class TreePickler(pickler: TastyPickler) {
4445 private val forwardSymRefs = Symbols .newMutableSymbolMap[List [Addr ]]
4546 private val pickledTypes = new java.util.IdentityHashMap [Type , Any ] // Value type is really Addr, but that's not compatible with null
4647
48+ /** A list of annotation trees for every member definition, so that later
49+ * parallel position pickling does not need to access and force symbols.
50+ */
51+ private val annotTrees = util.HashTable [untpd.MemberDef , mutable.ListBuffer [Tree ]]()
52+
53+ def treeAnnots (tree : untpd.MemberDef ): List [Tree ] =
54+ val ts = annotTrees.lookup(tree)
55+ if ts == null then Nil else ts.toList
56+
4757 private def withLength (op : => Unit ) = {
4858 val lengthAddr = reserveRef(relative = true )
4959 op
@@ -309,7 +319,8 @@ class TreePickler(pickler: TastyPickler) {
309319 if (! tree.isEmpty) pickleTree(tree)
310320 }
311321
312- def pickleDef (tag : Int , sym : Symbol , tpt : Tree , rhs : Tree = EmptyTree , pickleParams : => Unit = ())(using Context ): Unit = {
322+ def pickleDef (tag : Int , mdef : MemberDef , tpt : Tree , rhs : Tree = EmptyTree , pickleParams : => Unit = ())(using Context ): Unit = {
323+ val sym = mdef.symbol
313324 assert(symRefs(sym) == NoAddr , sym)
314325 registerDef(sym)
315326 writeByte(tag)
@@ -321,16 +332,16 @@ class TreePickler(pickler: TastyPickler) {
321332 case _ if tpt.isType => pickleTpt(tpt)
322333 }
323334 pickleTreeUnlessEmpty(rhs)
324- pickleModifiers(sym)
335+ pickleModifiers(sym, mdef )
325336 }
326337 }
327338
328339 def pickleParam (tree : Tree )(using Context ): Unit = {
329340 registerTreeAddr(tree)
330341 tree match {
331- case tree : ValDef => pickleDef(PARAM , tree.symbol , tree.tpt)
332- case tree : DefDef => pickleDef(PARAM , tree.symbol , tree.tpt, tree.rhs)
333- case tree : TypeDef => pickleDef(TYPEPARAM , tree.symbol , tree.rhs)
342+ case tree : ValDef => pickleDef(PARAM , tree, tree.tpt)
343+ case tree : DefDef => pickleDef(PARAM , tree, tree.tpt, tree.rhs)
344+ case tree : TypeDef => pickleDef(TYPEPARAM , tree, tree.rhs)
334345 }
335346 }
336347
@@ -520,7 +531,7 @@ class TreePickler(pickler: TastyPickler) {
520531 patterns.foreach(pickleTree)
521532 }
522533 case tree : ValDef =>
523- pickleDef(VALDEF , tree.symbol , tree.tpt, tree.rhs)
534+ pickleDef(VALDEF , tree, tree.tpt, tree.rhs)
524535 case tree : DefDef =>
525536 def pickleParamss (paramss : List [List [ValDef ]]): Unit = paramss match
526537 case Nil =>
@@ -531,9 +542,9 @@ class TreePickler(pickler: TastyPickler) {
531542 def pickleAllParams =
532543 pickleParams(tree.tparams)
533544 pickleParamss(tree.vparamss)
534- pickleDef(DEFDEF , tree.symbol , tree.tpt, tree.rhs, pickleAllParams)
545+ pickleDef(DEFDEF , tree, tree.tpt, tree.rhs, pickleAllParams)
535546 case tree : TypeDef =>
536- pickleDef(TYPEDEF , tree.symbol , tree.rhs)
547+ pickleDef(TYPEDEF , tree, tree.rhs)
537548 case tree : Template =>
538549 registerDef(tree.symbol)
539550 writeByte(TEMPLATE )
@@ -648,7 +659,7 @@ class TreePickler(pickler: TastyPickler) {
648659 pickleName(id.name)
649660 }
650661
651- def pickleModifiers (sym : Symbol )(using Context ): Unit = {
662+ def pickleModifiers (sym : Symbol , mdef : MemberDef )(using Context ): Unit = {
652663 import Flags ._
653664 var flags = sym.flags
654665 val privateWithin = sym.privateWithin
@@ -660,7 +671,7 @@ class TreePickler(pickler: TastyPickler) {
660671 if (flags.is(ParamAccessor ) && sym.isTerm && ! sym.isSetter)
661672 flags = flags &~ ParamAccessor // we only generate a tag for parameter setters
662673 pickleFlags(flags, sym.isTerm)
663- sym.annotations.foreach(pickleAnnotation(sym, _))
674+ val annots = sym.annotations.foreach(pickleAnnotation(sym, mdef , _))
664675 }
665676
666677 def pickleFlags (flags : FlagSet , isTerm : Boolean )(using Context ): Unit = {
@@ -723,12 +734,15 @@ class TreePickler(pickler: TastyPickler) {
723734 ann.symbol == defn.BodyAnnot // inline bodies are reconstituted automatically when unpickling
724735 }
725736
726- def pickleAnnotation (owner : Symbol , ann : Annotation )(using Context ): Unit = {
727- if ( ! isUnpicklable(owner, ann)) {
737+ def pickleAnnotation (owner : Symbol , mdef : MemberDef , ann : Annotation )(using Context ): Unit =
738+ if ! isUnpicklable(owner, ann) then
728739 writeByte(ANNOTATION )
729740 withLength { pickleType(ann.symbol.typeRef); pickleTree(ann.tree) }
730- }
731- }
741+ var treeBuf = annotTrees.lookup(mdef)
742+ if treeBuf == null then
743+ treeBuf = new mutable.ListBuffer [Tree ]
744+ annotTrees.enter(mdef, treeBuf)
745+ treeBuf += ann.tree
732746
733747// ---- main entry points ---------------------------------------
734748
0 commit comments