From 0ebb7a5662f2bcc6599010f5a81ed0a540581fd8 Mon Sep 17 00:00:00 2001 From: Johannes Rudolph Date: Mon, 19 Feb 2018 09:19:31 +0100 Subject: [PATCH] In initStringCodecs avoid reflect universe initialization This showed up in profiling. It's known that TypeTags are expensive. Even more so if the reflect universe is accessed during startup when the class loading and JIT compiler are busy enough with other stuff. --- .../src/main/scala/sbt/util/LogExchange.scala | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/internal/util-logging/src/main/scala/sbt/util/LogExchange.scala b/internal/util-logging/src/main/scala/sbt/util/LogExchange.scala index b5bb1cb56..7879eb80a 100644 --- a/internal/util-logging/src/main/scala/sbt/util/LogExchange.scala +++ b/internal/util-logging/src/main/scala/sbt/util/LogExchange.scala @@ -67,9 +67,15 @@ sealed abstract class LogExchange { import sbt.internal.util.codec.TraceEventShowLines._ import sbt.internal.util.codec.SuccessEventShowLines._ - registerStringCodec[Throwable] - registerStringCodec[TraceEvent] - registerStringCodec[SuccessEvent] + // Register these StringCodecs manually, because this method will be called at the very startup of sbt + // and we'll try not to initialize the universe in StringTypeTag.apply + // If these classes are moved around, both the fully qualified names and the strings need to be adapted. + // A better long-term solution could be to make StringTypeTag.apply a macro. + registerStringCodecByStringTypeTag[_root_.scala.Throwable](StringTypeTag("scala.Throwable")) + registerStringCodecByStringTypeTag[_root_.sbt.internal.util.TraceEvent]( + StringTypeTag("sbt.internal.util.TraceEvent")) + registerStringCodecByStringTypeTag[_root_.sbt.internal.util.SuccessEvent]( + StringTypeTag("sbt.internal.util.SuccessEvent")) } // This is a dummy layout to avoid casting error during PatternLayout.createDefaultLayout() @@ -102,6 +108,10 @@ sealed abstract class LogExchange { def registerStringCodec[A: ShowLines: TypeTag]: Unit = { val tag = StringTypeTag[A] + registerStringCodecByStringTypeTag(tag) + } + + private[sbt] def registerStringCodecByStringTypeTag[A: ShowLines](tag: StringTypeTag[A]): Unit = { val ev = implicitly[ShowLines[A]] val _ = getOrElseUpdateStringCodec(tag.key, ev) }