8219462: ZGC: Use wait/notify in ZNMethodTable

Reviewed-by: pliden
This commit is contained in:
Stefan Karlsson 2019-02-19 13:47:45 +01:00
parent 33d947b7e3
commit 45f74c8c95
2 changed files with 15 additions and 12 deletions

View File

@ -40,7 +40,6 @@
#include "memory/resourceArea.hpp"
#include "runtime/atomic.hpp"
#include "runtime/orderAccess.hpp"
#include "runtime/os.hpp"
#include "utilities/debug.hpp"
class ZNMethodDataImmediateOops {
@ -440,24 +439,24 @@ void ZNMethodTable::register_nmethod(nmethod* nm) {
disarm_nmethod(nm);
}
void ZNMethodTable::sweeper_wait_for_iteration() {
// The sweeper must wait for any ongoing iteration to complete
// before it can unregister an nmethod.
if (!Thread::current()->is_Code_cache_sweeper_thread()) {
return;
}
void ZNMethodTable::wait_until_iteration_done() {
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);
CodeCache_lock->wait(Monitor::_no_safepoint_check_flag);
}
}
void ZNMethodTable::unregister_nmethod(nmethod* nm) {
assert(CodeCache_lock->owned_by_self(), "Lock must be held");
ResourceMark rm;
sweeper_wait_for_iteration();
if (Thread::current()->is_Code_cache_sweeper_thread()) {
// The sweeper must wait for any ongoing iteration to complete
// before it can unregister an nmethod.
ZNMethodTable::wait_until_iteration_done();
}
ResourceMark rm;
log_unregister(nm);
@ -494,6 +493,7 @@ void ZNMethodTable::nmethod_entries_do_end() {
delete [] _iter_table;
}
_iter_table = NULL;
assert(_claimed >= _iter_table_size, "Failed to claim all table entries");
// Process deferred deletes
@ -502,6 +502,9 @@ void ZNMethodTable::nmethod_entries_do_end() {
FREE_C_HEAP_ARRAY(uint8_t, data);
}
_iter_deferred_deletes.clear();
// Notify iteration done
CodeCache_lock->notify_all();
}
void ZNMethodTable::entry_oops_do(ZNMethodTableEntry entry, OopClosure* cl) {

View File

@ -54,7 +54,7 @@ private:
static size_t first_index(const nmethod* nm, size_t size);
static size_t next_index(size_t prev_index, size_t size);
static void sweeper_wait_for_iteration();
static void wait_until_iteration_done();
static bool register_entry(ZNMethodTableEntry* table, size_t size, ZNMethodTableEntry entry);
static void unregister_entry(ZNMethodTableEntry* table, size_t size, nmethod* nm);