scala / bug

Scala 2 bug reports only. Please, no questions — proper bug reports only.
https://scala-lang.org
232 stars 21 forks source link

Scaladoc: repeated use of `{{{foo}}}` style markup eventually causes exponential runtime #12509

Closed SethTisue closed 1 year ago

SethTisue commented 2 years ago

Generating Scaladoc for this class is outrageously slow:

/**
 * {{{foo}}} {{{foo}}} {{{foo}}} {{{foo}}}
 * {{{foo}}} {{{foo}}} {{{foo}}} {{{foo}}}
 * {{{foo}}} {{{foo}}} {{{foo}}} {{{foo}}}
 * {{{foo}}} {{{foo}}} {{{foo}}} {{{foo}}}
 * {{{foo}}} {{{foo}}} {{{foo}}} {{{foo}}}
 * {{{foo}}} {{{foo}}} {{{foo}}} {{{foo}}}
 */
class C

As you add more repetitions the runtime increases very quickly: from a fraction of a second, to seconds, to minutes. (I suspect it's exponential not just quadratic.)

Reproducible on 2.13.7 and 2.12.15 and 2.11.12

This came up over at https://github.com/scala/community-build/pull/1516

The actual real-world Scaladoc comment that hit this was in https://github.com/scalafx/scalafx/commit/cd352900b8b9468b4543fc0c0d85bdf7f922de49 — fyi @romdep!

here's where it's getting bogged down, in scala.tools.nsc.doc.base.CommentFactoryBase$WikiParser:

``` "pool-22-thread-2" #313 prio=5 os_prio=31 tid=0x00007fe3c5425800 nid=0x8b3b runnable [0x000070000d80c000] java.lang.Thread.State: RUNNABLE at scala.tools.nsc.doc.base.CommentFactoryBase$WikiParser.$anonfun$inline$1(CommentFactoryBase.scala:907) at scala.tools.nsc.doc.base.CommentFactoryBase$WikiParser$$Lambda$4447/969341881.apply$mcZ$sp(Unknown Source) at scala.tools.nsc.doc.base.CommentFactoryBase$CharReader.readUntil(CommentFactoryBase.scala:1232) at scala.tools.nsc.doc.base.CommentFactoryBase$WikiParser.para(CommentFactoryBase.scala:906) at scala.tools.nsc.doc.base.CommentFactoryBase$WikiParser.block(CommentFactoryBase.scala:462) at scala.tools.nsc.doc.base.CommentFactoryBase$WikiParser.document(CommentFactoryBase.scala:443) at scala.tools.nsc.doc.base.CommentFactoryBase.parseWikiAtSymbol(CommentFactoryBase.scala:427) at scala.tools.nsc.doc.base.CommentFactoryBase.parseWikiAtSymbol$(CommentFactoryBase.scala:427) at scala.tools.nsc.doc.DocFactory$$anon$2.parseWikiAtSymbol(DocFactory.scala:78) at scala.tools.nsc.doc.base.CommentFactoryBase.parse0$1(CommentFactoryBase.scala:386) at scala.tools.nsc.doc.base.CommentFactoryBase.parse0$1(CommentFactoryBase.scala:269) at scala.tools.nsc.doc.base.CommentFactoryBase.parse0$1(CommentFactoryBase.scala:269) at scala.tools.nsc.doc.base.CommentFactoryBase.parse0$1(CommentFactoryBase.scala:269) at scala.tools.nsc.doc.base.CommentFactoryBase.parse0$1(CommentFactoryBase.scala:269) at scala.tools.nsc.doc.base.CommentFactoryBase.parse0$1(CommentFactoryBase.scala:269) at scala.tools.nsc.doc.base.CommentFactoryBase.parse0$1(CommentFactoryBase.scala:269) at scala.tools.nsc.doc.base.CommentFactoryBase.parse0$1(CommentFactoryBase.scala:269) at scala.tools.nsc.doc.base.CommentFactoryBase.parse0$1(CommentFactoryBase.scala:269) at scala.tools.nsc.doc.base.CommentFactoryBase.parse0$1(CommentFactoryBase.scala:269) at scala.tools.nsc.doc.base.CommentFactoryBase.parseAtSymbol(CommentFactoryBase.scala:417) at scala.tools.nsc.doc.base.CommentFactoryBase.parseAtSymbol$(CommentFactoryBase.scala:208) at scala.tools.nsc.doc.DocFactory$$anon$2.parseAtSymbol(DocFactory.scala:78) at scala.tools.nsc.doc.model.CommentFactory.parse(CommentFactory.scala:92) at scala.tools.nsc.doc.model.CommentFactory.parse$(CommentFactory.scala:90) at scala.tools.nsc.doc.DocFactory$$anon$2.parse(DocFactory.scala:78) at scala.tools.nsc.doc.model.CommentFactory.defineComment(CommentFactory.scala:82) at scala.tools.nsc.doc.model.CommentFactory.defineComment$(CommentFactory.scala:45) at scala.tools.nsc.doc.DocFactory$$anon$2.defineComment(DocFactory.scala:78) at scala.tools.nsc.doc.model.CommentFactory.$anonfun$comment$1(CommentFactory.scala:38) at scala.tools.nsc.doc.model.CommentFactory$$Lambda$4428/903195965.apply(Unknown Source) at scala.collection.mutable.HashMap.getOrElseUpdate(HashMap.scala:454) at scala.tools.nsc.doc.model.CommentFactory.comment(CommentFactory.scala:38) at scala.tools.nsc.doc.model.CommentFactory.comment$(CommentFactory.scala:36) at scala.tools.nsc.doc.DocFactory$$anon$2.comment(DocFactory.scala:78) at scala.tools.nsc.doc.model.ModelFactory$MemberImpl.comment$lzycompute(ModelFactory.scala:129) - locked <0x000000078553f358> (a scala.tools.nsc.doc.model.ModelFactory$modelCreation$$anon$7) at scala.tools.nsc.doc.model.ModelFactory$MemberImpl.comment(ModelFactory.scala:129) at scala.tools.nsc.doc.model.ModelFactory$MemberImpl.deprecation(ModelFactory.scala:184) at scala.tools.nsc.doc.html.page.EntityPage.$anonfun$x$19$1(Entity.scala:189) at scala.tools.nsc.doc.html.page.EntityPage.$anonfun$x$19$1$adapted(Entity.scala:189) at scala.tools.nsc.doc.html.page.EntityPage$$Lambda$4426/185807056.apply(Unknown Source) at scala.collection.StrictOptimizedIterableOps.$anonfun$partition$1(StrictOptimizedIterableOps.scala:34) at scala.collection.immutable.List$$Lambda$4427/1734334916.apply(Unknown Source) at scala.collection.IterableOnceOps.foreach(IterableOnce.scala:563) at scala.collection.IterableOnceOps.foreach$(IterableOnce.scala:561) at scala.collection.AbstractIterator.foreach(Iterator.scala:1296) at scala.collection.immutable.List.partition(List.scala:588) at scala.tools.nsc.doc.html.page.EntityPage.$init$(Entity.scala:189) at scala.tools.nsc.doc.html.page.EntityPage$$anon$1.(Entity.scala:1039) at scala.tools.nsc.doc.html.HtmlFactory.writeTemplates(HtmlFactory.scala:168) at scala.tools.nsc.doc.html.HtmlFactory.generate(HtmlFactory.scala:156) at scala.tools.nsc.doc.html.Doclet.generateImpl(Doclet.scala:30) at scala.tools.nsc.doc.doclet.Generator.generate(Generator.scala:35) at scala.tools.nsc.doc.DocFactory.generate$1(DocFactory.scala:139) at scala.tools.nsc.doc.DocFactory.document(DocFactory.scala:142) at xsbt.Runner.run(ScaladocBridge.scala:43) ```
SethTisue commented 2 years ago

LOL, Scala 3 is affected as well. (version tested: 3.1.1-RC1)