Skip to content

Commit 089bad7

Browse files
authored
Merge pull request scala#9596 from dwijnand/review-and-look-to-speed-up-statistics
2 parents 812453c + 518e6e0 commit 089bad7

File tree

9 files changed

+30
-56
lines changed

9 files changed

+30
-56
lines changed

src/compiler/scala/tools/nsc/Global.scala

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1281,11 +1281,8 @@ class Global(var currentSettings: Settings, reporter0: Reporter)
12811281
checkPhaseSettings(including = true, inclusions.toSeq: _*)
12821282
checkPhaseSettings(including = false, exclusions map (_.value): _*)
12831283

1284-
// Enable or disable depending on the current setting -- useful for interactive behaviour
1285-
statistics.initFromSettings(settings)
1286-
12871284
// Report the overhead of statistics measurements per every run
1288-
if (statistics.areStatisticsLocallyEnabled)
1285+
if (settings.areStatisticsEnabled)
12891286
statistics.reportStatisticsOverhead(reporter)
12901287

12911288
phase = first //parserPhase
@@ -1510,7 +1507,7 @@ class Global(var currentSettings: Settings, reporter0: Reporter)
15101507
warnDeprecatedAndConflictingSettings()
15111508
globalPhase = fromPhase
15121509

1513-
val timePhases = statistics.areStatisticsLocallyEnabled
1510+
val timePhases = settings.areStatisticsEnabled
15141511
val startTotal = if (timePhases) statistics.startTimer(totalCompileTime) else null
15151512

