@@ -2,6 +2,8 @@ package xsbt
2
2
3
3
import java .net .{URL , URLClassLoader }
4
4
5
+ import scala .collection .mutable
6
+
5
7
/** A classloader to run the compiler
6
8
*
7
9
* 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)
42
44
}
43
45
44
46
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
+
45
55
/** Fix the compiler bridge ClassLoader
46
56
*
47
57
* Soundtrack: https://www.youtube.com/watch?v=imamcajBEJs
@@ -70,7 +80,11 @@ object CompilerClassLoader {
70
80
* @param bridgeLoader The classloader that sbt uses to load the compiler bridge
71
81
* @return A fixed classloader that works with dotty
72
82
*/
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 {
74
88
case bridgeLoader : URLClassLoader =>
75
89
val dualLoader = bridgeLoader.getParent
76
90
val dualLoaderClass = dualLoader.getClass
0 commit comments