aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDmitry Petrashko <dark@d-d.me>2017-04-19 06:58:08 -0500
committerGitHub <noreply@github.com>2017-04-19 06:58:08 -0500
commit4623e1282ebe7dfc31cb12411fed16457ed289ca (patch)
tree468269c96b323121551e187ba56f238da036bead
parent2efb6dd13fd4600d991cf8efe186e860c8cbadc6 (diff)
parent934ab5b341a4c2548041138893d8a0dd4c8d4aa6 (diff)
downloaddotty-4623e1282ebe7dfc31cb12411fed16457ed289ca.tar.gz
dotty-4623e1282ebe7dfc31cb12411fed16457ed289ca.tar.bz2
dotty-4623e1282ebe7dfc31cb12411fed16457ed289ca.zip
Merge pull request #2262 from dotty-staging/fix/sbt-warm-compile
Make warm compilation speed with sbt 2x faster
-rw-r--r--sbt-bridge/src/xsbt/CompilerClassLoader.scala16
1 files changed, 15 insertions, 1 deletions
diff --git a/sbt-bridge/src/xsbt/CompilerClassLoader.scala b/sbt-bridge/src/xsbt/CompilerClassLoader.scala
index 3cb3f344f..071141dcf 100644
--- a/sbt-bridge/src/xsbt/CompilerClassLoader.scala
+++ b/sbt-bridge/src/xsbt/CompilerClassLoader.scala
@@ -2,6 +2,8 @@ package xsbt
import java.net.{URL, URLClassLoader}
+import scala.collection.mutable
+
/** A classloader to run the compiler
*
* A CompilerClassLoader is constructed from a list of `urls` that need to be on
@@ -42,6 +44,14 @@ class CompilerClassLoader(urls: Array[URL], sbtLoader: ClassLoader)
}
object CompilerClassLoader {
+ /** Cache the result of `fixBridgeLoader`.
+ *
+ * Reusing ClassLoaders is important for warm performance since otherwise the
+ * JIT code cache for the compiler will be discarded between every call to
+ * the sbt `compile` task.
+ */
+ private[this] val fixedLoaderCache = new mutable.WeakHashMap[ClassLoader, ClassLoader]
+
/** Fix the compiler bridge ClassLoader
*
* Soundtrack: https://www.youtube.com/watch?v=imamcajBEJs
@@ -70,7 +80,11 @@ object CompilerClassLoader {
* @param bridgeLoader The classloader that sbt uses to load the compiler bridge
* @return A fixed classloader that works with dotty
*/
- def fixBridgeLoader(bridgeLoader: ClassLoader) = bridgeLoader match {
+ def fixBridgeLoader(bridgeLoader: ClassLoader): ClassLoader = synchronized {
+ fixedLoaderCache.getOrElseUpdate(bridgeLoader, computeFixedLoader(bridgeLoader))
+ }
+
+ private[this] def computeFixedLoader(bridgeLoader: ClassLoader) = bridgeLoader match {
case bridgeLoader: URLClassLoader =>
val dualLoader = bridgeLoader.getParent
val dualLoaderClass = dualLoader.getClass