@@ -2597,6 +2597,7 @@ void G1CollectedHeap::unload_classes_and_code(const char* description, BoolObjec
25972597 GCTraceTime (Debug, gc, phases) debug (description, timer);
25982598
25992599 ClassUnloadingContext ctx (workers ()->active_workers (),
2600+ false /* unregister_nmethods_during_purge */ ,
26002601 false /* lock_codeblob_free_separately */ );
26012602 {
26022603 CodeCache::UnlinkingScope scope (is_alive);
@@ -2608,6 +2609,10 @@ void G1CollectedHeap::unload_classes_and_code(const char* description, BoolObjec
26082609 GCTraceTime (Debug, gc, phases) t (" Purge Unlinked NMethods" , timer);
26092610 ctx.purge_nmethods ();
26102611 }
2612+ {
2613+ GCTraceTime (Debug, gc, phases) ur (" Unregister NMethods" , timer);
2614+ G1CollectedHeap::heap ()->bulk_unregister_nmethods ();
2615+ }
26112616 {
26122617 GCTraceTime (Debug, gc, phases) t (" Free Code Blobs" , timer);
26132618 ctx.free_code_blobs ();
@@ -2619,6 +2624,33 @@ void G1CollectedHeap::unload_classes_and_code(const char* description, BoolObjec
26192624 }
26202625}
26212626
2627+ class G1BulkUnregisterNMethodTask : public WorkerTask {
2628+ HeapRegionClaimer _hrclaimer;
2629+
2630+ class UnregisterNMethodsHeapRegionClosure : public HeapRegionClosure {
2631+ public:
2632+
2633+ bool do_heap_region (HeapRegion* hr) {
2634+ hr->rem_set ()->bulk_remove_code_roots ();
2635+ return false ;
2636+ }
2637+ } _cl;
2638+
2639+ public:
2640+ G1BulkUnregisterNMethodTask (uint num_workers)
2641+ : WorkerTask(" G1 Remove Unlinked NMethods From Code Root Set Task" ),
2642+ _hrclaimer (num_workers) { }
2643+
2644+ void work (uint worker_id) {
2645+ G1CollectedHeap::heap ()->heap_region_par_iterate_from_worker_offset (&_cl, &_hrclaimer, worker_id);
2646+ }
2647+ };
2648+
2649+ void G1CollectedHeap::bulk_unregister_nmethods () {
2650+ uint num_workers = workers ()->active_workers ();
2651+ G1BulkUnregisterNMethodTask t (num_workers);
2652+ workers ()->run_task (&t);
2653+ }
26222654
26232655bool G1STWSubjectToDiscoveryClosure::do_object_b (oop obj) {
26242656 assert (obj != nullptr , " must not be null" );
@@ -3039,41 +3071,15 @@ class RegisterNMethodOopClosure: public OopClosure {
30393071 void do_oop (narrowOop* p) { ShouldNotReachHere (); }
30403072};
30413073
3042- class UnregisterNMethodOopClosure : public OopClosure {
3043- G1CollectedHeap* _g1h;
3044- nmethod* _nm;
3045-
3046- public:
3047- UnregisterNMethodOopClosure (G1CollectedHeap* g1h, nmethod* nm) :
3048- _g1h (g1h), _nm(nm) {}
3049-
3050- void do_oop (oop* p) {
3051- oop heap_oop = RawAccess<>::oop_load (p);
3052- if (!CompressedOops::is_null (heap_oop)) {
3053- oop obj = CompressedOops::decode_not_null (heap_oop);
3054- HeapRegion* hr = _g1h->heap_region_containing (obj);
3055- assert (!hr->is_continues_humongous (),
3056- " trying to remove code root " PTR_FORMAT " in continuation of humongous region " HR_FORMAT
3057- " starting at " HR_FORMAT,
3058- p2i (_nm), HR_FORMAT_PARAMS (hr), HR_FORMAT_PARAMS (hr->humongous_start_region ()));
3059-
3060- hr->remove_code_root (_nm);
3061- }
3062- }
3063-
3064- void do_oop (narrowOop* p) { ShouldNotReachHere (); }
3065- };
3066-
30673074void G1CollectedHeap::register_nmethod (nmethod* nm) {
30683075 guarantee (nm != nullptr , " sanity" );
30693076 RegisterNMethodOopClosure reg_cl (this , nm);
30703077 nm->oops_do (®_cl);
30713078}
30723079
30733080void G1CollectedHeap::unregister_nmethod (nmethod* nm) {
3074- guarantee (nm != nullptr , " sanity" );
3075- UnregisterNMethodOopClosure reg_cl (this , nm);
3076- nm->oops_do (®_cl, true );
3081+ // We always unregister nmethods in bulk during code unloading only.
3082+ ShouldNotReachHere ();
30773083}
30783084
30793085void G1CollectedHeap::update_used_after_gc (bool evacuation_failed) {
0 commit comments