@@ -2517,6 +2517,7 @@ void G1CollectedHeap::unload_classes_and_code(const char* description, BoolObjec
2517
2517
GCTraceTime (Debug, gc, phases) debug (description, timer);
2518
2518
2519
2519
ClassUnloadingContext ctx (workers ()->active_workers (),
2520
+ false /* unregister_nmethods_during_purge */ ,
2520
2521
false /* lock_codeblob_free_separately */ );
2521
2522
{
2522
2523
CodeCache::UnlinkingScope scope (is_alive);
@@ -2528,6 +2529,10 @@ void G1CollectedHeap::unload_classes_and_code(const char* description, BoolObjec
2528
2529
GCTraceTime (Debug, gc, phases) t (" Purge Unlinked NMethods" , timer);
2529
2530
ctx.purge_nmethods ();
2530
2531
}
2532
+ {
2533
+ GCTraceTime (Debug, gc, phases) ur (" Unregister NMethods" , timer);
2534
+ G1CollectedHeap::heap ()->bulk_unregister_nmethods ();
2535
+ }
2531
2536
{
2532
2537
GCTraceTime (Debug, gc, phases) t (" Free Code Blobs" , timer);
2533
2538
ctx.free_code_blobs ();
@@ -2539,6 +2544,33 @@ void G1CollectedHeap::unload_classes_and_code(const char* description, BoolObjec
2539
2544
}
2540
2545
}
2541
2546
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
+ }
2542
2574
2543
2575
bool G1STWSubjectToDiscoveryClosure::do_object_b (oop obj) {
2544
2576
assert (obj != nullptr , " must not be null" );
@@ -2963,41 +2995,15 @@ class RegisterNMethodOopClosure: public OopClosure {
2963
2995
void do_oop (narrowOop* p) { ShouldNotReachHere (); }
2964
2996
};
2965
2997
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
-
2991
2998
void G1CollectedHeap::register_nmethod (nmethod* nm) {
2992
2999
guarantee (nm != nullptr , " sanity" );
2993
3000
RegisterNMethodOopClosure reg_cl (this , nm);
2994
3001
nm->oops_do (®_cl);
2995
3002
}
2996
3003
2997
3004
void 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 ();
3001
3007
}
3002
3008
3003
3009
void G1CollectedHeap::update_used_after_gc (bool evacuation_failed) {
0 commit comments