38 #include "logging/log.hpp" |
38 #include "logging/log.hpp" |
39 #include "memory/allocation.inline.hpp" |
39 #include "memory/allocation.inline.hpp" |
40 #include "memory/resourceArea.hpp" |
40 #include "memory/resourceArea.hpp" |
41 #include "runtime/atomic.hpp" |
41 #include "runtime/atomic.hpp" |
42 #include "runtime/orderAccess.hpp" |
42 #include "runtime/orderAccess.hpp" |
43 #include "runtime/os.hpp" |
|
44 #include "utilities/debug.hpp" |
43 #include "utilities/debug.hpp" |
45 |
44 |
46 class ZNMethodDataImmediateOops { |
45 class ZNMethodDataImmediateOops { |
47 private: |
46 private: |
48 const size_t _nimmediate_oops; |
47 const size_t _nimmediate_oops; |
438 |
437 |
439 // Disarm nmethod entry barrier |
438 // Disarm nmethod entry barrier |
440 disarm_nmethod(nm); |
439 disarm_nmethod(nm); |
441 } |
440 } |
442 |
441 |
443 void ZNMethodTable::sweeper_wait_for_iteration() { |
442 void ZNMethodTable::wait_until_iteration_done() { |
444 // The sweeper must wait for any ongoing iteration to complete |
443 assert(CodeCache_lock->owned_by_self(), "Lock must be held"); |
445 // before it can unregister an nmethod. |
|
446 if (!Thread::current()->is_Code_cache_sweeper_thread()) { |
|
447 return; |
|
448 } |
|
449 |
444 |
450 while (_iter_table != NULL) { |
445 while (_iter_table != NULL) { |
451 MutexUnlockerEx mu(CodeCache_lock, Mutex::_no_safepoint_check_flag); |
446 CodeCache_lock->wait(Monitor::_no_safepoint_check_flag); |
452 os::naked_short_sleep(1); |
|
453 } |
447 } |
454 } |
448 } |
455 |
449 |
456 void ZNMethodTable::unregister_nmethod(nmethod* nm) { |
450 void ZNMethodTable::unregister_nmethod(nmethod* nm) { |
457 assert(CodeCache_lock->owned_by_self(), "Lock must be held"); |
451 assert(CodeCache_lock->owned_by_self(), "Lock must be held"); |
|
452 |
|
453 if (Thread::current()->is_Code_cache_sweeper_thread()) { |
|
454 // The sweeper must wait for any ongoing iteration to complete |
|
455 // before it can unregister an nmethod. |
|
456 ZNMethodTable::wait_until_iteration_done(); |
|
457 } |
|
458 |
458 ResourceMark rm; |
459 ResourceMark rm; |
459 |
|
460 sweeper_wait_for_iteration(); |
|
461 |
460 |
462 log_unregister(nm); |
461 log_unregister(nm); |
463 |
462 |
464 // Remove entry |
463 // Remove entry |
465 unregister_entry(_table, _size, nm); |
464 unregister_entry(_table, _size, nm); |
492 // Finish iteration |
491 // Finish iteration |
493 if (_iter_table != _table) { |
492 if (_iter_table != _table) { |
494 delete [] _iter_table; |
493 delete [] _iter_table; |
495 } |
494 } |
496 _iter_table = NULL; |
495 _iter_table = NULL; |
|
496 |
497 assert(_claimed >= _iter_table_size, "Failed to claim all table entries"); |
497 assert(_claimed >= _iter_table_size, "Failed to claim all table entries"); |
498 |
498 |
499 // Process deferred deletes |
499 // Process deferred deletes |
500 ZArrayIterator<void*> iter(&_iter_deferred_deletes); |
500 ZArrayIterator<void*> iter(&_iter_deferred_deletes); |
501 for (void* data; iter.next(&data);) { |
501 for (void* data; iter.next(&data);) { |
502 FREE_C_HEAP_ARRAY(uint8_t, data); |
502 FREE_C_HEAP_ARRAY(uint8_t, data); |
503 } |
503 } |
504 _iter_deferred_deletes.clear(); |
504 _iter_deferred_deletes.clear(); |
|
505 |
|
506 // Notify iteration done |
|
507 CodeCache_lock->notify_all(); |
505 } |
508 } |
506 |
509 |
507 void ZNMethodTable::entry_oops_do(ZNMethodTableEntry entry, OopClosure* cl) { |
510 void ZNMethodTable::entry_oops_do(ZNMethodTableEntry entry, OopClosure* cl) { |
508 nmethod* const nm = entry.method(); |
511 nmethod* const nm = entry.method(); |
509 |
512 |