Uploaded image for project: 'JDK'
  1. JDK
  2. JDK-8340602

C2: LoadNode::split_through_phi might exhaust nodes in case of base_is_phi

XMLWordPrintable

    • generic
    • generic

      # Description

      [JDK-6934604](https://github.com/openjdk/jdk/commit/b4977e887a53c898b96a7d37a3bf94742c7cc194) introduces the flag `AggressiveUnboxing` in jdk8u, and [JDK-8217919](https://github.com/openjdk/jdk/commit/71759e3177fcd6926bb36a30a26f9f3976f2aae8) enables it by default in jdk13u.

      But it seems that JDK-6934604 forgets to check duplicate `PhiNode` generated in the function `LoadNode::split_through_phi(PhaseGVN *phase)` (in memnode.cpp) in the case that `base` is phi but `mem` is not phi.
      More exactly, `LoadNode::Identity(PhaseTransform *phase)` doesn't search for `PhiNode` in the correct region in that case.

      This causes infinite split which is similar to the bugs fixed in [JDK-6673473](https://github.com/openjdk/jdk/commit/30dc0edfc877000c0ae20384f228b45ba82807b7).
      The infinite split results in "Out of nodes" and make the method "not compilable".

      Since JDK-8217919 (in jdk13u), all the following versions of jdks are affected by this bug when the expected optimization pattern appears in the code.
      For example, the following three jmh benchmarks in https://github.com/openjdk/jmh-jdk-microbenchmarks shows regressions in jdk17 compared to jdk8.

      |benchmark (throughput, unit: ops/s)|java8|java17|
      |---|---|---|
      |org.openjdk.bench.java.util.stream.tasks.IntegerMax.Bulk.bulk_seq_inner | 76.097 | 44.468 |
      |org.openjdk.bench.java.util.stream.tasks.IntegerMax.Lambda.bulk_seq_lambda | 75.778 | 43.762 |
      |org.openjdk.bench.java.util.stream.tasks.IntegerMax.Lambda.bulk_seq_methodRef | 77.505 | 47.492 |

      # Reproduction

      Compiled and run the reduced test case `Test.java` attached using

      ```bash
      java -Xbatch -XX:+UnlockDiagnosticVMOptions -XX:+LogCompilation -XX:LogFile=comp.log -XX:+UseParallelGC Test
      ```

      and you could find that `Test$Obj.calc` is tagged with "make_not_compilable" and see some output like

      ```xml
      <failure reason='Out of nodes' phase='compile'/>"
      ```

      I also attached the hs_err file generated when "-XX:+AbortVMOnCompilationFailure" is added.

      # Tentative fix

      You could set `AggressiveUnboxing` to `false` to disable this optimiztion thus bypassing this bug, but I'm not sure if it will cause other regressions since it has been set to `true` for several years.

      I have a patch attached (fix-infinite-split_through_phi.patch) trying to fix this with minimal side effect.

        1. Test.java
          0.9 kB
          Daohan Qu
        2. fix-infinite-split_through_phi.patch
          8 kB
          Daohan Qu

            dqu Daohan Qu
            dqu Daohan Qu
            Votes:
            0 Vote for this issue
            Watchers:
            3 Start watching this issue

              Created:
              Updated: