mirror of
https://github.com/openjdk/jdk.git
synced 2025-08-27 23:04:50 +02:00
8217309: ZGC: Fix ZNMethodTable corruption
Reviewed-by: eosterlund, stefank
This commit is contained in:
parent
25bd20f5d9
commit
ad65ea3c85
3 changed files with 14 additions and 20 deletions
|
@ -1100,7 +1100,11 @@ void nmethod::make_unloaded() {
|
||||||
"must be at safepoint");
|
"must be at safepoint");
|
||||||
|
|
||||||
// Unregister must be done before the state change
|
// 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 the unloading.
|
||||||
log_state_change();
|
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) {
|
if (size == 0) {
|
||||||
// Table is empty
|
// Table is empty
|
||||||
return false;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t index = first_index(nm, size);
|
size_t index = first_index(nm, size);
|
||||||
|
|
||||||
for (;;) {
|
for (;;) {
|
||||||
const ZNMethodTableEntry table_entry = table[index];
|
const ZNMethodTableEntry table_entry = table[index];
|
||||||
|
assert(table_entry.registered() || table_entry.unregistered(), "Entry not found");
|
||||||
if (!table_entry.registered() && !table_entry.unregistered()) {
|
|
||||||
// Entry not found
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (table_entry.registered() && table_entry.method() == nm) {
|
if (table_entry.registered() && table_entry.method() == nm) {
|
||||||
// Remove entry
|
// Remove entry
|
||||||
|
@ -287,7 +283,7 @@ bool ZNMethodTable::unregister_entry(ZNMethodTableEntry* table, size_t size, nme
|
||||||
// Destroy GC data
|
// Destroy GC data
|
||||||
ZNMethodData::destroy(gc_data(nm));
|
ZNMethodData::destroy(gc_data(nm));
|
||||||
set_gc_data(nm, NULL);
|
set_gc_data(nm, NULL);
|
||||||
return true;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
index = next_index(index, size);
|
index = next_index(index, size);
|
||||||
|
@ -451,8 +447,6 @@ void ZNMethodTable::sweeper_wait_for_iteration() {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
assert(CodeCache_lock->owned_by_self(), "Lock must be held");
|
|
||||||
|
|
||||||
while (_iter_table != NULL) {
|
while (_iter_table != NULL) {
|
||||||
MutexUnlockerEx mu(CodeCache_lock, Mutex::_no_safepoint_check_flag);
|
MutexUnlockerEx mu(CodeCache_lock, Mutex::_no_safepoint_check_flag);
|
||||||
os::naked_short_sleep(1);
|
os::naked_short_sleep(1);
|
||||||
|
@ -460,6 +454,7 @@ void ZNMethodTable::sweeper_wait_for_iteration() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void ZNMethodTable::unregister_nmethod(nmethod* nm) {
|
void ZNMethodTable::unregister_nmethod(nmethod* nm) {
|
||||||
|
assert(CodeCache_lock->owned_by_self(), "Lock must be held");
|
||||||
ResourceMark rm;
|
ResourceMark rm;
|
||||||
|
|
||||||
sweeper_wait_for_iteration();
|
sweeper_wait_for_iteration();
|
||||||
|
@ -467,14 +462,9 @@ void ZNMethodTable::unregister_nmethod(nmethod* nm) {
|
||||||
log_unregister(nm);
|
log_unregister(nm);
|
||||||
|
|
||||||
// Remove entry
|
// Remove entry
|
||||||
if (unregister_entry(_table, _size, nm)) {
|
unregister_entry(_table, _size, nm);
|
||||||
// Entry was unregistered. When unregister_entry() instead returns
|
_nunregistered++;
|
||||||
// false the nmethod was not in the table (because it didn't have
|
_nregistered--;
|
||||||
// any oops) so we do not want to decrease the number of registered
|
|
||||||
// entries in that case.
|
|
||||||
_nregistered--;
|
|
||||||
_nunregistered++;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void ZNMethodTable::disarm_nmethod(nmethod* nm) {
|
void ZNMethodTable::disarm_nmethod(nmethod* nm) {
|
||||||
|
|
|
@ -57,7 +57,7 @@ private:
|
||||||
static void sweeper_wait_for_iteration();
|
static void sweeper_wait_for_iteration();
|
||||||
|
|
||||||
static bool register_entry(ZNMethodTableEntry* table, size_t size, ZNMethodTableEntry entry);
|
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(size_t new_size);
|
||||||
static void rebuild_if_needed();
|
static void rebuild_if_needed();
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue