From 700448ddde619420df3a4849a39544921f946e19 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=93lafur=20P=C3=A1ll=20Geirsson?= Date: Wed, 14 Jun 2017 17:25:57 +0200 Subject: [PATCH 01/13] Compile benchmark with Dotty, fixes #29. Note, the benchmarks currently don't actually run with Dotty because of https://github.com/lampepfl/dotty/issues/2704. - When `scalaVersion := "0.x"`, then "src/main/dotc" is added to unmanagedSourceDirectories, otherwise "src/main/scalac" is added. - compilation/test checks the setup is OK without the need to remember cli args. - `fork in run` is necessary for -usejavacp to work with compilation/run - `FileVisitOption.FOLLOW_LINKS` produces duplicate filenames, which causes "X is already compiled in this run" errors in Dotty. --- build.sbt | 13 +++++- .../tools/benchmark/BenchmarkDriver.scala | 22 +++++++++ .../scala/tools/nsc/ScalacBenchmark.scala | 46 ++++++++++++------- .../tools/benchmark/BenchmarkDriver.scala | 36 +++++++++++++++ .../scala/tools/benchmark/BenchmarkTest.scala | 9 ++++ project/plugins.sbt | 3 ++ 6 files changed, 111 insertions(+), 18 deletions(-) create mode 100644 compilation/src/main/dotc/scala/tools/benchmark/BenchmarkDriver.scala create mode 100644 compilation/src/main/scalac/scala/tools/benchmark/BenchmarkDriver.scala create mode 100644 compilation/src/test/scala/scala/tools/benchmark/BenchmarkTest.scala diff --git a/build.sbt b/build.sbt index 1a1f48f..ffe9ffe 100644 --- a/build.sbt +++ b/build.sbt @@ -36,8 +36,17 @@ lazy val compilation = addJmh(project).settings( // We should be able to switch this project to a broad range of Scala versions for comparative // benchmarking. As such, this project should only depend on the high level `MainClass` compiler API. description := "Black box benchmark of the compiler", - libraryDependencies += scalaOrganization.value % "scala-compiler" % scalaVersion.value, - mainClass in (Jmh, run) := Some("scala.bench.ScalacBenchmarkRunner") + libraryDependencies += { + if (isDotty.value) "ch.epfl.lamp" %% "dotty-compiler" % scalaVersion.value + else scalaOrganization.value % "scala-compiler" % scalaVersion.value + }, + unmanagedSourceDirectories.in(Compile) += + sourceDirectory.in(Compile).value / (if (isDotty.value) "dotc" else "scalac"), + mainClass in (Jmh, run) := Some("scala.bench.ScalacBenchmarkRunner"), + libraryDependencies += "com.novocode" % "junit-interface" % "0.11" % Test, + testOptions in Test += Tests.Argument(TestFrameworks.JUnit), + fork in (Test, test) := true, + fork in run := true ).settings(addJavaOptions).dependsOn(infrastructure) lazy val micro = addJmh(project).settings( diff --git a/compilation/src/main/dotc/scala/tools/benchmark/BenchmarkDriver.scala b/compilation/src/main/dotc/scala/tools/benchmark/BenchmarkDriver.scala new file mode 100644 index 0000000..cb26be0 --- /dev/null +++ b/compilation/src/main/dotc/scala/tools/benchmark/BenchmarkDriver.scala @@ -0,0 +1,22 @@ +package scala.tools.benchmark + +import java.io.File +import scala.tools.nsc.BaseBenchmarkDriver +import dotty.tools.dotc.core.Contexts.ContextBase + +trait BenchmarkDriver extends BaseBenchmarkDriver { + def compileImpl(): Unit = { + implicit val ctx = (new ContextBase).initialCtx.fresh + ctx.setSetting(ctx.settings.usejavacp, true) + if (depsClasspath != null) { + ctx.setSetting(ctx.settings.classpath, + depsClasspath.mkString(File.pathSeparator)) + } + ctx.setSetting(ctx.settings.d, tempDir.getAbsolutePath) + ctx.setSetting(ctx.settings.language, List("Scala2")) + val compiler = new dotty.tools.dotc.Compiler + val reporter = + dotty.tools.dotc.Bench.doCompile(compiler, compilerArgs.toList) + assert(!reporter.hasErrors) + } +} diff --git a/compilation/src/main/scala/scala/tools/nsc/ScalacBenchmark.scala b/compilation/src/main/scala/scala/tools/nsc/ScalacBenchmark.scala index 2930021..fb62725 100644 --- a/compilation/src/main/scala/scala/tools/nsc/ScalacBenchmark.scala +++ b/compilation/src/main/scala/scala/tools/nsc/ScalacBenchmark.scala @@ -12,9 +12,20 @@ import org.openjdk.jmh.annotations.Mode._ import org.openjdk.jmh.annotations._ import scala.collection.JavaConverters._ +import scala.tools.benchmark.BenchmarkDriver + +trait BaseBenchmarkDriver { + def source: String + def extraArgs: String + def corpusVersion: String + def depsClasspath: String + def tempDir: File + def corpusSourcePath: Path + def compilerArgs: Array[String] +} @State(Scope.Benchmark) -class ScalacBenchmark { +class ScalacBenchmark extends BenchmarkDriver { @Param(value = Array()) var source: String = _ @@ -26,22 +37,9 @@ class ScalacBenchmark { @Param(value = Array("latest")) var corpusVersion: String = _ - var driver: Driver = _ - var depsClasspath: String = _ def compileImpl(): Unit = { - val (compilerArgs, sourceFiles) = - if (source.startsWith("@")) (List(source), List[String]()) - else { - import scala.collection.JavaConverters._ - val allFiles = Files.walk(findSourceDir, FileVisitOption.FOLLOW_LINKS).collect(Collectors.toList[Path]).asScala.toList - val files = allFiles.filter(f => { - val name = f.getFileName.toString - name.endsWith(".scala") || name.endsWith(".java") - }).map(_.toAbsolutePath.normalize.toString).toList - (List[String](), files) - } // MainClass is copy-pasted from compiler for source compatibility with 2.10.x - 2.13.x class MainClass extends Driver with EvalLoop { @@ -73,7 +71,21 @@ class ScalacBenchmark { assert(!driver.reporter.hasErrors) } - private var tempDir: File = null + def compilerArgs: List[String] = if (source.startsWith("@")) List(source) else Nil + + def sourceFiles: List[String] = + if (source.startsWith("@")) Nil + else { + import scala.collection.JavaConverters._ + val allFiles = Files.walk(findSourceDir, FileVisitOption.FOLLOW_LINKS).collect(Collectors.toList[Path]).asScala.toList + val files = allFiles.filter(f => { + val name = f.getFileName.toString + name.endsWith(".scala") || name.endsWith(".java") + }).map(_.toAbsolutePath.normalize.toString).toList + files + } + + var tempDir: File = null // Executed once per fork @Setup(Level.Trial) def initTemp(): Unit = { @@ -86,7 +98,7 @@ class ScalacBenchmark { BenchmarkUtils.deleteRecursive(tempDir.toPath) } - private def corpusSourcePath = Paths.get(s"../corpus/$source/$corpusVersion") + def corpusSourcePath: Path = Paths.get(s"../corpus/$source/$corpusVersion") @Setup(Level.Trial) def initDepsClasspath(): Unit = { val classPath = BenchmarkUtils.initDeps(corpusSourcePath) @@ -138,6 +150,8 @@ class ColdScalacBenchmark extends ScalacBenchmark { @OutputTimeUnit(TimeUnit.MILLISECONDS) @Warmup(iterations = 0) @Measurement(iterations = 1, time = 30, timeUnit = TimeUnit.SECONDS) +// @Fork triggers match error in dotty, see https://github.com/lampepfl/dotty/issues/2704 +// Comment out `@Fork` to run compilation/test with Dotty or wait for that issue to be fixed. @Fork(value = 3, jvmArgs = Array("-Xms2G", "-Xmx2G")) class WarmScalacBenchmark extends ScalacBenchmark { @Benchmark diff --git a/compilation/src/main/scalac/scala/tools/benchmark/BenchmarkDriver.scala b/compilation/src/main/scalac/scala/tools/benchmark/BenchmarkDriver.scala new file mode 100644 index 0000000..9a2e766 --- /dev/null +++ b/compilation/src/main/scalac/scala/tools/benchmark/BenchmarkDriver.scala @@ -0,0 +1,36 @@ +package scala.tools.benchmark + +import java.nio.file._ +import scala.tools.nsc._ + +trait BenchmarkDriver extends BaseBenchmarkDriver { + def compileImpl(): Unit = { + // MainClass is copy-pasted from compiler for source compatibility with 2.10.x - 2.13.x + class MainClass extends Driver with EvalLoop { + def resident(compiler: Global): Unit = loop { line => + val command = new CompilerCommand(line split "\\s+" toList, new Settings(scalacError)) + compiler.reporter.reset() + new compiler.Run() compile command.files + } + + override def newCompiler(): Global = Global(settings, reporter) + + override protected def processSettingsHook(): Boolean = { + if (source == "scala") + settings.sourcepath.value = Paths.get(s"../corpus/$source/$corpusVersion/library").toAbsolutePath.normalize.toString + else + settings.usejavacp.value = true + settings.outdir.value = tempDir.getAbsolutePath + settings.nowarn.value = true + if (depsClasspath != null) + settings.processArgumentString(s"-cp $depsClasspath") + if (extraArgs != null && extraArgs != "") + settings.processArgumentString(extraArgs) + true + } + } + val driver = new MainClass + driver.process(compilerArgs) + assert(!driver.reporter.hasErrors) + } +} \ No newline at end of file diff --git a/compilation/src/test/scala/scala/tools/benchmark/BenchmarkTest.scala b/compilation/src/test/scala/scala/tools/benchmark/BenchmarkTest.scala new file mode 100644 index 0000000..257944c --- /dev/null +++ b/compilation/src/test/scala/scala/tools/benchmark/BenchmarkTest.scala @@ -0,0 +1,9 @@ +package scala.tools.benchmark + +import scala.tools.nsc.ScalacBenchmarkStandalone +import org.junit.Test + +class BenchmarkTest { + @Test def compilesOK = + ScalacBenchmarkStandalone.main(Array("../corpus/vector", "1")) +} diff --git a/project/plugins.sbt b/project/plugins.sbt index f913d40..593ecca 100644 --- a/project/plugins.sbt +++ b/project/plugins.sbt @@ -3,3 +3,6 @@ logLevel := Level.Warn // sbt-jmh plugin - pulls in JMH dependencies too addSbtPlugin("pl.project13.scala" % "sbt-jmh" % "0.2.25") + +// sbt-dotty plugin - to support `scalaVersion := "0.x"` +addSbtPlugin("ch.epfl.lamp" % "sbt-dotty" % "0.1.2") From 16fe81afe7d7a4e6eadea105a2e87082c46f98bc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=93lafur=20P=C3=A1ll=20Geirsson?= Date: Wed, 14 Jun 2017 19:35:54 +0200 Subject: [PATCH 02/13] Re-enable FileVisitOption.FOLLOW_LINKS. This option seems to be necessary to run the JMH benchmarks. This change causes the Dotty tests to fail with the error: "object Vector in package immutable has already been compiled once during this run". --- .../src/main/scala/scala/tools/nsc/ScalacBenchmark.scala | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/compilation/src/main/scala/scala/tools/nsc/ScalacBenchmark.scala b/compilation/src/main/scala/scala/tools/nsc/ScalacBenchmark.scala index fb62725..83a4383 100644 --- a/compilation/src/main/scala/scala/tools/nsc/ScalacBenchmark.scala +++ b/compilation/src/main/scala/scala/tools/nsc/ScalacBenchmark.scala @@ -140,7 +140,7 @@ object ScalacBenchmarkStandalone { @BenchmarkMode(Array(SingleShotTime)) @OutputTimeUnit(TimeUnit.MILLISECONDS) // TODO -Xbatch reduces fork-to-fork variance, but incurs 5s -> 30s slowdown -@Fork(value = 16, jvmArgs = Array("-XX:CICompilerCount=2", "-Xms2G", "-Xmx2G")) +//@Fork(value = 16, jvmArgs = Array("-XX:CICompilerCount=2", "-Xms2G", "-Xmx2G")) class ColdScalacBenchmark extends ScalacBenchmark { @Benchmark def compile(): Unit = compileImpl() @@ -152,7 +152,7 @@ class ColdScalacBenchmark extends ScalacBenchmark { @Measurement(iterations = 1, time = 30, timeUnit = TimeUnit.SECONDS) // @Fork triggers match error in dotty, see https://github.com/lampepfl/dotty/issues/2704 // Comment out `@Fork` to run compilation/test with Dotty or wait for that issue to be fixed. -@Fork(value = 3, jvmArgs = Array("-Xms2G", "-Xmx2G")) +//@Fork(value = 3, jvmArgs = Array("-Xms2G", "-Xmx2G")) class WarmScalacBenchmark extends ScalacBenchmark { @Benchmark def compile(): Unit = compileImpl() @@ -162,7 +162,7 @@ class WarmScalacBenchmark extends ScalacBenchmark { @OutputTimeUnit(TimeUnit.MILLISECONDS) @Warmup(iterations = 10, time = 10, timeUnit = TimeUnit.SECONDS) @Measurement(iterations = 10, time = 10, timeUnit = TimeUnit.SECONDS) -@Fork(value = 3, jvmArgs = Array("-Xms2G", "-Xmx2G")) +//@Fork(value = 3, jvmArgs = Array("-Xms2G", "-Xmx2G")) class HotScalacBenchmark extends ScalacBenchmark { @Benchmark def compile(): Unit = compileImpl() From 1bd6dd5515e39497460fd5a2eafe45e1eb4407e1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=93lafur=20P=C3=A1ll=20Geirsson?= Date: Thu, 15 Jun 2017 10:10:53 +0200 Subject: [PATCH 03/13] Uncomment `@Fork`. --- .../src/main/scala/scala/tools/nsc/ScalacBenchmark.scala | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/compilation/src/main/scala/scala/tools/nsc/ScalacBenchmark.scala b/compilation/src/main/scala/scala/tools/nsc/ScalacBenchmark.scala index 83a4383..fb62725 100644 --- a/compilation/src/main/scala/scala/tools/nsc/ScalacBenchmark.scala +++ b/compilation/src/main/scala/scala/tools/nsc/ScalacBenchmark.scala @@ -140,7 +140,7 @@ object ScalacBenchmarkStandalone { @BenchmarkMode(Array(SingleShotTime)) @OutputTimeUnit(TimeUnit.MILLISECONDS) // TODO -Xbatch reduces fork-to-fork variance, but incurs 5s -> 30s slowdown -//@Fork(value = 16, jvmArgs = Array("-XX:CICompilerCount=2", "-Xms2G", "-Xmx2G")) +@Fork(value = 16, jvmArgs = Array("-XX:CICompilerCount=2", "-Xms2G", "-Xmx2G")) class ColdScalacBenchmark extends ScalacBenchmark { @Benchmark def compile(): Unit = compileImpl() @@ -152,7 +152,7 @@ class ColdScalacBenchmark extends ScalacBenchmark { @Measurement(iterations = 1, time = 30, timeUnit = TimeUnit.SECONDS) // @Fork triggers match error in dotty, see https://github.com/lampepfl/dotty/issues/2704 // Comment out `@Fork` to run compilation/test with Dotty or wait for that issue to be fixed. -//@Fork(value = 3, jvmArgs = Array("-Xms2G", "-Xmx2G")) +@Fork(value = 3, jvmArgs = Array("-Xms2G", "-Xmx2G")) class WarmScalacBenchmark extends ScalacBenchmark { @Benchmark def compile(): Unit = compileImpl() @@ -162,7 +162,7 @@ class WarmScalacBenchmark extends ScalacBenchmark { @OutputTimeUnit(TimeUnit.MILLISECONDS) @Warmup(iterations = 10, time = 10, timeUnit = TimeUnit.SECONDS) @Measurement(iterations = 10, time = 10, timeUnit = TimeUnit.SECONDS) -//@Fork(value = 3, jvmArgs = Array("-Xms2G", "-Xmx2G")) +@Fork(value = 3, jvmArgs = Array("-Xms2G", "-Xmx2G")) class HotScalacBenchmark extends ScalacBenchmark { @Benchmark def compile(): Unit = compileImpl() From ccc6b38a16042b651898389a677c1800ff1a00f8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=93lafur=20P=C3=A1ll=20Geirsson?= Date: Thu, 15 Jun 2017 10:14:18 +0200 Subject: [PATCH 04/13] Set corpusVersion in compilation/test. This prevents the "object vector is already compiled in this run" error when testing the Dotty compilation. --- .../scala/scala/tools/benchmark/BenchmarkTest.scala | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/compilation/src/test/scala/scala/tools/benchmark/BenchmarkTest.scala b/compilation/src/test/scala/scala/tools/benchmark/BenchmarkTest.scala index 257944c..b76b18e 100644 --- a/compilation/src/test/scala/scala/tools/benchmark/BenchmarkTest.scala +++ b/compilation/src/test/scala/scala/tools/benchmark/BenchmarkTest.scala @@ -1,9 +1,15 @@ package scala.tools.benchmark -import scala.tools.nsc.ScalacBenchmarkStandalone +import scala.tools.nsc.ScalacBenchmark import org.junit.Test class BenchmarkTest { - @Test def compilesOK = - ScalacBenchmarkStandalone.main(Array("../corpus/vector", "1")) + @Test def compilesOK() = { + val bench = new ScalacBenchmark + bench.source = "../corpus/vector" + bench.corpusVersion = "latest" + bench.initTemp() + bench.compileImpl() + bench.clearTemp() + } } From 49b2fb0d6ceaf37d3673a60aa4a9e157b084b8ee Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=93lafur=20P=C3=A1ll=20Geirsson?= Date: Thu, 15 Jun 2017 11:02:10 +0200 Subject: [PATCH 05/13] Explain `fork in (Test, test) := true`. --- build.sbt | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/build.sbt b/build.sbt index ffe9ffe..0ba0893 100644 --- a/build.sbt +++ b/build.sbt @@ -45,8 +45,7 @@ lazy val compilation = addJmh(project).settings( mainClass in (Jmh, run) := Some("scala.bench.ScalacBenchmarkRunner"), libraryDependencies += "com.novocode" % "junit-interface" % "0.11" % Test, testOptions in Test += Tests.Argument(TestFrameworks.JUnit), - fork in (Test, test) := true, - fork in run := true + fork in (Test, test) := true // jmh scoped tasks run with fork := true. ).settings(addJavaOptions).dependsOn(infrastructure) lazy val micro = addJmh(project).settings( From ef391dd60e590c7080760cd75c64fd87480d632b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=93lafur=20P=C3=A1ll=20Geirsson?= Date: Tue, 11 Jul 2017 17:42:16 +0200 Subject: [PATCH 06/13] Fix rebase on master. --- .../tools/benchmark/BenchmarkDriver.scala | 6 +-- .../scala/tools/nsc/ScalacBenchmark.scala | 39 ++----------------- .../tools/benchmark/BenchmarkDriver.scala | 10 +++-- 3 files changed, 13 insertions(+), 42 deletions(-) diff --git a/compilation/src/main/dotc/scala/tools/benchmark/BenchmarkDriver.scala b/compilation/src/main/dotc/scala/tools/benchmark/BenchmarkDriver.scala index cb26be0..448984e 100644 --- a/compilation/src/main/dotc/scala/tools/benchmark/BenchmarkDriver.scala +++ b/compilation/src/main/dotc/scala/tools/benchmark/BenchmarkDriver.scala @@ -6,7 +6,7 @@ import dotty.tools.dotc.core.Contexts.ContextBase trait BenchmarkDriver extends BaseBenchmarkDriver { def compileImpl(): Unit = { - implicit val ctx = (new ContextBase).initialCtx.fresh + implicit val ctx = new ContextBase().initialCtx.fresh ctx.setSetting(ctx.settings.usejavacp, true) if (depsClasspath != null) { ctx.setSetting(ctx.settings.classpath, @@ -15,8 +15,8 @@ trait BenchmarkDriver extends BaseBenchmarkDriver { ctx.setSetting(ctx.settings.d, tempDir.getAbsolutePath) ctx.setSetting(ctx.settings.language, List("Scala2")) val compiler = new dotty.tools.dotc.Compiler - val reporter = - dotty.tools.dotc.Bench.doCompile(compiler, compilerArgs.toList) + val args = compilerArgs ++ sourceFiles + val reporter = dotty.tools.dotc.Bench.doCompile(compiler, args) assert(!reporter.hasErrors) } } diff --git a/compilation/src/main/scala/scala/tools/nsc/ScalacBenchmark.scala b/compilation/src/main/scala/scala/tools/nsc/ScalacBenchmark.scala index fb62725..34dfb5b 100644 --- a/compilation/src/main/scala/scala/tools/nsc/ScalacBenchmark.scala +++ b/compilation/src/main/scala/scala/tools/nsc/ScalacBenchmark.scala @@ -21,7 +21,8 @@ trait BaseBenchmarkDriver { def depsClasspath: String def tempDir: File def corpusSourcePath: Path - def compilerArgs: Array[String] + def compilerArgs: List[String] + def sourceFiles: List[String] } @State(Scope.Benchmark) @@ -39,39 +40,7 @@ class ScalacBenchmark extends BenchmarkDriver { var depsClasspath: String = _ - def compileImpl(): Unit = { - - // MainClass is copy-pasted from compiler for source compatibility with 2.10.x - 2.13.x - class MainClass extends Driver with EvalLoop { - def resident(compiler: Global): Unit = loop { line => - val command = new CompilerCommand(line split "\\s+" toList, new Settings(scalacError)) - compiler.reporter.reset() - new compiler.Run() compile command.files - } - - override def newCompiler(): Global = Global(settings, reporter) - - override protected def processSettingsHook(): Boolean = { - if (source == "scala") - settings.sourcepath.value = Paths.get(s"../corpus/$source/$corpusVersion/library").toAbsolutePath.normalize.toString - else - settings.usejavacp.value = true - settings.outdir.value = tempDir.getAbsolutePath - settings.nowarn.value = true - if (depsClasspath != null) - settings.processArgumentString(s"-cp $depsClasspath") - true - } - } - val driver = new MainClass - - val extras = if (extraArgs != null && extraArgs != "") extraArgs.split('|').toList else Nil - val allArgs = compilerArgs ++ extras ++ sourceFiles - driver.process(allArgs.toArray) - assert(!driver.reporter.hasErrors) - } - - def compilerArgs: List[String] = if (source.startsWith("@")) List(source) else Nil + def compilerArgs: List[String] = if (source.startsWith("@")) source :: Nil else Nil def sourceFiles: List[String] = if (source.startsWith("@")) Nil @@ -81,7 +50,7 @@ class ScalacBenchmark extends BenchmarkDriver { val files = allFiles.filter(f => { val name = f.getFileName.toString name.endsWith(".scala") || name.endsWith(".java") - }).map(_.toAbsolutePath.normalize.toString).toList + }).map(_.toAbsolutePath.normalize.toString) files } diff --git a/compilation/src/main/scalac/scala/tools/benchmark/BenchmarkDriver.scala b/compilation/src/main/scalac/scala/tools/benchmark/BenchmarkDriver.scala index 9a2e766..03c9420 100644 --- a/compilation/src/main/scalac/scala/tools/benchmark/BenchmarkDriver.scala +++ b/compilation/src/main/scalac/scala/tools/benchmark/BenchmarkDriver.scala @@ -24,13 +24,15 @@ trait BenchmarkDriver extends BaseBenchmarkDriver { settings.nowarn.value = true if (depsClasspath != null) settings.processArgumentString(s"-cp $depsClasspath") - if (extraArgs != null && extraArgs != "") - settings.processArgumentString(extraArgs) true } } val driver = new MainClass - driver.process(compilerArgs) + + val extras = if (extraArgs != null && extraArgs != "") extraArgs.split('|').toList else Nil + val allArgs = compilerArgs ++ extras ++ sourceFiles + driver.process(allArgs.toArray) assert(!driver.reporter.hasErrors) } -} \ No newline at end of file + +} From 1a975a9469fcb9c525c860495e2d2107d2d9d40c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=93lafur=20P=C3=A1ll=20Geirsson?= Date: Wed, 12 Jul 2017 11:04:08 +0200 Subject: [PATCH 07/13] Fix -migration warning. --- .../src/main/dotc/scala/tools/benchmark/BenchmarkDriver.scala | 1 + corpus/vector/fb04376/Vector.scala | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/compilation/src/main/dotc/scala/tools/benchmark/BenchmarkDriver.scala b/compilation/src/main/dotc/scala/tools/benchmark/BenchmarkDriver.scala index 448984e..6579daf 100644 --- a/compilation/src/main/dotc/scala/tools/benchmark/BenchmarkDriver.scala +++ b/compilation/src/main/dotc/scala/tools/benchmark/BenchmarkDriver.scala @@ -12,6 +12,7 @@ trait BenchmarkDriver extends BaseBenchmarkDriver { ctx.setSetting(ctx.settings.classpath, depsClasspath.mkString(File.pathSeparator)) } + ctx.setSetting(ctx.settings.migration, true) ctx.setSetting(ctx.settings.d, tempDir.getAbsolutePath) ctx.setSetting(ctx.settings.language, List("Scala2")) val compiler = new dotty.tools.dotc.Compiler diff --git a/corpus/vector/fb04376/Vector.scala b/corpus/vector/fb04376/Vector.scala index a006da1..b7de3e9 100644 --- a/corpus/vector/fb04376/Vector.scala +++ b/corpus/vector/fb04376/Vector.scala @@ -82,7 +82,7 @@ override def companion: GenericCompanion[Vector] = Vector override def lengthCompare(len: Int): Int = length - len - private[collection] final def initIterator[B >: A](s: VectorIterator[B]) { + private[collection] final def initIterator[B >: A](s: VectorIterator[B]): Unit = { s.initFrom(this) if (dirty) s.stabilize(focus) if (s.depth > 1) s.gotoPos(startIndex, startIndex ^ focus) From 88190e119795fe9c1ae6911d39b508e5f02ae5fe Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=93lafur=20P=C3=A1ll=20Geirsson?= Date: Wed, 12 Jul 2017 11:26:13 +0200 Subject: [PATCH 08/13] Test dotty compilation in CI. --- .travis.yml | 2 +- build.sbt | 5 ++++- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/.travis.yml b/.travis.yml index 0e00462..63c9180 100644 --- a/.travis.yml +++ b/.travis.yml @@ -3,7 +3,7 @@ language: scala env: global: -script: sbt test:compile "hot -psource=scalap -w1 -f1" "micro/jmh:run -w1 -f1" +script: sbt test:compile "hot -psource=scalap -w1 -f1" "micro/jmh:run -w1 -f1" "; project compilation ; +test" jdk: - oraclejdk8 diff --git a/build.sbt b/build.sbt index 0ba0893..8129f01 100644 --- a/build.sbt +++ b/build.sbt @@ -2,7 +2,9 @@ name := "compiler-benchmark" version := "1.0-SNAPSHOT" -scalaVersion in ThisBuild := "2.11.8" +def scala211 = "2.11.11" +def dottyLatest = "0.2.0-RC1" +scalaVersion in ThisBuild := scala211 resolvers += "scala-integration" at "https://scala-ci.typesafe.com/artifactory/scala-integration/" @@ -40,6 +42,7 @@ lazy val compilation = addJmh(project).settings( if (isDotty.value) "ch.epfl.lamp" %% "dotty-compiler" % scalaVersion.value else scalaOrganization.value % "scala-compiler" % scalaVersion.value }, + crossScalaVersions := List(scala211, dottyLatest), unmanagedSourceDirectories.in(Compile) += sourceDirectory.in(Compile).value / (if (isDotty.value) "dotc" else "scalac"), mainClass in (Jmh, run) := Some("scala.bench.ScalacBenchmarkRunner"), From 6ed08f2a34d99e4e10a6fe381e8fd5bbe917a237 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=93lafur=20P=C3=A1ll=20Geirsson?= Date: Wed, 12 Jul 2017 12:14:20 +0200 Subject: [PATCH 09/13] Change order of tests on CI. The micro/jmh command causes a NPE exception which kills the sbt process with an exit code 0. This caused CI to report green even if the compilation/test command did not run. --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 63c9180..4e03515 100644 --- a/.travis.yml +++ b/.travis.yml @@ -3,7 +3,7 @@ language: scala env: global: -script: sbt test:compile "hot -psource=scalap -w1 -f1" "micro/jmh:run -w1 -f1" "; project compilation ; +test" +script: sbt test:compile "hot -psource=scalap -w1 -f1" "; project compilation ; +test" "micro/jmh:run -w1 -f1" jdk: - oraclejdk8 From ab1080a5206dc887a3bb0dca7135bfbc2a7f0680 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=93lafur=20P=C3=A1ll=20Geirsson?= Date: Wed, 12 Jul 2017 13:18:24 +0200 Subject: [PATCH 10/13] Run dotty jmh benchmarks in CI. The long sbt command in .travis.yml was getting unwieldy. This commit adds a `testAll` command which can easily be run locally from the sbt shell to test the command executed in CI. --- .travis.yml | 2 +- build.sbt | 12 ++++++++++++ 2 files changed, 13 insertions(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 4e03515..f0f1985 100644 --- a/.travis.yml +++ b/.travis.yml @@ -3,7 +3,7 @@ language: scala env: global: -script: sbt test:compile "hot -psource=scalap -w1 -f1" "; project compilation ; +test" "micro/jmh:run -w1 -f1" +script: sbt testAll jdk: - oraclejdk8 diff --git a/build.sbt b/build.sbt index 8129f01..4d720bb 100644 --- a/build.sbt +++ b/build.sbt @@ -6,6 +6,18 @@ def scala211 = "2.11.11" def dottyLatest = "0.2.0-RC1" scalaVersion in ThisBuild := scala211 +commands += Command.command("testAll") { s => + "test:compile" :: + "compilation/test" :: + "hot -psource=scalap -wi 1 -i 1 -f1" :: + "++0.2.0-RC1" :: + "compilation/test" :: + "hot -psource=vector -wi 1 -i 1 -f1" :: + "++2.11.8" :: + "micro/jmh:run -w1 -f1" :: + s +} + resolvers += "scala-integration" at "https://scala-ci.typesafe.com/artifactory/scala-integration/" // Convenient access to builds from PR validation From 4f27da128d53f0de74018f2bdce3a596fa5c5554 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=93lafur=20P=C3=A1ll=20Geirsson?= Date: Wed, 12 Jul 2017 13:18:49 +0200 Subject: [PATCH 11/13] Reuse extraArgs logic for dotc and scalac. --- .../src/main/dotc/scala/tools/benchmark/BenchmarkDriver.scala | 3 +-- .../src/main/scala/scala/tools/nsc/ScalacBenchmark.scala | 2 ++ .../main/scalac/scala/tools/benchmark/BenchmarkDriver.scala | 3 --- 3 files changed, 3 insertions(+), 5 deletions(-) diff --git a/compilation/src/main/dotc/scala/tools/benchmark/BenchmarkDriver.scala b/compilation/src/main/dotc/scala/tools/benchmark/BenchmarkDriver.scala index 6579daf..6047a33 100644 --- a/compilation/src/main/dotc/scala/tools/benchmark/BenchmarkDriver.scala +++ b/compilation/src/main/dotc/scala/tools/benchmark/BenchmarkDriver.scala @@ -16,8 +16,7 @@ trait BenchmarkDriver extends BaseBenchmarkDriver { ctx.setSetting(ctx.settings.d, tempDir.getAbsolutePath) ctx.setSetting(ctx.settings.language, List("Scala2")) val compiler = new dotty.tools.dotc.Compiler - val args = compilerArgs ++ sourceFiles - val reporter = dotty.tools.dotc.Bench.doCompile(compiler, args) + val reporter = dotty.tools.dotc.Bench.doCompile(compiler, allArgs) assert(!reporter.hasErrors) } } diff --git a/compilation/src/main/scala/scala/tools/nsc/ScalacBenchmark.scala b/compilation/src/main/scala/scala/tools/nsc/ScalacBenchmark.scala index 34dfb5b..f92274f 100644 --- a/compilation/src/main/scala/scala/tools/nsc/ScalacBenchmark.scala +++ b/compilation/src/main/scala/scala/tools/nsc/ScalacBenchmark.scala @@ -17,6 +17,8 @@ import scala.tools.benchmark.BenchmarkDriver trait BaseBenchmarkDriver { def source: String def extraArgs: String + def extras: List[String] = if (extraArgs != null && extraArgs != "") extraArgs.split('|').toList else Nil + def allArgs: List[String] = compilerArgs ++ extras ++ sourceFiles def corpusVersion: String def depsClasspath: String def tempDir: File diff --git a/compilation/src/main/scalac/scala/tools/benchmark/BenchmarkDriver.scala b/compilation/src/main/scalac/scala/tools/benchmark/BenchmarkDriver.scala index 03c9420..687414a 100644 --- a/compilation/src/main/scalac/scala/tools/benchmark/BenchmarkDriver.scala +++ b/compilation/src/main/scalac/scala/tools/benchmark/BenchmarkDriver.scala @@ -28,9 +28,6 @@ trait BenchmarkDriver extends BaseBenchmarkDriver { } } val driver = new MainClass - - val extras = if (extraArgs != null && extraArgs != "") extraArgs.split('|').toList else Nil - val allArgs = compilerArgs ++ extras ++ sourceFiles driver.process(allArgs.toArray) assert(!driver.reporter.hasErrors) } From 0a937bba9a21a2bcd8b13b25d4c605bf2a70810e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=93lafur=20P=C3=A1ll=20Geirsson?= Date: Wed, 12 Jul 2017 13:19:18 +0200 Subject: [PATCH 12/13] Remove outdated comment, the annotation issue has been fixed --- .../src/main/scala/scala/tools/nsc/ScalacBenchmark.scala | 2 -- 1 file changed, 2 deletions(-) diff --git a/compilation/src/main/scala/scala/tools/nsc/ScalacBenchmark.scala b/compilation/src/main/scala/scala/tools/nsc/ScalacBenchmark.scala index f92274f..aede754 100644 --- a/compilation/src/main/scala/scala/tools/nsc/ScalacBenchmark.scala +++ b/compilation/src/main/scala/scala/tools/nsc/ScalacBenchmark.scala @@ -121,8 +121,6 @@ class ColdScalacBenchmark extends ScalacBenchmark { @OutputTimeUnit(TimeUnit.MILLISECONDS) @Warmup(iterations = 0) @Measurement(iterations = 1, time = 30, timeUnit = TimeUnit.SECONDS) -// @Fork triggers match error in dotty, see https://github.com/lampepfl/dotty/issues/2704 -// Comment out `@Fork` to run compilation/test with Dotty or wait for that issue to be fixed. @Fork(value = 3, jvmArgs = Array("-Xms2G", "-Xmx2G")) class WarmScalacBenchmark extends ScalacBenchmark { @Benchmark From dd00264ade3c18f7c201d128781611a772feec5a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=93lafur=20P=C3=A1ll=20Geirsson?= Date: Wed, 12 Jul 2017 13:26:13 +0200 Subject: [PATCH 13/13] Reuse scala211 and dottyLatest variables in testAll. --- build.sbt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/build.sbt b/build.sbt index 4d720bb..9a89c2f 100644 --- a/build.sbt +++ b/build.sbt @@ -10,10 +10,10 @@ commands += Command.command("testAll") { s => "test:compile" :: "compilation/test" :: "hot -psource=scalap -wi 1 -i 1 -f1" :: - "++0.2.0-RC1" :: + s"++$dottyLatest" :: "compilation/test" :: "hot -psource=vector -wi 1 -i 1 -f1" :: - "++2.11.8" :: + s"++$scala211" :: "micro/jmh:run -w1 -f1" :: s }