Skip to content

Commit bad120f

Browse files
committed
Run position pickling in a separate task
Run position pickling and byte array assembly in a separate task
1 parent 212b8af commit bad120f

File tree

6 files changed

+51
-29
lines changed

6 files changed

+51
-29
lines changed

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

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -235,15 +235,15 @@ class GenBCodePipeline(val int: DottyBackendInterface)(using Context) extends BC
235235
if (!ctx.settings.YemitTastyInClass.value) {
236236
val outTastyFile = getFileForClassfile(outF, store.name, ".tasty")
237237
val outstream = new DataOutputStream(outTastyFile.bufferedOutput)
238-
try outstream.write(binary)
238+
try outstream.write(binary())
239239
catch case ex: ClosedByInterruptException =>
240240
try
241241
outTastyFile.delete() // don't leave an empty or half-written tastyfile around after an interrupt
242242
catch case _: Throwable =>
243243
throw ex
244244
finally outstream.close()
245245

246-
val uuid = new TastyHeaderUnpickler(binary).readHeader()
246+
val uuid = new TastyHeaderUnpickler(binary()).readHeader()
247247
val lo = uuid.getMostSignificantBits
248248
val hi = uuid.getLeastSignificantBits
249249

@@ -257,7 +257,7 @@ class GenBCodePipeline(val int: DottyBackendInterface)(using Context) extends BC
257257
// Create an empty file to signal that a tasty section exist in the corresponding .class
258258
// This is much cheaper and simpler to check than doing classfile parsing
259259
getFileForClassfile(outF, store.name, ".hasTasty")
260-
binary
260+
binary()
261261
}
262262
val dataAttr = createJAttribute(nme.TASTYATTR.mangledString, tasty, 0, tasty.length)
263263
store.visitAttribute(dataAttr)

