--- old/src/share/vm/oops/method.cpp 2016-07-20 02:12:34.729544981 -0700 +++ new/src/share/vm/oops/method.cpp 2016-07-20 02:12:34.610544281 -0700 @@ -110,6 +110,7 @@ // Release Method*. The nmethod will be gone when we get here because // we've walked the code cache. void Method::deallocate_contents(ClassLoaderData* loader_data) { + clear_jmethod_id(loader_data); MetadataFactory::free_metadata(loader_data, constMethod()); set_constMethod(NULL); MetadataFactory::free_metadata(loader_data, method_data()); @@ -1772,6 +1773,16 @@ #endif // ASSERT *m = _free_method; } + void clear_method(Method* m) { + for (JNIMethodBlock* b = this; b != NULL; b = b->_next) { + for (int i = 0; i< number_of_methods; i++) { + if (b->_methods[i] == m) { + b->_methods[i] = NULL; + } + } + } + // not found + } // During class unloading the methods are cleared, which is different // than freed. @@ -1844,7 +1855,9 @@ bool Method::is_method_id(jmethodID mid) { Method* m = resolve_jmethod_id(mid); - assert(m != NULL, "should be called with non-null method"); + if (m == NULL) { + return false; + } InstanceKlass* ik = m->method_holder(); if (ik == NULL) { return false; @@ -1866,6 +1879,10 @@ return o; }; +void Method::clear_jmethod_id(ClassLoaderData* loader_data) { + loader_data->jmethod_ids()->clear_method(this); +} + void Method::set_on_stack(const bool value) { // Set both the method itself and its constant pool. The constant pool // on stack means some method referring to it is also on the stack.