@@ -2517,6 +2517,7 @@ void G1CollectedHeap::unload_classes_and_code(const char* description, BoolObjec
25172517 GCTraceTime (Debug, gc, phases) debug (description, timer);
25182518
25192519 ClassUnloadingContext ctx (workers ()->active_workers (),
2520+ false /* unregister_nmethods_during_purge */ ,
25202521 false /* lock_codeblob_free_separately */ );
25212522 {
25222523 CodeCache::UnlinkingScope scope (is_alive);
@@ -2528,6 +2529,10 @@ void G1CollectedHeap::unload_classes_and_code(const char* description, BoolObjec
25282529 GCTraceTime (Debug, gc, phases) t (" Purge Unlinked NMethods" , timer);
25292530 ctx.purge_nmethods ();
25302531 }
2532+ {
2533+ GCTraceTime (Debug, gc, phases) ur (" Unregister NMethods" , timer);
2534+ G1CollectedHeap::heap ()->bulk_unregister_nmethods ();
2535+ }
25312536 {
25322537 GCTraceTime (Debug, gc, phases) t (" Free Code Blobs" , timer);
25332538 ctx.free_code_blobs ();
@@ -2539,6 +2544,33 @@ void G1CollectedHeap::unload_classes_and_code(const char* description, BoolObjec
25392544 }
25402545}
25412546
2547+ class G1BulkUnregisterNMethodTask : public WorkerTask {
2548+ HeapRegionClaimer _hrclaimer;
2549+
2550+ class UnregisterNMethodsHeapRegionClosure : public HeapRegionClosure {
2551+ public:
2552+
2553+ bool do_heap_region (HeapRegion* hr) {
2554+ hr->rem_set ()->bulk_remove_code_roots ();
2555+ return false ;
2556+ }
2557+ } _cl;
2558+
2559+ public:
2560+ G1BulkUnregisterNMethodTask (uint num_workers)
2561+ : WorkerTask(" G1 Remove Unlinked NMethods From Code Root Set Task" ),
2562+ _hrclaimer (num_workers) { }
2563+
2564+ void work (uint worker_id) {
2565+ G1CollectedHeap::heap ()->heap_region_par_iterate_from_worker_offset (&_cl, &_hrclaimer, worker_id);
2566+ }
2567+ };
2568+
2569+ void G1CollectedHeap::bulk_unregister_nmethods () {
2570+ uint num_workers = workers ()->active_workers ();
2571+ G1BulkUnregisterNMethodTask t (num_workers);
2572+ workers ()->run_task (&t);
2573+ }
25422574
25432575bool G1STWSubjectToDiscoveryClosure::do_object_b (oop obj) {
25442576 assert (obj != nullptr , " must not be null" );
@@ -2963,41 +2995,15 @@ class RegisterNMethodOopClosure: public OopClosure {
29632995 void do_oop (narrowOop* p) { ShouldNotReachHere (); }
29642996};
29652997
2966- class UnregisterNMethodOopClosure : public OopClosure {
2967- G1CollectedHeap* _g1h;
2968- nmethod* _nm;
2969-
2970- public:
2971- UnregisterNMethodOopClosure (G1CollectedHeap* g1h, nmethod* nm) :
2972- _g1h (g1h), _nm(nm) {}
2973-
2974- void do_oop (oop* p) {
2975- oop heap_oop = RawAccess<>::oop_load (p);
2976- if (!CompressedOops::is_null (heap_oop)) {
2977- oop obj = CompressedOops::decode_not_null (heap_oop);
2978- HeapRegion* hr = _g1h->heap_region_containing (obj);
2979- assert (!hr->is_continues_humongous (),
2980- " trying to remove code root " PTR_FORMAT " in continuation of humongous region " HR_FORMAT
2981- " starting at " HR_FORMAT,
2982- p2i (_nm), HR_FORMAT_PARAMS (hr), HR_FORMAT_PARAMS (hr->humongous_start_region ()));
2983-
2984- hr->remove_code_root (_nm);
2985- }
2986- }
2987-
2988- void do_oop (narrowOop* p) { ShouldNotReachHere (); }
2989- };
2990-
29912998void G1CollectedHeap::register_nmethod (nmethod* nm) {
29922999 guarantee (nm != nullptr , " sanity" );
29933000 RegisterNMethodOopClosure reg_cl (this , nm);
29943001 nm->oops_do (®_cl);
29953002}
29963003
29973004void G1CollectedHeap::unregister_nmethod (nmethod* nm) {
2998- guarantee (nm != nullptr , " sanity" );
2999- UnregisterNMethodOopClosure reg_cl (this , nm);
3000- nm->oops_do (®_cl, true );
3005+ // We always unregister nmethods in bulk during code unloading only.
3006+ ShouldNotReachHere ();
30013007}
30023008
30033009void G1CollectedHeap::update_used_after_gc (bool evacuation_failed) {
0 commit comments