15161513
while (globalPhase.hasNext && !reporter.hasErrors) {

src/compiler/scala/tools/nsc/MainBench.scala

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -29,9 +29,8 @@ object MainBench extends Driver with EvalLoop {
2929
var start = System.nanoTime()
3030
for (i <- 0 until NIter) {
3131
if (i == NIter-1) {
32-
theCompiler.settings.Ystatistics.value = List("all")
33-
theCompiler.statistics.enabled = true
34-
theCompiler.statistics.hotEnabled = true
32+
theCompiler.settings.Ystatistics.value = List("all")
33+
theCompiler.settings.YhotStatisticsEnabled.value = true
3534
}
3635
process(args)
3736
val end = System.nanoTime()

src/compiler/scala/tools/nsc/backend/jvm/ClassfileWriters.scala

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,7 @@ abstract class ClassfileWriters {
6363

6464
def apply(global: Global): ClassfileWriter = {
6565
//Note dont import global._ - its too easy to leak non threadsafe structures
66-
import global.{cleanup, log, settings, statistics}
66+
import global.{ cleanup, log, settings }
6767
def jarManifestMainClass: Option[String] = settings.mainClass.valueSetByUser.orElse {
6868
cleanup.getEntryPoints match {
6969
case List(name) => Some(name)
@@ -91,7 +91,7 @@ abstract class ClassfileWriters {
9191
new DebugClassWriter(basicClassWriter, asmp, dump)
9292
}
9393

94-
val enableStats = statistics.enabled && settings.YaddBackendThreads.value == 1
94+
val enableStats = settings.areStatisticsEnabled && settings.YaddBackendThreads.value == 1
9595
if (enableStats) new WithStatsWriter(withAdditionalFormats) else withAdditionalFormats
9696
}
9797

src/compiler/scala/tools/nsc/backend/jvm/GeneratedClassHandler.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,7 @@ private[jvm] object GeneratedClassHandler {
5959
new SyncWritingClassHandler(postProcessor)
6060

6161
case maxThreads =>
62-
if (statistics.enabled)
62+
if (settings.areStatisticsEnabled)
6363
runReporting.warning(NoPosition, "jvm statistics are not reliable with multi-threaded jvm class writing", WarningCategory.Other, site = "")
6464
val additionalThreads = maxThreads - 1
6565
// The thread pool queue is limited in size. When it's full, the `CallerRunsPolicy` causes

src/compiler/scala/tools/nsc/settings/ScalaSettings.scala

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ import scala.language.existentials
2323
import scala.annotation.elidable
2424
import scala.tools.util.PathResolver.Defaults
2525
import scala.collection.mutable
26-
import scala.reflect.internal.util.StringContextStripMarginOps
26+
import scala.reflect.internal.util.{ StatisticsStatics, StringContextStripMarginOps }
2727
import scala.tools.nsc.util.DefaultJarFactory
2828
import scala.util.chaining._
2929

@@ -496,9 +496,9 @@ trait ScalaSettings extends StandardScalaSettings with Warnings { _: MutableSett
496496
val Ystatistics = PhasesSetting("-Vstatistics", "Print compiler statistics for specific phases", "parser,typer,patmat,erasure,cleanup,jvm")
497497
.withPostSetHook(s => YstatisticsEnabled.value = s.value.nonEmpty)
498498
.withAbbreviation("-Ystatistics")
499-
val YstatisticsEnabled = BooleanSetting("-Ystatistics-enabled", "Internal setting, indicating that statistics are enabled for some phase.").internalOnly()
499+
val YstatisticsEnabled = BooleanSetting("-Ystatistics-enabled", "Internal setting, indicating that statistics are enabled for some phase.").internalOnly().withPostSetHook(s => if (s) StatisticsStatics.enableColdStatsAndDeoptimize())
500500
val YhotStatisticsEnabled = BooleanSetting("-Vhot-statistics", s"Enable `${Ystatistics.name}` to also print hot statistics.")
501-
.withAbbreviation("-Yhot-statistics")
501+
.withAbbreviation("-Yhot-statistics").withPostSetHook(s => if (s && YstatisticsEnabled) StatisticsStatics.enableHotStatsAndDeoptimize())
502502
val Yshowsyms = BooleanSetting("-Vsymbols", "Print the AST symbol hierarchy after each phase.") withAbbreviation "-Yshow-syms"
503503
val Ytyperdebug = BooleanSetting("-Vtyper", "Trace type assignments.") withAbbreviation "-Ytyper-debug"
504504
val Vimplicits = BooleanSetting("-Vimplicits", "Print dependent missing implicits.").withAbbreviation("-Xlog-implicits")

src/compiler/scala/tools/nsc/typechecker/Typers.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6003,7 +6003,7 @@ trait Typers extends Adaptations with Tags with TypersTracking with PatternTyper
60036003

60046004
def typed(tree: Tree, mode: Mode, pt: Type): Tree = {
60056005
lastTreeToTyper = tree
6006-
val statsEnabled = StatisticsStatics.areSomeHotStatsEnabled() && statistics.areHotStatsLocallyEnabled
6006+
val statsEnabled = StatisticsStatics.areSomeHotStatsEnabled && settings.areStatisticsEnabled && settings.YhotStatisticsEnabled
60076007
val startByType = if (statsEnabled) statistics.pushTimer(byTypeStack, byTypeNanos(tree.getClass)) else null
60086008
if (statsEnabled) statistics.incCounter(visitsByType, tree.getClass)
60096009
val shouldPrintTyping = printTypings && !phase.erasedTypes && !noPrintTyping(tree)

src/reflect/scala/reflect/internal/settings/MutableSettings.scala

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,8 @@ package scala
1616
package reflect.internal
1717
package settings
1818

19+
import scala.reflect.internal.util.StatisticsStatics
20+
1921
/** A mutable Settings object.
2022
*/
2123
abstract class MutableSettings extends AbsSettings {
@@ -69,4 +71,8 @@ object MutableSettings {
6971
import scala.language.implicitConversions
7072
/** Support the common use case, `if (settings.debug) println("Hello, martin.")` */
7173
@inline implicit def reflectSettingToBoolean(s: MutableSettings#BooleanSetting): Boolean = s.value
74+
75+
implicit class SettingsOps(private val settings: MutableSettings) extends AnyVal {
76+
@inline final def areStatisticsEnabled = StatisticsStatics.areSomeColdStatsEnabled && settings.YstatisticsEnabled
77+
}
7278
}

src/reflect/scala/reflect/internal/util/Statistics.scala

Lines changed: 10 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -22,57 +22,49 @@ import scala.annotation.nowarn
2222
import scala.runtime.LongRef
2323

2424
abstract class Statistics(val symbolTable: SymbolTable, settings: MutableSettings) {
25-
26-
initFromSettings(settings)
27-
28-
def initFromSettings(currentSettings: MutableSettings): Unit = {
29-
enabled = currentSettings.YstatisticsEnabled
30-
hotEnabled = currentSettings.YhotStatisticsEnabled
31-
}
32-
3325
type TimerSnapshot = (Long, Long)
3426

3527
/** If enabled, increment counter by one */
3628
@inline final def incCounter(c: Counter): Unit = {
37-
if (areStatisticsLocallyEnabled && c != null) c.value += 1
29+
if (enabled && c != null) c.value += 1
3830
}
3931

4032
/** If enabled, increment counter by given delta */
4133
@inline final def incCounter(c: Counter, delta: Int): Unit = {
42-
if (areStatisticsLocallyEnabled && c != null) c.value += delta
34+
if (enabled && c != null) c.value += delta
4335
}
4436

4537
/** If enabled, increment counter in map `ctrs` at index `key` by one */
4638
@inline final def incCounter[K](ctrs: QuantMap[K, Counter], key: K) =
47-
if (areStatisticsLocallyEnabled && ctrs != null) ctrs(key).value += 1
39+
if (enabled && ctrs != null) ctrs(key).value += 1
4840

4941
/** If enabled, start subcounter. While active it will track all increments of
5042
* its base counter.
5143
*/
5244
@inline final def startCounter(sc: SubCounter): (Int, Int) =
53-
if (areStatisticsLocallyEnabled && sc != null) sc.start() else null
45+
if (enabled && sc != null) sc.start() else null
5446

5547
/** If enabled, stop subcounter from tracking its base counter. */
5648
@inline final def stopCounter(sc: SubCounter, start: (Int, Int)): Unit = {
57-
if (areStatisticsLocallyEnabled && sc != null) sc.stop(start)
49+
if (enabled && sc != null) sc.stop(start)
5850
}
5951

6052
/** If enabled, start timer */
6153
@inline final def startTimer(tm: Timer): TimerSnapshot =
62-
if (areStatisticsLocallyEnabled && tm != null) tm.start() else null
54+
if (enabled && tm != null) tm.start() else null
6355

6456
/** If enabled, stop timer */
6557
@inline final def stopTimer(tm: Timer, start: TimerSnapshot): Unit = {
66-
if (areStatisticsLocallyEnabled && tm != null) tm.stop(start)
58+
if (enabled && tm != null) tm.stop(start)
6759
}
6860

6961
/** If enabled, push and start a new timer in timer stack */
7062
@inline final def pushTimer(timers: TimerStack, timer: => StackableTimer): TimerSnapshot =
71-
if (areStatisticsLocallyEnabled && timers != null) timers.push(timer) else null
63+
if (enabled && timers != null) timers.push(timer) else null
7264

7365
/** If enabled, stop and pop timer from timer stack */
7466
@inline final def popTimer(timers: TimerStack, prev: TimerSnapshot): Unit = {
75-
if (areStatisticsLocallyEnabled && timers != null) timers.pop(prev)
67+
if (enabled && timers != null) timers.pop(prev)
7668
}
7769

7870
/** Create a new counter that shows as `prefix` and is active in given phases */
@@ -294,29 +286,8 @@ quant)
294286
}
295287

296288
private[this] val qs = new mutable.HashMap[String, Quantity]
297-
private[scala] var areColdStatsLocallyEnabled: Boolean = false
298-
private[scala] var areHotStatsLocallyEnabled: Boolean = false
299-
300-
/** Represents whether normal statistics can or cannot be enabled. */
301-
@inline final def enabled: Boolean = areColdStatsLocallyEnabled
302-
def enabled_=(cond: Boolean) = {
303-
if (cond && !enabled) {
304-
StatisticsStatics.enableColdStatsAndDeoptimize()
305-
areColdStatsLocallyEnabled = true
306-
}
307-
}
308-
309-
/** Represents whether hot statistics can or cannot be enabled. */
310-
@inline final def hotEnabled: Boolean = enabled && areHotStatsLocallyEnabled
311-
def hotEnabled_=(cond: Boolean) = {
312-
if (cond && enabled && !areHotStatsLocallyEnabled) {
313-
StatisticsStatics.enableHotStatsAndDeoptimize()
314-
areHotStatsLocallyEnabled = true
315-
}
316-
}
317289

318-
/** Tells whether statistics should be definitely reported to the user for this `Global` instance. */
319-
@inline final def areStatisticsLocallyEnabled: Boolean = areColdStatsLocallyEnabled
290+
@inline final def enabled: Boolean = settings.areStatisticsEnabled
320291

321292
import scala.reflect.internal.Reporter
322293
/** Reports the overhead of measuring statistics via the nanoseconds variation. */

src/reflect/scala/reflect/runtime/Settings.scala

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ package reflect
1515
package runtime
1616

1717
import scala.reflect.internal.settings.MutableSettings
18+
import scala.reflect.internal.util.StatisticsStatics
1819

1920
/** The Settings class for runtime reflection.
2021
* This should be refined, so that settings are settable via command
@@ -57,8 +58,8 @@ private[reflect] class Settings extends MutableSettings {
5758
val uniqid = new BooleanSetting(false)
5859
val verbose = new BooleanSetting(false)
5960

60-
val YhotStatisticsEnabled = new BooleanSetting(false)
61-
val YstatisticsEnabled = new BooleanSetting(false)
61+
val YhotStatisticsEnabled = new BooleanSetting(false) { override def postSetHook() = if (v && YstatisticsEnabled) StatisticsStatics.enableHotStatsAndDeoptimize() }
62+
val YstatisticsEnabled = new BooleanSetting(false) { override def postSetHook() = if (v) StatisticsStatics.enableColdStatsAndDeoptimize() }
6263

6364
val Yrecursion = new IntSetting(0)
6465
def isScala212 = true

0 commit comments

Comments
 (0)