262 |
262 |
263 index = next_index(index, size); |
263 index = next_index(index, size); |
264 } |
264 } |
265 } |
265 } |
266 |
266 |
267 bool ZNMethodTable::unregister_entry(ZNMethodTableEntry* table, size_t size, nmethod* nm) { |
267 void ZNMethodTable::unregister_entry(ZNMethodTableEntry* table, size_t size, nmethod* nm) { |
268 if (size == 0) { |
268 if (size == 0) { |
269 // Table is empty |
269 // Table is empty |
270 return false; |
270 return; |
271 } |
271 } |
272 |
272 |
273 size_t index = first_index(nm, size); |
273 size_t index = first_index(nm, size); |
274 |
274 |
275 for (;;) { |
275 for (;;) { |
276 const ZNMethodTableEntry table_entry = table[index]; |
276 const ZNMethodTableEntry table_entry = table[index]; |
277 |
277 assert(table_entry.registered() || table_entry.unregistered(), "Entry not found"); |
278 if (!table_entry.registered() && !table_entry.unregistered()) { |
|
279 // Entry not found |
|
280 return false; |
|
281 } |
|
282 |
278 |
283 if (table_entry.registered() && table_entry.method() == nm) { |
279 if (table_entry.registered() && table_entry.method() == nm) { |
284 // Remove entry |
280 // Remove entry |
285 table[index] = ZNMethodTableEntry(true /* unregistered */); |
281 table[index] = ZNMethodTableEntry(true /* unregistered */); |
286 |
282 |
287 // Destroy GC data |
283 // Destroy GC data |
288 ZNMethodData::destroy(gc_data(nm)); |
284 ZNMethodData::destroy(gc_data(nm)); |
289 set_gc_data(nm, NULL); |
285 set_gc_data(nm, NULL); |
290 return true; |
286 return; |
291 } |
287 } |
292 |
288 |
293 index = next_index(index, size); |
289 index = next_index(index, size); |
294 } |
290 } |
295 } |
291 } |
449 // before it can unregister an nmethod. |
445 // before it can unregister an nmethod. |
450 if (!Thread::current()->is_Code_cache_sweeper_thread()) { |
446 if (!Thread::current()->is_Code_cache_sweeper_thread()) { |
451 return; |
447 return; |
452 } |
448 } |
453 |
449 |
454 assert(CodeCache_lock->owned_by_self(), "Lock must be held"); |
|
455 |
|
456 while (_iter_table != NULL) { |
450 while (_iter_table != NULL) { |
457 MutexUnlockerEx mu(CodeCache_lock, Mutex::_no_safepoint_check_flag); |
451 MutexUnlockerEx mu(CodeCache_lock, Mutex::_no_safepoint_check_flag); |
458 os::naked_short_sleep(1); |
452 os::naked_short_sleep(1); |
459 } |
453 } |
460 } |
454 } |
461 |
455 |
462 void ZNMethodTable::unregister_nmethod(nmethod* nm) { |
456 void ZNMethodTable::unregister_nmethod(nmethod* nm) { |
|
457 assert(CodeCache_lock->owned_by_self(), "Lock must be held"); |
463 ResourceMark rm; |
458 ResourceMark rm; |
464 |
459 |
465 sweeper_wait_for_iteration(); |
460 sweeper_wait_for_iteration(); |
466 |
461 |
467 log_unregister(nm); |
462 log_unregister(nm); |
468 |
463 |
469 // Remove entry |
464 // Remove entry |
470 if (unregister_entry(_table, _size, nm)) { |
465 unregister_entry(_table, _size, nm); |
471 // Entry was unregistered. When unregister_entry() instead returns |
466 _nunregistered++; |
472 // false the nmethod was not in the table (because it didn't have |
467 _nregistered--; |
473 // any oops) so we do not want to decrease the number of registered |
|
474 // entries in that case. |
|
475 _nregistered--; |
|
476 _nunregistered++; |
|
477 } |
|
478 } |
468 } |
479 |
469 |
480 void ZNMethodTable::disarm_nmethod(nmethod* nm) { |
470 void ZNMethodTable::disarm_nmethod(nmethod* nm) { |
481 BarrierSetNMethod* const bs = BarrierSet::barrier_set()->barrier_set_nmethod(); |
471 BarrierSetNMethod* const bs = BarrierSet::barrier_set()->barrier_set_nmethod(); |
482 if (bs != NULL) { |
472 if (bs != NULL) { |