Skip to content

Commit b03551d

Browse files
committed
Port: Update scalac profiler - capture more info on background threads
scala/scala#6264
1 parent 479f316 commit b03551d

File tree

2 files changed

+17
-17
lines changed

2 files changed

+17
-17
lines changed

compiler/src/dotty/tools/dotc/profile/AsyncHelper.scala

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ object AsyncHelper {
2828
val baseGroup = new ThreadGroup(s"scalac-${phase.phaseName}")
2929
private def childGroup(name: String) = new ThreadGroup(baseGroup, name)
3030

31-
protected def wrapRunnable(r: Runnable): Runnable
31+
protected def wrapRunnable(r: Runnable, shortId:String): Runnable
3232

3333
protected class CommonThreadFactory(shortId: String,
3434
daemon: Boolean = true,
@@ -38,7 +38,7 @@ object AsyncHelper {
3838
private val namePrefix = s"${baseGroup.getName}-$shortId-"
3939

4040
override def newThread(r: Runnable): Thread = {
41-
val wrapped = wrapRunnable(r)
41+
val wrapped = wrapRunnable(r, shortId)
4242
val t: Thread = new Thread(group, wrapped, namePrefix + threadNumber.getAndIncrement, 0)
4343
if (t.isDaemon != daemon) t.setDaemon(daemon)
4444
if (t.getPriority != priority) t.setPriority(priority)
@@ -61,7 +61,7 @@ object AsyncHelper {
6161
new ThreadPoolExecutor(nThreads, nThreads, 0L, TimeUnit.MILLISECONDS, new ArrayBlockingQueue[Runnable](maxQueueSize), threadFactory, rejectHandler)
6262
}
6363

64-
override protected def wrapRunnable(r: Runnable): Runnable = r
64+
override protected def wrapRunnable(r: Runnable, shortId:String): Runnable = r
6565
}
6666

6767
private class ProfilingAsyncHelper(phase: Phase, private val profiler: RealProfiler)(implicit ctx: Context) extends BaseAsyncHelper(phase) {
@@ -78,14 +78,14 @@ object AsyncHelper {
7878
new SinglePhaseInstrumentedThreadPoolExecutor(nThreads, nThreads, 0L, TimeUnit.MILLISECONDS, new ArrayBlockingQueue[Runnable](maxQueueSize), threadFactory, rejectHandler)
7979
}
8080

81-
override protected def wrapRunnable(r: Runnable): Runnable = () => {
81+
override protected def wrapRunnable(r: Runnable, shortId:String): Runnable = () => {
8282
val data = new ThreadProfileData
8383
localData.set(data)
8484

85-
val profileStart = Profiler.emptySnap
85+
val profileStart = profiler.snapThread(0)
8686
try r.run finally {
87-
val snap = profiler.snapThread()
88-
val threadRange = ProfileRange(profileStart, snap, phase, 0, "", Thread.currentThread())
87+
val snap = profiler.snapThread(data.idleNs)
88+
val threadRange = ProfileRange(profileStart, snap, phase, shortId, data.taskCount, Thread.currentThread())
8989
profiler.completeBackground(threadRange)
9090
}
9191
}

compiler/src/dotty/tools/dotc/profile/Profiler.scala

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ case class ProfileSnap(threadId: Long, threadName: String, snapTimeNanos : Long,
3232
copy(heapBytes = heapBytes)
3333
}
3434
}
35-
case class ProfileRange(start: ProfileSnap, end:ProfileSnap, phase:Phase, id:Int, purpose:String, thread:Thread) {
35+
case class ProfileRange(start: ProfileSnap, end:ProfileSnap, phase:Phase, purpose:String, taskCount:Int, thread:Thread) {
3636
def allocatedBytes = end.allocatedBytes - start.allocatedBytes
3737

3838
def userNs = end.userTimeNanos - start.userTimeNanos
@@ -105,15 +105,15 @@ private [profile] class RealProfiler(reporter : ProfileReporter)(implicit ctx: C
105105

106106
private val mainThread = Thread.currentThread()
107107

108-
private[profile] def snapThread(): ProfileSnap = {
108+
private[profile] def snapThread(idleTimeNanos: Long): ProfileSnap = {
109109
import RealProfiler._
110110
val current = Thread.currentThread()
111111

112112
ProfileSnap(
113113
threadId = current.getId,
114114
threadName = current.getName,
115115
snapTimeNanos = System.nanoTime(),
116-
idleTimeNanos = 0,
116+
idleTimeNanos = idleTimeNanos,
117117
cpuTimeNanos = threadMx.getCurrentThreadCpuTime,
118118
userTimeNanos = threadMx.getCurrentThreadUserTime,
119119
allocatedBytes = threadMx.getThreadAllocatedBytes(Thread.currentThread().getId),
@@ -158,13 +158,13 @@ private [profile] class RealProfiler(reporter : ProfileReporter)(implicit ctx: C
158158
val startTime = info.get("startTime").asInstanceOf[jLong].longValue()
159159
val endTime = info.get("endTime").asInstanceOf[jLong].longValue()
160160
val threads = info.get("GcThreadCount").asInstanceOf[jInt].longValue()
161-
reporter.reportGc(new GcEventData("", reportNs, startTime, endTime, name, action, cause, threads))
161+
reporter.reportGc(GcEventData("", reportNs, startTime, endTime, name, action, cause, threads))
162162
}
163163
}
164164

165165
override def afterPhase(phase: Phase, snapBefore: ProfileSnap): Unit = {
166166
assert(mainThread eq Thread.currentThread())
167-
val initialSnap = snapThread()
167+
val initialSnap = snapThread(0)
168168
if (ctx.settings.YprofileExternalTool.value.contains(phase.toString)) {
169169
println("Profile hook stop")
170170
ExternalToolHook.after()
@@ -174,7 +174,7 @@ private [profile] class RealProfiler(reporter : ProfileReporter)(implicit ctx: C
174174
initialSnap.updateHeap(readHeapUsage())
175175
} else initialSnap
176176

177-
reporter.reportForeground(this, new ProfileRange(snapBefore, finalSnap, phase, id, "", Thread.currentThread))
177+
reporter.reportForeground(this, ProfileRange(snapBefore, finalSnap, phase, "", 0, Thread.currentThread))
178178
}
179179

180180
override def beforePhase(phase: Phase): ProfileSnap = {
@@ -185,7 +185,7 @@ private [profile] class RealProfiler(reporter : ProfileReporter)(implicit ctx: C
185185
println("Profile hook start")
186186
ExternalToolHook.before()
187187
}
188-
snapThread()
188+
snapThread(0)
189189
}
190190

191191
}
@@ -233,8 +233,8 @@ object ConsoleProfileReporter extends ProfileReporter {
233233

234234
class StreamProfileReporter(out:PrintWriter) extends ProfileReporter {
235235
override def header(profiler: RealProfiler): Unit = {
236-
out.println(s"info, ${profiler.id}, ${profiler.outDir}")
237-
out.println(s"header(main/background),startNs,endNs,runId,phaseId,phaseName,purpose,threadId,threadName,runNs,idleNs,cpuTimeNs,userTimeNs,allocatedByte,heapSize")
236+
out.println(s"info, ${profiler.id}, version, 2, output, ${profiler.outDir}")
237+
out.println(s"header(main/background),startNs,endNs,runId,phaseId,phaseName,purpose,task-count,threadId,threadName,runNs,idleNs,cpuTimeNs,userTimeNs,allocatedByte,heapSize")
238238
out.println(s"header(GC),startNs,endNs,startMs,endMs,name,action,cause,threads")
239239
}
240240

@@ -245,7 +245,7 @@ class StreamProfileReporter(out:PrintWriter) extends ProfileReporter {
245245
reportCommon(EventType.MAIN, profiler, threadRange)
246246
}
247247
private def reportCommon(tpe:EventType.value, profiler: RealProfiler, threadRange: ProfileRange): Unit = {
248-
out.println(s"$tpe,${threadRange.start.snapTimeNanos},${threadRange.end.snapTimeNanos},${profiler.id},${threadRange.phase.id},${threadRange.phase.phaseName.replace(',', ' ')},${threadRange.purpose},${threadRange.thread.getId},${threadRange.thread.getName},${threadRange.runNs},${threadRange.idleNs},${threadRange.cpuNs},${threadRange.userNs},${threadRange.allocatedBytes},${if(tpe == EventType.MAIN) threadRange.end.heapBytes else ""}")
248+
out.println(s"$tpe,${threadRange.start.snapTimeNanos},${threadRange.end.snapTimeNanos},${profiler.id},${threadRange.phase.id},${threadRange.phase.phaseName.replace(',', ' ')},${threadRange.purpose},${threadRange.taskCount},${threadRange.thread.getId},${threadRange.thread.getName},${threadRange.runNs},${threadRange.idleNs},${threadRange.cpuNs},${threadRange.userNs},${threadRange.allocatedBytes},${threadRange.end.heapBytes} ")
249249
}
250250

251251
override def reportGc(data: GcEventData): Unit = {

0 commit comments

Comments
 (0)