Merge pull request #5096 from eatkins/background-classloading

Preload a number of classes in the background
This commit is contained in:
eugene yokota 2019-09-22 23:58:28 -04:00 committed by GitHub
commit ccecf1e412
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
1 changed files with 35 additions and 1 deletions

View File

@ -10,10 +10,43 @@ package sbt.internal
import java.io.File
import java.lang.reflect.InvocationTargetException
import java.net.{ URL, URLClassLoader }
import java.util.concurrent.{ ExecutorService, Executors }
import java.util.regex.Pattern
import sbt.plugins.{ CorePlugin, IvyPlugin, JvmPlugin }
import sbt.util.LogExchange
import xsbti._
private[internal] object ClassLoaderWarmup {
def warmup(): Unit = {
if (Runtime.getRuntime.availableProcessors > 1) {
val executorService: ExecutorService =
Executors.newFixedThreadPool(Runtime.getRuntime.availableProcessors - 1)
def submit[R](f: => R): Unit = {
executorService.submit(new Runnable {
override def run(): Unit = { f; () }
})
()
}
submit(LogExchange.context)
submit(Class.forName("sbt.internal.parser.SbtParserInit").getConstructor().newInstance())
submit(CorePlugin.projectSettings)
submit(IvyPlugin.projectSettings)
submit(JvmPlugin.projectSettings)
submit(() => {
try {
val clazz = Class.forName("scala.reflect.runtime.package$")
clazz.getMethod("universe").invoke(clazz.getField("MODULE$").get(null))
} catch {
case _: Exception =>
}
executorService.shutdown()
})
}
}
}
/**
* Generates a new app configuration and invokes xMainImpl.run. For AppConfigurations generated
* by recent launchers, it is unnecessary to modify the original configuration, but configurations
@ -42,7 +75,8 @@ private[sbt] class XMainConfiguration {
val instance = clazz.getField("MODULE$").get(null)
val runMethod = clazz.getMethod("run", classOf[xsbti.AppConfiguration])
try {
loader.loadClass("sbt.internal.parser.SbtParserInit").getConstructor().newInstance()
val clw = loader.loadClass("sbt.internal.ClassLoaderWarmup$")
clw.getMethod("warmup").invoke(clw.getField("MODULE$").get(null))
runMethod.invoke(instance, updatedConfiguration).asInstanceOf[xsbti.MainResult]
} catch {
case e: InvocationTargetException =>