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

C2: SubTypeCheckNode::verify() should not produce dependencies / oop pool entries

    XMLWordPrintable

Details

    • b09

    Description

      C2's SubTypeCheckNode::verify() produce dependencies which in turn produce entries in the oop pool which affect the unloading behaviour of the nmethod. This can hide issues of the release build which will not have the dependencies and oop pool entries.

      The attachment CallFinalVirtualFromOtherLoader.java is a reproducer. ClassA_LVL_1.testMethod_dojit() has a virtual call that can be statically bound because the target method is final. It is loaded by a subclassloader though. SubTypeCheckNode::verify() adds a dependency to the subclassloader 'CallFinalVirtualFromOtherLoader$DirectLeveledClassLoader$Level2' (see attachment output.log:1411). This is redundant as a dependency is added by ClassLoaderData::record_dependency().

      Without calling SubTypeCheckNode::verify() the dependency is not added (see output_UseNewCode.log:1406)
      The run was produced with the following patch:

      diff --git a/src/hotspot/share/opto/subtypenode.cpp b/src/hotspot/share/opto/subtypenode.cpp
      index 8ef50b73be9..04ccf6ae674 100644
      --- a/src/hotspot/share/opto/subtypenode.cpp
      +++ b/src/hotspot/share/opto/subtypenode.cpp
      @@ -110,7 +110,7 @@ Node *SubTypeCheckNode::Ideal(PhaseGVN* phase, bool can_reshape) {
       
         // Verify that optimizing the subtype check to a simple code pattern
         // when possible would not constant fold better
      - assert(verify(phase), "missing Value() optimization");
      + assert(UseNewCode || verify(phase), "missing Value() optimization");
       
         return NULL;
       }

      The redundant dependency is added here:

      #0 Dependencies::assert_leaf_type (this=0x7fe266d3fbe0 <Compile::dependencies()+36>, ctxk=0x7fe20baf7010) at .../jdk/src/hotspot/share/code/dependencies.cpp:84
      #1 0x00007fe267ba6799 in TypeInstPtr::as_klass_type (this=0x7fe1ec036978, try_for_exact=true) at .../jdk/src/hotspot/share/opto/type.cpp:4328
      #2 0x00007fe2677aad4d in LoadNode::klass_value_common (this=0x7fe1ec054d28, phase=0x7fe20baf8040) at .../jdk/src/hotspot/share/opto/memnode.cpp:2340
      #3 0x00007fe2677ab273 in LoadNKlassNode::Value (this=0x7fe1ec054d28, phase=0x7fe20baf8040) at .../jdk/src/hotspot/share/opto/memnode.cpp:2449
      #4 0x00007fe2678dc8cc in PhaseGVN::transform_no_reclaim (this=0x7fe20baf8040, n=0x7fe1ec054d28) at .../jdk/src/hotspot/share/opto/phaseX.cpp:862
      #5 0x00007fe2678dc77b in PhaseGVN::transform (this=0x7fe20baf8040, n=0x7fe1ec054d28) at .../jdk/src/hotspot/share/opto/phaseX.cpp:829
      #6 0x00007fe2677aa989 in LoadKlassNode::make (gvn=..., ctl=0x0, mem=0x7fe1ec0521e8, adr=0x7fe1ec054c88, at=0x7fe1ec023b28, tk=0x7fe1ec0269a8) at .../jdk/src/hotspot/share/opto/memnode.cpp:2276
      #7 0x00007fe267b0ac79 in SubTypeCheckNode::verify (this=0x7fe1ec054b80, phase=0x7fe20baf8040) at .../jdk/src/hotspot/share/opto/subtypenode.cpp:173
      #8 0x00007fe267b0a763 in SubTypeCheckNode::Ideal (this=0x7fe1ec054b80, phase=0x7fe20baf8040, can_reshape=false) at .../jdk/src/hotspot/share/opto/subtypenode.cpp:113
      #9 0x00007fe2678dc74a in PhaseGVN::apply_ideal (this=0x7fe20baf8040, k=0x7fe1ec054b80, can_reshape=false) at .../jdk/src/hotspot/share/opto/phaseX.cpp:820
      #10 0x00007fe2678dc7bf in PhaseGVN::transform_no_reclaim (this=0x7fe20baf8040, n=0x7fe1ec054b80) at .../jdk/src/hotspot/share/opto/phaseX.cpp:840
      #11 0x00007fe2678dc77b in PhaseGVN::transform (this=0x7fe20baf8040, n=0x7fe1ec054b80) at .../jdk/src/hotspot/share/opto/phaseX.cpp:829
      #12 0x00007fe2673354d0 in GraphKit::gen_subtype_check (this=0x7fe20baf75d0, obj_or_subklass=0x7fe1ec054a70, superklass=0x7fe1ec054b10) at .../jdk/src/hotspot/share/opto/graphKit.cpp:2834
      #13 0x00007fe2673359db in GraphKit::subtype_check_receiver (this=0x7fe20baf75d0, receiver=0x7fe1ec054a70, klass=0x7fe1ec02dec8, casted_receiver=0x7fe20baf7510) at .../jdk/src/hotspot/share/opto/graphKit.cpp:2879
      #14 0x00007fe266ef5a34 in PredictedCallGenerator::generate (this=0x7fe1ec056008, jvms=0x7fe1ec055d00) at .../jdk/src/hotspot/share/opto/callGenerator.cpp:885
      #15 0x00007fe267191119 in Parse::do_call (this=0x7fe20baf7b90) at .../jdk/src/hotspot/share/opto/doCall.cpp:662
      #16 0x00007fe2678c91c1 in Parse::do_one_bytecode (this=0x7fe20baf7b90) at .../jdk/src/hotspot/share/opto/parse2.cpp:2704
      #17 0x00007fe2678b8226 in Parse::do_one_block (this=0x7fe20baf7b90) at .../jdk/src/hotspot/share/opto/parse1.cpp:1555
      #18 0x00007fe2678b44c3 in Parse::do_all_blocks (this=0x7fe20baf7b90) at .../jdk/src/hotspot/share/opto/parse1.cpp:707
      #19 0x00007fe2678b400b in Parse::Parse (this=0x7fe20baf7b90, caller=0x7fe1ec055a70, parse_method=0x7fe1ec02c078, expected_uses=6784) at .../jdk/src/hotspot/share/opto/parse1.cpp:614

      This was noticed while working on JDK-8296440. The intention there was to assert during call resolution that the loader of a statically bound callee is reachable from the caller.

      Attachments

        Issue Links

          Activity

            People

              roland Roland Westrelin
              rrich Richard Reingruber
              Votes:
              0 Vote for this issue
              Watchers:
              6 Start watching this issue

              Dates

                Created:
                Updated:
                Resolved: