3515 3516 bool claim_resolved_method_task() { 3517 if (_resolved_method_task_claimed) { 3518 return false; 3519 } 3520 return Atomic::cmpxchg(1, &_resolved_method_task_claimed, 0) == 0; 3521 } 3522 3523 // These aren't big, one thread can do it all. 3524 void work() { 3525 if (claim_resolved_method_task()) { 3526 ResolvedMethodTable::unlink(); 3527 } 3528 } 3529 }; 3530 3531 3532 // To minimize the remark pause times, the tasks below are done in parallel. 3533 class G1ParallelCleaningTask : public AbstractGangTask { 3534 private: 3535 G1StringAndSymbolCleaningTask _string_symbol_task; 3536 G1CodeCacheUnloadingTask _code_cache_task; 3537 G1KlassCleaningTask _klass_cleaning_task; 3538 G1ResolvedMethodCleaningTask _resolved_method_cleaning_task; 3539 3540 public: 3541 // The constructor is run in the VMThread. 3542 G1ParallelCleaningTask(BoolObjectClosure* is_alive, uint num_workers, bool unloading_occurred) : 3543 AbstractGangTask("Parallel Cleaning"), 3544 _string_symbol_task(is_alive, true, true, G1StringDedup::is_enabled()), 3545 _code_cache_task(num_workers, is_alive, unloading_occurred), 3546 _klass_cleaning_task(), 3547 _resolved_method_cleaning_task() { 3548 } 3549 3550 // The parallel work done by all worker threads. 3551 void work(uint worker_id) { 3552 // Do first pass of code cache cleaning. 3553 _code_cache_task.work_first_pass(worker_id); 3554 3555 // Let the threads mark that the first pass is done. 3556 _code_cache_task.barrier_mark(worker_id); 3557 3558 // Clean the Strings and Symbols. 3559 _string_symbol_task.work(worker_id); 3560 3561 // Clean unreferenced things in the ResolvedMethodTable 3562 _resolved_method_cleaning_task.work(); 3563 3564 // Wait for all workers to finish the first code cache cleaning pass. 3565 _code_cache_task.barrier_wait(worker_id); 3566 3567 // Do the second code cache cleaning work, which realize on 3568 // the liveness information gathered during the first pass. 3569 _code_cache_task.work_second_pass(worker_id); 3570 3571 // Clean all klasses that were not unloaded. 3572 _klass_cleaning_task.work(); 3573 } 3574 }; 3575 3576 3577 void G1CollectedHeap::complete_cleaning(BoolObjectClosure* is_alive, 3578 bool class_unloading_occurred) { 3579 uint n_workers = workers()->active_workers(); 3580 3581 G1ParallelCleaningTask g1_unlink_task(is_alive, n_workers, class_unloading_occurred); 3582 workers()->run_task(&g1_unlink_task); 3583 } 3584 3585 void G1CollectedHeap::partial_cleaning(BoolObjectClosure* is_alive, 3586 bool process_strings, 3587 bool process_symbols, 3588 bool process_string_dedup) { 3589 if (!process_strings && !process_symbols && !process_string_dedup) { 3590 // Nothing to clean. 3591 return; 3592 } | 3515 3516 bool claim_resolved_method_task() { 3517 if (_resolved_method_task_claimed) { 3518 return false; 3519 } 3520 return Atomic::cmpxchg(1, &_resolved_method_task_claimed, 0) == 0; 3521 } 3522 3523 // These aren't big, one thread can do it all. 3524 void work() { 3525 if (claim_resolved_method_task()) { 3526 ResolvedMethodTable::unlink(); 3527 } 3528 } 3529 }; 3530 3531 3532 // To minimize the remark pause times, the tasks below are done in parallel. 3533 class G1ParallelCleaningTask : public AbstractGangTask { 3534 private: 3535 bool _unloading_occurred; 3536 G1StringAndSymbolCleaningTask _string_symbol_task; 3537 G1CodeCacheUnloadingTask _code_cache_task; 3538 G1KlassCleaningTask _klass_cleaning_task; 3539 G1ResolvedMethodCleaningTask _resolved_method_cleaning_task; 3540 3541 public: 3542 // The constructor is run in the VMThread. 3543 G1ParallelCleaningTask(BoolObjectClosure* is_alive, uint num_workers, bool unloading_occurred) : 3544 AbstractGangTask("Parallel Cleaning"), 3545 _string_symbol_task(is_alive, true, true, G1StringDedup::is_enabled()), 3546 _code_cache_task(num_workers, is_alive, unloading_occurred), 3547 _klass_cleaning_task(), 3548 _unloading_occurred(unloading_occurred), 3549 _resolved_method_cleaning_task() { 3550 } 3551 3552 // The parallel work done by all worker threads. 3553 void work(uint worker_id) { 3554 // Do first pass of code cache cleaning. 3555 _code_cache_task.work_first_pass(worker_id); 3556 3557 // Let the threads mark that the first pass is done. 3558 _code_cache_task.barrier_mark(worker_id); 3559 3560 // Clean the Strings and Symbols. 3561 _string_symbol_task.work(worker_id); 3562 3563 // Clean unreferenced things in the ResolvedMethodTable 3564 _resolved_method_cleaning_task.work(); 3565 3566 // Wait for all workers to finish the first code cache cleaning pass. 3567 _code_cache_task.barrier_wait(worker_id); 3568 3569 // Do the second code cache cleaning work, which realize on 3570 // the liveness information gathered during the first pass. 3571 _code_cache_task.work_second_pass(worker_id); 3572 3573 // Clean all klasses that were not unloaded. 3574 // The weak metadata in klass doesn't need to be 3575 // processed if there was no unloading. 3576 if (_unloading_occurred) { 3577 _klass_cleaning_task.work(); 3578 } 3579 } 3580 }; 3581 3582 3583 void G1CollectedHeap::complete_cleaning(BoolObjectClosure* is_alive, 3584 bool class_unloading_occurred) { 3585 uint n_workers = workers()->active_workers(); 3586 3587 G1ParallelCleaningTask g1_unlink_task(is_alive, n_workers, class_unloading_occurred); 3588 workers()->run_task(&g1_unlink_task); 3589 } 3590 3591 void G1CollectedHeap::partial_cleaning(BoolObjectClosure* is_alive, 3592 bool process_strings, 3593 bool process_symbols, 3594 bool process_string_dedup) { 3595 if (!process_strings && !process_symbols && !process_string_dedup) { 3596 // Nothing to clean. 3597 return; 3598 } |