3254 (alloc_buffer_waste + undo_waste) * HeapWordSize / K, |
3253 (alloc_buffer_waste + undo_waste) * HeapWordSize / K, |
3255 alloc_buffer_waste * HeapWordSize / K, |
3254 alloc_buffer_waste * HeapWordSize / K, |
3256 undo_waste * HeapWordSize / K); |
3255 undo_waste * HeapWordSize / K); |
3257 } |
3256 } |
3258 |
3257 |
3259 class G1StringAndSymbolCleaningTask : public AbstractGangTask { |
3258 class G1StringCleaningTask : public AbstractGangTask { |
3260 private: |
3259 private: |
3261 BoolObjectClosure* _is_alive; |
3260 BoolObjectClosure* _is_alive; |
3262 G1StringDedupUnlinkOrOopsDoClosure _dedup_closure; |
3261 G1StringDedupUnlinkOrOopsDoClosure _dedup_closure; |
3263 OopStorage::ParState<false /* concurrent */, false /* const */> _par_state_string; |
3262 OopStorage::ParState<false /* concurrent */, false /* const */> _par_state_string; |
3264 |
3263 |
3265 int _initial_string_table_size; |
3264 int _initial_string_table_size; |
3266 int _initial_symbol_table_size; |
|
3267 |
3265 |
3268 bool _process_strings; |
3266 bool _process_strings; |
3269 int _strings_processed; |
3267 int _strings_processed; |
3270 int _strings_removed; |
3268 int _strings_removed; |
3271 |
3269 |
3272 bool _process_symbols; |
|
3273 int _symbols_processed; |
|
3274 int _symbols_removed; |
|
3275 |
|
3276 bool _process_string_dedup; |
3270 bool _process_string_dedup; |
3277 |
3271 |
3278 public: |
3272 public: |
3279 G1StringAndSymbolCleaningTask(BoolObjectClosure* is_alive, bool process_strings, bool process_symbols, bool process_string_dedup) : |
3273 G1StringCleaningTask(BoolObjectClosure* is_alive, bool process_strings, bool process_string_dedup) : |
3280 AbstractGangTask("String/Symbol Unlinking"), |
3274 AbstractGangTask("String Unlinking"), |
3281 _is_alive(is_alive), |
3275 _is_alive(is_alive), |
3282 _dedup_closure(is_alive, NULL, false), |
3276 _dedup_closure(is_alive, NULL, false), |
3283 _par_state_string(StringTable::weak_storage()), |
3277 _par_state_string(StringTable::weak_storage()), |
3284 _process_strings(process_strings), _strings_processed(0), _strings_removed(0), |
3278 _process_strings(process_strings), _strings_processed(0), _strings_removed(0), |
3285 _process_symbols(process_symbols), _symbols_processed(0), _symbols_removed(0), |
|
3286 _process_string_dedup(process_string_dedup) { |
3279 _process_string_dedup(process_string_dedup) { |
3287 |
3280 |
3288 _initial_string_table_size = (int) StringTable::the_table()->table_size(); |
3281 _initial_string_table_size = (int) StringTable::the_table()->table_size(); |
3289 _initial_symbol_table_size = SymbolTable::the_table()->table_size(); |
|
3290 if (process_symbols) { |
|
3291 SymbolTable::clear_parallel_claimed_index(); |
|
3292 } |
|
3293 if (process_strings) { |
3282 if (process_strings) { |
3294 StringTable::reset_dead_counter(); |
3283 StringTable::reset_dead_counter(); |
3295 } |
3284 } |
3296 } |
3285 } |
3297 |
3286 |
3298 ~G1StringAndSymbolCleaningTask() { |
3287 ~G1StringCleaningTask() { |
3299 guarantee(!_process_symbols || SymbolTable::parallel_claimed_index() >= _initial_symbol_table_size, |
|
3300 "claim value %d after unlink less than initial symbol table size %d", |
|
3301 SymbolTable::parallel_claimed_index(), _initial_symbol_table_size); |
|
3302 |
|
3303 log_info(gc, stringtable)( |
3288 log_info(gc, stringtable)( |
3304 "Cleaned string and symbol table, " |
3289 "Cleaned string table, " |
3305 "strings: " SIZE_FORMAT " processed, " SIZE_FORMAT " removed, " |
3290 "strings: " SIZE_FORMAT " processed, " SIZE_FORMAT " removed", |
3306 "symbols: " SIZE_FORMAT " processed, " SIZE_FORMAT " removed", |
3291 strings_processed(), strings_removed()); |
3307 strings_processed(), strings_removed(), |
|
3308 symbols_processed(), symbols_removed()); |
|
3309 if (_process_strings) { |
3292 if (_process_strings) { |
3310 StringTable::finish_dead_counter(); |
3293 StringTable::finish_dead_counter(); |
3311 } |
3294 } |
3312 } |
3295 } |
3313 |
3296 |
3314 void work(uint worker_id) { |
3297 void work(uint worker_id) { |
3315 int strings_processed = 0; |
3298 int strings_processed = 0; |
3316 int strings_removed = 0; |
3299 int strings_removed = 0; |
3317 int symbols_processed = 0; |
|
3318 int symbols_removed = 0; |
|
3319 if (_process_strings) { |
3300 if (_process_strings) { |
3320 StringTable::possibly_parallel_unlink(&_par_state_string, _is_alive, &strings_processed, &strings_removed); |
3301 StringTable::possibly_parallel_unlink(&_par_state_string, _is_alive, &strings_processed, &strings_removed); |
3321 Atomic::add(strings_processed, &_strings_processed); |
3302 Atomic::add(strings_processed, &_strings_processed); |
3322 Atomic::add(strings_removed, &_strings_removed); |
3303 Atomic::add(strings_removed, &_strings_removed); |
3323 } |
3304 } |
3324 if (_process_symbols) { |
|
3325 SymbolTable::possibly_parallel_unlink(&symbols_processed, &symbols_removed); |
|
3326 Atomic::add(symbols_processed, &_symbols_processed); |
|
3327 Atomic::add(symbols_removed, &_symbols_removed); |
|
3328 } |
|
3329 if (_process_string_dedup) { |
3305 if (_process_string_dedup) { |
3330 G1StringDedup::parallel_unlink(&_dedup_closure, worker_id); |
3306 G1StringDedup::parallel_unlink(&_dedup_closure, worker_id); |
3331 } |
3307 } |
3332 } |
3308 } |
3333 |
3309 |
3334 size_t strings_processed() const { return (size_t)_strings_processed; } |
3310 size_t strings_processed() const { return (size_t)_strings_processed; } |
3335 size_t strings_removed() const { return (size_t)_strings_removed; } |
3311 size_t strings_removed() const { return (size_t)_strings_removed; } |
3336 |
|
3337 size_t symbols_processed() const { return (size_t)_symbols_processed; } |
|
3338 size_t symbols_removed() const { return (size_t)_symbols_removed; } |
|
3339 }; |
3312 }; |
3340 |
3313 |
3341 class G1CodeCacheUnloadingTask { |
3314 class G1CodeCacheUnloadingTask { |
3342 private: |
3315 private: |
3343 static Monitor* _lock; |
3316 static Monitor* _lock; |
3583 |
3556 |
3584 // To minimize the remark pause times, the tasks below are done in parallel. |
3557 // To minimize the remark pause times, the tasks below are done in parallel. |
3585 class G1ParallelCleaningTask : public AbstractGangTask { |
3558 class G1ParallelCleaningTask : public AbstractGangTask { |
3586 private: |
3559 private: |
3587 bool _unloading_occurred; |
3560 bool _unloading_occurred; |
3588 G1StringAndSymbolCleaningTask _string_symbol_task; |
3561 G1StringCleaningTask _string_task; |
3589 G1CodeCacheUnloadingTask _code_cache_task; |
3562 G1CodeCacheUnloadingTask _code_cache_task; |
3590 G1KlassCleaningTask _klass_cleaning_task; |
3563 G1KlassCleaningTask _klass_cleaning_task; |
3591 G1ResolvedMethodCleaningTask _resolved_method_cleaning_task; |
3564 G1ResolvedMethodCleaningTask _resolved_method_cleaning_task; |
3592 |
3565 |
3593 public: |
3566 public: |
3594 // The constructor is run in the VMThread. |
3567 // The constructor is run in the VMThread. |
3595 G1ParallelCleaningTask(BoolObjectClosure* is_alive, uint num_workers, bool unloading_occurred) : |
3568 G1ParallelCleaningTask(BoolObjectClosure* is_alive, uint num_workers, bool unloading_occurred) : |
3596 AbstractGangTask("Parallel Cleaning"), |
3569 AbstractGangTask("Parallel Cleaning"), |
3597 _unloading_occurred(unloading_occurred), |
3570 _unloading_occurred(unloading_occurred), |
3598 _string_symbol_task(is_alive, true, true, G1StringDedup::is_enabled()), |
3571 _string_task(is_alive, true, G1StringDedup::is_enabled()), |
3599 _code_cache_task(num_workers, is_alive, unloading_occurred), |
3572 _code_cache_task(num_workers, is_alive, unloading_occurred), |
3600 _klass_cleaning_task(), |
3573 _klass_cleaning_task(), |
3601 _resolved_method_cleaning_task() { |
3574 _resolved_method_cleaning_task() { |
3602 } |
3575 } |
3603 |
3576 |