@@ -471,10 +471,44 @@ class ClassfileLoader(val classfile: AbstractFile) extends SymbolLoader {
471471 classfileParser.run()
472472}
473473
474+ object TastyLoader :
475+
476+ /** A cache of tasty bytes read from AbstractFiles to avoid reading and
477+ * decompressing the same tasty file over multiple compiler runs.
478+ */
479+ private val tastyBytesCache = collection.mutable.WeakHashMap [AbstractFile , (Array [Byte ], Long )]()
480+
481+ /** Maximum number of files to cache tasty bytes for.
482+ *
483+ * Heuristic: cache entries up to 10% of max memory, assuming an average
484+ * tasty file size of 10 KB (in the standard library, there are currently 936
485+ * tasty files totalling ~6.9 MB, which is ~7.4 KB per (uncompressed) tasty
486+ * file). For 1 GB max memory, this gives a cache size of ~10_000 entries,
487+ * which should be more than enough in practice.
488+ *
489+ * This limit would probably only be reached when running many consecutive
490+ * compilations in the same JVM (e.g. in a build server).
491+ */
492+ private val maxTastyBytesCacheSize = Runtime .getRuntime.maxMemory() / 10 / 10_000
493+
494+ /** Get the bytes of the given tasty file, using the cache if possible. */
495+ def getTastyBytes (tastyFile : AbstractFile ): Array [Byte ] =
496+ tastyBytesCache.synchronized :
497+ val modifiedTime = tastyFile.lastModified
498+ tastyBytesCache.get(tastyFile) match
499+ case Some ((bytes, time)) if time == modifiedTime =>
500+ bytes
501+ case _ =>
502+ val bytes = tastyFile.toByteArray
503+ if tastyBytesCache.size >= maxTastyBytesCacheSize then
504+ tastyBytesCache.clear()
505+ tastyBytesCache.put(tastyFile, (bytes, modifiedTime))
506+ bytes
507+
474508class TastyLoader (val tastyFile : AbstractFile ) extends SymbolLoader {
475509 val isBestEffortTasty = tastyFile.hasBetastyExtension
476510
477- lazy val tastyBytes = tastyFile.toByteArray
511+ private def tastyBytes = TastyLoader .getTastyBytes(tastyFile)
478512
479513 private lazy val unpickler : tasty.DottyUnpickler =
480514 handleUnpicklingExceptions :
0 commit comments