< prev index next >

src/hotspot/share/gc/z/zNMethodTable.cpp

Print this page

        

*** 40,148 **** #include "memory/resourceArea.hpp" #include "runtime/atomic.hpp" #include "runtime/orderAccess.hpp" #include "utilities/debug.hpp" ! class ZNMethodDataImmediateOops { private: ! const size_t _nimmediate_oops; static size_t header_size(); ! ZNMethodDataImmediateOops(const GrowableArray<oop*>& immediate_oops); public: ! static ZNMethodDataImmediateOops* create(const GrowableArray<oop*>& immediate_oops); ! static void destroy(ZNMethodDataImmediateOops* data_immediate_oops); ! size_t immediate_oops_count() const; ! oop** immediate_oops_begin() const; ! oop** immediate_oops_end() const; }; ! size_t ZNMethodDataImmediateOops::header_size() { ! const size_t size = sizeof(ZNMethodDataImmediateOops); assert(is_aligned(size, sizeof(oop*)), "Header misaligned"); return size; } ! ZNMethodDataImmediateOops* ZNMethodDataImmediateOops::create(const GrowableArray<oop*>& immediate_oops) { ! // Allocate memory for the ZNMethodDataImmediateOops object // plus the immediate oop* array that follows right after. ! const size_t size = ZNMethodDataImmediateOops::header_size() + (sizeof(oop*) * immediate_oops.length()); ! void* const data_immediate_oops = NEW_C_HEAP_ARRAY(uint8_t, size, mtGC); ! return ::new (data_immediate_oops) ZNMethodDataImmediateOops(immediate_oops); } ! void ZNMethodDataImmediateOops::destroy(ZNMethodDataImmediateOops* data_immediate_oops) { ! ZNMethodTable::safe_delete(data_immediate_oops); } ! ZNMethodDataImmediateOops::ZNMethodDataImmediateOops(const GrowableArray<oop*>& immediate_oops) : ! _nimmediate_oops(immediate_oops.length()) { // Save all immediate oops ! for (size_t i = 0; i < _nimmediate_oops; i++) { ! immediate_oops_begin()[i] = immediate_oops.at(i); } } ! size_t ZNMethodDataImmediateOops::immediate_oops_count() const { ! return _nimmediate_oops; } ! oop** ZNMethodDataImmediateOops::immediate_oops_begin() const { // The immediate oop* array starts immediately after this object return (oop**)((uintptr_t)this + header_size()); } ! oop** ZNMethodDataImmediateOops::immediate_oops_end() const { ! return immediate_oops_begin() + immediate_oops_count(); } class ZNMethodData { private: ZReentrantLock _lock; ! ZNMethodDataImmediateOops* volatile _immediate_oops; ZNMethodData(nmethod* nm); public: static ZNMethodData* create(nmethod* nm); static void destroy(ZNMethodData* data); ZReentrantLock* lock(); ! ZNMethodDataImmediateOops* immediate_oops() const; ! ZNMethodDataImmediateOops* swap_immediate_oops(const GrowableArray<oop*>& immediate_oops); }; ZNMethodData* ZNMethodData::create(nmethod* nm) { void* const method = NEW_C_HEAP_ARRAY(uint8_t, sizeof(ZNMethodData), mtGC); return ::new (method) ZNMethodData(nm); } void ZNMethodData::destroy(ZNMethodData* data) { ! ZNMethodDataImmediateOops::destroy(data->immediate_oops()); ZNMethodTable::safe_delete(data); } ZNMethodData::ZNMethodData(nmethod* nm) : _lock(), ! _immediate_oops(NULL) {} ZReentrantLock* ZNMethodData::lock() { return &_lock; } ! ZNMethodDataImmediateOops* ZNMethodData::immediate_oops() const { ! return OrderAccess::load_acquire(&_immediate_oops); } ! ZNMethodDataImmediateOops* ZNMethodData::swap_immediate_oops(const GrowableArray<oop*>& immediate_oops) { ! ZNMethodDataImmediateOops* const data_immediate_oops = ! immediate_oops.is_empty() ? NULL : ZNMethodDataImmediateOops::create(immediate_oops); ! return Atomic::xchg(data_immediate_oops, &_immediate_oops); } static ZNMethodData* gc_data(const nmethod* nm) { return nm->gc_data<ZNMethodData>(); } --- 40,154 ---- #include "memory/resourceArea.hpp" #include "runtime/atomic.hpp" #include "runtime/orderAccess.hpp" #include "utilities/debug.hpp" ! class ZNMethodDataOops { private: ! const size_t _nimmediates; ! bool _has_non_immediates; static size_t header_size(); ! ZNMethodDataOops(const GrowableArray<oop*>& immediates, bool has_non_immediates); public: ! static ZNMethodDataOops* create(const GrowableArray<oop*>& immediates, bool has_non_immediates); ! static void destroy(ZNMethodDataOops* oops); ! size_t immediates_count() const; ! oop** immediates_begin() const; ! oop** immediates_end() const; ! ! bool has_non_immediates() const; }; ! size_t ZNMethodDataOops::header_size() { ! const size_t size = sizeof(ZNMethodDataOops); assert(is_aligned(size, sizeof(oop*)), "Header misaligned"); return size; } ! ZNMethodDataOops* ZNMethodDataOops::create(const GrowableArray<oop*>& immediates, bool has_non_immediates) { ! // Allocate memory for the ZNMethodDataOops object // plus the immediate oop* array that follows right after. ! const size_t size = ZNMethodDataOops::header_size() + (sizeof(oop*) * immediates.length()); ! void* const data = NEW_C_HEAP_ARRAY(uint8_t, size, mtGC); ! return ::new (data) ZNMethodDataOops(immediates, has_non_immediates); } ! void ZNMethodDataOops::destroy(ZNMethodDataOops* oops) { ! ZNMethodTable::safe_delete(oops); } ! ZNMethodDataOops::ZNMethodDataOops(const GrowableArray<oop*>& immediates, bool has_non_immediates) : ! _nimmediates(immediates.length()), ! _has_non_immediates(has_non_immediates) { // Save all immediate oops ! for (size_t i = 0; i < _nimmediates; i++) { ! immediates_begin()[i] = immediates.at(i); } } ! size_t ZNMethodDataOops::immediates_count() const { ! return _nimmediates; } ! oop** ZNMethodDataOops::immediates_begin() const { // The immediate oop* array starts immediately after this object return (oop**)((uintptr_t)this + header_size()); } ! oop** ZNMethodDataOops::immediates_end() const { ! return immediates_begin() + immediates_count(); ! } ! ! bool ZNMethodDataOops::has_non_immediates() const { ! return _has_non_immediates; } class ZNMethodData { private: ZReentrantLock _lock; ! ZNMethodDataOops* volatile _oops; ZNMethodData(nmethod* nm); public: static ZNMethodData* create(nmethod* nm); static void destroy(ZNMethodData* data); ZReentrantLock* lock(); ! ZNMethodDataOops* oops() const; ! ZNMethodDataOops* swap_oops(ZNMethodDataOops* oops); }; ZNMethodData* ZNMethodData::create(nmethod* nm) { void* const method = NEW_C_HEAP_ARRAY(uint8_t, sizeof(ZNMethodData), mtGC); return ::new (method) ZNMethodData(nm); } void ZNMethodData::destroy(ZNMethodData* data) { ! ZNMethodDataOops::destroy(data->oops()); ZNMethodTable::safe_delete(data); } ZNMethodData::ZNMethodData(nmethod* nm) : _lock(), ! _oops(NULL) {} ZReentrantLock* ZNMethodData::lock() { return &_lock; } ! ZNMethodDataOops* ZNMethodData::oops() const { ! return OrderAccess::load_acquire(&_oops); } ! ZNMethodDataOops* ZNMethodData::swap_oops(ZNMethodDataOops* new_oops) { ! return Atomic::xchg(new_oops, &_oops); } static ZNMethodData* gc_data(const nmethod* nm) { return nm->gc_data<ZNMethodData>(); }
*** 174,184 **** // Iteration not in progress, delete now FREE_C_HEAP_ARRAY(uint8_t, data); } } ! ZNMethodTableEntry ZNMethodTable::create_entry(nmethod* nm) { GrowableArray<oop*> immediate_oops; bool non_immediate_oops = false; // Find all oops relocations RelocIterator iter(nm); --- 180,190 ---- // Iteration not in progress, delete now FREE_C_HEAP_ARRAY(uint8_t, data); } } ! void ZNMethodTable::attach_gc_data(nmethod* nm) { GrowableArray<oop*> immediate_oops; bool non_immediate_oops = false; // Find all oops relocations RelocIterator iter(nm);
*** 209,224 **** if (data == NULL) { data = ZNMethodData::create(nm); set_gc_data(nm, data); } ! // Attach immediate oops in GC data ! ZNMethodDataImmediateOops* const old_data_immediate_oops = data->swap_immediate_oops(immediate_oops); ! ZNMethodDataImmediateOops::destroy(old_data_immediate_oops); ! // Create entry ! return ZNMethodTableEntry(nm, non_immediate_oops, !immediate_oops.is_empty()); } ZReentrantLock* ZNMethodTable::lock_for_nmethod(nmethod* nm) { ZNMethodData* const data = gc_data(nm); if (data == NULL) { --- 215,234 ---- if (data == NULL) { data = ZNMethodData::create(nm); set_gc_data(nm, data); } ! // Attach oops in GC data ! ZNMethodDataOops* const new_oops = ZNMethodDataOops::create(immediate_oops, non_immediate_oops); ! ZNMethodDataOops* const old_oops = data->swap_oops(new_oops); ! ZNMethodDataOops::destroy(old_oops); ! } ! void ZNMethodTable::detach_gc_data(nmethod* nm) { ! // Destroy GC data ! ZNMethodData::destroy(gc_data(nm)); ! set_gc_data(nm, NULL); } ZReentrantLock* ZNMethodTable::lock_for_nmethod(nmethod* nm) { ZNMethodData* const data = gc_data(nm); if (data == NULL) {
*** 238,249 **** assert(is_power_of_2(size), "Invalid size"); const size_t mask = size - 1; return (prev_index + 1) & mask; } ! bool ZNMethodTable::register_entry(ZNMethodTableEntry* table, size_t size, ZNMethodTableEntry entry) { ! const nmethod* const nm = entry.method(); size_t index = first_index(nm, size); for (;;) { const ZNMethodTableEntry table_entry = table[index]; --- 248,259 ---- assert(is_power_of_2(size), "Invalid size"); const size_t mask = size - 1; return (prev_index + 1) & mask; } ! bool ZNMethodTable::register_entry(ZNMethodTableEntry* table, size_t size, nmethod* nm) { ! const ZNMethodTableEntry entry(nm); size_t index = first_index(nm, size); for (;;) { const ZNMethodTableEntry table_entry = table[index];
*** 262,289 **** index = next_index(index, size); } } void ZNMethodTable::unregister_entry(ZNMethodTableEntry* table, size_t size, nmethod* nm) { - if (size == 0) { - // Table is empty - return; - } - size_t index = first_index(nm, size); for (;;) { const ZNMethodTableEntry table_entry = table[index]; assert(table_entry.registered() || table_entry.unregistered(), "Entry not found"); if (table_entry.registered() && table_entry.method() == nm) { // Remove entry table[index] = ZNMethodTableEntry(true /* unregistered */); - - // Destroy GC data - ZNMethodData::destroy(gc_data(nm)); - set_gc_data(nm, NULL); return; } index = next_index(index, size); } --- 272,290 ----
*** 307,317 **** // Transfer all registered entries for (size_t i = 0; i < _size; i++) { const ZNMethodTableEntry entry = _table[i]; if (entry.registered()) { ! register_entry(new_table, new_size, entry); } } if (_iter_table != _table) { // Delete old table --- 308,318 ---- // Transfer all registered entries for (size_t i = 0; i < _size; i++) { const ZNMethodTableEntry entry = _table[i]; if (entry.registered()) { ! register_entry(new_table, new_size, entry.method()); } } if (_iter_table != _table) { // Delete old table
*** 351,375 **** rebuild(_size * 2); } } } ! void ZNMethodTable::log_register(const nmethod* nm, ZNMethodTableEntry entry) { LogTarget(Trace, gc, nmethod) log; if (!log.is_enabled()) { return; } log.print("Register NMethod: %s.%s (" PTR_FORMAT "), " "Compiler: %s, Oops: %d, ImmediateOops: " SIZE_FORMAT ", NonImmediateOops: %s", nm->method()->method_holder()->external_name(), nm->method()->name()->as_C_string(), p2i(nm), nm->compiler_name(), nm->oops_count() - 1, ! entry.immediate_oops() ? gc_data(nm)->immediate_oops()->immediate_oops_count() : 0, ! entry.non_immediate_oops() ? "Yes" : "No"); LogTarget(Trace, gc, nmethod, oops) log_oops; if (!log_oops.is_enabled()) { return; } --- 352,378 ---- rebuild(_size * 2); } } } ! void ZNMethodTable::log_register(const nmethod* nm) { LogTarget(Trace, gc, nmethod) log; if (!log.is_enabled()) { return; } + const ZNMethodDataOops* const oops = gc_data(nm)->oops(); + log.print("Register NMethod: %s.%s (" PTR_FORMAT "), " "Compiler: %s, Oops: %d, ImmediateOops: " SIZE_FORMAT ", NonImmediateOops: %s", nm->method()->method_holder()->external_name(), nm->method()->name()->as_C_string(), p2i(nm), nm->compiler_name(), nm->oops_count() - 1, ! oops->immediates_count(), ! oops->has_non_immediates() ? "Yes" : "No"); LogTarget(Trace, gc, nmethod, oops) log_oops; if (!log_oops.is_enabled()) { return; }
*** 380,401 **** for (oop* p = begin; p < end; p++) { log_oops.print(" Oop[" SIZE_FORMAT "] " PTR_FORMAT " (%s)", (p - begin), p2i(*p), (*p)->klass()->external_name()); } - if (entry.immediate_oops()) { // Print nmethod immediate oops ! const ZNMethodDataImmediateOops* const nmi = gc_data(nm)->immediate_oops(); ! if (nmi != NULL) { ! oop** const begin = nmi->immediate_oops_begin(); ! oop** const end = nmi->immediate_oops_end(); for (oop** p = begin; p < end; p++) { log_oops.print(" ImmediateOop[" SIZE_FORMAT "] " PTR_FORMAT " @ " PTR_FORMAT " (%s)", (p - begin), p2i(**p), p2i(*p), (**p)->klass()->external_name()); } } - } } void ZNMethodTable::log_unregister(const nmethod* nm) { LogTarget(Debug, gc, nmethod) log; if (!log.is_enabled()) { --- 383,401 ---- for (oop* p = begin; p < end; p++) { log_oops.print(" Oop[" SIZE_FORMAT "] " PTR_FORMAT " (%s)", (p - begin), p2i(*p), (*p)->klass()->external_name()); } // Print nmethod immediate oops ! if (oops->immediates_count() > 0) { ! oop** const begin = oops->immediates_begin(); ! oop** const end = oops->immediates_end(); for (oop** p = begin; p < end; p++) { log_oops.print(" ImmediateOop[" SIZE_FORMAT "] " PTR_FORMAT " @ " PTR_FORMAT " (%s)", (p - begin), p2i(**p), p2i(*p), (**p)->klass()->external_name()); } } } void ZNMethodTable::log_unregister(const nmethod* nm) { LogTarget(Debug, gc, nmethod) log; if (!log.is_enabled()) {
*** 421,437 **** ResourceMark rm; // Grow/Shrink/Prune table if needed rebuild_if_needed(); ! // Create entry ! const ZNMethodTableEntry entry = create_entry(nm); ! log_register(nm, entry); // Insert new entry ! if (register_entry(_table, _size, entry)) { // New entry registered. When register_entry() instead returns // false the nmethod was already in the table so we do not want // to increase number of registered entries in that case. _nregistered++; } --- 421,437 ---- ResourceMark rm; // Grow/Shrink/Prune table if needed rebuild_if_needed(); ! // Create and attach gc data ! attach_gc_data(nm); ! log_register(nm); // Insert new entry ! if (register_entry(_table, _size, nm)) { // New entry registered. When register_entry() instead returns // false the nmethod was already in the table so we do not want // to increase number of registered entries in that case. _nregistered++; }
*** 463,492 **** // Remove entry unregister_entry(_table, _size, nm); _nunregistered++; _nregistered--; } void ZNMethodTable::disarm_nmethod(nmethod* nm) { BarrierSetNMethod* const bs = BarrierSet::barrier_set()->barrier_set_nmethod(); if (bs != NULL) { bs->disarm(nm); } } ! void ZNMethodTable::nmethod_entries_do_begin() { MutexLockerEx mu(CodeCache_lock, Mutex::_no_safepoint_check_flag); // Prepare iteration _iter_table = _table; _iter_table_size = _size; _claimed = 0; assert(_iter_deferred_deletes.is_empty(), "Should be emtpy"); } ! void ZNMethodTable::nmethod_entries_do_end() { MutexLockerEx mu(CodeCache_lock, Mutex::_no_safepoint_check_flag); // Finish iteration if (_iter_table != _table) { delete [] _iter_table; --- 463,494 ---- // Remove entry unregister_entry(_table, _size, nm); _nunregistered++; _nregistered--; + + detach_gc_data(nm); } void ZNMethodTable::disarm_nmethod(nmethod* nm) { BarrierSetNMethod* const bs = BarrierSet::barrier_set()->barrier_set_nmethod(); if (bs != NULL) { bs->disarm(nm); } } ! void ZNMethodTable::nmethods_do_begin() { MutexLockerEx mu(CodeCache_lock, Mutex::_no_safepoint_check_flag); // Prepare iteration _iter_table = _table; _iter_table_size = _size; _claimed = 0; assert(_iter_deferred_deletes.is_empty(), "Should be emtpy"); } ! void ZNMethodTable::nmethods_do_end() { MutexLockerEx mu(CodeCache_lock, Mutex::_no_safepoint_check_flag); // Finish iteration if (_iter_table != _table) { delete [] _iter_table;
*** 504,565 **** // Notify iteration done CodeCache_lock->notify_all(); } ! void ZNMethodTable::entry_oops_do(ZNMethodTableEntry entry, OopClosure* cl) { ! nmethod* const nm = entry.method(); ! // Process oops table oop* const begin = nm->oops_begin(); oop* const end = nm->oops_end(); for (oop* p = begin; p < end; p++) { if (*p != Universe::non_oop_word()) { cl->do_oop(p); } } // Process immediate oops ! if (entry.immediate_oops()) { ! const ZNMethodDataImmediateOops* const nmi = gc_data(nm)->immediate_oops(); ! if (nmi != NULL) { ! oop** const begin = nmi->immediate_oops_begin(); ! oop** const end = nmi->immediate_oops_end(); for (oop** p = begin; p < end; p++) { if (**p != Universe::non_oop_word()) { cl->do_oop(*p); } } } - } // Process non-immediate oops ! if (entry.non_immediate_oops()) { ! nmethod* const nm = entry.method(); nm->fix_oop_relocations(); } } ! class ZNMethodTableEntryToOopsDo : public ZNMethodTableEntryClosure { private: OopClosure* _cl; public: ! ZNMethodTableEntryToOopsDo(OopClosure* cl) : _cl(cl) {} ! void do_nmethod_entry(ZNMethodTableEntry entry) { ! ZNMethodTable::entry_oops_do(entry, _cl); } }; void ZNMethodTable::oops_do(OopClosure* cl) { ! ZNMethodTableEntryToOopsDo entry_cl(cl); ! nmethod_entries_do(&entry_cl); } ! void ZNMethodTable::nmethod_entries_do(ZNMethodTableEntryClosure* cl) { for (;;) { // Claim table partition. Each partition is currently sized to span // two cache lines. This number is just a guess, but seems to work well. const size_t partition_size = (ZCacheLineSize * 2) / sizeof(ZNMethodTableEntry); const size_t partition_start = MIN2(Atomic::add(partition_size, &_claimed) - partition_size, _iter_table_size); --- 506,563 ---- // Notify iteration done CodeCache_lock->notify_all(); } ! void ZNMethodTable::oops_do(nmethod* nm, OopClosure* cl) { // Process oops table oop* const begin = nm->oops_begin(); oop* const end = nm->oops_end(); for (oop* p = begin; p < end; p++) { if (*p != Universe::non_oop_word()) { cl->do_oop(p); } } + ZNMethodDataOops* const oops = gc_data(nm)->oops(); + // Process immediate oops ! if (oops->immediates_count() > 0) { ! oop** const begin = oops->immediates_begin(); ! oop** const end = oops->immediates_end(); for (oop** p = begin; p < end; p++) { if (**p != Universe::non_oop_word()) { cl->do_oop(*p); } } } // Process non-immediate oops ! if (oops->has_non_immediates()) { nm->fix_oop_relocations(); } } ! class ZNMethodToOopsDo : public ZNMethodClosure { private: OopClosure* _cl; public: ! ZNMethodToOopsDo(OopClosure* cl) : _cl(cl) {} ! void do_nmethod(nmethod* nm) { ! ZNMethodTable::oops_do(nm, _cl); } }; void ZNMethodTable::oops_do(OopClosure* cl) { ! ZNMethodToOopsDo nm_cl(cl); ! nmethods_do(&nm_cl); } ! void ZNMethodTable::nmethods_do(ZNMethodClosure* cl) { for (;;) { // Claim table partition. Each partition is currently sized to span // two cache lines. This number is just a guess, but seems to work well. const size_t partition_size = (ZCacheLineSize * 2) / sizeof(ZNMethodTableEntry); const size_t partition_start = MIN2(Atomic::add(partition_size, &_claimed) - partition_size, _iter_table_size);
*** 571,587 **** // Process table partition for (size_t i = partition_start; i < partition_end; i++) { const ZNMethodTableEntry entry = _iter_table[i]; if (entry.registered()) { ! cl->do_nmethod_entry(entry); } } } } ! class ZNMethodTableUnlinkClosure : public ZNMethodTableEntryClosure { private: bool _unloading_occurred; volatile bool _failed; void set_failed() { --- 569,585 ---- // Process table partition for (size_t i = partition_start; i < partition_end; i++) { const ZNMethodTableEntry entry = _iter_table[i]; if (entry.registered()) { ! cl->do_nmethod(entry.method()); } } } } ! class ZNMethodTableUnlinkClosure : public ZNMethodClosure { private: bool _unloading_occurred; volatile bool _failed; void set_failed() {
*** 591,606 **** public: ZNMethodTableUnlinkClosure(bool unloading_occurred) : _unloading_occurred(unloading_occurred), _failed(false) {} ! virtual void do_nmethod_entry(ZNMethodTableEntry entry) { if (failed()) { return; } - nmethod* const nm = entry.method(); if (!nm->is_alive()) { return; } ZLocker<ZReentrantLock> locker(ZNMethodTable::lock_for_nmethod(nm)); --- 589,603 ---- public: ZNMethodTableUnlinkClosure(bool unloading_occurred) : _unloading_occurred(unloading_occurred), _failed(false) {} ! virtual void do_nmethod(nmethod* nm) { if (failed()) { return; } if (!nm->is_alive()) { return; } ZLocker<ZReentrantLock> locker(ZNMethodTable::lock_for_nmethod(nm));
*** 617,627 **** return; } // Heal oops and disarm ZNMethodOopClosure cl; ! ZNMethodTable::entry_oops_do(entry, &cl); ZNMethodTable::disarm_nmethod(nm); // Clear compiled ICs and exception caches if (!nm->unload_nmethod_caches(_unloading_occurred)) { set_failed(); --- 614,624 ---- return; } // Heal oops and disarm ZNMethodOopClosure cl; ! ZNMethodTable::oops_do(nm, &cl); ZNMethodTable::disarm_nmethod(nm); // Clear compiled ICs and exception caches if (!nm->unload_nmethod_caches(_unloading_occurred)) { set_failed();
*** 641,660 **** public: ZNMethodTableUnlinkTask(bool unloading_occurred, ICRefillVerifier* verifier) : ZTask("ZNMethodTableUnlinkTask"), _cl(unloading_occurred), _verifier(verifier) { ! ZNMethodTable::nmethod_entries_do_begin(); } ~ZNMethodTableUnlinkTask() { ! ZNMethodTable::nmethod_entries_do_end(); } virtual void work() { ICRefillVerifierMark mark(_verifier); ! ZNMethodTable::nmethod_entries_do(&_cl); } bool success() const { return !_cl.failed(); } --- 638,657 ---- public: ZNMethodTableUnlinkTask(bool unloading_occurred, ICRefillVerifier* verifier) : ZTask("ZNMethodTableUnlinkTask"), _cl(unloading_occurred), _verifier(verifier) { ! ZNMethodTable::nmethods_do_begin(); } ~ZNMethodTableUnlinkTask() { ! ZNMethodTable::nmethods_do_end(); } virtual void work() { ICRefillVerifierMark mark(_verifier); ! ZNMethodTable::nmethods_do(&_cl); } bool success() const { return !_cl.failed(); }
*** 678,691 **** SuspendibleThreadSetLeaver sts; InlineCacheBuffer::refill_ic_stubs(); } } ! class ZNMethodTablePurgeClosure : public ZNMethodTableEntryClosure { public: ! virtual void do_nmethod_entry(ZNMethodTableEntry entry) { ! nmethod* const nm = entry.method(); if (nm->is_alive() && nm->is_unloading()) { nm->make_unloaded(); } } }; --- 675,687 ---- SuspendibleThreadSetLeaver sts; InlineCacheBuffer::refill_ic_stubs(); } } ! class ZNMethodTablePurgeClosure : public ZNMethodClosure { public: ! virtual void do_nmethod(nmethod* nm) { if (nm->is_alive() && nm->is_unloading()) { nm->make_unloaded(); } } };
*** 696,714 **** public: ZNMethodTablePurgeTask() : ZTask("ZNMethodTablePurgeTask"), _cl() { ! ZNMethodTable::nmethod_entries_do_begin(); } ~ZNMethodTablePurgeTask() { ! ZNMethodTable::nmethod_entries_do_end(); } virtual void work() { ! ZNMethodTable::nmethod_entries_do(&_cl); } }; void ZNMethodTable::purge(ZWorkers* workers) { ZNMethodTablePurgeTask task; --- 692,710 ---- public: ZNMethodTablePurgeTask() : ZTask("ZNMethodTablePurgeTask"), _cl() { ! ZNMethodTable::nmethods_do_begin(); } ~ZNMethodTablePurgeTask() { ! ZNMethodTable::nmethods_do_end(); } virtual void work() { ! ZNMethodTable::nmethods_do(&_cl); } }; void ZNMethodTable::purge(ZWorkers* workers) { ZNMethodTablePurgeTask task;
< prev index next >