< prev index next >

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

Print this page
rev 12505 : 8171235: Move archive object code from G1MarkSweep into G1ArchiveAllocator
Reviewed-by: tschatzl, kbarrett
rev 12506 : 8171238: Unify cleanup code used in G1 Remark and Full GC marking
Reviewed-by:
rev 12507 : [mq]: 8171238-rev-tsch


3511 }
3512 
3513 void G1CollectedHeap::print_termination_stats(uint worker_id,
3514                                               double elapsed_ms,
3515                                               double strong_roots_ms,
3516                                               double term_ms,
3517                                               size_t term_attempts,
3518                                               size_t alloc_buffer_waste,
3519                                               size_t undo_waste) const {
3520   log_debug(gc, task, stats)
3521               ("%3d %9.2f %9.2f %6.2f "
3522                "%9.2f %6.2f " SIZE_FORMAT_W(8) " "
3523                SIZE_FORMAT_W(7) " " SIZE_FORMAT_W(7) " " SIZE_FORMAT_W(7),
3524                worker_id, elapsed_ms, strong_roots_ms, strong_roots_ms * 100 / elapsed_ms,
3525                term_ms, term_ms * 100 / elapsed_ms, term_attempts,
3526                (alloc_buffer_waste + undo_waste) * HeapWordSize / K,
3527                alloc_buffer_waste * HeapWordSize / K,
3528                undo_waste * HeapWordSize / K);
3529 }
3530 
3531 class G1StringSymbolTableUnlinkTask : public AbstractGangTask {
3532 private:
3533   BoolObjectClosure* _is_alive;
3534   G1StringDedupUnlinkOrOopsDoClosure _dedup_closure;
3535 
3536   int _initial_string_table_size;
3537   int _initial_symbol_table_size;
3538 
3539   bool  _process_strings;
3540   int _strings_processed;
3541   int _strings_removed;
3542 
3543   bool  _process_symbols;
3544   int _symbols_processed;
3545   int _symbols_removed;
3546 
3547   bool _process_string_dedup;
3548 
3549 public:
3550   G1StringSymbolTableUnlinkTask(BoolObjectClosure* is_alive, bool process_strings, bool process_symbols, bool process_string_dedup) :
3551     AbstractGangTask("String/Symbol Unlinking"),
3552     _is_alive(is_alive),
3553     _dedup_closure(is_alive, NULL, false),
3554     _process_strings(process_strings), _strings_processed(0), _strings_removed(0),
3555     _process_symbols(process_symbols), _symbols_processed(0), _symbols_removed(0),
3556     _process_string_dedup(process_string_dedup) {
3557 
3558     _initial_string_table_size = StringTable::the_table()->table_size();
3559     _initial_symbol_table_size = SymbolTable::the_table()->table_size();
3560     if (process_strings) {
3561       StringTable::clear_parallel_claimed_index();
3562     }
3563     if (process_symbols) {
3564       SymbolTable::clear_parallel_claimed_index();
3565     }
3566   }
3567 
3568   ~G1StringSymbolTableUnlinkTask() {
3569     guarantee(!_process_strings || StringTable::parallel_claimed_index() >= _initial_string_table_size,
3570               "claim value %d after unlink less than initial string table size %d",
3571               StringTable::parallel_claimed_index(), _initial_string_table_size);
3572     guarantee(!_process_symbols || SymbolTable::parallel_claimed_index() >= _initial_symbol_table_size,
3573               "claim value %d after unlink less than initial symbol table size %d",
3574               SymbolTable::parallel_claimed_index(), _initial_symbol_table_size);
3575 
3576     log_info(gc, stringtable)(
3577         "Cleaned string and symbol table, "
3578         "strings: " SIZE_FORMAT " processed, " SIZE_FORMAT " removed, "
3579         "symbols: " SIZE_FORMAT " processed, " SIZE_FORMAT " removed",
3580         strings_processed(), strings_removed(),
3581         symbols_processed(), symbols_removed());
3582   }
3583 
3584   void work(uint worker_id) {
3585     int strings_processed = 0;
3586     int strings_removed = 0;
3587     int symbols_processed = 0;
3588     int symbols_removed = 0;


3817 
3818   void work() {
3819     ResourceMark rm;
3820 
3821     // One worker will clean the subklass/sibling klass tree.
3822     if (claim_clean_klass_tree_task()) {
3823       Klass::clean_subklass_tree(_is_alive);
3824     }
3825 
3826     // All workers will help cleaning the classes,
3827     InstanceKlass* klass;
3828     while ((klass = claim_next_klass()) != NULL) {
3829       clean_klass(klass);
3830     }
3831   }
3832 };
3833 
3834 // To minimize the remark pause times, the tasks below are done in parallel.
3835 class G1ParallelCleaningTask : public AbstractGangTask {
3836 private:
3837   G1StringSymbolTableUnlinkTask _string_symbol_task;
3838   G1CodeCacheUnloadingTask      _code_cache_task;
3839   G1KlassCleaningTask           _klass_cleaning_task;
3840 
3841 public:
3842   // The constructor is run in the VMThread.
3843   G1ParallelCleaningTask(BoolObjectClosure* is_alive, uint num_workers, bool unloading_occurred) :
3844       AbstractGangTask("Parallel Cleaning"),
3845       _string_symbol_task(is_alive, true, true, G1StringDedup::is_enabled()),
3846       _code_cache_task(num_workers, is_alive, unloading_occurred),
3847       _klass_cleaning_task(is_alive) {
3848   }
3849 
3850   // The parallel work done by all worker threads.
3851   void work(uint worker_id) {
3852     // Do first pass of code cache cleaning.
3853     _code_cache_task.work_first_pass(worker_id);
3854 
3855     // Let the threads mark that the first pass is done.
3856     _code_cache_task.barrier_mark(worker_id);
3857 
3858     // Clean the Strings and Symbols.
3859     _string_symbol_task.work(worker_id);
3860 
3861     // Wait for all workers to finish the first code cache cleaning pass.
3862     _code_cache_task.barrier_wait(worker_id);
3863 
3864     // Do the second code cache cleaning work, which realize on
3865     // the liveness information gathered during the first pass.
3866     _code_cache_task.work_second_pass(worker_id);
3867 
3868     // Clean all klasses that were not unloaded.
3869     _klass_cleaning_task.work();
3870   }
3871 };
3872 
3873 
3874 void G1CollectedHeap::full_cleaning(BoolObjectClosure* is_alive,
3875                                     bool class_unloading_occurred) {
3876   uint n_workers = workers()->active_workers();
3877 
3878   G1ParallelCleaningTask g1_unlink_task(is_alive, n_workers, class_unloading_occurred);
3879   workers()->run_task(&g1_unlink_task);
3880 }
3881 
3882 void G1CollectedHeap::partial_cleaning(BoolObjectClosure* is_alive,
3883                                        bool process_strings,
3884                                        bool process_symbols,
3885                                        bool process_string_dedup) {
3886   if (!process_strings && !process_symbols && !process_string_dedup) {
3887     // Nothing to clean.
3888     return;
3889   }
3890 
3891   G1StringSymbolTableUnlinkTask g1_unlink_task(is_alive, process_strings, process_symbols, process_string_dedup);
3892   workers()->run_task(&g1_unlink_task);
3893 
3894 }
3895 
3896 class G1RedirtyLoggedCardsTask : public AbstractGangTask {
3897  private:
3898   DirtyCardQueueSet* _queue;
3899   G1CollectedHeap* _g1h;
3900  public:
3901   G1RedirtyLoggedCardsTask(DirtyCardQueueSet* queue, G1CollectedHeap* g1h) : AbstractGangTask("Redirty Cards"),
3902     _queue(queue), _g1h(g1h) { }
3903 
3904   virtual void work(uint worker_id) {
3905     G1GCPhaseTimes* phase_times = _g1h->g1_policy()->phase_times();
3906     G1GCParPhaseTimesTracker x(phase_times, G1GCPhaseTimes::RedirtyCards, worker_id);
3907 
3908     RedirtyLoggedCardTableEntryClosure cl(_g1h);
3909     _queue->par_apply_closure_to_all_completed_buffers(&cl);
3910 
3911     phase_times->record_thread_work_item(G1GCPhaseTimes::RedirtyCards, worker_id, cl.num_dirtied());




3511 }
3512 
3513 void G1CollectedHeap::print_termination_stats(uint worker_id,
3514                                               double elapsed_ms,
3515                                               double strong_roots_ms,
3516                                               double term_ms,
3517                                               size_t term_attempts,
3518                                               size_t alloc_buffer_waste,
3519                                               size_t undo_waste) const {
3520   log_debug(gc, task, stats)
3521               ("%3d %9.2f %9.2f %6.2f "
3522                "%9.2f %6.2f " SIZE_FORMAT_W(8) " "
3523                SIZE_FORMAT_W(7) " " SIZE_FORMAT_W(7) " " SIZE_FORMAT_W(7),
3524                worker_id, elapsed_ms, strong_roots_ms, strong_roots_ms * 100 / elapsed_ms,
3525                term_ms, term_ms * 100 / elapsed_ms, term_attempts,
3526                (alloc_buffer_waste + undo_waste) * HeapWordSize / K,
3527                alloc_buffer_waste * HeapWordSize / K,
3528                undo_waste * HeapWordSize / K);
3529 }
3530 
3531 class G1StringAndSymbolCleaningTask : public AbstractGangTask {
3532 private:
3533   BoolObjectClosure* _is_alive;
3534   G1StringDedupUnlinkOrOopsDoClosure _dedup_closure;
3535 
3536   int _initial_string_table_size;
3537   int _initial_symbol_table_size;
3538 
3539   bool  _process_strings;
3540   int _strings_processed;
3541   int _strings_removed;
3542 
3543   bool  _process_symbols;
3544   int _symbols_processed;
3545   int _symbols_removed;
3546 
3547   bool _process_string_dedup;
3548 
3549 public:
3550   G1StringAndSymbolCleaningTask(BoolObjectClosure* is_alive, bool process_strings, bool process_symbols, bool process_string_dedup) :
3551     AbstractGangTask("String/Symbol Unlinking"),
3552     _is_alive(is_alive),
3553     _dedup_closure(is_alive, NULL, false),
3554     _process_strings(process_strings), _strings_processed(0), _strings_removed(0),
3555     _process_symbols(process_symbols), _symbols_processed(0), _symbols_removed(0),
3556     _process_string_dedup(process_string_dedup) {
3557 
3558     _initial_string_table_size = StringTable::the_table()->table_size();
3559     _initial_symbol_table_size = SymbolTable::the_table()->table_size();
3560     if (process_strings) {
3561       StringTable::clear_parallel_claimed_index();
3562     }
3563     if (process_symbols) {
3564       SymbolTable::clear_parallel_claimed_index();
3565     }
3566   }
3567 
3568   ~G1StringAndSymbolCleaningTask() {
3569     guarantee(!_process_strings || StringTable::parallel_claimed_index() >= _initial_string_table_size,
3570               "claim value %d after unlink less than initial string table size %d",
3571               StringTable::parallel_claimed_index(), _initial_string_table_size);
3572     guarantee(!_process_symbols || SymbolTable::parallel_claimed_index() >= _initial_symbol_table_size,
3573               "claim value %d after unlink less than initial symbol table size %d",
3574               SymbolTable::parallel_claimed_index(), _initial_symbol_table_size);
3575 
3576     log_info(gc, stringtable)(
3577         "Cleaned string and symbol table, "
3578         "strings: " SIZE_FORMAT " processed, " SIZE_FORMAT " removed, "
3579         "symbols: " SIZE_FORMAT " processed, " SIZE_FORMAT " removed",
3580         strings_processed(), strings_removed(),
3581         symbols_processed(), symbols_removed());
3582   }
3583 
3584   void work(uint worker_id) {
3585     int strings_processed = 0;
3586     int strings_removed = 0;
3587     int symbols_processed = 0;
3588     int symbols_removed = 0;


3817 
3818   void work() {
3819     ResourceMark rm;
3820 
3821     // One worker will clean the subklass/sibling klass tree.
3822     if (claim_clean_klass_tree_task()) {
3823       Klass::clean_subklass_tree(_is_alive);
3824     }
3825 
3826     // All workers will help cleaning the classes,
3827     InstanceKlass* klass;
3828     while ((klass = claim_next_klass()) != NULL) {
3829       clean_klass(klass);
3830     }
3831   }
3832 };
3833 
3834 // To minimize the remark pause times, the tasks below are done in parallel.
3835 class G1ParallelCleaningTask : public AbstractGangTask {
3836 private:
3837   G1StringAndSymbolCleaningTask _string_symbol_task;
3838   G1CodeCacheUnloadingTask      _code_cache_task;
3839   G1KlassCleaningTask           _klass_cleaning_task;
3840 
3841 public:
3842   // The constructor is run in the VMThread.
3843   G1ParallelCleaningTask(BoolObjectClosure* is_alive, uint num_workers, bool unloading_occurred) :
3844       AbstractGangTask("Parallel Cleaning"),
3845       _string_symbol_task(is_alive, true, true, G1StringDedup::is_enabled()),
3846       _code_cache_task(num_workers, is_alive, unloading_occurred),
3847       _klass_cleaning_task(is_alive) {
3848   }
3849 
3850   // The parallel work done by all worker threads.
3851   void work(uint worker_id) {
3852     // Do first pass of code cache cleaning.
3853     _code_cache_task.work_first_pass(worker_id);
3854 
3855     // Let the threads mark that the first pass is done.
3856     _code_cache_task.barrier_mark(worker_id);
3857 
3858     // Clean the Strings and Symbols.
3859     _string_symbol_task.work(worker_id);
3860 
3861     // Wait for all workers to finish the first code cache cleaning pass.
3862     _code_cache_task.barrier_wait(worker_id);
3863 
3864     // Do the second code cache cleaning work, which realize on
3865     // the liveness information gathered during the first pass.
3866     _code_cache_task.work_second_pass(worker_id);
3867 
3868     // Clean all klasses that were not unloaded.
3869     _klass_cleaning_task.work();
3870   }
3871 };
3872 
3873 
3874 void G1CollectedHeap::complete_cleaning(BoolObjectClosure* is_alive,
3875                                         bool class_unloading_occurred) {
3876   uint n_workers = workers()->active_workers();
3877 
3878   G1ParallelCleaningTask g1_unlink_task(is_alive, n_workers, class_unloading_occurred);
3879   workers()->run_task(&g1_unlink_task);
3880 }
3881 
3882 void G1CollectedHeap::partial_cleaning(BoolObjectClosure* is_alive,
3883                                        bool process_strings,
3884                                        bool process_symbols,
3885                                        bool process_string_dedup) {
3886   if (!process_strings && !process_symbols && !process_string_dedup) {
3887     // Nothing to clean.
3888     return;
3889   }
3890 
3891   G1StringAndSymbolCleaningTask g1_unlink_task(is_alive, process_strings, process_symbols, process_string_dedup);
3892   workers()->run_task(&g1_unlink_task);
3893 
3894 }
3895 
3896 class G1RedirtyLoggedCardsTask : public AbstractGangTask {
3897  private:
3898   DirtyCardQueueSet* _queue;
3899   G1CollectedHeap* _g1h;
3900  public:
3901   G1RedirtyLoggedCardsTask(DirtyCardQueueSet* queue, G1CollectedHeap* g1h) : AbstractGangTask("Redirty Cards"),
3902     _queue(queue), _g1h(g1h) { }
3903 
3904   virtual void work(uint worker_id) {
3905     G1GCPhaseTimes* phase_times = _g1h->g1_policy()->phase_times();
3906     G1GCParPhaseTimesTracker x(phase_times, G1GCPhaseTimes::RedirtyCards, worker_id);
3907 
3908     RedirtyLoggedCardTableEntryClosure cl(_g1h);
3909     _queue->par_apply_closure_to_all_completed_buffers(&cl);
3910 
3911     phase_times->record_thread_work_item(G1GCPhaseTimes::RedirtyCards, worker_id, cl.num_dirtied());


< prev index next >