Skip to content

Commit 6710ac3

Browse files
committed
Support name table sharing across Global instances
- Add UI to enable name table sharing - Expose name table caching through PipelineMain
1 parent ad99127 commit 6710ac3

File tree

5 files changed

+189
-104
lines changed

5 files changed

+189
-104
lines changed

src/compiler/scala/tools/nsc/Global.scala

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ import io.{AbstractFile, Path, SourceReader}
2323
import reporters.Reporter
2424
import util.{ClassPath, returning}
2525
import scala.reflect.ClassTag
26+
import scala.reflect.internal.{NameTable, Names}
2627
import scala.reflect.internal.util.{BatchSourceFile, FreshNameCreator, NoSourceFile, ScalaClassLoader, ScriptSourceFile, SourceFile, StatisticsStatics}
2728
import scala.reflect.internal.pickling.PickleBuffer
2829
import symtab.{Flags, SymbolTable, SymbolTrackers}
@@ -35,7 +36,6 @@ import transform.patmat.PatternMatching
3536
import transform._
3637
import backend.{JavaPlatform, ScalaPrimitives}
3738
import backend.jvm.{BackendStats, GenBCode}
38-
import scala.concurrent.Future
3939
import scala.language.postfixOps
4040
import scala.tools.nsc.ast.{TreeGen => AstTreeGen}
4141
import scala.tools.nsc.classpath._
@@ -59,6 +59,13 @@ class Global(var currentSettings: Settings, reporter0: Reporter)
5959

6060
override def isCompilerUniverse = true
6161
override val useOffsetPositions = !currentSettings.Yrangepos
62+
override protected def newNameTable: NameTable[this.type] = {
63+
if (currentSettings.YcacheNameTable) {
64+
val NoFiles = Nil
65+
Global.nameTableCache.getOrCreate(NoFiles, () => new NameTable[Names.dummyNamesInstance.type](synchronizeNames = true, Names.dummyNamesInstance), closeableRegistry, checkStamps = true).asInstanceOf[NameTable[this.type]]
66+
}
67+
else super.newNameTable
68+
}
6269

6370
type RuntimeClass = java.lang.Class[_]
6471
implicit val RuntimeClassTag: ClassTag[RuntimeClass] = ClassTag[RuntimeClass](classOf[RuntimeClass])
@@ -1736,4 +1743,7 @@ object Global {
17361743
override def keepsTypeParams = false
17371744
def run() { throw new Error("InitPhase.run") }
17381745
}
1746+
1747+
// TODO factor reference counting caching out of FileBasedCache for use in spots like this.
1748+
private val nameTableCache = new FileBasedCache[NameTable[_]]
17391749
}

src/compiler/scala/tools/nsc/PipelineMain.scala

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -426,6 +426,8 @@ class PipelineMainClass(argFiles: Seq[Path], pipelineSettings: PipelineMain.Pipe
426426
command.settings.YcacheMacroClassLoader.value = "always"
427427
if (cachePlugin)
428428
command.settings.YcachePluginClassLoader.value = "always"
429+
if (cacheNameTable)
430+
command.settings.YcacheNameTable.value = true
429431

430432
if (strategy != Traditional) {
431433
command.settings.YpickleJava.value = true
@@ -686,7 +688,7 @@ object PipelineMain {
686688
case object Traditional extends BuildStrategy
687689

688690
case class PipelineSettings(label: String, parallelism: Int, strategy: BuildStrategy, useJars: Boolean,
689-
configuredPickleCache: Option[Path], cacheMacro: Boolean, cachePlugin: Boolean,
691+
configuredPickleCache: Option[Path], cacheMacro: Boolean, cachePlugin: Boolean, cacheNameTable: Boolean,
690692
stripExternalClassPath: Boolean, useTraditionalForLeaf: Boolean, logDir: Option[Path],
691693
createReporter: (Settings => Reporter))
692694
def defaultSettings: PipelineSettings = {
@@ -696,12 +698,13 @@ object PipelineMain {
696698
val useJars = java.lang.Boolean.getBoolean("scala.pipeline.use.jar")
697699
val cacheMacro = java.lang.Boolean.getBoolean("scala.pipeline.cache.macro.classloader")
698700
val cachePlugin = java.lang.Boolean.getBoolean("scala.pipeline.cache.plugin.classloader")
701+
val cacheNameTable = java.lang.Boolean.getBoolean("scala.pipeline.cache.name.table")
699702
val stripExternalClassPath = java.lang.Boolean.getBoolean("scala.pipeline.strip.external.classpath")
700703
val useTraditionalForLeaf = java.lang.Boolean.getBoolean("scala.pipeline.use.traditional.for.leaf")
701704
val configuredPickleCache = Option(System.getProperty("scala.pipeline.picklecache")).map(Paths.get(_))
702705
val logDir = Paths.get(".")
703706
new PipelineSettings("1", parallelism, strategy, useJars, configuredPickleCache,
704-
cacheMacro, cachePlugin, stripExternalClassPath, useTraditionalForLeaf, Some(logDir), new ConsoleReporter(_))
707+
cacheMacro, cachePlugin, cacheNameTable, stripExternalClassPath, useTraditionalForLeaf, Some(logDir), new ConsoleReporter(_))
705708
}
706709

707710
def main(args: Array[String]): Unit = {

src/compiler/scala/tools/nsc/settings/ScalaSettings.scala

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -244,6 +244,7 @@ trait ScalaSettings extends AbsScalaSettings
244244
val YpartialUnification = BooleanSetting ("-Ypartial-unification", "Enable partial unification in type constructor inference")
245245
val Yvirtpatmat = BooleanSetting ("-Yvirtpatmat", "Enable pattern matcher virtualization")
246246
val Youtline = BooleanSetting ("-Youtline", "Don't compile method bodies. Use together with `-Ystop-afer:pickler to generate the pickled signatures for all source files.").internalOnly()
247+
val YcacheNameTable = BooleanSetting ("-Ycache-name-table", "Share a single name table for concurrently running instances of the compiler")
247248

248249
val exposeEmptyPackage = BooleanSetting ("-Yexpose-empty-package", "Internal only: expose the empty package.").internalOnly()
249250
val Ydelambdafy = ChoiceSetting ("-Ydelambdafy", "strategy", "Strategy used for translating lambdas into JVM code.", List("inline", "method"), "method")

0 commit comments

Comments
 (0)