Skip to content

Commit

Permalink
Support name table sharing across Global instances
Browse files Browse the repository at this point in the history
  - Add UI to enable name table sharing
  - Expose name table caching through PipelineMain
  • Loading branch information
retronym committed May 30, 2019
1 parent c35194d commit f9fe6f2
Show file tree
Hide file tree
Showing 5 changed files with 189 additions and 104 deletions.
12 changes: 11 additions & 1 deletion src/compiler/scala/tools/nsc/Global.scala
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ import io.{AbstractFile, Path, SourceReader}
import reporters.Reporter
import util.{ClassPath, returning}
import scala.reflect.ClassTag
import scala.reflect.internal.{NameTable, Names}
import scala.reflect.internal.util.{BatchSourceFile, FreshNameCreator, NoSourceFile, ScalaClassLoader, ScriptSourceFile, SourceFile, StatisticsStatics}
import scala.reflect.internal.pickling.PickleBuffer
import symtab.{Flags, SymbolTable, SymbolTrackers}
Expand All @@ -35,7 +36,6 @@ import transform.patmat.PatternMatching
import transform._
import backend.{JavaPlatform, ScalaPrimitives}
import backend.jvm.{BackendStats, GenBCode}
import scala.concurrent.Future
import scala.language.postfixOps
import scala.tools.nsc.ast.{TreeGen => AstTreeGen}
import scala.tools.nsc.classpath._
Expand All @@ -59,6 +59,13 @@ class Global(var currentSettings: Settings, reporter0: Reporter)

override def isCompilerUniverse = true
override val useOffsetPositions = !currentSettings.Yrangepos
override protected def newNameTable: NameTable[this.type] = {
if (currentSettings.YcacheNameTable) {
val NoFiles = Nil
Global.nameTableCache.getOrCreate(NoFiles, () => new NameTable[Names.dummyNamesInstance.type](synchronizeNames = true, Names.dummyNamesInstance), closeableRegistry, checkStamps = true).asInstanceOf[NameTable[this.type]]
}
else super.newNameTable
}

type RuntimeClass = java.lang.Class[_]
implicit val RuntimeClassTag: ClassTag[RuntimeClass] = ClassTag[RuntimeClass](classOf[RuntimeClass])
Expand Down Expand Up @@ -1736,4 +1743,7 @@ object Global {
override def keepsTypeParams = false
def run() { throw new Error("InitPhase.run") }
}

// TODO factor reference counting caching out of FileBasedCache for use in spots like this.
private val nameTableCache = new FileBasedCache[NameTable[_]]
}
7 changes: 5 additions & 2 deletions src/compiler/scala/tools/nsc/PipelineMain.scala
Original file line number Diff line number Diff line change
Expand Up @@ -426,6 +426,8 @@ class PipelineMainClass(argFiles: Seq[Path], pipelineSettings: PipelineMain.Pipe
command.settings.YcacheMacroClassLoader.value = "always"
if (cachePlugin)
command.settings.YcachePluginClassLoader.value = "always"
if (cacheNameTable)
command.settings.YcacheNameTable.value = true

if (strategy != Traditional) {
command.settings.YpickleJava.value = true
Expand Down Expand Up @@ -686,7 +688,7 @@ object PipelineMain {
case object Traditional extends BuildStrategy

case class PipelineSettings(label: String, parallelism: Int, strategy: BuildStrategy, useJars: Boolean,
configuredPickleCache: Option[Path], cacheMacro: Boolean, cachePlugin: Boolean,
configuredPickleCache: Option[Path], cacheMacro: Boolean, cachePlugin: Boolean, cacheNameTable: Boolean,
stripExternalClassPath: Boolean, useTraditionalForLeaf: Boolean, logDir: Option[Path],
createReporter: (Settings => Reporter))
def defaultSettings: PipelineSettings = {
Expand All @@ -696,12 +698,13 @@ object PipelineMain {
val useJars = java.lang.Boolean.getBoolean("scala.pipeline.use.jar")
val cacheMacro = java.lang.Boolean.getBoolean("scala.pipeline.cache.macro.classloader")
val cachePlugin = java.lang.Boolean.getBoolean("scala.pipeline.cache.plugin.classloader")
val cacheNameTable = java.lang.Boolean.getBoolean("scala.pipeline.cache.name.table")
val stripExternalClassPath = java.lang.Boolean.getBoolean("scala.pipeline.strip.external.classpath")
val useTraditionalForLeaf = java.lang.Boolean.getBoolean("scala.pipeline.use.traditional.for.leaf")
val configuredPickleCache = Option(System.getProperty("scala.pipeline.picklecache")).map(Paths.get(_))
val logDir = Paths.get(".")
new PipelineSettings("1", parallelism, strategy, useJars, configuredPickleCache,
cacheMacro, cachePlugin, stripExternalClassPath, useTraditionalForLeaf, Some(logDir), new ConsoleReporter(_))
cacheMacro, cachePlugin, cacheNameTable, stripExternalClassPath, useTraditionalForLeaf, Some(logDir), new ConsoleReporter(_))
}

def main(args: Array[String]): Unit = {
Expand Down
1 change: 1 addition & 0 deletions src/compiler/scala/tools/nsc/settings/ScalaSettings.scala
Original file line number Diff line number Diff line change
Expand Up @@ -244,6 +244,7 @@ trait ScalaSettings extends AbsScalaSettings
val YpartialUnification = BooleanSetting ("-Ypartial-unification", "Enable partial unification in type constructor inference")
val Yvirtpatmat = BooleanSetting ("-Yvirtpatmat", "Enable pattern matcher virtualization")
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()
val YcacheNameTable = BooleanSetting ("-Ycache-name-table", "Share a single name table for concurrently running instances of the compiler")

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

0 comments on commit f9fe6f2

Please sign in to comment.