Skip to content

Commit 75d2cb7

Browse files
committed
Use JMH's new first-party support for async-profiler
1 parent 5abc165 commit 75d2cb7

File tree

6 files changed

+37
-7
lines changed

6 files changed

+37
-7
lines changed

build.sbt

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,7 @@ lazy val jvm = addJmh(project).settings(
7777

7878
lazy val addJavaOptions = javaOptions ++= {
7979
def refOf(version: String) = {
80-
val HasSha = """.*(?:bin|pre)-([0-9a-f]{7,})(?:-.*)?""".r
80+
val HasSha = """.*(?:bin|pre)-([0-9a-f]{7,})(?:-.*)?""".r
8181
version match {
8282
case HasSha(sha) => sha
8383
case _ => "v" + version
@@ -100,5 +100,8 @@ def addJmh(project: Project): Project = {
100100
// IntelliJ SBT project import doesn't like sbt-jmh's default setup, which results the prod and test
101101
// output paths overlapping. This is because sbt-jmh declares the `jmh` config as extending `test`, but
102102
// configures `classDirectory in Jmh := classDirectory in Compile`.
103-
project.enablePlugins(JmhPlugin).overrideConfigs(JmhConfig.extend(Compile))
103+
project.enablePlugins(JmhPlugin).overrideConfigs(JmhConfig.extend(Compile)).settings(
104+
version in Jmh := "1.24" // duplicated in project/build.sbt
105+
)
104106
}
107+

compilation/src/main/scala/scala/tools/nsc/ScalacBenchmark.scala

Lines changed: 18 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import java.util.concurrent.TimeUnit
77
import com.typesafe.config.ConfigFactory
88
import org.openjdk.jmh.annotations.Mode._
99
import org.openjdk.jmh.annotations._
10+
import org.openjdk.jmh.profile.AsyncProfiler
1011

1112
import scala.tools.benchmark.BenchmarkDriver
1213

@@ -22,6 +23,20 @@ trait BaseBenchmarkDriver {
2223
def compilerArgs: List[String]
2324
def sourceFiles: List[String]
2425
def isResident: Boolean = false
26+
def compileProfiled(): Unit = {
27+
val profiler: AsyncProfiler.JavaApi = try {
28+
AsyncProfiler.JavaApi.getInstance()
29+
} catch {
30+
case _: LinkageError => null
31+
}
32+
if (profiler != null) profiler.filterThread(Thread.currentThread(), true)
33+
try {
34+
compileImpl()
35+
} finally {
36+
if (profiler != null) profiler.filterThread(Thread.currentThread(), false)
37+
}
38+
}
39+
def compileImpl(): Unit
2540
}
2641

2742
@State(Scope.Benchmark)
@@ -123,7 +138,7 @@ object ScalacBenchmarkStandalone {
123138
@Fork(value = 16, jvmArgs = Array("-XX:CICompilerCount=2", "-Xms2G", "-Xmx2G", "-Xss2M"))
124139
class ColdScalacBenchmark extends ScalacBenchmark {
125140
@Benchmark
126-
def compile(): Unit = compileImpl()
141+
def compile(): Unit = compileProfiled()
127142
}
128143

129144
@BenchmarkMode(Array(org.openjdk.jmh.annotations.Mode.SampleTime))
@@ -133,7 +148,7 @@ class ColdScalacBenchmark extends ScalacBenchmark {
133148
@Fork(value = 3, jvmArgs = Array("-Xms2G", "-Xmx2G", "-Xss2M"))
134149
class WarmScalacBenchmark extends ScalacBenchmark {
135150
@Benchmark
136-
def compile(): Unit = compileImpl()
151+
def compile(): Unit = compileProfiled()
137152
}
138153

139154
@BenchmarkMode(Array(org.openjdk.jmh.annotations.Mode.SampleTime))
@@ -143,5 +158,5 @@ class WarmScalacBenchmark extends ScalacBenchmark {
143158
@Fork(value = 3, jvmArgs = Array("-Xms2G", "-Xmx2G", "-Xss2M"))
144159
class HotScalacBenchmark extends ScalacBenchmark {
145160
@Benchmark
146-
def compile(): Unit = compileImpl()
161+
def compile(): Unit = compileProfiled()
147162
}

compilation/src/main/scalac/scala/tools/benchmark/BenchmarkDriver.scala

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import java.io.File
44
import java.nio.file._
55

66
import com.typesafe.config.ConfigFactory
7+
import org.openjdk.jmh.profile.AsyncProfiler
78

89
import scala.tools.nsc._
910

infrastructure/src/main/java/scala/bench/ScalacBenchmarkRunner.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,7 @@ public static Options setParameters(CommandLineOptions clOpts) throws IOExceptio
7272
}
7373

7474
public static void main(String[] args) throws Exception {
75+
System.out.println(java.util.Arrays.asList(args));
7576
CommandLineOptions opts = new CommandLineOptions(args);
7677
// Support `-h/-l/lp/lprof/lrf`.
7778
if (opts.shouldHelp() || opts.shouldList() || opts.shouldListProfilers() || opts.shouldListResultFormats() || opts.shouldListWithParams()) {

project/Profilers.scala

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ abstract class Profiler(val name: String) {
1010
val flameGraphOpts = s"--minwidth,1,--colors,java,--cp,--width,1800"
1111
}
1212
object Profiler {
13-
def all = List(basic, jfr, asyncAlloc, asyncCpu, perfNorm)
13+
def all = List(basic, jfr, asyncAlloc, asyncCpu, asyncWall, perfNorm)
1414

1515
def commands = Profiler.all.map { prof => Command.arb(profParser("prof" + prof.toString.capitalize))(commandImpl(List(prof))) } :+
1616
Command.arb(profParser("prof"))(commandImpl(Profiler.all))
@@ -40,11 +40,12 @@ case object jfr extends Profiler("jfr") {
4040
sealed abstract class async(event: String) extends Profiler("async-" + event) {
4141
val framebuf = 33554432
4242
def command(outDir: File): String = {
43-
s"""-prof "jmh.extras.Async:dir=${outDir.getAbsolutePath};flameGraphOpts=$flameGraphOpts;verbose=true;event=$event;framebuf=${framebuf}" """
43+
s"""-prof "async:dir=${outDir.getAbsolutePath};libPath=${System.getenv("ASYNC_PROFILER_DIR")}/build/libasyncProfiler.so;minwidth=1;width=1800;verbose=true;event=$event;filter=${event == "wall"};flat=40;trace=10;framebuf=${framebuf};output=flamegraph,jfr,text" """
4444
} // + ";simplename=true" TODO add this after upgrading next sbt-jmh release
4545
}
4646
case object asyncCpu extends async("cpu")
4747
case object asyncAlloc extends async("alloc")
48+
case object asyncWall extends async("wall")
4849
case object perfNorm extends Profiler("perfNorm") {
4950
def command(outDir: File): String = "-prof perfnorm"
5051
}

project/build.sbt

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
val jmhV = "1.24" // duplicated in build.sbt
2+
3+
libraryDependencies ++= List(
4+
"org.openjdk.jmh" % "jmh-core" % jmhV,
5+
"org.openjdk.jmh" % "jmh-generator-bytecode" % jmhV,
6+
"org.openjdk.jmh" % "jmh-generator-reflection" % jmhV
7+
)
8+
9+
resolvers in Global += Resolver.mavenLocal

0 commit comments

Comments
 (0)