JDK-8169867 : Method::restore_unshareable_info() does not invoke Method::link_method()
  • Type: Bug
  • Component: hotspot
  • Sub-Component: runtime
  • Affected Version: 9
  • Priority: P3
  • Status: Resolved
  • Resolution: Fixed
  • Submitted: 2016-11-17
  • Updated: 2020-06-14
  • Resolved: 2016-11-29
The Version table provides details related to the release that this issue/RFE will be addressed.

Unresolved : Release in which this issue/RFE will be addressed.
Resolved: Release in which this issue/RFE has been resolved.
Fixed : Release in which this issue/RFE has been fixed. The release containing this fix may be available for download as an Early Access Release or a General Availability Release.

To download the current JDK release, click here.
JDK 9
9 b150Fixed
Related Reports
Relates :  
Description
While working on JDK-8169711, I noticed that the assert in Method::link_method() is not always triggered (sometimes we just crash). This is because
1) the "_from_compiled_entry == NULL" check in Method::restore_unshareable_info() is always false and therefore link_method() is not invoked and
2) in Method::link_method() we only execute the check if the adapter (which is shared) was not yet initialized. See attached method.cpp.patch for a suggestion on how to refactor the method.
Comments
http://hg.openjdk.java.net/jdk/jdk/rev/14af45789042
14-06-2020

I found a problem in my previous patch. Here's the fix (on top of the previous patch): diff -r 3404f61c7081 src/share/vm/oops/method.cpp --- a/src/share/vm/oops/method.cpp Sun Nov 27 19:44:44 2016 -0800 +++ b/src/share/vm/oops/method.cpp Sun Nov 27 19:50:35 2016 -0800 @@ -1031,11 +1031,13 @@ // leftover methods that weren't linked. if (is_shared()) { address entry = Interpreter::entry_for_cds_method(h_method); - assert(entry != NULL && entry == _i2i_entry && entry == _from_interpreted_entry, + assert(entry != NULL && entry == _i2i_entry, "should be correctly set during dump time"); if (adapter() != NULL) { return; } + assert(entry == _from_interpreted_entry, + "should be correctly set during dump time"); } else if (_i2i_entry != NULL) { return; } The problem is: if the method has been compiled, then a shared method's _from_interpreted_entry would be different than _i2i_entry (see Method::set_code()). I am not sure if Method::link_method() would ever be called after it's been compiled, but I think it's safer to make the asserts no stronger than before this patch.
28-11-2016

RFR: http://cr.openjdk.java.net/~iklam/jdk9/8169867_cds_not_calling_link_method.v01/
21-11-2016

Hi Ioi, yes, I've attached a slightly modified test for JDK-8169711 that crashes with a SIGSEGV instead of triggering the assert in Method::link_method(). This is because link_method() is not executed and we therefore don't notice that the _i2i_entry is invalid: # A fatal error has been detected by the Java Runtime Environment: # # SIGSEGV (0xb) at pc=0x00007f019c659100, pid=12633, tid=12635 Stack: [0x00007f9691e7e000,0x00007f9691f7f000], sp=0x00007f9691f7d6e8, free space=1021k Native frames: (J=compiled Java code, j=interpreted, Vv=VM code, C=native code) C 0x00007f019c659100 j java.util.zip.CRC32.update([BII)V+44 java.base@9-internal j TestInterpreterMethodEntries.main([Ljava/lang/String;)V+42
18-11-2016

Hi Tobias, could you elaborate on "(sometimes we just crash)"? Do you have a test case for that?
17-11-2016

Re: the "_from_compiled_entry == NULL" check in Method::restore_unshareable_info() is always false and therefore link_method() is not invoked This is true, and was overlooked when CDS method trampoline was introduced. The reasons that CDS methods work (in most cases anyway), is because Method::link_method is called on this path (notice this=0x800a03688, in the range of SharedBaseAddress+<xxx>, which is in the range of the CDS Read-Only space). #0 Method::link_method (this=0x800a03630, h_method=..., __the_thread__=0x7ffff0019800) at hotspot/src/share/vm/oops/method.cpp:962 #1 0x00007ffff6196aba in InstanceKlass::link_methods (this=0x800a03688, __the_thread__=0x7ffff0019800) at hotspot/src/share/vm/oops/instanceKlass.cpp:673 #2 0x00007ffff61965d3 in InstanceKlass::link_class_impl (this_k=..., throw_verifyerror=true, __the_thread__=0x7ffff0019800) at hotspot/src/share/vm/oops/instanceKlass.cpp:614 #3 0x00007ffff61962e5 in InstanceKlass::link_class_impl (this_k=..., throw_verifyerror=true, __the_thread__=0x7ffff0019800) at hotspot/src/share/vm/oops/instanceKlass.cpp:566 #4 0x00007ffff6195db5 in InstanceKlass::link_class (this=0x800a06428, __the_thread__=0x7ffff0019800) at hotspot/src/share/vm/oops/instanceKlass.cpp:502 #5 0x00007ffff6196d1b in InstanceKlass::initialize_impl (this_k=..., __the_thread__=0x7ffff0019800) at hotspot/src/share/vm/oops/instanceKlass.cpp:701 #6 0x00007ffff6195b0f in InstanceKlass::initialize (this=0x800a06428, __the_thread__=0x7ffff0019800) at hotspot/src/share/vm/oops/instanceKlass.cpp:470 #7 0x00007ffff67f979c in initialize_class (class_name=0x800000258, __the_thread__=0x7ffff0019800)
17-11-2016