@@ -2,6 +2,8 @@ package xsbt
22
33import 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
4446object 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