-
Notifications
You must be signed in to change notification settings - Fork 395
Deadlock in concurrent initialization of ir.Names
and ir.Types
.
#5135
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Comments
I've had a look at this, and it seems like the abstraction culprit is Because we group You will also note (unless I made a mistake thinking about this), that doing so will make all the "it is OK to use well known names" comments go away in #5136. |
I considered that, but it would be inconvenient. We often want to import "all" well-known names with a wildcard import. Or even just all well-known import ClassName.{apply => _, _} everywhere. I don't think that's great, though. |
Ah, yes. That's a bit annoying, indeed. What about I just feel that putting everything in WellKnownNames only masks the problem. I'm also wondering if the choice of putting all names inside |
Hum, on the contrary. If there is still a problem somewhere, the fact that they're all in a single If we have |
Ouch... I have not thought about it this way. But yes indeed, being able to detect the problem in the future clearly trumps "nice" organization. I have to admit, I feel this is quite sad in a language focusing so much on static analysis like Scala :-/ I'll review #5136 in detail then. |
Fix #5135: Move well-known names to a new object WellKnownNames.
Our mutual initialization of
ir.Names
andir.Types
can cause a deadlock if both start concurrently from two different threads. Here is the relevant portion of a thread dump:I had occasionally noticed
ir2_12/test
to be stuck, but I had always attributed that to an sbt glitch. Fortunately (in a sense), adding new tests forNames
in #5003 turned the likelihood of this happening from "very rare" to "very often". That let me diagnose the issue properly.The problem is that we have an inter-dependency between the constructor of
object Names
and that ofobject Types
.For "
Names
depends onTypes
": in the constructor ofobject Names
we havescala-js/ir/shared/src/main/scala/org/scalajs/ir/Names.scala
Lines 653 to 666 in cf05126
which requires the
Types.XRef
s of primitive types. Those areval
s inobject Types
, so we need to initializeobject Types
(this wouldn't happen if they wereobject
s, but they areval
s because they are instances of acase class
).For "
Types
depends onNames
": in the constructor ofobject Types
we havescala-js/ir/shared/src/main/scala/org/scalajs/ir/Types.scala
Lines 383 to 397 in cf05126
which similarly accesses
val
s defined inobject Names
.This is not an issue in sequential initialization, because the interdependencies only require
val
s defined before the cycle starts anew. So whether we start fromNames
or fromTypes
, we get all the things initialized in the right order. But in a concurrent scenario, the global initialization locks on JVM class initializers (rightly) create a deadlock.We need to break this cycle somehow. My best idea so far is to move all those
val
s to a thirdobject WellKnownNames
, that neitherTypes
norNames
is allowed to depend on.The text was updated successfully, but these errors were encountered: