Closed EnzeXing closed 3 months ago
Note that the deadlock happens only when using the publishLocal
version, not the released version.
The following does not deadlock:
scala-cli -S 2.13.14 deadlock.scala --main-class Test
The following does deadlock:
git checkout v2.13.14
sbt publishLocal
scala-cli -S 2.13.14-bin-SNAPSHOT deadlock.scala --main-class Test
Both are 2.13.14, but one is the released library and the other is publishLocal
.
We think this is because the build process for the released version does more inlining than the publishLocal
version.
In particular, the call to augmentString
appears in the bytecode of the publishLocal
version but does not appear in the bytecode of the released version; it has been inlined.
I fixed the PR comment to reference this ticket. Comments there note that it is a difference with inlining (qua optimization).
Edit: setupPublishCore
enables optimization before publishLocal
, for local testing.
Edit again: maybe the previous comment was using "royal we" to express the linked PR comments.
Description
The source code of the standard library includes object initialization cycles, including a cycle between
Predef
andcollection.immutable.Vector
, which could lead to deadlock when two threads initialize them simultaneously.Test
deadlock.scala
``` object Test extends App { val createPredef = new Runnable { def run = { val _ = Predef; } } val createVector = new Runnable { def run = { val _ = scala.collection.immutable.Vector; } } val t1 = new Thread(createPredef) val t2 = new Thread(createVector) t1.start() t2.start() t1.join() t2.join() } ```Reproduction steps
Scala version: (2.13.15)
Problem
The test deadlocks due to cyclic initialization between
Predef
andcollection.immutable.Vector
. Specifically,Predef
triggers initialization ofVector
throughand the constructor of Vector contains another call to
Predef.augmentString
, as shown in Vector.tastyThe warning is given by the global initialization checker that is under development to fix initialization warning in standard tasty library (https://github.com/scala/scala3/issues/18882), and this issue is linked to a PR with a fix to manually inline the call to
Predef.augmentString
(https://github.com/scala/scala/pull/10793). Our current conclusion is that such calls must be inlined to ensure soundness, which may happen in released build.To reproduce the warning using the global initialization checker, apply the following patch to Dotty main branch:
and in sbt:
The checker will report the following warning: