Skip to content
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

Deadlock in NI build wrt. classloading: "Image generator watchdog detected no activity" #7850

Closed
JaroslavTulach opened this issue Sep 20, 2023 · 6 comments · Fixed by #7943
Closed
Assignees
Labels
-ci -compiler p-high Should be completed in the next sprint

Comments

@JaroslavTulach
Copy link
Member

There seem to be a deadlock in classloading of compiler passes caused by heavily parallel initialization of class constructors (e.g. <cinit>) during build of engine-runner/buildNativeImage.

Two builds showing the deadlock:

In both cases there are two threads initializing the compiler passes objects, each in different order:

"ForkJoinPool-2-worker-9" Id=76 in RUNNABLE
 at org.enso.compiler.pass.resolve.GlobalNames$.<clinit>(GlobalNames.scala:50)
 at org.enso.compiler.pass.analyse.TailCall$.<clinit>(TailCall.scala:58)
 at org.enso.compiler.pass.desugar.NestedPatternMatch$.<clinit>(NestedPatternMatch.scala:87)
 at org.enso.compiler.pass.optimise.ApplicationSaturation$.<clinit>(ApplicationSaturation.scala:37)
 at org.enso.compiler.pass.desugar.LambdaShorthandToLambda$.<clinit>(LambdaShorthandToLambda.scala:56)
 at org.enso.compiler.pass.resolve.IgnoredBindings$.<clinit>(IgnoredBindings.scala:47)
 at org.enso.compiler.pass.optimise.LambdaConsolidate$.<clinit>(LambdaConsolidate.scala:65)
 at org.enso.compiler.pass.analyse.DemandAnalysis$.<clinit>(DemandAnalysis.scala:46)
 at org.enso.compiler.pass.analyse.DataflowAnalysis$.<clinit>(DataflowAnalysis.scala:57)
 at org.enso.compiler.pass.desugar.SectionsToBinOp$.<clinit>(SectionsToBinOp.scala:36)
 at org.enso.compiler.pass.analyse.AliasAnalysis$.<clinit>(AliasAnalysis.scala:81)
 at org.enso.compiler.pass.desugar.FunctionBinding$.<clinit>(FunctionBinding.scala:46)
 at org.enso.compiler.pass.desugar.GenerateMethodBodies$.<clinit>(GenerateMethodBodies.scala:52)
 at org.enso.compiler.pass.resolve.DocumentationComments$.<clinit>(DocumentationComments.scala:42)
 at org.enso.compiler.pass.resolve.ModuleAnnotations$.<clinit>(ModuleAnnotations.scala:24)
 at org.enso.compiler.pass.desugar.ComplexType$.<clinit>(ComplexType.scala:56)
 at org.enso.compiler.pass.analyse.CachePreferenceAnalysis$.<clinit>(CachePreferenceAnalysis.scala:39)
 at [email protected]/jdk.internal.misc.Unsafe.ensureClassInitialized0(Native Method)
 at [email protected]/jdk.internal.misc.Unsafe.ensureClassInitialized(Unsafe.java:1155)
 at app/org.graalvm.nativeimage.builder/com.oracle.svm.hosted.classinitialization.ClassInitializationSupport.ensureClassInitialized(ClassInitializationSupport.java:168)

vs.

"ForkJoinPool-2-worker-12" Id=79 in RUNNABLE
at org.enso.compiler.pass.analyse.BindingAnalysis$.<clinit>(BindingAnalysis.scala:35)
at [email protected]/jdk.internal.misc.Unsafe.ensureClassInitialized0(Native Method)
at [email protected]/jdk.internal.misc.Unsafe.ensureClassInitialized(Unsafe.java:1155)
at app/org.graalvm.nativeimage.builder/com.oracle.svm.hosted.classinitialization.ClassInitializationSupport.ensureClassInitialized(ClassInitializationSupport.java:168)

These singletons that depend on other singletons seem to be dangerous. I am not sure how to convince scala to generate deadlock free code. @hubertp, please advice!

@hubertp
Copy link
Collaborator

hubertp commented Sep 20, 2023

We don't have circular dependencies between passes - there is even a check for that. But passes can depend on the same pass (in this case BindingAnalysis is the usual culprit).

@JaroslavTulach
Copy link
Member Author

JaroslavTulach commented Sep 20, 2023

What the BindingAnalysis<cinit> is blocked then? Another failed build:

@JaroslavTulach
Copy link
Member Author

JaroslavTulach commented Sep 20, 2023

What does your disassembler says? Mine is showing:

enso$ /graalvm/bin/javap -c -cp ./engine/runtime/target/scala-2.13/classes/ 'org.enso.compiler.pass.analyse.BindingAnalysis$'
public final class org.enso.compiler.pass.analyse.BindingAnalysis$ implements org.enso.compiler.pass.IRPass,scala.Product {
  public static final org.enso.compiler.pass.analyse.BindingAnalysis$ MODULE$;

  public static {};
    Code:
       0: new           #2                  // class org/enso/compiler/pass/analyse/BindingAnalysis$
       3: dup
       4: invokespecial #64                 // Method "<init>":()V
       7: putstatic     #66                 // Field MODULE$:Lorg/enso/compiler/pass/analyse/BindingAnalysis$;
      10: getstatic     #66                 // Field MODULE$:Lorg/enso/compiler/pass/analyse/BindingAnalysis$;
      13: invokestatic  #70                 // InterfaceMethod org/enso/compiler/pass/IRPass.$init$:(Lorg/enso/compiler/pass/IRPass;)V
      16: getstatic     #66                 // Field MODULE$:Lorg/enso/compiler/pass/analyse/BindingAnalysis$;
      19: invokestatic  #73                 // InterfaceMethod scala/Product.$init$:(Lscala/Product;)V
      22: new           #75                 // class scala/collection/immutable/$colon$colon
      25: dup
      26: getstatic     #80                 // Field org/enso/compiler/pass/desugar/ComplexType$.MODULE$:Lorg/enso/compiler/pass/desugar/ComplexType$;
      29: new           #75                 // class scala/collection/immutable/$colon$colon
      32: dup
      33: getstatic     #85                 // Field org/enso/compiler/pass/desugar/FunctionBinding$.MODULE$:Lorg/enso/compiler/pass/desugar/FunctionBinding$;
      36: new           #75                 // class scala/collection/immutable/$colon$colon
      39: dup
      40: getstatic     #90                 // Field org/enso/compiler/pass/desugar/GenerateMethodBodies$.MODULE$:Lorg/enso/compiler/pass/desugar/GenerateMethodBodies$;
      43: getstatic     #95                 // Field scala/collection/immutable/Nil$.MODULE$:Lscala/collection/immutable/Nil$;
      46: invokespecial #98                 // Method scala/collection/immutable/$colon$colon."<init>":(Ljava/lang/Object;Lscala/collection/immutable/List;)V
      49: invokespecial #98                 // Method scala/collection/immutable/$colon$colon."<init>":(Ljava/lang/Object;Lscala/collection/immutable/List;)V
      52: invokespecial #98                 // Method scala/collection/immutable/$colon$colon."<init>":(Ljava/lang/Object;Lscala/collection/immutable/List;)V
      55: putstatic     #100                // Field precursorPasses:Lscala/collection/immutable/Seq;
      58: getstatic     #102                // Field bitmap$init$0:B
      61: iconst_1
      62: ior
      63: i2b
      64: putstatic     #102                // Field bitmap$init$0:B
      67: new           #75                 // class scala/collection/immutable/$colon$colon
      70: dup
      71: getstatic     #107                // Field org/enso/compiler/pass/resolve/MethodDefinitions$.MODULE$:Lorg/enso/compiler/pass/resolve/MethodDefinitions$;
      74: new           #75                 // class scala/collection/immutable/$colon$colon
      77: dup
      78: getstatic     #112                // Field org/enso/compiler/pass/resolve/Patterns$.MODULE$:Lorg/enso/compiler/pass/resolve/Patterns$;
      81: getstatic     #95                 // Field scala/collection/immutable/Nil$.MODULE$:Lscala/collection/immutable/Nil$;
      84: invokespecial #98                 // Method scala/collection/immutable/$colon$colon."<init>":(Ljava/lang/Object;Lscala/collection/immutable/List;)V
      87: invokespecial #98                 // Method scala/collection/immutable/$colon$colon."<init>":(Ljava/lang/Object;Lscala/collection/immutable/List;)V
      90: putstatic     #114                // Field invalidatedPasses:Lscala/collection/immutable/Seq;
      93: getstatic     #102                // Field bitmap$init$0:B
      96: iconst_2
      97: ior
      98: i2b
      99: putstatic     #102                // Field bitmap$init$0:B
     102: return

while this method is being executed, it has a lock on the class initializer - other class can access any field of BindingsAnalysis$. However, it is clear that the pass is accessing static fields of other classes (which are also behind a class loading lock). Clearly there is an access to GenerateMethodBodies$.MODULE$ - a class which participated in a deadlock just recently.

@JaroslavTulach
Copy link
Member Author

We don't have circular dependencies between passes

In class org.enso.compiler.pass.desugar.GenerateMethodBodies$ there is

    33: getstatic     #117                // Field org/enso/compiler/pass/desugar/FunctionBinding$.MODULE$:Lorg/enso/compiler/pass/desugar/FunctionBinding$;

and in class class org.enso.compiler.pass.desugar.FunctionBinding$ there is

      81: getstatic     #208                // Field org/enso/compiler/pass/desugar/GenerateMethodBodies$.MODULE$:Lorg/enso/compiler/pass/desugar/GenerateMethodBodies$;

There is a cyclic dependency (of the <cinit> initializers) and it is causing the native image build to get stuck!

@JaroslavTulach
Copy link
Member Author

JaroslavTulach commented Sep 28, 2023

Another failure: https://github.com/enso-org/enso/actions/runs/6335322564/job/17206297931?pr=7909#step:10:1293

GitHub
Hybrid visual and textual functional programming. Contribute to enso-org/enso development by creating an account on GitHub.

@Akirathan
Copy link
Member

Akirathan commented Oct 2, 2023

Three more failures:

GitHub
Hybrid visual and textual functional programming. Contribute to enso-org/enso development by creating an account on GitHub.
GitHub
Hybrid visual and textual functional programming. Contribute to enso-org/enso development by creating an account on GitHub.

@JaroslavTulach JaroslavTulach moved this from 📤 Backlog to 👁️ Code review in Issues Board Oct 2, 2023
@mergify mergify bot closed this as completed in #7943 Oct 2, 2023
mergify bot pushed a commit that referenced this issue Oct 2, 2023
@github-project-automation github-project-automation bot moved this from 👁️ Code review to 🟢 Accepted in Issues Board Oct 2, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
-ci -compiler p-high Should be completed in the next sprint
Projects
Archived in project
Development

Successfully merging a pull request may close this issue.

3 participants