8217309: ZGC: Fix ZNMethodTable corruption
Reviewed-by: eosterlund, stefank
This commit is contained in:
parent
25bd20f5d9
commit
ad65ea3c85
@ -1100,7 +1100,11 @@ void nmethod::make_unloaded() {
|
||||
"must be at safepoint");
|
||||
|
||||
// Unregister must be done before the state change
|
||||
Universe::heap()->unregister_nmethod(this);
|
||||
{
|
||||
MutexLockerEx ml(SafepointSynchronize::is_at_safepoint() ? NULL : CodeCache_lock,
|
||||
Mutex::_no_safepoint_check_flag);
|
||||
Universe::heap()->unregister_nmethod(this);
|
||||
}
|
||||
|
||||
// Log the unloading.
|
||||
log_state_change();
|
||||
|
@ -264,21 +264,17 @@ bool ZNMethodTable::register_entry(ZNMethodTableEntry* table, size_t size, ZNMet
|
||||
}
|
||||
}
|
||||
|
||||
bool ZNMethodTable::unregister_entry(ZNMethodTableEntry* table, size_t size, nmethod* nm) {
|
||||
void ZNMethodTable::unregister_entry(ZNMethodTableEntry* table, size_t size, nmethod* nm) {
|
||||
if (size == 0) {
|
||||
// Table is empty
|
||||
return false;
|
||||
return;
|
||||
}
|
||||
|
||||
size_t index = first_index(nm, size);
|
||||
|
||||
for (;;) {
|
||||
const ZNMethodTableEntry table_entry = table[index];
|
||||
|
||||
if (!table_entry.registered() && !table_entry.unregistered()) {
|
||||
// Entry not found
|
||||
return false;
|
||||
}
|
||||
assert(table_entry.registered() || table_entry.unregistered(), "Entry not found");
|
||||
|
||||
if (table_entry.registered() && table_entry.method() == nm) {
|
||||
// Remove entry
|
||||
@ -287,7 +283,7 @@ bool ZNMethodTable::unregister_entry(ZNMethodTableEntry* table, size_t size, nme
|
||||
// Destroy GC data
|
||||
ZNMethodData::destroy(gc_data(nm));
|
||||
set_gc_data(nm, NULL);
|
||||
return true;
|
||||
return;
|
||||
}
|
||||
|
||||
index = next_index(index, size);
|
||||
@ -451,8 +447,6 @@ void ZNMethodTable::sweeper_wait_for_iteration() {
|
||||
return;
|
||||
}
|
||||
|
||||
assert(CodeCache_lock->owned_by_self(), "Lock must be held");
|
||||
|
||||
while (_iter_table != NULL) {
|
||||
MutexUnlockerEx mu(CodeCache_lock, Mutex::_no_safepoint_check_flag);
|
||||
os::naked_short_sleep(1);
|
||||
@ -460,6 +454,7 @@ void ZNMethodTable::sweeper_wait_for_iteration() {
|
||||
}
|
||||
|
||||
void ZNMethodTable::unregister_nmethod(nmethod* nm) {
|
||||
assert(CodeCache_lock->owned_by_self(), "Lock must be held");
|
||||
ResourceMark rm;
|
||||
|
||||
sweeper_wait_for_iteration();
|
||||
@ -467,14 +462,9 @@ void ZNMethodTable::unregister_nmethod(nmethod* nm) {
|
||||
log_unregister(nm);
|
||||
|
||||
// Remove entry
|
||||
if (unregister_entry(_table, _size, nm)) {
|
||||
// Entry was unregistered. When unregister_entry() instead returns
|
||||
// false the nmethod was not in the table (because it didn't have
|
||||
// any oops) so we do not want to decrease the number of registered
|
||||
// entries in that case.
|
||||
_nregistered--;
|
||||
_nunregistered++;
|
||||
}
|
||||
unregister_entry(_table, _size, nm);
|
||||
_nunregistered++;
|
||||
_nregistered--;
|
||||
}
|
||||
|
||||
void ZNMethodTable::disarm_nmethod(nmethod* nm) {
|
||||
|
@ -57,7 +57,7 @@ private:
|
||||
static void sweeper_wait_for_iteration();
|
||||
|
||||
static bool register_entry(ZNMethodTableEntry* table, size_t size, ZNMethodTableEntry entry);
|
||||
static bool unregister_entry(ZNMethodTableEntry* table, size_t size, nmethod* nm);
|
||||
static void unregister_entry(ZNMethodTableEntry* table, size_t size, nmethod* nm);
|
||||
|
||||
static void rebuild(size_t new_size);
|
||||
static void rebuild_if_needed();
|
||||
|
Loading…
Reference in New Issue
Block a user