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

assert(proj != __null) at compile.cpp:3251

    Details

    • Type: Bug
    • Status: Resolved
    • Priority: P3
    • Resolution: Fixed
    • Affects Version/s: 7u201, 8u192, 9, 10, 11, 12
    • Fix Version/s: 12
    • Component/s: hotspot
    • Labels:
    • Subcomponent:
    • Resolved In Build:
      b27

      Backports

        Description

        # Internal Error (/home/roland/hs/src/hotspot/share/opto/compile.cpp:3251), pid=14408, tid=14421
        # assert(proj != __null) failed: must be found


        The crash occurs in final_graph_reshape in the following code:

          case Op_Proj: {
            if (OptimizeStringConcat) {
              ProjNode* p = n->as_Proj();
              if (p->_is_io_use) {
                // Separate projections were used for the exception path which
                // are normally removed by a late inline. If it wasn't inlined
                // then they will hang around and should just be replaced with
                // the original one.
                Node* proj = NULL;
                // Replace with just one
                for (SimpleDUIterator i(p->in(0)); i.has_next(); i.next()) {
                  Node *use = i.get();
                  if (use->is_Proj() && p != use && use->as_Proj()->_con == p->_con) {
                    proj = use;
                    break;
                  }
                }
                assert(proj != NULL, "must be found");
                p->subsume_by(proj, this);
              }
            }
            break;
          }

        because a call only has control/memory/io uses for the exception path
        but none for the fall through path. This happens because after the call,
        the fallthrough path leads to an infinite loop and that infinite loop
        and the path that leads to it is removed. The infinite loop is removed
        because there are 2 passes of PhaseRemoveUseless that are executed. One
        as part of Compile::inline_string_calls(), and another one right after,
        both at the end of parsing:

            if (_late_inlines.length() == 0 && !has_mh_late_inlines() && !failing() && has_stringbuilder()) {
              inline_string_calls(true);
            }

            if (failing()) return;

            print_method(PHASE_BEFORE_REMOVEUSELESS, 3);

            // Remove clutter produced by parsing.
            if (!failing()) {
              ResourceMark rm;
              PhaseRemoveUseless pru(initial_gvn(), &for_igvn);
            }

        During parsing, safepoint nodes in infinite loops are kept live with an
        extra precedence edge from the Root node to the safepoint. That edge is
        removed as part of PhaseRemoveUseless. So the first pass of
        PhaseRemoveUseless disconnects the safepoint node in the infinite loop,
        the second finds the safepoint node has no uses and removes it.

          Attachments

            Issue Links

              Activity

                People

                • Assignee:
                  roland Roland Westrelin
                  Reporter:
                  roland Roland Westrelin
                • Votes:
                  0 Vote for this issue
                  Watchers:
                  3 Start watching this issue

                  Dates

                  • Created:
                    Updated:
                    Resolved: