8161144: Fix for JDK-8147451 failed: Crash in Method::checked_resolve_jmethod_id(_jmethodID*)

Fri, 05 Aug 2016 10:47:35 +0000

author
shshahma
date
Fri, 05 Aug 2016 10:47:35 +0000
changeset 8583
d18eb5b5a3d6
parent 8582
56ff16dd9b8c
child 8586
1ccd27199595

8161144: Fix for JDK-8147451 failed: Crash in Method::checked_resolve_jmethod_id(_jmethodID*)
Summary: Method::deallocate_contents() should clear 'this' from list of Methods in JNIMethodBlock, when class is unloaded.
Reviewed-by: coleenp, dholmes

src/share/vm/oops/method.cpp file | annotate | diff | comparison | revisions
src/share/vm/oops/method.hpp file | annotate | diff | comparison | revisions
     1.1 --- a/src/share/vm/oops/method.cpp	Mon Aug 08 13:17:49 2016 -0700
     1.2 +++ b/src/share/vm/oops/method.cpp	Fri Aug 05 10:47:35 2016 +0000
     1.3 @@ -111,6 +111,7 @@
     1.4  // Release Method*.  The nmethod will be gone when we get here because
     1.5  // we've walked the code cache.
     1.6  void Method::deallocate_contents(ClassLoaderData* loader_data) {
     1.7 +  clear_jmethod_id(loader_data);
     1.8    MetadataFactory::free_metadata(loader_data, constMethod());
     1.9    set_constMethod(NULL);
    1.10    MetadataFactory::free_metadata(loader_data, method_data());
    1.11 @@ -1800,6 +1801,17 @@
    1.12  #endif // ASSERT
    1.13      *m = _free_method;
    1.14    }
    1.15 +  void clear_method(Method* m) {
    1.16 +    for (JNIMethodBlock* b = this; b != NULL; b = b->_next) {
    1.17 +      for (int i = 0; i < number_of_methods; i++) {
    1.18 +        if (b->_methods[i] == m) {
    1.19 +          b->_methods[i] = NULL;
    1.20 +          return;
    1.21 +        }
    1.22 +      }
    1.23 +    }
    1.24 +    // not found
    1.25 +  }
    1.26  
    1.27    // During class unloading the methods are cleared, which is different
    1.28    // than freed.
    1.29 @@ -1872,7 +1884,9 @@
    1.30  
    1.31  bool Method::is_method_id(jmethodID mid) {
    1.32    Method* m = resolve_jmethod_id(mid);
    1.33 -  assert(m != NULL, "should be called with non-null method");
    1.34 +  if (m == NULL) {
    1.35 +    return false;
    1.36 +  }
    1.37    InstanceKlass* ik = m->method_holder();
    1.38    if (ik == NULL) {
    1.39      return false;
    1.40 @@ -1905,6 +1919,10 @@
    1.41    }
    1.42  }
    1.43  
    1.44 +void Method::clear_jmethod_id(ClassLoaderData* loader_data) {
    1.45 +  loader_data->jmethod_ids()->clear_method(this);
    1.46 +}
    1.47 +
    1.48  // Called when the class loader is unloaded to make all methods weak.
    1.49  void Method::clear_jmethod_ids(ClassLoaderData* loader_data) {
    1.50    loader_data->jmethod_ids()->clear_all_methods();
     2.1 --- a/src/share/vm/oops/method.hpp	Mon Aug 08 13:17:49 2016 -0700
     2.2 +++ b/src/share/vm/oops/method.hpp	Fri Aug 05 10:47:35 2016 +0000
     2.3 @@ -768,6 +768,8 @@
     2.4  
     2.5    // Helper routines for intrinsic_id() and vmIntrinsics::method().
     2.6    void init_intrinsic_id();     // updates from _none if a match
     2.7 +  void clear_jmethod_id(ClassLoaderData* loader_data);
     2.8 +
     2.9    static vmSymbols::SID klass_id_for_intrinsics(Klass* holder);
    2.10  
    2.11    bool     jfr_towrite()                { return _jfr_towrite;              }

mercurial