Mercurial > hg > truffle
comparison src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp @ 14303:893ce66f7473
8027476: Improve performance of Stringtable unlink
8027455: Improve symbol table scan times during gc pauses
Summary: Parallelize string table and symbol table scan during remark and full GC. Some additional statistics output if the experimental flag G1TraceStringSymbolTableScrubbing is set.
Reviewed-by: mgerdin, coleenp, brutisso
author | tschatzl |
---|---|
date | Mon, 20 Jan 2014 11:47:07 +0100 |
parents | ff355e26c78d |
children | c685ef164975 |
comparison
equal
deleted
inserted
replaced
14265:3e2b76368121 | 14303:893ce66f7473 |
---|---|
5191 G1CollectedHeap::g1_process_weak_roots(OopClosure* root_closure) { | 5191 G1CollectedHeap::g1_process_weak_roots(OopClosure* root_closure) { |
5192 CodeBlobToOopClosure roots_in_blobs(root_closure, /*do_marking=*/ false); | 5192 CodeBlobToOopClosure roots_in_blobs(root_closure, /*do_marking=*/ false); |
5193 SharedHeap::process_weak_roots(root_closure, &roots_in_blobs); | 5193 SharedHeap::process_weak_roots(root_closure, &roots_in_blobs); |
5194 } | 5194 } |
5195 | 5195 |
5196 class G1StringSymbolTableUnlinkTask : public AbstractGangTask { | |
5197 private: | |
5198 BoolObjectClosure* _is_alive; | |
5199 int _initial_string_table_size; | |
5200 int _initial_symbol_table_size; | |
5201 | |
5202 bool _process_strings; | |
5203 int _strings_processed; | |
5204 int _strings_removed; | |
5205 | |
5206 bool _process_symbols; | |
5207 int _symbols_processed; | |
5208 int _symbols_removed; | |
5209 public: | |
5210 G1StringSymbolTableUnlinkTask(BoolObjectClosure* is_alive, bool process_strings, bool process_symbols) : | |
5211 AbstractGangTask("Par String/Symbol table unlink"), _is_alive(is_alive), | |
5212 _process_strings(process_strings), _strings_processed(0), _strings_removed(0), | |
5213 _process_symbols(process_symbols), _symbols_processed(0), _symbols_removed(0) { | |
5214 | |
5215 _initial_string_table_size = StringTable::the_table()->table_size(); | |
5216 _initial_symbol_table_size = SymbolTable::the_table()->table_size(); | |
5217 if (process_strings) { | |
5218 StringTable::clear_parallel_claimed_index(); | |
5219 } | |
5220 if (process_symbols) { | |
5221 SymbolTable::clear_parallel_claimed_index(); | |
5222 } | |
5223 } | |
5224 | |
5225 ~G1StringSymbolTableUnlinkTask() { | |
5226 guarantee(!_process_strings || StringTable::parallel_claimed_index() >= _initial_string_table_size, | |
5227 err_msg("claim value "INT32_FORMAT" after unlink less than initial string table size "INT32_FORMAT, | |
5228 StringTable::parallel_claimed_index(), _initial_string_table_size)); | |
5229 guarantee(!_process_strings || SymbolTable::parallel_claimed_index() >= _initial_symbol_table_size, | |
5230 err_msg("claim value "INT32_FORMAT" after unlink less than initial symbol table size "INT32_FORMAT, | |
5231 SymbolTable::parallel_claimed_index(), _initial_symbol_table_size)); | |
5232 } | |
5233 | |
5234 void work(uint worker_id) { | |
5235 if (G1CollectedHeap::use_parallel_gc_threads()) { | |
5236 int strings_processed = 0; | |
5237 int strings_removed = 0; | |
5238 int symbols_processed = 0; | |
5239 int symbols_removed = 0; | |
5240 if (_process_strings) { | |
5241 StringTable::possibly_parallel_unlink(_is_alive, &strings_processed, &strings_removed); | |
5242 Atomic::add(strings_processed, &_strings_processed); | |
5243 Atomic::add(strings_removed, &_strings_removed); | |
5244 } | |
5245 if (_process_symbols) { | |
5246 SymbolTable::possibly_parallel_unlink(&symbols_processed, &symbols_removed); | |
5247 Atomic::add(symbols_processed, &_symbols_processed); | |
5248 Atomic::add(symbols_removed, &_symbols_removed); | |
5249 } | |
5250 } else { | |
5251 if (_process_strings) { | |
5252 StringTable::unlink(_is_alive, &_strings_processed, &_strings_removed); | |
5253 } | |
5254 if (_process_symbols) { | |
5255 SymbolTable::unlink(&_symbols_processed, &_symbols_removed); | |
5256 } | |
5257 } | |
5258 } | |
5259 | |
5260 size_t strings_processed() const { return (size_t)_strings_processed; } | |
5261 size_t strings_removed() const { return (size_t)_strings_removed; } | |
5262 | |
5263 size_t symbols_processed() const { return (size_t)_symbols_processed; } | |
5264 size_t symbols_removed() const { return (size_t)_symbols_removed; } | |
5265 }; | |
5266 | |
5267 void G1CollectedHeap::unlink_string_and_symbol_table(BoolObjectClosure* is_alive, | |
5268 bool process_strings, bool process_symbols) { | |
5269 uint n_workers = (G1CollectedHeap::use_parallel_gc_threads() ? | |
5270 _g1h->workers()->active_workers() : 1); | |
5271 | |
5272 G1StringSymbolTableUnlinkTask g1_unlink_task(is_alive, process_strings, process_symbols); | |
5273 if (G1CollectedHeap::use_parallel_gc_threads()) { | |
5274 set_par_threads(n_workers); | |
5275 workers()->run_task(&g1_unlink_task); | |
5276 set_par_threads(0); | |
5277 } else { | |
5278 g1_unlink_task.work(0); | |
5279 } | |
5280 if (G1TraceStringSymbolTableScrubbing) { | |
5281 gclog_or_tty->print_cr("Cleaned string and symbol table, " | |
5282 "strings: "SIZE_FORMAT" processed, "SIZE_FORMAT" removed, " | |
5283 "symbols: "SIZE_FORMAT" processed, "SIZE_FORMAT" removed", | |
5284 g1_unlink_task.strings_processed(), g1_unlink_task.strings_removed(), | |
5285 g1_unlink_task.symbols_processed(), g1_unlink_task.symbols_removed()); | |
5286 } | |
5287 } | |
5288 | |
5196 // Weak Reference Processing support | 5289 // Weak Reference Processing support |
5197 | 5290 |
5198 // An always "is_alive" closure that is used to preserve referents. | 5291 // An always "is_alive" closure that is used to preserve referents. |
5199 // If the object is non-null then it's alive. Used in the preservation | 5292 // If the object is non-null then it's alive. Used in the preservation |
5200 // of referent objects that are pointed to by reference objects | 5293 // of referent objects that are pointed to by reference objects |