Skip to content

Commit 3d58ebc

Browse files
committed
Don't keep full picklers around until backend.
The memory footprint captured by pickler seems to be about 1/3rd of total footprint. So we gain a lot by not making this die sooner rather than later.
1 parent 601a286 commit 3d58ebc

File tree

3 files changed

+17
-14
lines changed

3 files changed

+17
-14
lines changed

src/dotty/tools/backend/jvm/GenBCode.scala

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -203,8 +203,7 @@ class GenBCodePipeline(val entryPoints: List[Symbol], val int: DottyBackendInter
203203
val plainC = pcb.cnode
204204

205205
if (claszSymbol.isClass) // @DarkDimius is this test needed here?
206-
for (pickler <- ctx.compilationUnit.picklers.get(claszSymbol.asClass)) {
207-
val binary = pickler.assembleParts()
206+
for (binary <- ctx.compilationUnit.pickled.get(claszSymbol.asClass)) {
208207
val dataAttr = new CustomAttr(nme.TASTYATTR.toString, binary)
209208
(if (mirrorC ne null) mirrorC else plainC).visitAttribute(dataAttr)
210209
}

src/dotty/tools/dotc/CompilationUnit.scala

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -17,12 +17,8 @@ class CompilationUnit(val source: SourceFile) {
1717

1818
def isJava = source.file.name.endsWith(".java")
1919

20-
/**
21-
* Picklers used to create TASTY sections, indexed by toplevel class to which they belong.
22-
* Sections: Header, ASTs and Positions are populated by `pickler` phase.
23-
* Subsequent phases can add new sections.
24-
*/
25-
var picklers: Map[ClassSymbol, TastyPickler] = Map()
20+
/** Pickled TASTY binaries, indexed by class. */
21+
var pickled: Map[ClassSymbol, Array[Byte]] = Map()
2622

2723
var unpicklers: Map[ClassSymbol, TastyUnpickler] = Map()
2824
}

src/dotty/tools/dotc/transform/Pickler.scala

Lines changed: 14 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,9 @@ class Pickler extends Phase {
2525
s.close
2626
}
2727

28+
// Maps that keep a record if -Ytest-pickler is set.
2829
private val beforePickling = new mutable.HashMap[ClassSymbol, String]
30+
private val picklers = new mutable.HashMap[ClassSymbol, TastyPickler]
2931

3032
/** Drop any elements of this list that are linked module classes of other elements in the list */
3133
private def dropCompanionModuleClasses(clss: List[ClassSymbol])(implicit ctx: Context): List[ClassSymbol] = {
@@ -40,9 +42,11 @@ class Pickler extends Phase {
4042

4143
for { cls <- dropCompanionModuleClasses(topLevelClasses(unit.tpdTree))
4244
tree <- sliceTopLevel(unit.tpdTree, cls) } {
43-
if (ctx.settings.YtestPickler.value) beforePickling(cls) = tree.show
4445
val pickler = new TastyPickler()
45-
unit.picklers += (cls -> pickler)
46+
if (ctx.settings.YtestPickler.value) {
47+
beforePickling(cls) = tree.show
48+
picklers(cls) = pickler
49+
}
4650
val treePkl = pickler.treePkl
4751
treePkl.pickle(tree :: Nil)
4852
treePkl.compactify()
@@ -51,8 +55,12 @@ class Pickler extends Phase {
5155
if (tree.pos.exists)
5256
new PositionPickler(pickler, treePkl.buf.addrsOfTree).picklePositions(tree :: Nil)
5357

58+
// other pickle sections go here.
59+
val pickled = pickler.assembleParts()
60+
unit.pickled += (cls -> pickled)
61+
5462
def rawBytes = // not needed right now, but useful to print raw format.
55-
pickler.assembleParts().iterator.grouped(10).toList.zipWithIndex.map {
63+
pickled.iterator.grouped(10).toList.zipWithIndex.map {
5664
case (row, i) => s"${i}0: ${row.mkString(" ")}"
5765
}
5866
// println(i"rawBytes = \n$rawBytes%\n%") // DEBUG
@@ -66,18 +74,18 @@ class Pickler extends Phase {
6674
override def runOn(units: List[CompilationUnit])(implicit ctx: Context): List[CompilationUnit] = {
6775
val result = super.runOn(units)
6876
if (ctx.settings.YtestPickler.value)
69-
testUnpickler(units)(
77+
testUnpickler(
7078
ctx.fresh
7179
.setPeriod(Period(ctx.runId + 1, FirstPhaseId))
7280
.addMode(Mode.ReadPositions))
7381
result
7482
}
7583

76-
private def testUnpickler(units: List[CompilationUnit])(implicit ctx: Context): Unit = {
84+
private def testUnpickler(implicit ctx: Context): Unit = {
7785
pickling.println(i"testing unpickler at run ${ctx.runId}")
7886
ctx.initialize()
7987
val unpicklers =
80-
for (unit <- units; (cls, pickler) <- unit.picklers) yield {
88+
for ((cls, pickler) <- picklers) yield {
8189
val unpickler = new DottyUnpickler(pickler.assembleParts())
8290
unpickler.enter(roots = Set())
8391
cls -> unpickler

0 commit comments

Comments
 (0)