Skip to content

Commit 4623e12

Browse files
authored
Merge pull request #2262 from dotty-staging/fix/sbt-warm-compile
Make warm compilation speed with sbt 2x faster
2 parents 2efb6dd + 934ab5b commit 4623e12

File tree

1 file changed

+15
-1
lines changed

1 file changed

+15
-1
lines changed

sbt-bridge/src/xsbt/CompilerClassLoader.scala

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@ package xsbt
22

33
import java.net.{URL, URLClassLoader}
44

5+
import scala.collection.mutable
6+
57
/** A classloader to run the compiler
68
*
79
* 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)
4244
}
4345

4446
object CompilerClassLoader {
47+
/** Cache the result of `fixBridgeLoader`.
48+
*
49+
* Reusing ClassLoaders is important for warm performance since otherwise the
50+
* JIT code cache for the compiler will be discarded between every call to
51+
* the sbt `compile` task.
52+
*/
53+
private[this] val fixedLoaderCache = new mutable.WeakHashMap[ClassLoader, ClassLoader]
54+
4555
/** Fix the compiler bridge ClassLoader
4656
*
4757
* Soundtrack: https://www.youtube.com/watch?v=imamcajBEJs
@@ -70,7 +80,11 @@ object CompilerClassLoader {
7080
* @param bridgeLoader The classloader that sbt uses to load the compiler bridge
7181
* @return A fixed classloader that works with dotty
7282
*/
73-
def fixBridgeLoader(bridgeLoader: ClassLoader) = bridgeLoader match {
83+
def fixBridgeLoader(bridgeLoader: ClassLoader): ClassLoader = synchronized {
84+
fixedLoaderCache.getOrElseUpdate(bridgeLoader, computeFixedLoader(bridgeLoader))
85+
}
86+
87+
private[this] def computeFixedLoader(bridgeLoader: ClassLoader) = bridgeLoader match {
7488
case bridgeLoader: URLClassLoader =>
7589
val dualLoader = bridgeLoader.getParent
7690
val dualLoaderClass = dualLoader.getClass

0 commit comments

Comments
 (0)