SD-232 Recycle classloaders to be anti-hostile to JIT.

The compiler interface subclasses `scala.tools.nsc.Global`,
and loading this new subclass before each `compile` task forces
HotSpot JIT to deoptimize larges swathes of compiled code. It's
a bit like SBT has rigged the dice to always descend the longest
ladder in a game of Snakes and Ladders.

The slowdown seems to be larger with Scala 2.12. There are a number
of variables at play, but I think the main factor here is that
we now rely on JIT to devirtualize calls to final methods in traits
whereas we used to emit static calls. JIT does a good job at this,
so long as classloading doesn't undo that good work.

This commit extends the existing `ClassLoaderCache` to encompass
the classloader that includes the compiler interface JAR. I've
resorted to adding a var to `AnalyzingCompiler` to inject the
dependency to get the cache to the spot I need it without binary
incompatible changes to the intervening method signatures.
This commit is contained in:
Jason Zaugg 2016-09-22 17:24:30 +10:00 committed by Eugene Yokota
parent 69385029ed
commit 3c508ce52d
1 changed files with 7 additions and 2 deletions

View File

@ -307,8 +307,13 @@ object Defaults extends BuildCommon {
if (plugin) scalaBase / ("sbt-" + sbtv) else scalaBase
}
def compilersSetting = compilers := Compiler.compilers(scalaInstance.value, classpathOptions.value, javaHome.value,
bootIvyConfiguration.value, fileToStore.value, scalaCompilerBridgeSource.value)(appConfiguration.value, streams.value.log)
def compilersSetting = compilers := {
val compilers = Compiler.compilers(scalaInstance.value, classpathOptions.value, javaHome.value,
bootIvyConfiguration.value, fileToStore.value, scalaCompilerBridgeSource.value)(appConfiguration.value, streams.value.log)
if (!java.lang.Boolean.getBoolean("sbt.disable.interface.classloader.cache"))
compilers.scalac.setClassLoaderCache(state.value.classLoaderCache)
compilers
}
lazy val configTasks = docTaskSettings(doc) ++ inTask(compile)(compileInputsSettings) ++ configGlobal ++ compileAnalysisSettings ++ Seq(
compile := compileTask.value,