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: |