Skip to content

Commit 3b99733

Browse files
authored
Respect cacheResult flag in safe initialization cache. (#16905)
The safe initialization checker only needs to cache entries on certain `cachedEval` calls, specified by a `cacheResult` flag. This PR reduces the size of the safe initialization cache during compilation with `-Ysafe-init` by respecting the value of the flag, and only caching when it is true.
2 parents 585bbef + 7a7f144 commit 3b99733

File tree

4 files changed

+41
-27
lines changed

4 files changed

+41
-27
lines changed

compiler/src/dotty/tools/dotc/transform/init/Cache.scala

Lines changed: 28 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -93,41 +93,46 @@ class Cache[Config, Res]:
9393
*
9494
* The algorithmic skeleton is as follows:
9595
*
96+
* if don't cache result then
97+
* return eval(expr)
9698
* if this.current.contains(config, expr) then
9799
* return cached value
98100
* else
99101
* val assumed = this.last(config, expr) or bottom value if absent
100102
* this.current(config, expr) = assumed
101-
* val actual = eval(exp)
103+
* val actual = eval(expr)
102104
*
103105
* if assumed != actual then
104106
* this.changed = true
105107
* this.current(config, expr) = actual
106108
*
107109
*/
108110
def cachedEval(config: Config, expr: Tree, cacheResult: Boolean, default: Res)(eval: Tree => Res): Res =
109-
this.get(config, expr) match
110-
case Some(value) => value
111-
case None =>
112-
val assumeValue: Res =
113-
this.last.get(config, expr) match
114-
case Some(value) => value
115-
case None =>
116-
this.last = this.last.updatedNested(config, expr, default)
117-
default
118-
119-
this.current = this.current.updatedNested(config, expr, assumeValue)
120-
121-
val actual = eval(expr)
122-
if actual != assumeValue then
123-
// println("Changed! from = " + assumeValue + ", to = " + actual)
124-
this.changed = true
125-
// TODO: respect cacheResult to reduce cache size
126-
this.current = this.current.updatedNested(config, expr, actual)
127-
// this.current = this.current.removed(config, expr)
128-
end if
129-
130-
actual
111+
if !cacheResult then
112+
eval(expr)
113+
else
114+
this.get(config, expr) match
115+
case Some(value) => value
116+
case None =>
117+
val assumeValue: Res =
118+
this.last.get(config, expr) match
119+
case Some(value) => value
120+
case None =>
121+
this.last = this.last.updatedNested(config, expr, default)
122+
default
123+
124+
this.current = this.current.updatedNested(config, expr, assumeValue)
125+
126+
val actual = eval(expr)
127+
if actual != assumeValue then
128+
// println("Changed! from = " + assumeValue + ", to = " + actual)
129+
this.changed = true
130+
this.current = this.current.updatedNested(config, expr, actual)
131+
// this.current = this.current.removed(config, expr)
132+
end if
133+
134+
actual
135+
end if
131136
end cachedEval
132137

133138
def hasChanged = changed

compiler/src/dotty/tools/dotc/transform/init/Semantic.scala

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -893,7 +893,7 @@ object Semantic:
893893

894894
case Cold => Cold
895895

896-
case ref: Ref => eval(vdef.rhs, ref, enclosingClass)
896+
case ref: Ref => eval(vdef.rhs, ref, enclosingClass, cacheResult = sym.is(Flags.Lazy))
897897

898898
case _ =>
899899
report.error("[Internal error] unexpected this value when accessing local variable, sym = " + sym.show + ", thisValue = " + thisValue2.show + Trace.show, Trace.position)
@@ -989,7 +989,7 @@ object Semantic:
989989
val errors = Reporter.stopEarly {
990990
val res = {
991991
given Trace = Trace.empty
992-
eval(body, thisV, klass)
992+
eval(body, thisV, klass, cacheResult = true)
993993
}
994994
given Trace = Trace.empty.add(body)
995995
res.promote("The function return value is not hot. Found = " + res.show + ".")

tests/init/neg/apply2.scala

100644100755
Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,8 @@ object O:
33
println(n)
44

55
class B:
6-
val a = A(this)
6+
val a = A(this) // error
77

88
val b = new B
9-
val n = 10 // error
9+
val n = 10
1010
end O

tests/init/pos/self-ref.scala

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
class A {
2+
def foo(a: Int) = {
3+
lazy val x: Int = if (a == 0) x else 0
4+
println(x)
5+
}
6+
foo(0)
7+
8+
val y = 5
9+
}

0 commit comments

Comments
 (0)