Mercurial > hg > graal-jvmci-8
comparison src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp @ 17634:5a32d2a3cc1e
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 | 86e6d691f2e1 |
children | 889068b9a088 |
comparison
equal
deleted
inserted
replaced
17633:04f1d5d36714 | 17634:5a32d2a3cc1e |
---|---|
5210 G1CollectedHeap::g1_process_weak_roots(OopClosure* root_closure) { | 5210 G1CollectedHeap::g1_process_weak_roots(OopClosure* root_closure) { |
5211 CodeBlobToOopClosure roots_in_blobs(root_closure, /*do_marking=*/ false); | 5211 CodeBlobToOopClosure roots_in_blobs(root_closure, /*do_marking=*/ false); |
5212 SharedHeap::process_weak_roots(root_closure, &roots_in_blobs); | 5212 SharedHeap::process_weak_roots(root_closure, &roots_in_blobs); |
5213 } | 5213 } |
5214 | 5214 |
5215 class G1StringSymbolTableUnlinkTask : public AbstractGangTask { | |
5216 private: | |
5217 BoolObjectClosure* _is_alive; | |
5218 int _initial_string_table_size; | |
5219 int _initial_symbol_table_size; | |
5220 | |
5221 bool _process_strings; | |
5222 int _strings_processed; | |
5223 int _strings_removed; | |
5224 | |
5225 bool _process_symbols; | |
5226 int _symbols_processed; | |
5227 int _symbols_removed; | |
5228 public: | |
5229 G1StringSymbolTableUnlinkTask(BoolObjectClosure* is_alive, bool process_strings, bool process_symbols) : | |
5230 AbstractGangTask("Par String/Symbol table unlink"), _is_alive(is_alive), | |
5231 _process_strings(process_strings), _strings_processed(0), _strings_removed(0), | |
5232 _process_symbols(process_symbols), _symbols_processed(0), _symbols_removed(0) { | |
5233 | |
5234 _initial_string_table_size = StringTable::the_table()->table_size(); | |
5235 _initial_symbol_table_size = SymbolTable::the_table()->table_size(); | |
5236 if (process_strings) { | |
5237 StringTable::clear_parallel_claimed_index(); | |
5238 } | |
5239 if (process_symbols) { | |
5240 SymbolTable::clear_parallel_claimed_index(); | |
5241 } | |
5242 } | |
5243 | |
5244 ~G1StringSymbolTableUnlinkTask() { | |
5245 guarantee(!_process_strings || StringTable::parallel_claimed_index() >= _initial_string_table_size, | |
5246 err_msg("claim value "INT32_FORMAT" after unlink less than initial string table size "INT32_FORMAT, | |
5247 StringTable::parallel_claimed_index(), _initial_string_table_size)); | |
5248 guarantee(!_process_strings || SymbolTable::parallel_claimed_index() >= _initial_symbol_table_size, | |
5249 err_msg("claim value "INT32_FORMAT" after unlink less than initial symbol table size "INT32_FORMAT, | |
5250 SymbolTable::parallel_claimed_index(), _initial_symbol_table_size)); | |
5251 } | |
5252 | |
5253 void work(uint worker_id) { | |
5254 if (G1CollectedHeap::use_parallel_gc_threads()) { | |
5255 int strings_processed = 0; | |
5256 int strings_removed = 0; | |
5257 int symbols_processed = 0; | |
5258 int symbols_removed = 0; | |
5259 if (_process_strings) { | |
5260 StringTable::possibly_parallel_unlink(_is_alive, &strings_processed, &strings_removed); | |
5261 Atomic::add(strings_processed, &_strings_processed); | |
5262 Atomic::add(strings_removed, &_strings_removed); | |
5263 } | |
5264 if (_process_symbols) { | |
5265 SymbolTable::possibly_parallel_unlink(&symbols_processed, &symbols_removed); | |
5266 Atomic::add(symbols_processed, &_symbols_processed); | |
5267 Atomic::add(symbols_removed, &_symbols_removed); | |
5268 } | |
5269 } else { | |
5270 if (_process_strings) { | |
5271 StringTable::unlink(_is_alive, &_strings_processed, &_strings_removed); | |
5272 } | |
5273 if (_process_symbols) { | |
5274 SymbolTable::unlink(&_symbols_processed, &_symbols_removed); | |
5275 } | |
5276 } | |
5277 } | |
5278 | |
5279 size_t strings_processed() const { return (size_t)_strings_processed; } | |
5280 size_t strings_removed() const { return (size_t)_strings_removed; } | |
5281 | |
5282 size_t symbols_processed() const { return (size_t)_symbols_processed; } | |
5283 size_t symbols_removed() const { return (size_t)_symbols_removed; } | |
5284 }; | |
5285 | |
5286 void G1CollectedHeap::unlink_string_and_symbol_table(BoolObjectClosure* is_alive, | |
5287 bool process_strings, bool process_symbols) { | |
5288 uint n_workers = (G1CollectedHeap::use_parallel_gc_threads() ? | |
5289 _g1h->workers()->active_workers() : 1); | |
5290 | |
5291 G1StringSymbolTableUnlinkTask g1_unlink_task(is_alive, process_strings, process_symbols); | |
5292 if (G1CollectedHeap::use_parallel_gc_threads()) { | |
5293 set_par_threads(n_workers); | |
5294 workers()->run_task(&g1_unlink_task); | |
5295 set_par_threads(0); | |
5296 } else { | |
5297 g1_unlink_task.work(0); | |
5298 } | |
5299 if (G1TraceStringSymbolTableScrubbing) { | |
5300 gclog_or_tty->print_cr("Cleaned string and symbol table, " | |
5301 "strings: "SIZE_FORMAT" processed, "SIZE_FORMAT" removed, " | |
5302 "symbols: "SIZE_FORMAT" processed, "SIZE_FORMAT" removed", | |
5303 g1_unlink_task.strings_processed(), g1_unlink_task.strings_removed(), | |
5304 g1_unlink_task.symbols_processed(), g1_unlink_task.symbols_removed()); | |
5305 } | |
5306 } | |
5307 | |
5215 // Weak Reference Processing support | 5308 // Weak Reference Processing support |
5216 | 5309 |
5217 // An always "is_alive" closure that is used to preserve referents. | 5310 // An always "is_alive" closure that is used to preserve referents. |
5218 // If the object is non-null then it's alive. Used in the preservation | 5311 // If the object is non-null then it's alive. Used in the preservation |
5219 // of referent objects that are pointed to by reference objects | 5312 // of referent objects that are pointed to by reference objects |