@@ -113,52 +113,52 @@ private [profile] object RealProfiler {
113
113
val threadMx = ExtendedThreadMxBean .proxy
114
114
if (threadMx.isThreadCpuTimeSupported) threadMx.setThreadCpuTimeEnabled(true )
115
115
private val idGen = new AtomicInteger ()
116
+ private val baselineSnap = snapThread(0 )
117
+
116
118
lazy val allPlugins = ServiceLoader .load(classOf [ProfilerPlugin ]).iterator().asScala.toList
119
+
120
+ private [profile] def snapThread ( idleTimeNanos: Long ): ProfileSnap = {
121
+ val current = Thread .currentThread()
122
+ val allocatedBytes = threadMx.getThreadAllocatedBytes(Thread .currentThread().getId)
123
+ ProfileSnap (
124
+ threadId = current.getId,
125
+ threadName = current.getName,
126
+ snapTimeNanos = System .nanoTime(),
127
+ idleTimeNanos = idleTimeNanos,
128
+ cpuTimeNanos = threadMx.getCurrentThreadCpuTime,
129
+ userTimeNanos = threadMx.getCurrentThreadUserTime,
130
+ allocatedBytes = allocatedBytes,
131
+ heapBytes = readHeapUsage(),
132
+ totalClassesLoaded = classLoaderMx.getTotalLoadedClassCount,
133
+ totalJITCompilationTime = compileMx.getTotalCompilationTime
134
+ )
135
+ }
136
+ private def readHeapUsage () = RealProfiler .memoryMx.getHeapMemoryUsage.getUsed
117
137
}
118
138
119
139
private [profile] class RealProfiler (reporter : ProfileReporter , val settings : Settings ) extends Profiler with NotificationListener {
120
140
private val mainThread = Thread .currentThread()
141
+ val id = RealProfiler .idGen.incrementAndGet()
121
142
val tracePath = {
122
143
if (settings.YprofileDestination .isSetByUser) new File (new java.io.File (settings.YprofileDestination .value)).changeExtension(" trace" ).jfile.toPath
123
144
else Files .createTempFile(" scalac-" , " .trace" )
124
145
}
125
146
private val chromeTrace = new ChromeTrace (tracePath)
126
- chromeTrace.traceAsyncEventStart(" scalac-" + mainThread.getId, mainThread.getId , " 0" )
147
+ chromeTrace.traceAsyncEventStart(" scalac-" + id, id , " 0" )
127
148
128
149
def completeBackground (threadRange : ProfileRange ): Unit = {
129
150
reporter.reportBackground(this , threadRange)
130
151
}
131
152
132
153
def outDir = settings.outputDirs.getSingleOutput.getOrElse(settings.outputDirs.outputs.head._2.file).toString
133
154
134
- val id = RealProfiler .idGen.incrementAndGet()
135
155
RealProfiler .gcMx foreach {
136
156
case emitter : NotificationEmitter => emitter.addNotificationListener(this , null , null )
137
157
case gc => println(s " Cant connect gcListener to ${gc.getClass}" )
138
158
}
139
159
140
160
val active = RealProfiler .allPlugins map (_.generate(this , settings))
141
161
142
-
143
- private [profile] def snapThread ( idleTimeNanos: Long ): ProfileSnap = {
144
- import RealProfiler ._
145
- val current = Thread .currentThread()
146
- val allocatedBytes = threadMx.getThreadAllocatedBytes(Thread .currentThread().getId)
147
- ProfileSnap (
148
- threadId = current.getId,
149
- threadName = current.getName,
150
- snapTimeNanos = System .nanoTime(),
151
- idleTimeNanos = idleTimeNanos,
152
- cpuTimeNanos = threadMx.getCurrentThreadCpuTime,
153
- userTimeNanos = threadMx.getCurrentThreadUserTime,
154
- allocatedBytes = allocatedBytes,
155
- heapBytes = readHeapUsage(),
156
- totalClassesLoaded = classLoaderMx.getTotalLoadedClassCount,
157
- totalJITCompilationTime = compileMx.getTotalCompilationTime
158
- )
159
- }
160
- private def readHeapUsage () = RealProfiler .memoryMx.getHeapMemoryUsage.getUsed
161
-
162
162
private def doGC : Unit = {
163
163
System .gc()
164
164
System .runFinalization()
@@ -179,7 +179,7 @@ private [profile] class RealProfiler(reporter : ProfileReporter, val settings: S
179
179
val startNanos = gcEvent.endNanos - durationNanos
180
180
chromeTrace.traceDurationEvent(gcEvent.name, startNanos, durationNanos, GcThreadId )
181
181
}
182
- chromeTrace.traceAsyncEventEnd(" scalac-" + mainThread.getId , 0 , " 0" )
182
+ chromeTrace.traceAsyncEventEnd(" scalac-" + id , 0 , " 0" )
183
183
184
184
println(" Trace file: " + tracePath)
185
185
chromeTrace.close()
@@ -215,97 +215,84 @@ private [profile] class RealProfiler(reporter : ProfileReporter, val settings: S
215
215
216
216
override def beforePhase (phase : Phase ): ProfileSnap = {
217
217
assert(mainThread eq Thread .currentThread())
218
- chromeTrace.traceAsyncEventStart(phase.name, mainThread.getId , " 0" )
218
+ chromeTrace.traceAsyncEventStart(phase.name, id , " 0" )
219
219
if (settings.YprofileRunGcBetweenPhases .containsPhase(phase))
220
220
doGC
221
221
if (settings.YprofileExternalTool .containsPhase(phase)) {
222
222
println(" Profile hook start" )
223
223
ExternalToolHook .before()
224
224
}
225
225
active foreach {_.beforePhase(phase)}
226
- val snap = snapThread(0 )
227
- if (phase.prev eq null ) baseline = snap
228
- snap
226
+ RealProfiler .snapThread(0 )
229
227
}
230
228
231
229
override def afterPhase (phase : Phase , snapBefore : ProfileSnap ): Unit = {
232
230
assert(mainThread eq Thread .currentThread())
233
- val initialSnap = snapThread(0 )
231
+ val initialSnap = RealProfiler . snapThread(0 )
234
232
active foreach {_.afterPhase(phase)}
235
233
if (settings.YprofileExternalTool .containsPhase(phase)) {
236
234
println(" Profile hook stop" )
237
235
ExternalToolHook .after()
238
236
}
239
237
val finalSnap = if (settings.YprofileRunGcBetweenPhases .containsPhase(phase)) {
240
238
doGC
241
- initialSnap.updateHeap(readHeapUsage())
239
+ initialSnap.updateHeap(RealProfiler . readHeapUsage())
242
240
} else initialSnap
243
- chromeTrace.traceAsyncEventEnd(phase.name, mainThread.getId , " 0 " )
241
+ chromeTrace.traceAsyncEventEnd(phase.name, id , " -GC " )
244
242
245
243
reporter.reportForeground(this , ProfileRange (snapBefore, finalSnap, phase, " " , 0 , Thread .currentThread))
246
244
}
247
245
248
246
override def beforeUnit (phase : Phase , file : AbstractFile ): ProfileSnap = {
249
247
assert(mainThread eq Thread .currentThread())
250
- chromeTrace.traceAsyncEventStart(file.name, mainThread.getId , " 0" )
251
- snapThread(0 )
248
+ chromeTrace.traceAsyncEventStart(file.name, id , " 0" )
249
+ RealProfiler . snapThread(0 )
252
250
}
253
251
254
252
override def afterUnit (phase : Phase , file : AbstractFile , snapBefore : ProfileSnap ): Unit = {
255
253
assert(mainThread eq Thread .currentThread())
256
- val initialSnap = snapThread(0 )
257
- chromeTrace.traceAsyncEventEnd(file.name, mainThread.getId , " 0" )
258
- chromeTrace.traceCounterEvent(" allocBytes" , " allocBytes" , initialSnap.allocatedBytes - this .baseline .allocatedBytes)
259
- chromeTrace.traceCounterEvent(" heapBytes" , " heapBytes" , initialSnap.heapBytes - this .baseline .heapBytes)
260
- chromeTrace.traceCounterEvent(" classesLoaded" , " classesLoaded" , initialSnap.totalClassesLoaded - this .baseline .totalClassesLoaded)
261
- chromeTrace.traceCounterEvent(" jitCompilationTime" , " jitCompilationTime" , initialSnap.totalJITCompilationTime - this .baseline .totalJITCompilationTime)
262
- chromeTrace.traceCounterEvent(" userTime" , " userTime" , initialSnap.userTimeNanos - this .baseline .userTimeNanos)
263
- chromeTrace.traceCounterEvent(" cpuTime" , " cpuTime" , initialSnap.cpuTimeNanos - this .baseline .cpuTimeNanos)
264
- chromeTrace.traceCounterEvent(" idleTime" , " idleTime" , initialSnap.idleTimeNanos - this .baseline .idleTimeNanos)
254
+ val initialSnap = RealProfiler . snapThread(0 )
255
+ chromeTrace.traceAsyncEventEnd(file.name, id , " 0" )
256
+ chromeTrace.traceCounterEvent(" allocBytes" , " allocBytes" , initialSnap.allocatedBytes - RealProfiler .baselineSnap .allocatedBytes)
257
+ chromeTrace.traceCounterEvent(" heapBytes" , " heapBytes" , initialSnap.heapBytes - RealProfiler .baselineSnap .heapBytes)
258
+ chromeTrace.traceCounterEvent(" classesLoaded" , " classesLoaded" , initialSnap.totalClassesLoaded - RealProfiler .baselineSnap .totalClassesLoaded)
259
+ chromeTrace.traceCounterEvent(" jitCompilationTime" , " jitCompilationTime" , initialSnap.totalJITCompilationTime - RealProfiler .baselineSnap .totalJITCompilationTime)
260
+ chromeTrace.traceCounterEvent(" userTime" , " userTime" , initialSnap.userTimeNanos - RealProfiler .baselineSnap .userTimeNanos)
261
+ chromeTrace.traceCounterEvent(" cpuTime" , " cpuTime" , initialSnap.cpuTimeNanos - RealProfiler .baselineSnap .cpuTimeNanos)
262
+ chromeTrace.traceCounterEvent(" idleTime" , " idleTime" , initialSnap.idleTimeNanos - RealProfiler .baselineSnap .idleTimeNanos)
265
263
}
266
264
267
- private var baseline : ProfileSnap = _
268
-
269
- private val completingStack = new mutable.ArrayStack [Global # Symbol ]
270
- private val stringsOf = (0 to 128 ).map(_.toString).toArray
271
- def intToString (i : Int ) = if (i < 128 ) stringsOf(i) else i.toString
272
-
273
- private def traceId = if (completingStack.isEmpty) mainThread.getId else mainThread.getId << 32 | (completingStack.top.id.toLong & 0xffffffffL)
274
265
override def beforeTypedImplDef (sym : Global # Symbol ): Unit = {
275
- chromeTrace.traceAsyncEventStart(sym.rawname.toString, traceId, intToString(completingStack.length) )
266
+ chromeTrace.traceAsyncEventStart(sym.rawname.toString, id, " " )
276
267
}
277
268
override def afterTypedImplDef (sym : Global # Symbol ): Unit = {
278
- chromeTrace.traceAsyncEventEnd(sym.rawname.toString, traceId, intToString(completingStack.length) )
269
+ chromeTrace.traceAsyncEventEnd(sym.rawname.toString, id, " " )
279
270
}
280
271
281
272
override def beforeImplicitSearch (pt : Global # Symbol ): Unit = {
282
- chromeTrace.traceAsyncEventStart(" <implicit> " + pt.rawname, traceId, intToString(completingStack.length) , colour = " yellow" )
273
+ chromeTrace.traceAsyncEventStart(" ?[ " + pt.rawname + " ] " , id, " " , colour = " yellow" )
283
274
}
284
275
285
276
override def afterImplicitSearch (pt : Global # Symbol ): Unit = {
286
- chromeTrace.traceAsyncEventEnd(" <implicit> " + pt.rawname, traceId, intToString(completingStack.length) , colour = " yellow" )
277
+ chromeTrace.traceAsyncEventEnd(" ?[ " + pt.rawname + " ] " , id, " " , colour = " yellow" )
287
278
}
288
279
289
280
override def beforeMacroExpansion (macroSym : Global # Symbol ): Unit = {
290
- chromeTrace.traceAsyncEventStart(" <macro> " + macroSym.rawname, traceId, intToString(completingStack.length) , colour = " olive" )
281
+ chromeTrace.traceAsyncEventStart(" « " + macroSym.rawname + " » " , id, " " , colour = " olive" )
291
282
}
292
283
293
284
override def afterMacroExpansion (macroSym : Global # Symbol ): Unit = {
294
- chromeTrace.traceAsyncEventEnd(" <macro> " + macroSym.rawname, traceId, intToString(completingStack.length) , colour = " olive" )
285
+ chromeTrace.traceAsyncEventEnd(" « " + macroSym.rawname + " » " , id, " " , colour = " olive" )
295
286
}
296
287
297
288
override def beforeCompletion (root : Global # Symbol ): Unit = {
298
- chromeTrace.traceAsyncEventStart(" <wait>" , traceId, intToString(completingStack.length), colour = " thread_state_sleeping" )
299
- completingStack.push(root)
300
- chromeTrace.traceAsyncEventStart(" <completion>" , traceId, intToString(completingStack.length))
301
- chromeTrace.traceAsyncEventStart(root.rawname.toString, traceId, intToString(completingStack.length))
289
+ chromeTrace.traceAsyncEventStart(" ↯" , id, " " , colour = " thread_state_sleeping" )
290
+ chromeTrace.traceAsyncEventStart(root.rawname.toString, id, " " )
302
291
}
303
292
304
293
override def afterCompletion (root : Global # Symbol ): Unit = {
305
- chromeTrace.traceAsyncEventEnd(root.rawname.toString, traceId, intToString(completingStack.length))
306
- chromeTrace.traceAsyncEventEnd(" <completion>" , traceId, intToString(completingStack.length))
307
- completingStack.pop()
308
- chromeTrace.traceAsyncEventEnd(" <wait>" , traceId, intToString(completingStack.length))
294
+ chromeTrace.traceAsyncEventEnd(root.rawname.toString, id, " " )
295
+ chromeTrace.traceAsyncEventEnd(" ↯" , id, " " , colour = " thread_state_sleeping" )
309
296
}
310
297
}
311
298
0 commit comments