Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
4 changes: 0 additions & 4 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -14,10 +14,6 @@ jobs:
matrix:
scala:
- "3.3.2"
- "3.3.7"
- "3.4.3"
- "3.5.2"
- "3.6.4"
- "3.7.4"
- "3.8.0-RC3"
steps:
Expand Down
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,14 +13,14 @@ JMH benchmarks for measuring Scala 3 compiler performance.
| [fansi](https://github.com/com-lihaoyi/fansi) | 0.5.1 | 960 | sourcecode, utest | yes |
| [indigo](https://github.com/PurpleKingdomGames/indigo) ⚡ | 0.22.0 | 25'270 | scalajs-dom, ultraviolet | no |
| [re2s](https://github.com/twitter/rsc/tree/1d2b8962604206b1328e94257885117fd252bd23/examples/re2s/src/main/scala/java/util/regex) | 1d2b8962 | 9'021 | none | no |
| [scala-parallel-collections](https://github.com/scala/scala-parallel-collections) | v1.2.0 | 11'512 | junit | yes |
| [scala-parallel-collections](https://github.com/scala/scala-parallel-collections) | v1.2.0 | 8'887 | junit | yes |
| [scala-parser-combinators](https://github.com/scala/scala-parser-combinators) | 2.4.0 | 2'325 | junit | yes |
| [scala.today](https://github.com/VirtusLab/scala.today) | 2dd97e7 | 1'103 | tapir, ox, magnum, etc. | no |
| [scala-yaml](https://github.com/VirtusLab/scala-yaml) | 0.3.1 | 6'473 | pprint, munit | yes |
| [scalaz](https://github.com/scalaz/scalaz) | v7.2.36 | 27'757| none | no |
| [sourcecode](https://github.com/com-lihaoyi/sourcecode) | 0.4.4 | 638 | none | yes |
| [tasty-query](https://github.com/scalacenter/tasty-query) | v1.6.1 | 13'482 | none | no |
| [tictactoe](https://github.com/KatlasTsoulouhas/scala3-tictactoe) | - | 441 | cats-effect, cats-core | yes |
| [tictactoe](https://github.com/katlasik/scala3-tictactoe) | 6873dfd | 441 | cats-effect, cats-core | yes |

⚡ = Scala.js benchmark (requires Scala 3.6.4+)

Expand Down
3 changes: 3 additions & 0 deletions bench-sources/dotty/compiler/src/dotty/tools/FatalError.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
package dotty.tools

case class FatalError(msg: String) extends Exception(msg)
189 changes: 189 additions & 0 deletions bench-sources/dotty/compiler/src/dotty/tools/MainGenericCompiler.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,189 @@
package dotty.tools

import scala.annotation.tailrec
import scala.io.Source
import scala.util.Try
import java.io.File
import java.lang.Thread
import scala.annotation.internal.sharable
import dotty.tools.dotc.util.ClasspathFromClassloader
import dotty.tools.runner.ObjectRunner
import dotty.tools.dotc.config.Properties.envOrNone
import dotty.tools.io.Jar
import dotty.tools.runner.ScalaClassLoader
import java.nio.file.Paths
import dotty.tools.dotc.config.CommandLineParser
import dotty.tools.scripting.StringDriver

enum CompileMode:
case Guess
case Compile
case Decompile
case PrintTasty
case Script

case class CompileSettings(
verbose: Boolean = false,
classPath: List[String] = List.empty,
compileMode: CompileMode = CompileMode.Guess,
exitCode: Int = 0,
javaArgs: List[String] = List.empty,
javaProps: List[(String, String)] = List.empty,
scalaArgs: List[String] = List.empty,
residualArgs: List[String] = List.empty,
scriptArgs: List[String] = List.empty,
targetScript: String = "",
compiler: Boolean = false,
quiet: Boolean = false,
colors: Boolean = false,
) {
def withCompileMode(em: CompileMode): CompileSettings = this.compileMode match
case CompileMode.Guess =>
this.copy(compileMode = em)
case _ =>
println(s"compile_mode==[$compileMode], attempted overwrite by [$em]")
this.copy(exitCode = 1)
end withCompileMode

def withScalaArgs(args: String*): CompileSettings =
this.copy(scalaArgs = scalaArgs.appendedAll(args.toList.filter(_.nonEmpty)))

def withJavaArgs(args: String*): CompileSettings =
this.copy(javaArgs = javaArgs.appendedAll(args.toList.filter(_.nonEmpty)))

def withJavaProps(args: (String, String)*): CompileSettings =
this.copy(javaProps = javaProps.appendedAll(args.toList))

def withResidualArgs(args: String*): CompileSettings =
this.copy(residualArgs = residualArgs.appendedAll(args.toList.filter(_.nonEmpty)))

def withScriptArgs(args: String*): CompileSettings =
this.copy(scriptArgs = scriptArgs.appendedAll(args.toList.filter(_.nonEmpty)))

def withTargetScript(file: String): CompileSettings =
Try(Source.fromFile(file)).toOption match
case Some(_) => this.copy(targetScript = file)
case None =>
println(s"not found $file")
this.copy(exitCode = 2)
end withTargetScript

def withCompiler: CompileSettings =
this.copy(compiler = true)

def withQuiet: CompileSettings =
this.copy(quiet = true)

def withColors: CompileSettings =
this.copy(colors = true)

def withNoColors: CompileSettings =
this.copy(colors = false)
}

object MainGenericCompiler {

val classpathSeparator: String = File.pathSeparator

def processClasspath(cp: String, tail: List[String]): (List[String], List[String]) =
val cpEntries = cp.split(classpathSeparator).toList
val singleEntryClasspath: Boolean = cpEntries.take(2).size == 1
val globdir: String = if singleEntryClasspath then cp.replaceAll("[\\\\/][^\\\\/]*$", "") else "" // slash/backslash agnostic
def validGlobbedJar(s: String): Boolean = s.startsWith(globdir) && ((s.toLowerCase.endsWith(".jar") || s.toLowerCase.endsWith(".zip")))
if singleEntryClasspath && validGlobbedJar(cpEntries.head) then
// reassemble globbed wildcard classpath
// globdir is wildcard directory for globbed jar files, reconstruct the intended classpath
val cpJars = tail.takeWhile( f => validGlobbedJar(f) )
val remainingArgs = tail.drop(cpJars.size)
(remainingArgs, cpEntries ++ cpJars)
else
(tail, cpEntries)

@sharable val javaOption = raw"""-J(.*)""".r
@sharable val javaPropOption = raw"""-D(.+?)=(.?)""".r
@tailrec
def process(args: List[String], settings: CompileSettings): CompileSettings = args match
case Nil =>
settings
case "--" :: tail =>
process(Nil, settings.withResidualArgs(tail.toList*))
case ("-v" | "-verbose" | "--verbose") :: tail =>
process(tail, settings.withScalaArgs("-verbose"))
case ("-q" | "-quiet") :: tail =>
process(tail, settings.withQuiet)
case "-script" :: targetScript :: tail =>
process(Nil, settings
.withCompileMode(CompileMode.Script)
.withJavaProps("script.path" -> targetScript)
.withTargetScript(targetScript)
.withScriptArgs(tail*))
case "-compile" :: tail =>
process(tail, settings.withCompileMode(CompileMode.Compile))
case "-decompile" :: tail =>
process(tail, settings.withCompileMode(CompileMode.Decompile))
case "-print-tasty" :: tail =>
process(tail, settings.withCompileMode(CompileMode.PrintTasty))
case "-colors" :: tail =>
process(tail, settings.withColors)
case "-no-colors" :: tail =>
process(tail, settings.withNoColors)
case "-with-compiler" :: tail =>
process(tail, settings.withCompiler)
case ("-cp" | "-classpath" | "--class-path") :: cp :: tail =>
val (tailargs, newEntries) = processClasspath(cp, tail)
process(tailargs, settings.copy(classPath = settings.classPath ++ newEntries.filter(_.nonEmpty)))
case "-Oshort" :: tail =>
// Nothing is to be done here. Request that the user adds the relevant flags manually.
val addTC="-XX:+TieredCompilation"
val tStopAtLvl="-XX:TieredStopAtLevel=1"
println(s"ignoring deprecated -Oshort flag, please add `-J$addTC` and `-J$tStopAtLvl` flags manually")
process(tail, settings)
case javaOption(stripped: String) :: tail =>
process(tail, settings.withJavaArgs(stripped))
case javaPropOption(opt: String, value: String) :: tail =>
process(tail, settings.withJavaProps(opt -> value))
case arg :: tail =>
process(tail, settings.withResidualArgs(arg))
end process

def main(args: Array[String]): Unit =
val settings = process(args.toList, CompileSettings())
if settings.exitCode != 0 then System.exit(settings.exitCode)

def classpathSetting =
if settings.classPath.isEmpty then List()
else List("-classpath", settings.classPath.mkString(classpathSeparator))

def reconstructedArgs() =
classpathSetting ++ settings.scalaArgs ++ settings.residualArgs

def addJavaProps(): Unit =
settings.javaProps.foreach { (k, v) => sys.props(k) = v }

def run(settings: CompileSettings): Unit = settings.compileMode match
case CompileMode.Compile =>
addJavaProps()
val properArgs = reconstructedArgs()
dotty.tools.dotc.Main.main(properArgs.toArray)
case CompileMode.Decompile =>
addJavaProps()
val properArgs = reconstructedArgs()
dotty.tools.dotc.decompiler.Main.main(properArgs.toArray)
case CompileMode.PrintTasty =>
addJavaProps()
val properArgs = reconstructedArgs()
dotty.tools.dotc.core.tasty.TastyPrinter.main(properArgs.toArray)
case CompileMode.Script => // Naive copy from scalac bash script
addJavaProps()
val properArgs =
reconstructedArgs()
++ List("-script", settings.targetScript)
++ settings.scriptArgs
scripting.Main.main(properArgs.toArray)
case CompileMode.Guess =>
run(settings.withCompileMode(CompileMode.Compile))
end run

run(settings)
end main
}
Loading
Loading