@@ -113,52 +113,52 @@ private [profile] object RealProfiler {
113113 val threadMx = ExtendedThreadMxBean .proxy
114114 if (threadMx.isThreadCpuTimeSupported) threadMx.setThreadCpuTimeEnabled(true )
115115 private val idGen = new AtomicInteger ()
116+ private val baselineSnap = snapThread(0 )
117+
116118 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
117137}
118138
119139private [profile] class RealProfiler (reporter : ProfileReporter , val settings : Settings ) extends Profiler with NotificationListener {
120140 private val mainThread = Thread .currentThread()
141+ val id = RealProfiler .idGen.incrementAndGet()
121142 val tracePath = {
122143 if (settings.YprofileDestination .isSetByUser) new File (new java.io.File (settings.YprofileDestination .value)).changeExtension(" trace" ).jfile.toPath
123144 else Files .createTempFile(" scalac-" , " .trace" )
124145 }
125146 private val chromeTrace = new ChromeTrace (tracePath)
126- chromeTrace.traceAsyncEventStart(" scalac-" + mainThread.getId, mainThread.getId , " 0" )
147+ chromeTrace.traceAsyncEventStart(" scalac-" + id, id , " 0" )
127148
128149 def completeBackground (threadRange : ProfileRange ): Unit = {
129150 reporter.reportBackground(this , threadRange)
130151 }
131152
132153 def outDir = settings.outputDirs.getSingleOutput.getOrElse(settings.outputDirs.outputs.head._2.file).toString
133154
134- val id = RealProfiler .idGen.incrementAndGet()
135155 RealProfiler .gcMx foreach {
136156 case emitter : NotificationEmitter => emitter.addNotificationListener(this , null , null )
137157 case gc => println(s " Cant connect gcListener to ${gc.getClass}" )
138158 }
139159
140160 val active = RealProfiler .allPlugins map (_.generate(this , settings))
141161
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-
162162 private def doGC : Unit = {
163163 System .gc()
164164 System .runFinalization()
@@ -179,7 +179,7 @@ private [profile] class RealProfiler(reporter : ProfileReporter, val settings: S
179179 val startNanos = gcEvent.endNanos - durationNanos
180180 chromeTrace.traceDurationEvent(gcEvent.name, startNanos, durationNanos, GcThreadId )
181181 }
182- chromeTrace.traceAsyncEventEnd(" scalac-" + mainThread.getId, 0 , " 0" )
182+ chromeTrace.traceAsyncEventEnd(" scalac-" + id, id , " 0" )
183183
184184 println(" Trace file: " + tracePath)
185185 chromeTrace.close()
@@ -215,97 +215,84 @@ private [profile] class RealProfiler(reporter : ProfileReporter, val settings: S
215215
216216 override def beforePhase (phase : Phase ): ProfileSnap = {
217217 assert(mainThread eq Thread .currentThread())
218- chromeTrace.traceAsyncEventStart(phase.name, mainThread.getId , " 0" )
218+ chromeTrace.traceAsyncEventStart(phase.name, id , " 0" )
219219 if (settings.YprofileRunGcBetweenPhases .containsPhase(phase))
220220 doGC
221221 if (settings.YprofileExternalTool .containsPhase(phase)) {
222222 println(" Profile hook start" )
223223 ExternalToolHook .before()
224224 }
225225 active foreach {_.beforePhase(phase)}
226- val snap = snapThread(0 )
227- if (phase.prev eq null ) baseline = snap
228- snap
226+ RealProfiler .snapThread(0 )
229227 }
230228
231229 override def afterPhase (phase : Phase , snapBefore : ProfileSnap ): Unit = {
232230 assert(mainThread eq Thread .currentThread())
233- val initialSnap = snapThread(0 )
231+ val initialSnap = RealProfiler . snapThread(0 )
234232 active foreach {_.afterPhase(phase)}
235233 if (settings.YprofileExternalTool .containsPhase(phase)) {
236234 println(" Profile hook stop" )
237235 ExternalToolHook .after()
238236 }
239237 val finalSnap = if (settings.YprofileRunGcBetweenPhases .containsPhase(phase)) {
240238 doGC
241- initialSnap.updateHeap(readHeapUsage())
239+ initialSnap.updateHeap(RealProfiler . readHeapUsage())
242240 } else initialSnap
243- chromeTrace.traceAsyncEventEnd(phase.name, mainThread.getId , " 0 " )
241+ chromeTrace.traceAsyncEventEnd(phase.name, id , " -GC " )
244242
245243 reporter.reportForeground(this , ProfileRange (snapBefore, finalSnap, phase, " " , 0 , Thread .currentThread))
246244 }
247245
248246 override def beforeUnit (phase : Phase , file : AbstractFile ): ProfileSnap = {
249247 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 )
252250 }
253251
254252 override def afterUnit (phase : Phase , file : AbstractFile , snapBefore : ProfileSnap ): Unit = {
255253 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)
265263 }
266264
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)
274265 override def beforeTypedImplDef (sym : Global # Symbol ): Unit = {
275- chromeTrace.traceAsyncEventStart(sym.rawname.toString, traceId, intToString(completingStack.length) )
266+ chromeTrace.traceAsyncEventStart(sym.rawname.toString, id, " " )
276267 }
277268 override def afterTypedImplDef (sym : Global # Symbol ): Unit = {
278- chromeTrace.traceAsyncEventEnd(sym.rawname.toString, traceId, intToString(completingStack.length) )
269+ chromeTrace.traceAsyncEventEnd(sym.rawname.toString, id, " " )
279270 }
280271
281272 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" )
283274 }
284275
285276 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" )
287278 }
288279
289280 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" )
291282 }
292283
293284 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" )
295286 }
296287
297288 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, " " )
302291 }
303292
304293 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" )
309296 }
310297}
311298
0 commit comments