compiler/src/dotty/tools/dotc/CompilationUnit.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ class CompilationUnit protected (val source: SourceFile) {
3030
var sourceVersion: Option[SourceVersion] = None
3131

3232
/** Pickled TASTY binaries, indexed by class. */
33-
var pickled: Map[ClassSymbol, Array[Byte]] = Map()
33+
var pickled: Map[ClassSymbol, () => Array[Byte]] = Map()
3434

3535
/** The fresh name creator for the current unit.
3636
* FIXME(#7661): This is not fine-grained enough to enable reproducible builds,

compiler/src/dotty/tools/dotc/decompiler/DecompilationPrinter.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ class DecompilationPrinter extends Phase {
3939
private def printToOutput(out: PrintStream)(using Context): Unit = {
4040
val unit = ctx.compilationUnit
4141
if (ctx.settings.printTasty.value)
42-
println(new TastyPrinter(unit.pickled.head._2).printContents())
42+
println(new TastyPrinter(unit.pickled.head._2()).printContents())
4343
else {
4444
val unitFile = unit.source.toString.replace("\\", "/").replace(".class", ".tasty")
4545
out.println(s"/** Decompiled from $unitFile */")

compiler/src/dotty/tools/dotc/decompiler/IDEDecompilerDriver.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ class IDEDecompilerDriver(val settings: List[String]) extends dotc.Driver {
3535
val unit = ctx.run.units.head
3636

3737
val decompiled = ReflectionImpl.showTree(unit.tpdTree)
38-
val tree = new TastyHTMLPrinter(unit.pickled.head._2).printContents()
38+
val tree = new TastyHTMLPrinter(unit.pickled.head._2()).printContents()
3939

4040
reporter.removeBufferedMessages.foreach(message => System.err.println(message))
4141
(tree, decompiled)

compiler/src/dotty/tools/dotc/fromtasty/ReadTasty.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ class ReadTasty extends Phase {
4040
if (cls.rootTree.isEmpty) None
4141
else {
4242
val unit = CompilationUnit(cls, cls.rootTree, forceTrees = true)
43-
unit.pickled += (cls -> unpickler.unpickler.bytes)
43+
unit.pickled += (cls -> (() => unpickler.unpickler.bytes))
4444
Some(unit)
4545
}
4646
case tree: Tree[?] =>

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

Lines changed: 44 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ import Symbols._
1313
import Flags.Module
1414
import reporting.ThrowingReporter
1515
import collection.mutable
16+
import scala.concurrent.ExecutionContext.global
1617

1718
object Pickler {
1819
val name: String = "pickler"
@@ -45,6 +46,42 @@ class Pickler extends Phase {
4546
clss.filterNot(companionModuleClasses.contains)
4647
}
4748

49+
class PickleCompleter:
50+
private var pickled: Array[Byte] = null
51+
52+
def complete(pickler: TastyPickler, cls: ClassSymbol, tree: Tree)(using Context): Unit =
53+
val treePkl = pickler.treePkl
54+
if tree.span.exists then
55+
new PositionPickler(pickler, treePkl.buf.addrOfTree).picklePositions(tree :: Nil)
56+
57+
if !ctx.settings.YdropComments.value then
58+
new CommentPickler(pickler, treePkl.buf.addrOfTree).pickleComment(tree)
59+
60+
val pickled = pickler.assembleParts()
61+
62+
def rawBytes = // not needed right now, but useful to print raw format.
63+
pickled.iterator.grouped(10).toList.zipWithIndex.map {
64+
case (row, i) => s"${i}0: ${row.mkString(" ")}"
65+
}
66+
67+
synchronized {
68+
this.pickled = pickled
69+
// println(i"rawBytes = \n$rawBytes%\n%") // DEBUG
70+
if pickling ne noPrinter then
71+
pickling.synchronized {
72+
println(i"**** pickled info of $cls")
73+
println(new TastyPrinter(pickled).printContents())
74+
}
75+
notifyAll()
76+
}
77+
end complete
78+
79+
def bytes: Array[Byte] = synchronized {
80+
if pickled == null then wait()
81+
pickled
82+
}
83+
end PickleCompleter
84+
4885
override def run(using Context): Unit = {
4986
val unit = ctx.compilationUnit
5087
pickling.println(i"unpickling in run ${ctx.runId}")
@@ -55,35 +92,20 @@ class Pickler extends Phase {
5592
}
5693
{
5794
val pickler = new TastyPickler(cls)
58-
if (ctx.settings.YtestPickler.value) {
95+
if ctx.settings.YtestPickler.value then
5996
beforePickling(cls) = tree.show
6097
picklers(cls) = pickler
61-
}
6298
val treePkl = pickler.treePkl
6399
treePkl.pickle(tree :: Nil)
64100
treePkl.compactify()
65101
pickler.addrOfTree = treePkl.buf.addrOfTree
66102
pickler.addrOfSym = treePkl.addrOfSym
67-
if (tree.span.exists)
68-
new PositionPickler(pickler, treePkl.buf.addrOfTree).picklePositions(tree :: Nil)
69-
70-
if (!ctx.settings.YdropComments.value)
71-
new CommentPickler(pickler, treePkl.buf.addrOfTree).pickleComment(tree)
72-
73-
// other pickle sections go here.
74-
val pickled = pickler.assembleParts()
75-
unit.pickled += (cls -> pickled)
76-
77-
def rawBytes = // not needed right now, but useful to print raw format.
78-
pickled.iterator.grouped(10).toList.zipWithIndex.map {
79-
case (row, i) => s"${i}0: ${row.mkString(" ")}"
80-
}
81-
82-
// println(i"rawBytes = \n$rawBytes%\n%") // DEBUG
83-
if (pickling ne noPrinter) {
84-
println(i"**** pickled info of $cls")
85-
println(new TastyPrinter(pickled).printContents())
86-
}
103+
val completer = PickleCompleter()
104+
if ctx.settings.YtestPickler.value then
105+
completer.complete(pickler, cls, tree)
106+
else
107+
global.execute(() => completer.complete(pickler, cls, tree))
108+
unit.pickled += (cls -> (() => completer.bytes))
87109
}
88110
}
89111

0 commit comments

Comments
 (0)