Skip to content

Commit f088428

Browse files
committed
Avoid concurrency issue
1 parent a5d2281 commit f088428

File tree

1 file changed

+23
-24
lines changed

1 file changed

+23
-24
lines changed

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

Lines changed: 23 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -236,8 +236,6 @@ object Semantic:
236236
case tree: Tree => tree
237237
case null => ???
238238

239-
private val queryTreeMapper: MutableTreeWrapper = new MutableTreeWrapper
240-
241239
class Cache:
242240
/** The cache for expression values from last iteration */
243241
private var last: ExprValueCache = Map.empty
@@ -288,14 +286,15 @@ object Semantic:
288286
/** Used to revert heap to last stable heap. */
289287
private var heapStable: Heap = Map.empty
290288

291-
def hasChanged = changed
289+
/** Used to avoid allocation, its state does not matter */
290+
private given MutableTreeWrapper = new MutableTreeWrapper
292291

293-
def contains(value: Value, expr: Tree) =
294-
current.contains(value, expr) || stable.contains(value, expr)
292+
def hasChanged = changed
295293

296-
def apply(value: Value, expr: Tree) =
297-
if current.contains(value, expr) then current.get(value, expr)
298-
else stable.get(value, expr)
294+
def get(value: Value, expr: Tree): Option[Value] =
295+
current.get(value, expr) match
296+
case None => stable.get(value, expr)
297+
case res => res
299298

300299
/** Conditionally perform an operation
301300
*
@@ -330,12 +329,12 @@ object Semantic:
330329
*/
331330
def assume(value: Value, expr: Tree, cacheResult: Boolean)(fun: => Value): Contextual[Value] =
332331
val assumeValue: Value =
333-
if last.contains(value, expr) then
334-
last.get(value, expr)
335-
else
332+
last.get(value, expr) match
333+
case Some(value) => value
334+
case None =>
336335
this.last = last.updatedNested(value, expr, Hot)
337336
Hot
338-
end if
337+
339338
this.current = current.updatedNested(value, expr, assumeValue)
340339

341340
val actual = fun
@@ -408,17 +407,13 @@ object Semantic:
408407
end Cache
409408

410409
extension (cache: ExprValueCache)
411-
private def contains(value: Value, expr: Tree) =
412-
queryTreeMapper.queryTree = expr
413-
cache.contains(value) && cache(value).contains(queryTreeMapper)
410+
private def get(value: Value, expr: Tree)(using queryWrapper: MutableTreeWrapper): Option[Value] =
411+
queryWrapper.queryTree = expr
412+
cache.get(value).flatMap(_.get(queryWrapper))
414413

415-
private def get(value: Value, expr: Tree): Value =
416-
queryTreeMapper.queryTree = expr
417-
cache(value)(queryTreeMapper)
418-
419-
private def removed(value: Value, expr: Tree) =
420-
queryTreeMapper.queryTree = expr
421-
val innerMap2 = cache(value).removed(queryTreeMapper)
414+
private def removed(value: Value, expr: Tree)(using queryWrapper: MutableTreeWrapper) =
415+
queryWrapper.queryTree = expr
416+
val innerMap2 = cache(value).removed(queryWrapper)
422417
cache.updated(value, innerMap2)
423418

424419
private def updatedNested(value: Value, expr: Tree, result: Value): ExprValueCache =
@@ -1167,10 +1162,14 @@ object Semantic:
11671162
* it is located.
11681163
*
11691164
* This method only handles cache logic and delegates the work to `cases`.
1165+
*
1166+
* The parameter `cacheResult` is used to reduce the size of the cache.
11701167
*/
11711168
def eval(expr: Tree, thisV: Ref, klass: ClassSymbol, cacheResult: Boolean = false): Contextual[Value] = log("evaluating " + expr.show + ", this = " + thisV.show + " in " + klass.show, printer, (_: Value).show) {
1172-
if (cache.contains(thisV, expr)) cache(thisV, expr)
1173-
else cache.assume(thisV, expr, cacheResult) { cases(expr, thisV, klass) }
1169+
cache.get(thisV, expr) match
1170+
case Some(value) => value
1171+
case None =>
1172+
cache.assume(thisV, expr, cacheResult) { cases(expr, thisV, klass) }
11741173
}
11751174

11761175
/** Evaluate a list of expressions */

0 commit comments

Comments
 (0)