< prev index next >

src/hotspot/share/gc/g1/g1CollectedHeap.cpp

Print this page




3605 
3606       for (int i = 0; i < num_claimed_nmethods; i++) {
3607         clean_nmethod(claimed_nmethods[i]);
3608       }
3609     }
3610   }
3611 
3612   void work_second_pass(uint worker_id) {
3613     CompiledMethod* nm;
3614     // Take care of postponed nmethods.
3615     while ((nm = claim_postponed_nmethod()) != NULL) {
3616       clean_nmethod_postponed(nm);
3617     }
3618   }
3619 };
3620 
3621 Monitor* G1CodeCacheUnloadingTask::_lock = new Monitor(Mutex::leaf, "Code Cache Unload lock", false, Monitor::_safepoint_check_never);
3622 
3623 class G1KlassCleaningTask : public StackObj {
3624   BoolObjectClosure*                      _is_alive;
3625   volatile jint                           _clean_klass_tree_claimed;
3626   ClassLoaderDataGraphKlassIteratorAtomic _klass_iterator;
3627 
3628  public:
3629   G1KlassCleaningTask(BoolObjectClosure* is_alive) :
3630       _is_alive(is_alive),
3631       _clean_klass_tree_claimed(0),
3632       _klass_iterator() {
3633   }
3634 
3635  private:
3636   bool claim_clean_klass_tree_task() {
3637     if (_clean_klass_tree_claimed) {
3638       return false;
3639     }
3640 
3641     return Atomic::cmpxchg(1, (jint*)&_clean_klass_tree_claimed, 0) == 0;
3642   }
3643 
3644   InstanceKlass* claim_next_klass() {
3645     Klass* klass;
3646     do {
3647       klass =_klass_iterator.next_klass();
3648     } while (klass != NULL && !klass->is_instance_klass());
3649 
3650     // this can be null so don't call InstanceKlass::cast
3651     return static_cast<InstanceKlass*>(klass);
3652   }
3653 
3654 public:
3655 
3656   void clean_klass(InstanceKlass* ik) {
3657     ik->clean_weak_instanceklass_links(_is_alive);
3658   }
3659 
3660   void work() {
3661     ResourceMark rm;
3662 
3663     // One worker will clean the subklass/sibling klass tree.
3664     if (claim_clean_klass_tree_task()) {
3665       Klass::clean_subklass_tree(_is_alive);
3666     }
3667 
3668     // All workers will help cleaning the classes,
3669     InstanceKlass* klass;
3670     while ((klass = claim_next_klass()) != NULL) {
3671       clean_klass(klass);
3672     }
3673   }
3674 };
3675 
3676 class G1ResolvedMethodCleaningTask : public StackObj {
3677   BoolObjectClosure* _is_alive;
3678   volatile jint      _resolved_method_task_claimed;
3679 public:
3680   G1ResolvedMethodCleaningTask(BoolObjectClosure* is_alive) :
3681       _is_alive(is_alive), _resolved_method_task_claimed(0) {}
3682 
3683   bool claim_resolved_method_task() {
3684     if (_resolved_method_task_claimed) {
3685       return false;
3686     }
3687     return Atomic::cmpxchg(1, (jint*)&_resolved_method_task_claimed, 0) == 0;
3688   }
3689 
3690   // These aren't big, one thread can do it all.
3691   void work() {
3692     if (claim_resolved_method_task()) {
3693       ResolvedMethodTable::unlink(_is_alive);
3694     }
3695   }
3696 };
3697 
3698 
3699 // To minimize the remark pause times, the tasks below are done in parallel.
3700 class G1ParallelCleaningTask : public AbstractGangTask {
3701 private:
3702   G1StringAndSymbolCleaningTask _string_symbol_task;
3703   G1CodeCacheUnloadingTask      _code_cache_task;
3704   G1KlassCleaningTask           _klass_cleaning_task;
3705   G1ResolvedMethodCleaningTask  _resolved_method_cleaning_task;
3706 
3707 public:




3605 
3606       for (int i = 0; i < num_claimed_nmethods; i++) {
3607         clean_nmethod(claimed_nmethods[i]);
3608       }
3609     }
3610   }
3611 
3612   void work_second_pass(uint worker_id) {
3613     CompiledMethod* nm;
3614     // Take care of postponed nmethods.
3615     while ((nm = claim_postponed_nmethod()) != NULL) {
3616       clean_nmethod_postponed(nm);
3617     }
3618   }
3619 };
3620 
3621 Monitor* G1CodeCacheUnloadingTask::_lock = new Monitor(Mutex::leaf, "Code Cache Unload lock", false, Monitor::_safepoint_check_never);
3622 
3623 class G1KlassCleaningTask : public StackObj {
3624   BoolObjectClosure*                      _is_alive;
3625   volatile int                            _clean_klass_tree_claimed;
3626   ClassLoaderDataGraphKlassIteratorAtomic _klass_iterator;
3627 
3628  public:
3629   G1KlassCleaningTask(BoolObjectClosure* is_alive) :
3630       _is_alive(is_alive),
3631       _clean_klass_tree_claimed(0),
3632       _klass_iterator() {
3633   }
3634 
3635  private:
3636   bool claim_clean_klass_tree_task() {
3637     if (_clean_klass_tree_claimed) {
3638       return false;
3639     }
3640 
3641     return Atomic::cmpxchg(1, &_clean_klass_tree_claimed, 0) == 0;
3642   }
3643 
3644   InstanceKlass* claim_next_klass() {
3645     Klass* klass;
3646     do {
3647       klass =_klass_iterator.next_klass();
3648     } while (klass != NULL && !klass->is_instance_klass());
3649 
3650     // this can be null so don't call InstanceKlass::cast
3651     return static_cast<InstanceKlass*>(klass);
3652   }
3653 
3654 public:
3655 
3656   void clean_klass(InstanceKlass* ik) {
3657     ik->clean_weak_instanceklass_links(_is_alive);
3658   }
3659 
3660   void work() {
3661     ResourceMark rm;
3662 
3663     // One worker will clean the subklass/sibling klass tree.
3664     if (claim_clean_klass_tree_task()) {
3665       Klass::clean_subklass_tree(_is_alive);
3666     }
3667 
3668     // All workers will help cleaning the classes,
3669     InstanceKlass* klass;
3670     while ((klass = claim_next_klass()) != NULL) {
3671       clean_klass(klass);
3672     }
3673   }
3674 };
3675 
3676 class G1ResolvedMethodCleaningTask : public StackObj {
3677   BoolObjectClosure* _is_alive;
3678   volatile int       _resolved_method_task_claimed;
3679 public:
3680   G1ResolvedMethodCleaningTask(BoolObjectClosure* is_alive) :
3681       _is_alive(is_alive), _resolved_method_task_claimed(0) {}
3682 
3683   bool claim_resolved_method_task() {
3684     if (_resolved_method_task_claimed) {
3685       return false;
3686     }
3687     return Atomic::cmpxchg(1, &_resolved_method_task_claimed, 0) == 0;
3688   }
3689 
3690   // These aren't big, one thread can do it all.
3691   void work() {
3692     if (claim_resolved_method_task()) {
3693       ResolvedMethodTable::unlink(_is_alive);
3694     }
3695   }
3696 };
3697 
3698 
3699 // To minimize the remark pause times, the tasks below are done in parallel.
3700 class G1ParallelCleaningTask : public AbstractGangTask {
3701 private:
3702   G1StringAndSymbolCleaningTask _string_symbol_task;
3703   G1CodeCacheUnloadingTask      _code_cache_task;
3704   G1KlassCleaningTask           _klass_cleaning_task;
3705   G1ResolvedMethodCleaningTask  _resolved_method_cleaning_task;
3706 
3707 public:


< prev index next >