Skip to content

Commit 34d64f3

Browse files
authored
Merge pull request #1725 from dotty-staging/change-pickle-early
Don't retain picklers until backend.
2 parents 5b40951 + 8932d98 commit 34d64f3

File tree

9 files changed

+37
-31
lines changed

9 files changed

+37
-31
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/Compiler.scala

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ import typer.{FrontEnd, Typer, ImportInfo, RefChecks}
1111
import reporting.{Reporter, ConsoleReporter}
1212
import Phases.Phase
1313
import transform._
14+
import util.FreshNameCreator
1415
import transform.TreeTransforms.{TreeTransform, TreeTransformer}
1516
import core.DenotTransformers.DenotTransformer
1617
import core.Denotations.SingleDenotation
@@ -140,7 +141,8 @@ class Compiler {
140141
.setTyper(new Typer)
141142
.setMode(Mode.ImplicitsEnabled)
142143
.setTyperState(new MutableTyperState(ctx.typerState, ctx.typerState.reporter, isCommittable = true))
143-
ctx.initialize()(start) // re-initialize the base context with start
144+
.setFreshNames(new FreshNameCreator.Default)
145+
ctx.initialize()(start) // re-initialize the base context with start
144146
def addImport(ctx: Context, refFn: () => TermRef) =
145147
ctx.fresh.setImportInfo(ImportInfo.rootImport(refFn)(ctx))
146148
(start.setRunInfo(new RunInfo(start)) /: defn.RootImportFns)(addImport)

src/dotty/tools/dotc/Run.scala

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,9 @@ class Run(comp: Compiler)(implicit ctx: Context) {
8282
ctx.informTime(s"$phase ", start)
8383
}
8484
if (!ctx.reporter.hasErrors) Rewrites.writeBack()
85+
for (unit <- units)
86+
Stats.record("retained typed trees at end", unit.tpdTree.treeSize)
87+
Stats.record("total trees at end", ast.Trees.ntrees)
8588
}
8689

8790
private sealed trait PrintedTree

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

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -105,7 +105,7 @@ object SymDenotations {
105105
ownerIfExists: Symbol,
106106
final val name: Name,
107107
initFlags: FlagSet,
108-
final val initInfo: Type,
108+
initInfo: Type,
109109
initPrivateWithin: Symbol = NoSymbol) extends SingleDenotation(symbol) {
110110

111111
//assert(symbol.id != 4940, name)
@@ -232,7 +232,7 @@ object SymDenotations {
232232
case _ =>
233233
}
234234
*/
235-
if (Config.checkNoSkolemsInInfo) assertNoSkolems(initInfo)
235+
if (Config.checkNoSkolemsInInfo) assertNoSkolems(tp)
236236
myInfo = tp
237237
}
238238

@@ -751,7 +751,7 @@ object SymDenotations {
751751
// def isOverridable: Boolean = !!! need to enforce that classes cannot be redefined
752752
def isSkolem: Boolean = name == nme.SKOLEM
753753

754-
def isInlineMethod(implicit ctx: Context): Boolean = is(InlineMethod, butNot = Accessor)
754+
def isInlineMethod(implicit ctx: Context): Boolean = is(InlineMethod, butNot = Accessor)
755755

756756
// ------ access to related symbols ---------------------------------
757757

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.addrOfTree).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

src/dotty/tools/dotc/typer/FrontEnd.scala

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,6 @@ import config.Printers.{typr, default}
1212
import util.Stats._
1313
import scala.util.control.NonFatal
1414
import ast.Trees._
15-
import util.FreshNameCreator
1615

1716
class FrontEnd extends Phase {
1817

@@ -49,8 +48,8 @@ class FrontEnd extends Phase {
4948
val unit = ctx.compilationUnit
5049
unit.tpdTree = ctx.typer.typedExpr(unit.untpdTree)
5150
typr.println("typed: " + unit.source)
52-
record("retainedUntypedTrees", unit.untpdTree.treeSize)
53-
record("retainedTypedTrees", unit.tpdTree.treeSize)
51+
record("retained untyped trees", unit.untpdTree.treeSize)
52+
record("retained typed trees after typer", unit.tpdTree.treeSize)
5453
}
5554

5655
private def firstTopLevelDef(trees: List[tpd.Tree])(implicit ctx: Context): Symbol = trees match {
@@ -64,13 +63,15 @@ class FrontEnd extends Phase {
6463
unit.isJava || firstTopLevelDef(unit.tpdTree :: Nil).isPrimitiveValueClass
6564

6665
override def runOn(units: List[CompilationUnit])(implicit ctx: Context): List[CompilationUnit] = {
67-
val unitContexts = for (unit <- units) yield
68-
ctx.fresh.setCompilationUnit(unit).setFreshNames(new FreshNameCreator.Default)
66+
val unitContexts = for (unit <- units) yield {
67+
ctx.inform(s"compiling ${unit.source}")
68+
ctx.fresh.setCompilationUnit(unit)
69+
}
6970
unitContexts foreach (parse(_))
7071
record("parsedTrees", ast.Trees.ntrees)
7172
unitContexts foreach (enterSyms(_))
7273
unitContexts foreach (typeCheck(_))
73-
record("totalTrees", ast.Trees.ntrees)
74+
record("total trees after typer", ast.Trees.ntrees)
7475
unitContexts.map(_.compilationUnit).filterNot(discardAfterTyper)
7576
}
7677

src/dotty/tools/dotc/typer/ProtoTypes.scala

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -477,11 +477,9 @@ object ProtoTypes {
477477
def apply(tp: Type) = wildApprox(tp, this)
478478
}
479479

480-
@sharable private lazy val dummyTree = untpd.Literal(Constant(null))
481-
482480
/** Dummy tree to be used as an argument of a FunProto or ViewProto type */
483481
object dummyTreeOfType {
484-
def apply(tp: Type): Tree = dummyTree withTypeUnchecked tp
482+
def apply(tp: Type): Tree = untpd.Literal(Constant(null)) withTypeUnchecked tp
485483
def unapply(tree: Tree): Option[Type] = tree match {
486484
case Literal(Constant(null)) => Some(tree.typeOpt)
487485
case _ => None

test/test/DottyTest.scala

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -14,24 +14,23 @@ import dotty.tools.dotc.Compiler
1414
import dotty.tools.dotc
1515
import dotty.tools.dotc.core.Phases.Phase
1616

17-
class DottyTest /*extends ContextEscapeDetection*/ {
17+
class DottyTest extends ContextEscapeDetection{
1818

1919
dotty.tools.dotc.parsing.Scanners // initialize keywords
2020

2121
implicit var ctx: Contexts.Context = {
22-
val base = new ContextBase
22+
val base = new ContextBase {}
2323
import base.settings._
2424
val ctx = base.initialCtx.fresh
2525
base.initialize()(ctx)
2626
ctx.setSetting(ctx.settings.encoding, "UTF8")
2727
ctx
2828
}
29-
/*
29+
3030
override def getCtx: Context = ctx
3131
override def clearCtx() = {
3232
ctx = null
3333
}
34-
*/
3534
private def compilerWithChecker(phase: String)(assertion:(tpd.Tree, Context) => Unit) = new Compiler {
3635
override def phases = {
3736
val allPhases = super.phases

0 commit comments

Comments
 (0)