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

The constant pool forgets it has a Dynamic entry if there are overpass methods

XMLWordPrintable

    • Icon: Bug Bug
    • Resolution: Fixed
    • Icon: P3 P3
    • 11
    • 11, repo-amber
    • hotspot
    • None
    • b07

      If a class file's constant pool contains a Dynamic entry then when the class is initialized a bit is set in the constant pool structure noting that there exists such an entry. See classfileParser.cpp#566. This bit is required for JVMCI to function correctly (specific details as to why this is required are not clear to me).

      If the class file is an interface with default methods that are overpass methods then HotSpot rewrites the constant pool structure adjusting entries related to those overpass methods. See the method defaultMethods.cpp:switchover_constant_pool which calls BytecodeConstantPool::create_constant_pool. That latter method does not preserve the bit noting that there exists a Dynamic entry.

      To reproduce clone the amber repo, switch to the condy-folding branch, and build a fastdebug build. The following simple program will cause HotSpot to crash

      mport java.time.*;
      import java.time.chrono.*;
      import java.time.format.*;
      import java.time.temporal.*;
      import java.time.zone.*;
      import java.util.List;

      public class A {
          public static void main(String[] args) throws Exception {
              String[] l = new String[] {
                      "java.time.chrono.ChronoLocalDate"
              };
              for (String c : l) {
                  Class.forName(c);
              }
          }
      }

      The following patch fixes the issue:

      diff -r f6a1ff6755b3 src/hotspot/share/classfile/bytecodeAssembler.cpp
      --- a/src/hotspot/share/classfile/bytecodeAssembler.cpp Wed Mar 07 16:34:02 2018 -0500
      +++ b/src/hotspot/share/classfile/bytecodeAssembler.cpp Thu Mar 08 08:24:59 2018 -0800
      @@ -55,6 +55,10 @@
         cp->set_pool_holder(_orig->pool_holder());
         _orig->copy_cp_to(1, _orig->length() - 1, cp, 1, CHECK_NULL);
       
      + if (_orig->has_dynamic_constant()) {
      + cp->set_has_dynamic_constant();
      + }
      +
         for (int i = 0; i < _entries.length(); ++i) {
           BytecodeCPEntry entry = _entries.at(i);
           int idx = i + _orig->length();

            psandoz Paul Sandoz
            psandoz Paul Sandoz
            Votes:
            0 Vote for this issue
            Watchers:
            3 Start watching this issue

              Created:
              Updated:
              Resolved: