Skip to content

Commit 45cb72c

Browse files
committed
Refine statistics
- new option -Ydetailed-stats provdies stats without starting a "heart-beat" thread. - track times of all phase groups under -Ydetailed-stats, even if -verbose if off. - better tracking of base types, which seem to be more prominent and expensive under new scheme.
1 parent 239fb8f commit 45cb72c

File tree

4 files changed

+36
-17
lines changed

4 files changed

+36
-17
lines changed

compiler/src/dotty/tools/dotc/Run.scala

Lines changed: 11 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -105,7 +105,7 @@ class Run(comp: Compiler, ictx: Context) {
105105
compileUnits()(ctx)
106106
}
107107

108-
protected def compileUnits()(implicit ctx: Context) = Stats.monitorHeartBeat {
108+
protected def compileUnits()(implicit ctx: Context) = Stats.maybeMonitored {
109109
ctx.checkSingleThreaded()
110110

111111
// If testing pickler, make sure to stop after pickling phase:
@@ -118,17 +118,18 @@ class Run(comp: Compiler, ictx: Context) {
118118
ctx.usePhases(phases)
119119
var lastPrintedTree: PrintedTree = NoPrintedTree
120120
for (phase <- ctx.allPhases)
121-
if (phase.isRunnable) {
122-
val start = System.currentTimeMillis
123-
units = phase.runOn(units)
124-
if (ctx.settings.Xprint.value.containsPhase(phase)) {
125-
for (unit <- units) {
126-
lastPrintedTree =
127-
printTree(lastPrintedTree)(ctx.fresh.setPhase(phase.next).setCompilationUnit(unit))
121+
if (phase.isRunnable)
122+
Stats.trackTime(s"$phase ms ") {
123+
val start = System.currentTimeMillis
124+
units = phase.runOn(units)
125+
if (ctx.settings.Xprint.value.containsPhase(phase)) {
126+
for (unit <- units) {
127+
lastPrintedTree =
128+
printTree(lastPrintedTree)(ctx.fresh.setPhase(phase.next).setCompilationUnit(unit))
129+
}
128130
}
131+
ctx.informTime(s"$phase ", start)
129132
}
130-
ctx.informTime(s"$phase ", start)
131-
}
132133
if (!ctx.reporter.hasErrors) Rewrites.writeBack()
133134
for (unit <- units)
134135
Stats.record("retained typed trees at end", unit.tpdTree.treeSize)

compiler/src/dotty/tools/dotc/config/ScalaSettings.scala

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -87,7 +87,8 @@ class ScalaSettings extends Settings.SettingGroup {
8787
val YmethodInfer = BooleanSetting("-Yinfer-argument-types", "Infer types for arguments of overriden methods.")
8888
val YtraceContextCreation = BooleanSetting("-Ytrace-context-creation", "Store stack trace of context creations.")
8989
val YshowSuppressedErrors = BooleanSetting("-Yshow-suppressed-errors", "Also show follow-on errors and warnings that are normally supressed.")
90-
val Yheartbeat = BooleanSetting("-Yheartbeat", "show heartbeat stack trace of compiler operations.")
90+
val YdetailedStats = BooleanSetting("-Ydetailed-stats", "show detailed internal compiler stats (needs Stats.enabled to be set to true).")
91+
val Yheartbeat = BooleanSetting("-Ydetailed-stats", "show heartbeat stack trace of compiler operations (needs Stats.enabled to be set to true).")
9192
val Yprintpos = BooleanSetting("-Yprintpos", "show tree positions.")
9293
val YnoDeepSubtypes = BooleanSetting("-Yno-deep-subtypes", "throw an exception on deep subtyping call stacks.")
9394
val YnoPatmatOpt = BooleanSetting("-Yno-patmat-opt", "disable all pattern matching optimizations.")

compiler/src/dotty/tools/dotc/core/SymDenotations.scala

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1638,7 +1638,10 @@ object SymDenotations {
16381638
}
16391639

16401640
def computeBaseTypeOf(tp: Type): Type = {
1641-
Stats.record("computeBaseTypeOf")
1641+
if (Stats.monitored) {
1642+
Stats.record("computeBaseType, total")
1643+
Stats.record(s"computeBaseType, ${tp.getClass}")
1644+
}
16421645
if (symbol.isStatic && tp.derivesFrom(symbol) && symbol.typeParams.isEmpty)
16431646
symbol.appliedRef
16441647
else tp match {
@@ -1675,7 +1678,11 @@ object SymDenotations {
16751678
if (basetp == null) {
16761679
btrCache.put(tp, NoPrefix)
16771680
basetp = computeBaseTypeOf(tp)
1678-
if (isCachable(tp, baseTypeCache)) btrCache.put(tp, basetp)
1681+
if (!basetp.exists) Stats.record("base type miss")
1682+
if (isCachable(tp, baseTypeCache)) {
1683+
if (!basetp.exists) Stats.record("cached base type miss")
1684+
btrCache.put(tp, basetp)
1685+
}
16791686
else btrCache.remove(tp)
16801687
} else if (basetp == NoPrefix)
16811688
throw CyclicReference(this)

compiler/src/dotty/tools/dotc/util/Stats.scala

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,16 @@ import collection.mutable
4242
finally stack = stack.tail
4343
} else op
4444

45+
@inline
46+
def trackTime[T](fn: String)(op: => T) =
47+
if (enabled) doTrackTime(fn)(op) else op
48+
49+
def doTrackTime[T](fn: String)(op: => T) =
50+
if (monitored) {
51+
val start = System.nanoTime
52+
try op finally record(fn, ((System.nanoTime - start) / 1000).toInt)
53+
} else op
54+
4555
class HeartBeat extends Thread() {
4656
@volatile private[Stats] var continue = true
4757

@@ -61,10 +71,10 @@ import collection.mutable
6171
}
6272
}
6373

64-
def monitorHeartBeat[T](op: => T)(implicit ctx: Context) = {
65-
if (ctx.settings.Yheartbeat.value) {
66-
var hb = new HeartBeat()
67-
hb.start()
74+
def maybeMonitored[T](op: => T)(implicit ctx: Context) = {
75+
if (ctx.settings.YdetailedStats.value) {
76+
val hb = new HeartBeat()
77+
if (ctx.settings.Yheartbeat.value) hb.start()
6878
monitored = true
6979
try op
7080
finally {

0 commit comments

Comments
 (0)