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

Shared archive failed on old version class with jsr bytecode

XMLWordPrintable

    • Icon: Bug Bug
    • Resolution: Fixed
    • Icon: P4 P4
    • 21
    • 21
    • hotspot
    • b14

      CDS can archive old version class lower than version 50. Some old version class contain 'jsr' which is not generated in newer version. CDS will run fail on sharing CDS with old version with 'jsr'.

      Here is the simple test:
      import org.apache.xerces.parsers.SAXParser;
      public class SaxExample {
          public static void main(String... args) throws Exception {
              SAXParser parser = new SAXParser();
              System.out.println("Hello, SAXParser world!");
          }
      }

      You can get the version of xercesImpl-2.12.0.jar from here:
      https://mvnrepository.com/artifact/xerces/xercesImpl/2.12.0

      put this jar on path, and create CDS archive, run with it then get:
      --------------- T H R E A D ---------------

      Current thread (0xf5918040): JavaThread "main" [_thread_in_vm, id=17441, stack(0xf5af8000,0xf5b49000)]

      Stack: [0xf5af8000,0xf5b49000], sp=0xf5b4796c, free space=318k
      Native frames: (J=compiled Java code, j=interpreted, Vv=VM code, C=native code)
      V [libjvm.so+0x580d94] Array<Method*>::at_put(int, Method* const&)+0x68
      V [libjvm.so+0xca9679] Rewriter::Rewriter(InstanceKlass*, constantPoolHandle const&, Array<Method*>*, JavaThread*)+0x369
      V [libjvm.so+0xca9289] Rewriter::rewrite(InstanceKlass*, JavaThread*)+0x119
      V [libjvm.so+0x858451] InstanceKlass::rewrite_class(JavaThread*)+0xa5
      V [libjvm.so+0x858141] InstanceKlass::link_class_impl(JavaThread*)+0x3a1
      V [libjvm.so+0x857cfb] InstanceKlass::link_class(JavaThread*)+0x67
      V [libjvm.so+0x8586cf] InstanceKlass::initialize_impl(JavaThread*)+0x55
      V [libjvm.so+0x857c11] InstanceKlass::initialize(JavaThread*)+0x2d
      V [libjvm.so+0xa5b853] LinkResolver::resolve_static_call(CallInfo&, LinkInfo const&, bool, JavaThread*)+0x97
      V [libjvm.so+0xa5e522] LinkResolver::resolve_invokestatic(CallInfo&, constantPoolHandle const&, int, JavaThread*)+0x50
      V [libjvm.so+0xa5e181] LinkResolver::resolve_invoke(CallInfo&, Handle, constantPoolHandle const&, int, Bytecodes::Code, JavaThread*)+0x41
      V [libjvm.so+0x877964] InterpreterRuntime::resolve_invoke(JavaThread*, Bytecodes::Code)+0x2b0
      V [libjvm.so+0x8782b0] InterpreterRuntime::resolve_from_cache(JavaThread*, Bytecodes::Code)+0x8e
      j org.apache.xerces.parsers.SAXParser.<init>(Lorg/apache/xerces/util/SymbolTable;Lorg/apache/xerces/xni/grammars/XMLGrammarPool;)V+5
      j org.apache.xerces.parsers.SAXParser.<init>()V+3
      j SaxExample.main([Ljava/lang/String;)V+4
      v ~StubRoutines::call_stub
      V [libjvm.so+0x882e51] JavaCalls::call_helper(JavaValue*, methodHandle const&, JavaCallArguments*, JavaThread*)+0x3eb
      V [libjvm.so+0xbf997b] os::os_exception_wrapper(void (*)(JavaValue*, methodHandle const&, JavaCallArguments*, JavaThread*), JavaValue*, methodHandle const&, JavaCallArguments*, JavaThread*)+0x21
      V [libjvm.so+0x882a5c] JavaCalls::call(JavaValue*, methodHandle const&, JavaCallArguments*, JavaThread*)+0x2e
      V [libjvm.so+0x9357c1] jni_invoke_static(JNIEnv_*, JavaValue*, _jobject*, JNICallType, _jmethodID*, JNI_ArgumentPusher*, JavaThread*)+0x185
      V [libjvm.so+0x93feb3] jni_CallStaticVoidMethod+0x110
      C [libjli.so+0x8a27] JavaMain+0xb26
      C [libjli.so+0xe987] ThreadJavaMain+0x30
      C [libpthread.so.0+0x6bbc] start_thread+0xcc

      'jsr' gets rewritten then the code is wrriten back to the read only shared region.

      Maybe the fix could like this?
      diff --git a/src/hotspot/share/interpreter/rewriter.cpp b/src/hotspot/share/interpreter/rewriter.cpp
      index 080735ba41d..92a7af2cf0b 100644
      --- a/src/hotspot/share/interpreter/rewriter.cpp
      +++ b/src/hotspot/share/interpreter/rewriter.cpp
      @@ -617,6 +617,9 @@ Rewriter::Rewriter(InstanceKlass* klass, const constantPoolHandle& cpool, Array<
         // rewritten in the RO section of the shared archive.
         // Relocated bytecodes don't have to be restored, only the cp cache entries
         int len = _methods->length();
      + // Don't write back to RO space for old jsr rewritten, the rewritten still
      + // needed for contant pool indices
      + bool do_update = !(UseSharedSpaces && _klass->is_shared() && _klass->major_version() < 50);
         for (int i = len-1; i >= 0; i--) {
           methodHandle m(THREAD, _methods->at(i));

      @@ -630,7 +633,9 @@ Rewriter::Rewriter(InstanceKlass* klass, const constantPoolHandle& cpool, Array<
               return;
             }
             // Method might have gotten rewritten.
      - methods->at_put(i, m());
      + if (do_update) {
      + methods->at_put(i, m());
      + }
           }
         }
       }
       

            ccheung Calvin Cheung
            minqi Yumin Qi
            Votes:
            0 Vote for this issue
            Watchers:
            9 Start watching this issue

              Created:
              Updated:
              Resolved: