mirror of
https://github.com/openjdk/jdk.git
synced 2025-09-16 17:14:41 +02:00
8296955: Kitchensink.java failed with "double free or corruption (!prev): <addr>"
Reviewed-by: kbarrett, eosterlund, sspitsyn, dcubed
This commit is contained in:
parent
8962c723a8
commit
d453190300
3 changed files with 39 additions and 75 deletions
|
@ -2148,15 +2148,8 @@ jmethodID InstanceKlass::get_jmethod_id(const methodHandle& method_h) {
|
|||
// the cache can't grow so we can just get the current values
|
||||
get_jmethod_id_length_value(jmeths, idnum, &length, &id);
|
||||
} else {
|
||||
// cache can grow so we have to be more careful
|
||||
if (Threads::number_of_threads() == 0 ||
|
||||
SafepointSynchronize::is_at_safepoint()) {
|
||||
// we're single threaded or at a safepoint - no locking needed
|
||||
get_jmethod_id_length_value(jmeths, idnum, &length, &id);
|
||||
} else {
|
||||
MutexLocker ml(JmethodIdCreation_lock, Mutex::_no_safepoint_check_flag);
|
||||
get_jmethod_id_length_value(jmeths, idnum, &length, &id);
|
||||
}
|
||||
MutexLocker ml(JmethodIdCreation_lock, Mutex::_no_safepoint_check_flag);
|
||||
get_jmethod_id_length_value(jmeths, idnum, &length, &id);
|
||||
}
|
||||
}
|
||||
// implied else:
|
||||
|
@ -2166,8 +2159,8 @@ jmethodID InstanceKlass::get_jmethod_id(const methodHandle& method_h) {
|
|||
length <= idnum || // cache is too short
|
||||
id == NULL) { // cache doesn't contain entry
|
||||
|
||||
// This function can be called by the VMThread so we have to do all
|
||||
// things that might block on a safepoint before grabbing the lock.
|
||||
// This function can be called by the VMThread or GC worker threads so we
|
||||
// have to do all things that might block on a safepoint before grabbing the lock.
|
||||
// Otherwise, we can deadlock with the VMThread or have a cache
|
||||
// consistency issue. These vars keep track of what we might have
|
||||
// to free after the lock is dropped.
|
||||
|
@ -2186,25 +2179,20 @@ jmethodID InstanceKlass::get_jmethod_id(const methodHandle& method_h) {
|
|||
}
|
||||
|
||||
// allocate a new jmethodID that might be used
|
||||
jmethodID new_id = NULL;
|
||||
if (method_h->is_old() && !method_h->is_obsolete()) {
|
||||
// The method passed in is old (but not obsolete), we need to use the current version
|
||||
Method* current_method = method_with_idnum((int)idnum);
|
||||
assert(current_method != NULL, "old and but not obsolete, so should exist");
|
||||
new_id = Method::make_jmethod_id(class_loader_data(), current_method);
|
||||
} else {
|
||||
// It is the current version of the method or an obsolete method,
|
||||
// use the version passed in
|
||||
new_id = Method::make_jmethod_id(class_loader_data(), method_h());
|
||||
}
|
||||
|
||||
if (Threads::number_of_threads() == 0 ||
|
||||
SafepointSynchronize::is_at_safepoint()) {
|
||||
// we're single threaded or at a safepoint - no locking needed
|
||||
id = get_jmethod_id_fetch_or_update(idnum, new_id, new_jmeths,
|
||||
&to_dealloc_id, &to_dealloc_jmeths);
|
||||
} else {
|
||||
{
|
||||
MutexLocker ml(JmethodIdCreation_lock, Mutex::_no_safepoint_check_flag);
|
||||
jmethodID new_id = NULL;
|
||||
if (method_h->is_old() && !method_h->is_obsolete()) {
|
||||
// The method passed in is old (but not obsolete), we need to use the current version
|
||||
Method* current_method = method_with_idnum((int)idnum);
|
||||
assert(current_method != NULL, "old and but not obsolete, so should exist");
|
||||
new_id = Method::make_jmethod_id(class_loader_data(), current_method);
|
||||
} else {
|
||||
// It is the current version of the method or an obsolete method,
|
||||
// use the version passed in
|
||||
new_id = Method::make_jmethod_id(class_loader_data(), method_h());
|
||||
}
|
||||
|
||||
id = get_jmethod_id_fetch_or_update(idnum, new_id, new_jmeths,
|
||||
&to_dealloc_id, &to_dealloc_jmeths);
|
||||
}
|
||||
|
@ -2254,9 +2242,7 @@ jmethodID InstanceKlass::get_jmethod_id_fetch_or_update(
|
|||
assert(new_id != NULL, "sanity check");
|
||||
assert(to_dealloc_id_p != NULL, "sanity check");
|
||||
assert(to_dealloc_jmeths_p != NULL, "sanity check");
|
||||
assert(Threads::number_of_threads() == 0 ||
|
||||
SafepointSynchronize::is_at_safepoint() ||
|
||||
JmethodIdCreation_lock->owned_by_self(), "sanity check");
|
||||
assert(JmethodIdCreation_lock->owned_by_self(), "sanity check");
|
||||
|
||||
// reacquire the cache - we are locked, single threaded or at a safepoint
|
||||
jmethodID* jmeths = methods_jmethod_ids_acquire();
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue