1 # HG changeset patch 2 # User mgerdin 3 # Date 1417443896 -3600 4 # Mon Dec 01 15:24:56 2014 +0100 5 # Node ID b31893aea8834508c334f4cef3b1d3bf410b4ac7 6 # Parent 7a045fce642673a5a53000d4258e2f59004e5cb6 7 8075210: Refactor strong root processing in order to allow G1 to evolve separately from GenCollectedHeap 8 Summary: Create a G1RootProcessor and move SharedHeap root processing to GenCollectedHeap 9 Reviewed-by: brutisso, tschatzl, ehelin 10 11 diff --git a/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepGeneration.cpp b/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepGeneration.cpp 12 --- a/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepGeneration.cpp 13 +++ b/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepGeneration.cpp 14 @@ -506,7 +506,7 @@ 15 _collector_policy(cp), 16 _should_unload_classes(CMSClassUnloadingEnabled), 17 _concurrent_cycles_since_last_unload(0), 18 - _roots_scanning_options(SharedHeap::SO_None), 19 + _roots_scanning_options(GenCollectedHeap::SO_None), 20 _inter_sweep_estimate(CMS_SweepWeight, CMS_SweepPadding), 21 _intra_sweep_estimate(CMS_SweepWeight, CMS_SweepPadding), 22 _gc_tracer_cm(new (ResourceObj::C_HEAP, mtGC) CMSTracer()), 23 @@ -2496,7 +2496,7 @@ 24 gch->gen_process_roots(_cmsGen->level(), 25 true, // younger gens are roots 26 true, // activate StrongRootsScope 27 - SharedHeap::ScanningOption(roots_scanning_options()), 28 + GenCollectedHeap::ScanningOption(roots_scanning_options()), 29 should_unload_classes(), 30 ¬Older, 31 NULL, 32 @@ -2564,7 +2564,7 @@ 33 gch->gen_process_roots(_cmsGen->level(), 34 true, // younger gens are roots 35 true, // activate StrongRootsScope 36 - SharedHeap::ScanningOption(roots_scanning_options()), 37 + GenCollectedHeap::ScanningOption(roots_scanning_options()), 38 should_unload_classes(), 39 ¬Older, 40 NULL, 41 @@ -2748,7 +2748,7 @@ 42 void CMSCollector::setup_cms_unloading_and_verification_state() { 43 const bool should_verify = VerifyBeforeGC || VerifyAfterGC || VerifyDuringGC 44 || VerifyBeforeExit; 45 - const int rso = SharedHeap::SO_AllCodeCache; 46 + const int rso = GenCollectedHeap::SO_AllCodeCache; 47 48 // We set the proper root for this CMS cycle here. 49 if (should_unload_classes()) { // Should unload classes this cycle 50 @@ -3087,7 +3087,7 @@ 51 gch->gen_process_roots(_cmsGen->level(), 52 true, // younger gens are roots 53 true, // activate StrongRootsScope 54 - SharedHeap::ScanningOption(roots_scanning_options()), 55 + GenCollectedHeap::ScanningOption(roots_scanning_options()), 56 should_unload_classes(), 57 ¬Older, 58 NULL, 59 @@ -4521,13 +4521,13 @@ 60 gch->gen_process_roots(_collector->_cmsGen->level(), 61 false, // yg was scanned above 62 false, // this is parallel code 63 - SharedHeap::ScanningOption(_collector->CMSCollector::roots_scanning_options()), 64 + GenCollectedHeap::ScanningOption(_collector->CMSCollector::roots_scanning_options()), 65 _collector->should_unload_classes(), 66 &par_mri_cl, 67 NULL, 68 &cld_closure); 69 assert(_collector->should_unload_classes() 70 - || (_collector->CMSCollector::roots_scanning_options() & SharedHeap::SO_AllCodeCache), 71 + || (_collector->CMSCollector::roots_scanning_options() & GenCollectedHeap::SO_AllCodeCache), 72 "if we didn't scan the code cache, we have to be ready to drop nmethods with expired weak oops"); 73 _timer.stop(); 74 if (PrintCMSStatistics != 0) { 75 @@ -4657,14 +4657,14 @@ 76 gch->gen_process_roots(_collector->_cmsGen->level(), 77 false, // yg was scanned above 78 false, // this is parallel code 79 - SharedHeap::ScanningOption(_collector->CMSCollector::roots_scanning_options()), 80 + GenCollectedHeap::ScanningOption(_collector->CMSCollector::roots_scanning_options()), 81 _collector->should_unload_classes(), 82 &par_mrias_cl, 83 NULL, 84 NULL); // The dirty klasses will be handled below 85 86 assert(_collector->should_unload_classes() 87 - || (_collector->CMSCollector::roots_scanning_options() & SharedHeap::SO_AllCodeCache), 88 + || (_collector->CMSCollector::roots_scanning_options() & GenCollectedHeap::SO_AllCodeCache), 89 "if we didn't scan the code cache, we have to be ready to drop nmethods with expired weak oops"); 90 _timer.stop(); 91 if (PrintCMSStatistics != 0) { 92 @@ -5248,14 +5248,14 @@ 93 gch->gen_process_roots(_cmsGen->level(), 94 true, // younger gens as roots 95 false, // use the local StrongRootsScope 96 - SharedHeap::ScanningOption(roots_scanning_options()), 97 + GenCollectedHeap::ScanningOption(roots_scanning_options()), 98 should_unload_classes(), 99 &mrias_cl, 100 NULL, 101 NULL); // The dirty klasses will be handled below 102 103 assert(should_unload_classes() 104 - || (roots_scanning_options() & SharedHeap::SO_AllCodeCache), 105 + || (roots_scanning_options() & GenCollectedHeap::SO_AllCodeCache), 106 "if we didn't scan the code cache, we have to be ready to drop nmethods with expired weak oops"); 107 } 108 109 diff --git a/src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp b/src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp 110 --- a/src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp 111 +++ b/src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp 112 @@ -48,6 +48,7 @@ 113 #include "gc_implementation/g1/g1ParScanThreadState.inline.hpp" 114 #include "gc_implementation/g1/g1RegionToSpaceMapper.hpp" 115 #include "gc_implementation/g1/g1RemSet.inline.hpp" 116 +#include "gc_implementation/g1/g1RootProcessor.hpp" 117 #include "gc_implementation/g1/g1StringDedup.hpp" 118 #include "gc_implementation/g1/g1YCTypes.hpp" 119 #include "gc_implementation/g1/heapRegion.inline.hpp" 120 @@ -89,18 +90,6 @@ 121 // apply to TLAB allocation, which is not part of this interface: it 122 // is done by clients of this interface.) 123 124 -// Notes on implementation of parallelism in different tasks. 125 -// 126 -// G1ParVerifyTask uses heap_region_par_iterate_chunked() for parallelism. 127 -// The number of GC workers is passed to heap_region_par_iterate_chunked(). 128 -// It does use run_task() which sets _n_workers in the task. 129 -// G1ParTask executes g1_process_roots() -> 130 -// SharedHeap::process_roots() which calls eventually to 131 -// CardTableModRefBS::par_non_clean_card_iterate_work() which uses 132 -// SequentialSubTasksDone. SharedHeap::process_roots() also 133 -// directly uses SubTasksDone (_process_strong_tasks field in SharedHeap). 134 -// 135 - 136 // Local to this file. 137 138 class RefineCardTableEntryClosure: public CardTableEntryClosure { 139 @@ -1767,7 +1756,6 @@ 140 _is_alive_closure_stw(this), 141 _ref_processor_cm(NULL), 142 _ref_processor_stw(NULL), 143 - _process_strong_tasks(new SubTasksDone(G1H_PS_NumElements)), 144 _bot_shared(NULL), 145 _evac_failure_scan_stack(NULL), 146 _mark_in_progress(false), 147 @@ -1801,9 +1789,6 @@ 148 _gc_tracer_cm(new (ResourceObj::C_HEAP, mtGC) G1OldTracer()) { 149 150 _g1h = this; 151 - if (_process_strong_tasks == NULL || !_process_strong_tasks->valid()) { 152 - vm_exit_during_initialization("Failed necessary allocation."); 153 - } 154 155 _allocator = G1Allocator::create_allocator(_g1h); 156 _humongous_object_threshold_in_words = HeapRegion::GrainWords / 2; 157 @@ -3107,11 +3092,12 @@ 158 G1VerifyCodeRootOopClosure codeRootsCl(this, &rootsCl, vo); 159 G1VerifyCodeRootBlobClosure blobsCl(&codeRootsCl); 160 161 - process_all_roots(true, // activate StrongRootsScope 162 - SO_AllCodeCache, // roots scanning options 163 - &rootsCl, 164 - &cldCl, 165 - &blobsCl); 166 + { 167 + G1RootProcessor root_processor(this); 168 + root_processor.process_all_roots(&rootsCl, 169 + &cldCl, 170 + &blobsCl); 171 + } 172 173 bool failures = rootsCl.failures() || codeRootsCl.failures(); 174 175 @@ -4360,60 +4346,11 @@ 176 } 177 }; 178 179 -class G1CodeBlobClosure : public CodeBlobClosure { 180 - class HeapRegionGatheringOopClosure : public OopClosure { 181 - G1CollectedHeap* _g1h; 182 - OopClosure* _work; 183 - nmethod* _nm; 184 - 185 - template <typename T> 186 - void do_oop_work(T* p) { 187 - _work->do_oop(p); 188 - T oop_or_narrowoop = oopDesc::load_heap_oop(p); 189 - if (!oopDesc::is_null(oop_or_narrowoop)) { 190 - oop o = oopDesc::decode_heap_oop_not_null(oop_or_narrowoop); 191 - HeapRegion* hr = _g1h->heap_region_containing_raw(o); 192 - assert(!_g1h->obj_in_cs(o) || hr->rem_set()->strong_code_roots_list_contains(_nm), "if o still in CS then evacuation failed and nm must already be in the remset"); 193 - hr->add_strong_code_root(_nm); 194 - } 195 - } 196 - 197 - public: 198 - HeapRegionGatheringOopClosure(OopClosure* oc) : _g1h(G1CollectedHeap::heap()), _work(oc), _nm(NULL) {} 199 - 200 - void do_oop(oop* o) { 201 - do_oop_work(o); 202 - } 203 - 204 - void do_oop(narrowOop* o) { 205 - do_oop_work(o); 206 - } 207 - 208 - void set_nm(nmethod* nm) { 209 - _nm = nm; 210 - } 211 - }; 212 - 213 - HeapRegionGatheringOopClosure _oc; 214 -public: 215 - G1CodeBlobClosure(OopClosure* oc) : _oc(oc) {} 216 - 217 - void do_code_blob(CodeBlob* cb) { 218 - nmethod* nm = cb->as_nmethod_or_null(); 219 - if (nm != NULL) { 220 - if (!nm->test_set_oops_do_mark()) { 221 - _oc.set_nm(nm); 222 - nm->oops_do(&_oc); 223 - nm->fix_oop_relocations(); 224 - } 225 - } 226 - } 227 -}; 228 - 229 class G1ParTask : public AbstractGangTask { 230 protected: 231 G1CollectedHeap* _g1h; 232 RefToScanQueueSet *_queues; 233 + G1RootProcessor* _root_processor; 234 ParallelTaskTerminator _terminator; 235 uint _n_workers; 236 237 @@ -4421,10 +4358,11 @@ 238 Mutex* stats_lock() { return &_stats_lock; } 239 240 public: 241 - G1ParTask(G1CollectedHeap* g1h, RefToScanQueueSet *task_queues) 242 + G1ParTask(G1CollectedHeap* g1h, RefToScanQueueSet *task_queues, G1RootProcessor* root_processor) 243 : AbstractGangTask("G1 collection"), 244 _g1h(g1h), 245 _queues(task_queues), 246 + _root_processor(root_processor), 247 _terminator(0, _queues), 248 _stats_lock(Mutex::leaf, "parallel G1 stats lock", true) 249 {} 250 @@ -4438,13 +4376,7 @@ 251 ParallelTaskTerminator* terminator() { return &_terminator; } 252 253 virtual void set_for_termination(int active_workers) { 254 - // This task calls set_n_termination() in par_non_clean_card_iterate_work() 255 - // in the young space (_par_seq_tasks) in the G1 heap 256 - // for SequentialSubTasksDone. 257 - // This task also uses SubTasksDone in SharedHeap and G1CollectedHeap 258 - // both of which need setting by set_n_termination(). 259 - _g1h->SharedHeap::set_n_termination(active_workers); 260 - _g1h->set_n_termination(active_workers); 261 + _root_processor->set_num_workers(active_workers); 262 terminator()->reset_for_reuse(active_workers); 263 _n_workers = active_workers; 264 } 265 @@ -4513,24 +4445,21 @@ 266 false, // Process all klasses. 267 true); // Need to claim CLDs. 268 269 - G1CodeBlobClosure scan_only_code_cl(&scan_only_root_cl); 270 - G1CodeBlobClosure scan_mark_code_cl(&scan_mark_root_cl); 271 - // IM Weak code roots are handled later. 272 - 273 OopClosure* strong_root_cl; 274 OopClosure* weak_root_cl; 275 CLDClosure* strong_cld_cl; 276 CLDClosure* weak_cld_cl; 277 - CodeBlobClosure* strong_code_cl; 278 + 279 + bool trace_metadata = false; 280 281 if (_g1h->g1_policy()->during_initial_mark_pause()) { 282 // We also need to mark copied objects. 283 strong_root_cl = &scan_mark_root_cl; 284 strong_cld_cl = &scan_mark_cld_cl; 285 - strong_code_cl = &scan_mark_code_cl; 286 if (ClassUnloadingWithConcurrentMark) { 287 weak_root_cl = &scan_mark_weak_root_cl; 288 weak_cld_cl = &scan_mark_weak_cld_cl; 289 + trace_metadata = true; 290 } else { 291 weak_root_cl = &scan_mark_root_cl; 292 weak_cld_cl = &scan_mark_cld_cl; 293 @@ -4540,21 +4469,21 @@ 294 weak_root_cl = &scan_only_root_cl; 295 strong_cld_cl = &scan_only_cld_cl; 296 weak_cld_cl = &scan_only_cld_cl; 297 - strong_code_cl = &scan_only_code_cl; 298 } 299 300 - 301 - G1ParPushHeapRSClosure push_heap_rs_cl(_g1h, &pss); 302 - 303 pss.start_strong_roots(); 304 - _g1h->g1_process_roots(strong_root_cl, 305 - weak_root_cl, 306 - &push_heap_rs_cl, 307 - strong_cld_cl, 308 - weak_cld_cl, 309 - strong_code_cl, 310 - worker_id); 311 - 312 + 313 + _root_processor->evacuate_roots(strong_root_cl, 314 + weak_root_cl, 315 + strong_cld_cl, 316 + weak_cld_cl, 317 + trace_metadata, 318 + worker_id); 319 + 320 + G1ParPushHeapRSClosure push_heap_rs_cl(_g1h, &pss); 321 + _root_processor->scan_remembered_sets(&push_heap_rs_cl, 322 + weak_root_cl, 323 + worker_id); 324 pss.end_strong_roots(); 325 326 { 327 @@ -4585,87 +4514,6 @@ 328 } 329 }; 330 331 -// *** Common G1 Evacuation Stuff 332 - 333 -// This method is run in a GC worker. 334 - 335 -void 336 -G1CollectedHeap:: 337 -g1_process_roots(OopClosure* scan_non_heap_roots, 338 - OopClosure* scan_non_heap_weak_roots, 339 - OopsInHeapRegionClosure* scan_rs, 340 - CLDClosure* scan_strong_clds, 341 - CLDClosure* scan_weak_clds, 342 - CodeBlobClosure* scan_strong_code, 343 - uint worker_i) { 344 - 345 - // First scan the shared roots. 346 - double ext_roots_start = os::elapsedTime(); 347 - double closure_app_time_sec = 0.0; 348 - 349 - bool during_im = _g1h->g1_policy()->during_initial_mark_pause(); 350 - bool trace_metadata = during_im && ClassUnloadingWithConcurrentMark; 351 - 352 - BufferingOopClosure buf_scan_non_heap_roots(scan_non_heap_roots); 353 - BufferingOopClosure buf_scan_non_heap_weak_roots(scan_non_heap_weak_roots); 354 - 355 - process_roots(false, // no scoping; this is parallel code 356 - SharedHeap::SO_None, 357 - &buf_scan_non_heap_roots, 358 - &buf_scan_non_heap_weak_roots, 359 - scan_strong_clds, 360 - // Unloading Initial Marks handle the weak CLDs separately. 361 - (trace_metadata ? NULL : scan_weak_clds), 362 - scan_strong_code); 363 - 364 - // Now the CM ref_processor roots. 365 - if (!_process_strong_tasks->is_task_claimed(G1H_PS_refProcessor_oops_do)) { 366 - // We need to treat the discovered reference lists of the 367 - // concurrent mark ref processor as roots and keep entries 368 - // (which are added by the marking threads) on them live 369 - // until they can be processed at the end of marking. 370 - ref_processor_cm()->weak_oops_do(&buf_scan_non_heap_roots); 371 - } 372 - 373 - if (trace_metadata) { 374 - // Barrier to make sure all workers passed 375 - // the strong CLD and strong nmethods phases. 376 - active_strong_roots_scope()->wait_until_all_workers_done_with_threads(n_par_threads()); 377 - 378 - // Now take the complement of the strong CLDs. 379 - ClassLoaderDataGraph::roots_cld_do(NULL, scan_weak_clds); 380 - } 381 - 382 - // Finish up any enqueued closure apps (attributed as object copy time). 383 - buf_scan_non_heap_roots.done(); 384 - buf_scan_non_heap_weak_roots.done(); 385 - 386 - double obj_copy_time_sec = buf_scan_non_heap_roots.closure_app_seconds() 387 - + buf_scan_non_heap_weak_roots.closure_app_seconds(); 388 - 389 - g1_policy()->phase_times()->record_time_secs(G1GCPhaseTimes::ObjCopy, worker_i, obj_copy_time_sec); 390 - 391 - double ext_root_time_sec = os::elapsedTime() - ext_roots_start - obj_copy_time_sec; 392 - g1_policy()->phase_times()->record_time_secs(G1GCPhaseTimes::ExtRootScan, worker_i, ext_root_time_sec); 393 - 394 - // During conc marking we have to filter the per-thread SATB buffers 395 - // to make sure we remove any oops into the CSet (which will show up 396 - // as implicitly live). 397 - { 398 - G1GCParPhaseTimesTracker x(g1_policy()->phase_times(), G1GCPhaseTimes::SATBFiltering, worker_i); 399 - if (!_process_strong_tasks->is_task_claimed(G1H_PS_filter_satb_buffers) && mark_in_progress()) { 400 - JavaThread::satb_mark_queue_set().filter_thread_buffers(); 401 - } 402 - } 403 - 404 - // Now scan the complement of the collection set. 405 - G1CodeBlobClosure scavenge_cs_nmethods(scan_non_heap_weak_roots); 406 - 407 - g1_rem_set()->oops_into_collection_set_do(scan_rs, &scavenge_cs_nmethods, worker_i); 408 - 409 - _process_strong_tasks->all_tasks_completed(); 410 -} 411 - 412 class G1StringSymbolTableUnlinkTask : public AbstractGangTask { 413 private: 414 BoolObjectClosure* _is_alive; 415 @@ -5612,7 +5460,6 @@ 416 workers()->set_active_workers(n_workers); 417 set_par_threads(n_workers); 418 419 - G1ParTask g1_par_task(this, _task_queues); 420 421 init_for_evac_failure(NULL); 422 423 @@ -5621,7 +5468,8 @@ 424 double end_par_time_sec; 425 426 { 427 - StrongRootsScope srs(this); 428 + G1RootProcessor root_processor(this); 429 + G1ParTask g1_par_task(this, _task_queues, &root_processor); 430 // InitialMark needs claim bits to keep track of the marked-through CLDs. 431 if (g1_policy()->during_initial_mark_pause()) { 432 ClassLoaderDataGraph::clear_claimed_marks(); 433 @@ -5637,9 +5485,9 @@ 434 end_par_time_sec = os::elapsedTime(); 435 436 // Closing the inner scope will execute the destructor 437 - // for the StrongRootsScope object. We record the current 438 + // for the G1RootProcessor object. We record the current 439 // elapsed time before closing the scope so that time 440 - // taken for the SRS destructor is NOT included in the 441 + // taken for the destructor is NOT included in the 442 // reported parallel time. 443 } 444 445 diff --git a/src/share/vm/gc_implementation/g1/g1CollectedHeap.hpp b/src/share/vm/gc_implementation/g1/g1CollectedHeap.hpp 446 --- a/src/share/vm/gc_implementation/g1/g1CollectedHeap.hpp 447 +++ b/src/share/vm/gc_implementation/g1/g1CollectedHeap.hpp 448 @@ -780,22 +780,6 @@ 449 // statistics or updating free lists. 450 void abandon_collection_set(HeapRegion* cs_head); 451 452 - // Applies "scan_non_heap_roots" to roots outside the heap, 453 - // "scan_rs" to roots inside the heap (having done "set_region" to 454 - // indicate the region in which the root resides), 455 - // and does "scan_metadata" If "scan_rs" is 456 - // NULL, then this step is skipped. The "worker_i" 457 - // param is for use with parallel roots processing, and should be 458 - // the "i" of the calling parallel worker thread's work(i) function. 459 - // In the sequential case this param will be ignored. 460 - void g1_process_roots(OopClosure* scan_non_heap_roots, 461 - OopClosure* scan_non_heap_weak_roots, 462 - OopsInHeapRegionClosure* scan_rs, 463 - CLDClosure* scan_strong_clds, 464 - CLDClosure* scan_weak_clds, 465 - CodeBlobClosure* scan_strong_code, 466 - uint worker_i); 467 - 468 // The concurrent marker (and the thread it runs in.) 469 ConcurrentMark* _cm; 470 ConcurrentMarkThread* _cmThread; 471 @@ -982,21 +966,10 @@ 472 // of G1CollectedHeap::_gc_time_stamp. 473 uint* _worker_cset_start_region_time_stamp; 474 475 - enum G1H_process_roots_tasks { 476 - G1H_PS_filter_satb_buffers, 477 - G1H_PS_refProcessor_oops_do, 478 - // Leave this one last. 479 - G1H_PS_NumElements 480 - }; 481 - 482 - SubTasksDone* _process_strong_tasks; 483 - 484 volatile bool _free_regions_coming; 485 486 public: 487 488 - SubTasksDone* process_strong_tasks() { return _process_strong_tasks; } 489 - 490 void set_refine_cte_cl_concurrency(bool concurrent); 491 492 RefToScanQueue *task_queue(int i) const; 493 @@ -1029,21 +1002,11 @@ 494 // Initialize weak reference processing. 495 virtual void ref_processing_init(); 496 497 - void set_par_threads(uint t) { 498 - SharedHeap::set_par_threads(t); 499 - // Done in SharedHeap but oddly there are 500 - // two _process_strong_tasks's in a G1CollectedHeap 501 - // so do it here too. 502 - _process_strong_tasks->set_n_threads(t); 503 - } 504 - 505 + // Explicitly import set_par_threads into this scope 506 + using SharedHeap::set_par_threads; 507 // Set _n_par_threads according to a policy TBD. 508 void set_par_threads(); 509 510 - void set_n_termination(int t) { 511 - _process_strong_tasks->set_n_threads(t); 512 - } 513 - 514 virtual CollectedHeap::Name kind() const { 515 return CollectedHeap::G1CollectedHeap; 516 } 517 diff --git a/src/share/vm/gc_implementation/g1/g1MarkSweep.cpp b/src/share/vm/gc_implementation/g1/g1MarkSweep.cpp 518 --- a/src/share/vm/gc_implementation/g1/g1MarkSweep.cpp 519 +++ b/src/share/vm/gc_implementation/g1/g1MarkSweep.cpp 520 @@ -31,6 +31,7 @@ 521 #include "code/icBuffer.hpp" 522 #include "gc_implementation/g1/g1Log.hpp" 523 #include "gc_implementation/g1/g1MarkSweep.hpp" 524 +#include "gc_implementation/g1/g1RootProcessor.hpp" 525 #include "gc_implementation/g1/g1StringDedup.hpp" 526 #include "gc_implementation/shared/gcHeapSummary.hpp" 527 #include "gc_implementation/shared/gcTimer.hpp" 528 @@ -125,21 +126,22 @@ 529 GCTraceTime tm("phase 1", G1Log::fine() && Verbose, true, gc_timer(), gc_tracer()->gc_id()); 530 GenMarkSweep::trace(" 1"); 531 532 - SharedHeap* sh = SharedHeap::heap(); 533 + G1CollectedHeap* g1h = G1CollectedHeap::heap(); 534 535 // Need cleared claim bits for the roots processing 536 ClassLoaderDataGraph::clear_claimed_marks(); 537 538 MarkingCodeBlobClosure follow_code_closure(&GenMarkSweep::follow_root_closure, !CodeBlobToOopClosure::FixRelocations); 539 - sh->process_strong_roots(true, // activate StrongRootsScope 540 - SharedHeap::SO_None, 541 - &GenMarkSweep::follow_root_closure, 542 - &GenMarkSweep::follow_cld_closure, 543 - &follow_code_closure); 544 + { 545 + G1RootProcessor root_processor(g1h); 546 + root_processor.process_strong_roots(&GenMarkSweep::follow_root_closure, 547 + &GenMarkSweep::follow_cld_closure, 548 + &follow_code_closure); 549 + } 550 551 // Process reference objects found during marking 552 ReferenceProcessor* rp = GenMarkSweep::ref_processor(); 553 - assert(rp == G1CollectedHeap::heap()->ref_processor_stw(), "Sanity"); 554 + assert(rp == g1h->ref_processor_stw(), "Sanity"); 555 556 rp->setup_policy(clear_all_softrefs); 557 const ReferenceProcessorStats& stats = 558 @@ -225,6 +227,12 @@ 559 } 560 }; 561 562 +class G1AlwaysTrueClosure: public BoolObjectClosure { 563 +public: 564 + bool do_object_b(oop p) { return true; } 565 +}; 566 +static G1AlwaysTrueClosure always_true; 567 + 568 void G1MarkSweep::mark_sweep_phase3() { 569 G1CollectedHeap* g1h = G1CollectedHeap::heap(); 570 571 @@ -232,24 +240,23 @@ 572 GCTraceTime tm("phase 3", G1Log::fine() && Verbose, true, gc_timer(), gc_tracer()->gc_id()); 573 GenMarkSweep::trace("3"); 574 575 - SharedHeap* sh = SharedHeap::heap(); 576 - 577 // Need cleared claim bits for the roots processing 578 ClassLoaderDataGraph::clear_claimed_marks(); 579 580 CodeBlobToOopClosure adjust_code_closure(&GenMarkSweep::adjust_pointer_closure, CodeBlobToOopClosure::FixRelocations); 581 - sh->process_all_roots(true, // activate StrongRootsScope 582 - SharedHeap::SO_AllCodeCache, 583 - &GenMarkSweep::adjust_pointer_closure, 584 - &GenMarkSweep::adjust_cld_closure, 585 - &adjust_code_closure); 586 + { 587 + G1RootProcessor root_processor(g1h); 588 + root_processor.process_all_roots(&GenMarkSweep::adjust_pointer_closure, 589 + &GenMarkSweep::adjust_cld_closure, 590 + &adjust_code_closure); 591 + } 592 593 assert(GenMarkSweep::ref_processor() == g1h->ref_processor_stw(), "Sanity"); 594 g1h->ref_processor_stw()->weak_oops_do(&GenMarkSweep::adjust_pointer_closure); 595 596 // Now adjust pointers in remaining weak roots. (All of which should 597 // have been cleared if they pointed to non-surviving objects.) 598 - sh->process_weak_roots(&GenMarkSweep::adjust_pointer_closure); 599 + JNIHandles::weak_oops_do(&always_true, &GenMarkSweep::adjust_pointer_closure); 600 601 if (G1StringDedup::is_enabled()) { 602 G1StringDedup::oops_do(&GenMarkSweep::adjust_pointer_closure); 603 diff --git a/src/share/vm/gc_implementation/g1/g1RemSet.cpp b/src/share/vm/gc_implementation/g1/g1RemSet.cpp 604 --- a/src/share/vm/gc_implementation/g1/g1RemSet.cpp 605 +++ b/src/share/vm/gc_implementation/g1/g1RemSet.cpp 606 @@ -79,8 +79,7 @@ 607 _cards_scanned(NULL), _total_cards_scanned(0), 608 _prev_period_summary() 609 { 610 - _seq_task = new SubTasksDone(NumSeqTasks); 611 guarantee(n_workers() > 0, "There should be some workers"); 612 _cset_rs_update_cl = NEW_C_HEAP_ARRAY(OopsInHeapRegionClosure*, n_workers(), mtGC); 613 for (uint i = 0; i < n_workers(); i++) { 614 _cset_rs_update_cl[i] = NULL; 615 @@ -90,7 +89,6 @@ 616 } 617 618 G1RemSet::~G1RemSet() { 619 - delete _seq_task; 620 for (uint i = 0; i < n_workers(); i++) { 621 assert(_cset_rs_update_cl[i] == NULL, "it should be"); 622 } 623 diff --git a/src/share/vm/gc_implementation/g1/g1RemSet.hpp b/src/share/vm/gc_implementation/g1/g1RemSet.hpp 624 --- a/src/share/vm/gc_implementation/g1/g1RemSet.hpp 625 +++ b/src/share/vm/gc_implementation/g1/g1RemSet.hpp 626 @@ -58,7 +58,6 @@ 627 }; 628 629 CardTableModRefBS* _ct_bs; 630 - SubTasksDone* _seq_task; 631 G1CollectorPolicy* _g1p; 632 633 ConcurrentG1Refine* _cg1r; 634 diff --git a/src/share/vm/gc_implementation/g1/g1RootProcessor.cpp b/src/share/vm/gc_implementation/g1/g1RootProcessor.cpp 635 new file mode 100644 636 --- /dev/null 637 +++ b/src/share/vm/gc_implementation/g1/g1RootProcessor.cpp 638 @@ -0,0 +1,290 @@ 639 +/* 640 + * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved. 641 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 642 + * 643 + * This code is free software; you can redistribute it and/or modify it 644 + * under the terms of the GNU General Public License version 2 only, as 645 + * published by the Free Software Foundation. 646 + * 647 + * This code is distributed in the hope that it will be useful, but WITHOUT 648 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 649 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 650 + * version 2 for more details (a copy is included in the LICENSE file that 651 + * accompanied this code). 652 + * 653 + * You should have received a copy of the GNU General Public License version 654 + * 2 along with this work; if not, write to the Free Software Foundation, 655 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 656 + * 657 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 658 + * or visit www.oracle.com if you need additional information or have any 659 + * questions. 660 + * 661 + */ 662 + 663 +#include "precompiled.hpp" 664 + 665 +#include "classfile/symbolTable.hpp" 666 +#include "classfile/systemDictionary.hpp" 667 +#include "code/codeCache.hpp" 668 +#include "gc_implementation/g1/bufferingOopClosure.hpp" 669 +#include "gc_implementation/g1/g1CollectedHeap.inline.hpp" 670 +#include "gc_implementation/g1/g1CollectorPolicy.hpp" 671 +#include "gc_implementation/g1/g1GCPhaseTimes.hpp" 672 +#include "gc_implementation/g1/g1RemSet.inline.hpp" 673 +#include "gc_implementation/g1/g1RootProcessor.hpp" 674 +#include "memory/allocation.inline.hpp" 675 +#include "runtime/fprofiler.hpp" 676 +#include "runtime/mutex.hpp" 677 +#include "services/management.hpp" 678 + 679 +class G1CodeBlobClosure : public CodeBlobClosure { 680 + class HeapRegionGatheringOopClosure : public OopClosure { 681 + G1CollectedHeap* _g1h; 682 + OopClosure* _work; 683 + nmethod* _nm; 684 + 685 + template <typename T> 686 + void do_oop_work(T* p) { 687 + _work->do_oop(p); 688 + T oop_or_narrowoop = oopDesc::load_heap_oop(p); 689 + if (!oopDesc::is_null(oop_or_narrowoop)) { 690 + oop o = oopDesc::decode_heap_oop_not_null(oop_or_narrowoop); 691 + HeapRegion* hr = _g1h->heap_region_containing_raw(o); 692 + assert(!_g1h->obj_in_cs(o) || hr->rem_set()->strong_code_roots_list_contains(_nm), "if o still in CS then evacuation failed and nm must already be in the remset"); 693 + hr->add_strong_code_root(_nm); 694 + } 695 + } 696 + 697 + public: 698 + HeapRegionGatheringOopClosure(OopClosure* oc) : _g1h(G1CollectedHeap::heap()), _work(oc), _nm(NULL) {} 699 + 700 + void do_oop(oop* o) { 701 + do_oop_work(o); 702 + } 703 + 704 + void do_oop(narrowOop* o) { 705 + do_oop_work(o); 706 + } 707 + 708 + void set_nm(nmethod* nm) { 709 + _nm = nm; 710 + } 711 + }; 712 + 713 + HeapRegionGatheringOopClosure _oc; 714 +public: 715 + G1CodeBlobClosure(OopClosure* oc) : _oc(oc) {} 716 + 717 + void do_code_blob(CodeBlob* cb) { 718 + nmethod* nm = cb->as_nmethod_or_null(); 719 + if (nm != NULL) { 720 + if (!nm->test_set_oops_do_mark()) { 721 + _oc.set_nm(nm); 722 + nm->oops_do(&_oc); 723 + nm->fix_oop_relocations(); 724 + } 725 + } 726 + } 727 +}; 728 + 729 + 730 +void G1RootProcessor::worker_has_discovered_all_strong_classes() { 731 + uint n_workers = _g1h->n_par_threads(); 732 + assert(ClassUnloadingWithConcurrentMark, "Currently only needed when doing G1 Class Unloading"); 733 + 734 + uint new_value = (uint)Atomic::add(1, &_n_workers_discovered_strong_classes); 735 + if (new_value == n_workers) { 736 + // This thread is last. Notify the others. 737 + MonitorLockerEx ml(&_lock, Mutex::_no_safepoint_check_flag); 738 + _lock.notify_all(); 739 + } 740 +} 741 + 742 +void G1RootProcessor::wait_until_all_strong_classes_discovered() { 743 + uint n_workers = _g1h->n_par_threads(); 744 + assert(ClassUnloadingWithConcurrentMark, "Currently only needed when doing G1 Class Unloading"); 745 + 746 + if ((uint)_n_workers_discovered_strong_classes != n_workers) { 747 + MonitorLockerEx ml(&_lock, Mutex::_no_safepoint_check_flag); 748 + while ((uint)_n_workers_discovered_strong_classes != n_workers) { 749 + _lock.wait(Mutex::_no_safepoint_check_flag, 0, false); 750 + } 751 + } 752 +} 753 + 754 +G1RootProcessor::G1RootProcessor(G1CollectedHeap* g1h) : 755 + _g1h(g1h), 756 + _process_strong_tasks(new SubTasksDone(G1RP_PS_NumElements)), 757 + _srs(g1h), 758 + _lock(Mutex::leaf, "G1 Root Scanning barrier lock", false), 759 + _n_workers_discovered_strong_classes(0) {} 760 + 761 +void G1RootProcessor::evacuate_roots(OopClosure* scan_non_heap_roots, 762 + OopClosure* scan_non_heap_weak_roots, 763 + CLDClosure* scan_strong_clds, 764 + CLDClosure* scan_weak_clds, 765 + bool trace_metadata, 766 + uint worker_i) { 767 + // First scan the shared roots. 768 + double ext_roots_start = os::elapsedTime(); 769 + 770 + BufferingOopClosure buf_scan_non_heap_roots(scan_non_heap_roots); 771 + BufferingOopClosure buf_scan_non_heap_weak_roots(scan_non_heap_weak_roots); 772 + 773 + OopClosure* const weak_roots = &buf_scan_non_heap_weak_roots; 774 + OopClosure* const strong_roots = &buf_scan_non_heap_roots; 775 + 776 + // CodeBlobClosures are not interoperable with BufferingOopClosures 777 + G1CodeBlobClosure root_code_blobs(scan_non_heap_roots); 778 + 779 + process_java_roots(strong_roots, 780 + trace_metadata ? scan_strong_clds : NULL, 781 + scan_strong_clds, 782 + trace_metadata ? NULL : scan_weak_clds, 783 + &root_code_blobs); 784 + 785 + // This is the point where this worker thread will not find more strong CLDs/nmethods. 786 + // Report this so G1 can synchronize the strong and weak CLDs/nmethods processing. 787 + if (trace_metadata) { 788 + worker_has_discovered_all_strong_classes(); 789 + } 790 + 791 + process_vm_roots(strong_roots, weak_roots); 792 + 793 + // Now the CM ref_processor roots. 794 + if (!_process_strong_tasks->is_task_claimed(G1RP_PS_refProcessor_oops_do)) { 795 + // We need to treat the discovered reference lists of the 796 + // concurrent mark ref processor as roots and keep entries 797 + // (which are added by the marking threads) on them live 798 + // until they can be processed at the end of marking. 799 + _g1h->ref_processor_cm()->weak_oops_do(&buf_scan_non_heap_roots); 800 + } 801 + 802 + if (trace_metadata) { 803 + // Barrier to make sure all workers passed 804 + // the strong CLD and strong nmethods phases. 805 + wait_until_all_strong_classes_discovered(); 806 + 807 + // Now take the complement of the strong CLDs. 808 + ClassLoaderDataGraph::roots_cld_do(NULL, scan_weak_clds); 809 + } 810 + 811 + // Finish up any enqueued closure apps (attributed as object copy time). 812 + buf_scan_non_heap_roots.done(); 813 + buf_scan_non_heap_weak_roots.done(); 814 + 815 + double obj_copy_time_sec = buf_scan_non_heap_roots.closure_app_seconds() 816 + + buf_scan_non_heap_weak_roots.closure_app_seconds(); 817 + 818 + G1GCPhaseTimes* phase_times = _g1h->g1_policy()->phase_times(); 819 + phase_times->record_time_secs(G1GCPhaseTimes::ObjCopy, worker_i, obj_copy_time_sec); 820 + 821 + double ext_root_time_sec = os::elapsedTime() - ext_roots_start - obj_copy_time_sec; 822 + 823 + phase_times->record_time_secs(G1GCPhaseTimes::ExtRootScan, worker_i, ext_root_time_sec); 824 + 825 + // During conc marking we have to filter the per-thread SATB buffers 826 + // to make sure we remove any oops into the CSet (which will show up 827 + // as implicitly live). 828 + { 829 + G1GCParPhaseTimesTracker x(phase_times, G1GCPhaseTimes::SATBFiltering, worker_i); 830 + if (!_process_strong_tasks->is_task_claimed(G1RP_PS_filter_satb_buffers) && _g1h->mark_in_progress()) { 831 + JavaThread::satb_mark_queue_set().filter_thread_buffers(); 832 + } 833 + } 834 + 835 + _process_strong_tasks->all_tasks_completed(); 836 +} 837 + 838 +void G1RootProcessor::process_strong_roots(OopClosure* oops, 839 + CLDClosure* clds, 840 + CodeBlobClosure* blobs) { 841 + 842 + process_java_roots(oops, clds, clds, NULL, blobs); 843 + process_vm_roots(oops, NULL); 844 + 845 + _process_strong_tasks->all_tasks_completed(); 846 +} 847 + 848 +void G1RootProcessor::process_all_roots(OopClosure* oops, 849 + CLDClosure* clds, 850 + CodeBlobClosure* blobs) { 851 + 852 + process_java_roots(oops, NULL, clds, clds, NULL); 853 + process_vm_roots(oops, oops); 854 + 855 + if (!_process_strong_tasks->is_task_claimed(G1RP_PS_CodeCache_oops_do)) { 856 + CodeCache::blobs_do(blobs); 857 + } 858 + 859 + _process_strong_tasks->all_tasks_completed(); 860 +} 861 + 862 +void G1RootProcessor::process_java_roots(OopClosure* strong_roots, 863 + CLDClosure* thread_stack_clds, 864 + CLDClosure* strong_clds, 865 + CLDClosure* weak_clds, 866 + CodeBlobClosure* strong_code) { 867 + assert(thread_stack_clds == NULL || weak_clds == NULL, "There is overlap between those, only one may be set"); 868 + // Iterating over the CLDG and the Threads are done early to allow us to 869 + // first process the strong CLDs and nmethods and then, after a barrier, 870 + // let the thread process the weak CLDs and nmethods. 871 + 872 + if (!_process_strong_tasks->is_task_claimed(G1RP_PS_ClassLoaderDataGraph_oops_do)) { 873 + ClassLoaderDataGraph::roots_cld_do(strong_clds, weak_clds); 874 + } 875 + 876 + Threads::possibly_parallel_oops_do(strong_roots, thread_stack_clds, strong_code); 877 +} 878 + 879 +void G1RootProcessor::process_vm_roots(OopClosure* strong_roots, 880 + OopClosure* weak_roots) { 881 + 882 + if (!_process_strong_tasks->is_task_claimed(G1RP_PS_Universe_oops_do)) { 883 + Universe::oops_do(strong_roots); 884 + } 885 + 886 + if (!_process_strong_tasks->is_task_claimed(G1RP_PS_JNIHandles_oops_do)) { 887 + JNIHandles::oops_do(strong_roots); 888 + } 889 + 890 + if (!_process_strong_tasks-> is_task_claimed(G1RP_PS_ObjectSynchronizer_oops_do)) { 891 + ObjectSynchronizer::oops_do(strong_roots); 892 + } 893 + 894 + if (!_process_strong_tasks->is_task_claimed(G1RP_PS_FlatProfiler_oops_do)) { 895 + FlatProfiler::oops_do(strong_roots); 896 + } 897 + 898 + if (!_process_strong_tasks->is_task_claimed(G1RP_PS_Management_oops_do)) { 899 + Management::oops_do(strong_roots); 900 + } 901 + 902 + if (!_process_strong_tasks->is_task_claimed(G1RP_PS_jvmti_oops_do)) { 903 + JvmtiExport::oops_do(strong_roots); 904 + } 905 + 906 + if (!_process_strong_tasks->is_task_claimed(G1RP_PS_SystemDictionary_oops_do)) { 907 + SystemDictionary::roots_oops_do(strong_roots, weak_roots); 908 + } 909 + 910 + // All threads execute the following. A specific chunk of buckets 911 + // from the StringTable are the individual tasks. 912 + if (weak_roots != NULL) { 913 + StringTable::possibly_parallel_oops_do(weak_roots); 914 + } 915 +} 916 + 917 +void G1RootProcessor::scan_remembered_sets(G1ParPushHeapRSClosure* scan_rs, 918 + OopClosure* scan_non_heap_weak_roots, 919 + uint worker_i) { 920 + // Now scan the complement of the collection set. 921 + G1CodeBlobClosure scavenge_cs_nmethods(scan_non_heap_weak_roots); 922 + 923 + _g1h->g1_rem_set()->oops_into_collection_set_do(scan_rs, &scavenge_cs_nmethods, worker_i); 924 +} 925 + 926 +void G1RootProcessor::set_num_workers(int active_workers) { 927 + _process_strong_tasks->set_n_threads(active_workers); 928 +} 929 diff --git a/src/share/vm/gc_implementation/g1/g1RootProcessor.hpp b/src/share/vm/gc_implementation/g1/g1RootProcessor.hpp 930 new file mode 100644 931 --- /dev/null 932 +++ b/src/share/vm/gc_implementation/g1/g1RootProcessor.hpp 933 @@ -0,0 +1,116 @@ 934 +/* 935 + * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved. 936 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 937 + * 938 + * This code is free software; you can redistribute it and/or modify it 939 + * under the terms of the GNU General Public License version 2 only, as 940 + * published by the Free Software Foundation. 941 + * 942 + * This code is distributed in the hope that it will be useful, but WITHOUT 943 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 944 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 945 + * version 2 for more details (a copy is included in the LICENSE file that 946 + * accompanied this code). 947 + * 948 + * You should have received a copy of the GNU General Public License version 949 + * 2 along with this work; if not, write to the Free Software Foundation, 950 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 951 + * 952 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 953 + * or visit www.oracle.com if you need additional information or have any 954 + * questions. 955 + * 956 + */ 957 + 958 +#ifndef SHARE_VM_GC_IMPLEMENTATION_G1_ROOTPROCESSOR_HPP 959 +#define SHARE_VM_GC_IMPLEMENTATION_G1_ROOTPROCESSOR_HPP 960 + 961 +#include "memory/allocation.hpp" 962 +#include "memory/sharedHeap.hpp" 963 +#include "runtime/mutex.hpp" 964 + 965 +class CLDClosure; 966 +class CodeBlobClosure; 967 +class G1CollectedHeap; 968 +class G1ParPushHeapRSClosure; 969 +class Monitor; 970 +class OopClosure; 971 +class SubTasksDone; 972 + 973 +// Scoped object to assist in applying oop, CLD and code blob closures to 974 +// root locations. Handles claiming of different root scanning tasks 975 +// and takes care of global state for root scanning via a StrongRootsScope. 976 +// In the parallel case there is a shared G1RootProcessor object where all 977 +// worker thread call the process_roots methods. 978 +class G1RootProcessor : public StackObj { 979 + G1CollectedHeap* _g1h; 980 + SubTasksDone* _process_strong_tasks; 981 + SharedHeap::StrongRootsScope _srs; 982 + 983 + // Used to implement the Thread work barrier. 984 + Monitor _lock; 985 + volatile jint _n_workers_discovered_strong_classes; 986 + 987 + enum G1H_process_roots_tasks { 988 + G1RP_PS_Universe_oops_do, 989 + G1RP_PS_JNIHandles_oops_do, 990 + G1RP_PS_ObjectSynchronizer_oops_do, 991 + G1RP_PS_FlatProfiler_oops_do, 992 + G1RP_PS_Management_oops_do, 993 + G1RP_PS_SystemDictionary_oops_do, 994 + G1RP_PS_ClassLoaderDataGraph_oops_do, 995 + G1RP_PS_jvmti_oops_do, 996 + G1RP_PS_CodeCache_oops_do, 997 + G1RP_PS_filter_satb_buffers, 998 + G1RP_PS_refProcessor_oops_do, 999 + // Leave this one last. 1000 + G1RP_PS_NumElements 1001 + }; 1002 + 1003 + void worker_has_discovered_all_strong_classes(); 1004 + void wait_until_all_strong_classes_discovered(); 1005 + 1006 + void process_java_roots(OopClosure* scan_non_heap_roots, 1007 + CLDClosure* thread_stack_clds, 1008 + CLDClosure* scan_strong_clds, 1009 + CLDClosure* scan_weak_clds, 1010 + CodeBlobClosure* scan_strong_code); 1011 + 1012 + void process_vm_roots(OopClosure* scan_non_heap_roots, 1013 + OopClosure* scan_non_heap_weak_roots); 1014 + 1015 +public: 1016 + G1RootProcessor(G1CollectedHeap* g1h); 1017 + 1018 + // Apply closures to the strongly and weakly reachable roots in the system 1019 + // in a single pass. 1020 + // Record and report timing measurements for sub phases using the worker_i 1021 + void evacuate_roots(OopClosure* scan_non_heap_roots, 1022 + OopClosure* scan_non_heap_weak_roots, 1023 + CLDClosure* scan_strong_clds, 1024 + CLDClosure* scan_weak_clds, 1025 + bool trace_metadata, 1026 + uint worker_i); 1027 + 1028 + // Apply oops, clds and blobs to all strongly reachable roots in the system 1029 + void process_strong_roots(OopClosure* oops, 1030 + CLDClosure* clds, 1031 + CodeBlobClosure* blobs); 1032 + 1033 + // Apply oops, clds and blobs to strongly and weakly reachable roots in the system 1034 + void process_all_roots(OopClosure* oops, 1035 + CLDClosure* clds, 1036 + CodeBlobClosure* blobs); 1037 + 1038 + // Apply scan_rs to all locations in the union of the remembered sets for all 1039 + // regions in the collection set 1040 + // (having done "set_region" to indicate the region in which the root resides), 1041 + void scan_remembered_sets(G1ParPushHeapRSClosure* scan_rs, 1042 + OopClosure* scan_non_heap_weak_roots, 1043 + uint worker_i); 1044 + 1045 + // Inform the root processor about the number of worker threads 1046 + void set_num_workers(int active_workers); 1047 +}; 1048 + 1049 +#endif // SHARE_VM_GC_IMPLEMENTATION_G1_ROOTPROCESSOR_HPP 1050 diff --git a/src/share/vm/gc_implementation/parNew/parNewGeneration.cpp b/src/share/vm/gc_implementation/parNew/parNewGeneration.cpp 1051 --- a/src/share/vm/gc_implementation/parNew/parNewGeneration.cpp 1052 +++ b/src/share/vm/gc_implementation/parNew/parNewGeneration.cpp 1053 @@ -618,7 +618,7 @@ 1054 true, // Process younger gens, if any, 1055 // as strong roots. 1056 false, // no scope; this is parallel code 1057 - SharedHeap::SO_ScavengeCodeCache, 1058 + GenCollectedHeap::SO_ScavengeCodeCache, 1059 GenCollectedHeap::StrongAndWeakRoots, 1060 &par_scan_state.to_space_root_closure(), 1061 &par_scan_state.older_gen_closure(), 1062 diff --git a/src/share/vm/memory/defNewGeneration.cpp b/src/share/vm/memory/defNewGeneration.cpp 1063 --- a/src/share/vm/memory/defNewGeneration.cpp 1064 +++ b/src/share/vm/memory/defNewGeneration.cpp 1065 @@ -626,7 +626,7 @@ 1066 true, // Process younger gens, if any, 1067 // as strong roots. 1068 true, // activate StrongRootsScope 1069 - SharedHeap::SO_ScavengeCodeCache, 1070 + GenCollectedHeap::SO_ScavengeCodeCache, 1071 GenCollectedHeap::StrongAndWeakRoots, 1072 &fsc_with_no_gc_barrier, 1073 &fsc_with_gc_barrier, 1074 diff --git a/src/share/vm/memory/genCollectedHeap.cpp b/src/share/vm/memory/genCollectedHeap.cpp 1075 --- a/src/share/vm/memory/genCollectedHeap.cpp 1076 +++ b/src/share/vm/memory/genCollectedHeap.cpp 1077 @@ -26,6 +26,7 @@ 1078 #include "classfile/symbolTable.hpp" 1079 #include "classfile/systemDictionary.hpp" 1080 #include "classfile/vmSymbols.hpp" 1081 +#include "code/codeCache.hpp" 1082 #include "code/icBuffer.hpp" 1083 #include "gc_implementation/shared/collectorCounters.hpp" 1084 #include "gc_implementation/shared/gcTrace.hpp" 1085 @@ -47,6 +48,7 @@ 1086 #include "runtime/handles.inline.hpp" 1087 #include "runtime/java.hpp" 1088 #include "runtime/vmThread.hpp" 1089 +#include "services/management.hpp" 1090 #include "services/memoryService.hpp" 1091 #include "utilities/vmError.hpp" 1092 #include "utilities/workgroup.hpp" 1093 @@ -61,7 +63,15 @@ 1094 1095 // The set of potentially parallel tasks in root scanning. 1096 enum GCH_strong_roots_tasks { 1097 - // We probably want to parallelize both of these internally, but for now... 1098 + GCH_PS_Universe_oops_do, 1099 + GCH_PS_JNIHandles_oops_do, 1100 + GCH_PS_ObjectSynchronizer_oops_do, 1101 + GCH_PS_FlatProfiler_oops_do, 1102 + GCH_PS_Management_oops_do, 1103 + GCH_PS_SystemDictionary_oops_do, 1104 + GCH_PS_ClassLoaderDataGraph_oops_do, 1105 + GCH_PS_jvmti_oops_do, 1106 + GCH_PS_CodeCache_oops_do, 1107 GCH_PS_younger_gens, 1108 // Leave this one last. 1109 GCH_PS_NumElements 1110 @@ -71,13 +81,9 @@ 1111 SharedHeap(policy), 1112 _rem_set(NULL), 1113 _gen_policy(policy), 1114 - _gen_process_roots_tasks(new SubTasksDone(GCH_PS_NumElements)), 1115 + _process_strong_tasks(new SubTasksDone(GCH_PS_NumElements)), 1116 _full_collections_completed(0) 1117 { 1118 - if (_gen_process_roots_tasks == NULL || 1119 - !_gen_process_roots_tasks->valid()) { 1120 - vm_exit_during_initialization("Failed necessary allocation."); 1121 - } 1122 assert(policy != NULL, "Sanity check"); 1123 } 1124 1125 @@ -569,29 +575,137 @@ 1126 1127 void GenCollectedHeap::set_par_threads(uint t) { 1128 SharedHeap::set_par_threads(t); 1129 - _gen_process_roots_tasks->set_n_threads(t); 1130 + set_n_termination(t); 1131 } 1132 1133 -void GenCollectedHeap:: 1134 -gen_process_roots(int level, 1135 - bool younger_gens_as_roots, 1136 - bool activate_scope, 1137 - SharedHeap::ScanningOption so, 1138 - OopsInGenClosure* not_older_gens, 1139 - OopsInGenClosure* weak_roots, 1140 - OopsInGenClosure* older_gens, 1141 - CLDClosure* cld_closure, 1142 - CLDClosure* weak_cld_closure, 1143 - CodeBlobClosure* code_closure) { 1144 +void GenCollectedHeap::set_n_termination(uint t) { 1145 + _process_strong_tasks->set_n_threads(t); 1146 +} 1147 + 1148 +#ifdef ASSERT 1149 +class AssertNonScavengableClosure: public OopClosure { 1150 +public: 1151 + virtual void do_oop(oop* p) { 1152 + assert(!Universe::heap()->is_in_partial_collection(*p), 1153 + "Referent should not be scavengable."); } 1154 + virtual void do_oop(narrowOop* p) { ShouldNotReachHere(); } 1155 +}; 1156 +static AssertNonScavengableClosure assert_is_non_scavengable_closure; 1157 +#endif 1158 + 1159 +void GenCollectedHeap::process_roots(bool activate_scope, 1160 + ScanningOption so, 1161 + OopClosure* strong_roots, 1162 + OopClosure* weak_roots, 1163 + CLDClosure* strong_cld_closure, 1164 + CLDClosure* weak_cld_closure, 1165 + CodeBlobClosure* code_roots) { 1166 + StrongRootsScope srs(this, activate_scope); 1167 1168 // General roots. 1169 - SharedHeap::process_roots(activate_scope, so, 1170 - not_older_gens, weak_roots, 1171 - cld_closure, weak_cld_closure, 1172 - code_closure); 1173 + assert(_strong_roots_parity != 0, "must have called prologue code"); 1174 + assert(code_roots != NULL, "code root closure should always be set"); 1175 + // _n_termination for _process_strong_tasks should be set up stream 1176 + // in a method not running in a GC worker. Otherwise the GC worker 1177 + // could be trying to change the termination condition while the task 1178 + // is executing in another GC worker. 1179 + 1180 + if (!_process_strong_tasks->is_task_claimed(GCH_PS_ClassLoaderDataGraph_oops_do)) { 1181 + ClassLoaderDataGraph::roots_cld_do(strong_cld_closure, weak_cld_closure); 1182 + } 1183 + 1184 + // Some CLDs contained in the thread frames should be considered strong. 1185 + // Don't process them if they will be processed during the ClassLoaderDataGraph phase. 1186 + CLDClosure* roots_from_clds_p = (strong_cld_closure != weak_cld_closure) ? strong_cld_closure : NULL; 1187 + // Only process code roots from thread stacks if we aren't visiting the entire CodeCache anyway 1188 + CodeBlobClosure* roots_from_code_p = (so & SO_AllCodeCache) ? NULL : code_roots; 1189 + 1190 + Threads::possibly_parallel_oops_do(strong_roots, roots_from_clds_p, roots_from_code_p); 1191 + 1192 + if (!_process_strong_tasks->is_task_claimed(GCH_PS_Universe_oops_do)) { 1193 + Universe::oops_do(strong_roots); 1194 + } 1195 + // Global (strong) JNI handles 1196 + if (!_process_strong_tasks->is_task_claimed(GCH_PS_JNIHandles_oops_do)) { 1197 + JNIHandles::oops_do(strong_roots); 1198 + } 1199 + 1200 + if (!_process_strong_tasks->is_task_claimed(GCH_PS_ObjectSynchronizer_oops_do)) { 1201 + ObjectSynchronizer::oops_do(strong_roots); 1202 + } 1203 + if (!_process_strong_tasks->is_task_claimed(GCH_PS_FlatProfiler_oops_do)) { 1204 + FlatProfiler::oops_do(strong_roots); 1205 + } 1206 + if (!_process_strong_tasks->is_task_claimed(GCH_PS_Management_oops_do)) { 1207 + Management::oops_do(strong_roots); 1208 + } 1209 + if (!_process_strong_tasks->is_task_claimed(GCH_PS_jvmti_oops_do)) { 1210 + JvmtiExport::oops_do(strong_roots); 1211 + } 1212 + 1213 + if (!_process_strong_tasks->is_task_claimed(GCH_PS_SystemDictionary_oops_do)) { 1214 + SystemDictionary::roots_oops_do(strong_roots, weak_roots); 1215 + } 1216 + 1217 + // All threads execute the following. A specific chunk of buckets 1218 + // from the StringTable are the individual tasks. 1219 + if (weak_roots != NULL) { 1220 + if (CollectedHeap::use_parallel_gc_threads()) { 1221 + StringTable::possibly_parallel_oops_do(weak_roots); 1222 + } else { 1223 + StringTable::oops_do(weak_roots); 1224 + } 1225 + } 1226 + 1227 + if (!_process_strong_tasks->is_task_claimed(GCH_PS_CodeCache_oops_do)) { 1228 + if (so & SO_ScavengeCodeCache) { 1229 + assert(code_roots != NULL, "must supply closure for code cache"); 1230 + 1231 + // We only visit parts of the CodeCache when scavenging. 1232 + CodeCache::scavenge_root_nmethods_do(code_roots); 1233 + } 1234 + if (so & SO_AllCodeCache) { 1235 + assert(code_roots != NULL, "must supply closure for code cache"); 1236 + 1237 + // CMSCollector uses this to do intermediate-strength collections. 1238 + // We scan the entire code cache, since CodeCache::do_unloading is not called. 1239 + CodeCache::blobs_do(code_roots); 1240 + } 1241 + // Verify that the code cache contents are not subject to 1242 + // movement by a scavenging collection. 1243 + DEBUG_ONLY(CodeBlobToOopClosure assert_code_is_non_scavengable(&assert_is_non_scavengable_closure, !CodeBlobToOopClosure::FixRelocations)); 1244 + DEBUG_ONLY(CodeCache::asserted_non_scavengable_nmethods_do(&assert_code_is_non_scavengable)); 1245 + } 1246 + 1247 +} 1248 + 1249 +void GenCollectedHeap::gen_process_roots(int level, 1250 + bool younger_gens_as_roots, 1251 + bool activate_scope, 1252 + ScanningOption so, 1253 + bool only_strong_roots, 1254 + OopsInGenClosure* not_older_gens, 1255 + OopsInGenClosure* older_gens, 1256 + CLDClosure* cld_closure) { 1257 + const bool is_adjust_phase = !only_strong_roots && !younger_gens_as_roots; 1258 + 1259 + bool is_moving_collection = false; 1260 + if (level == 0 || is_adjust_phase) { 1261 + // young collections are always moving 1262 + is_moving_collection = true; 1263 + } 1264 + 1265 + MarkingCodeBlobClosure mark_code_closure(not_older_gens, is_moving_collection); 1266 + OopsInGenClosure* weak_roots = only_strong_roots ? NULL : not_older_gens; 1267 + CLDClosure* weak_cld_closure = only_strong_roots ? NULL : cld_closure; 1268 + 1269 + process_roots(activate_scope, so, 1270 + not_older_gens, weak_roots, 1271 + cld_closure, weak_cld_closure, 1272 + &mark_code_closure); 1273 1274 if (younger_gens_as_roots) { 1275 - if (!_gen_process_roots_tasks->is_task_claimed(GCH_PS_younger_gens)) { 1276 + if (!_process_strong_tasks->is_task_claimed(GCH_PS_younger_gens)) { 1277 for (int i = 0; i < level; i++) { 1278 not_older_gens->set_generation(_gens[i]); 1279 _gens[i]->oop_iterate(not_older_gens); 1280 1281 @@ -607,43 +721,18 @@ 1282 older_gens->reset_generation(); 1283 } 1284 1285 - _gen_process_roots_tasks->all_tasks_completed(); 1286 + _process_strong_tasks->all_tasks_completed(); 1287 } 1288 1289 -void GenCollectedHeap:: 1290 -gen_process_roots(int level, 1291 - bool younger_gens_as_roots, 1292 - bool activate_scope, 1293 - SharedHeap::ScanningOption so, 1294 - bool only_strong_roots, 1295 - OopsInGenClosure* not_older_gens, 1296 - OopsInGenClosure* older_gens, 1297 - CLDClosure* cld_closure) { 1298 1299 - const bool is_adjust_phase = !only_strong_roots && !younger_gens_as_roots; 1300 - 1301 - bool is_moving_collection = false; 1302 - if (level == 0 || is_adjust_phase) { 1303 - // young collections are always moving 1304 - is_moving_collection = true; 1305 - } 1306 - 1307 - MarkingCodeBlobClosure mark_code_closure(not_older_gens, is_moving_collection); 1308 - CodeBlobClosure* code_closure = &mark_code_closure; 1309 - 1310 - gen_process_roots(level, 1311 - younger_gens_as_roots, 1312 - activate_scope, so, 1313 - not_older_gens, only_strong_roots ? NULL : not_older_gens, 1314 - older_gens, 1315 - cld_closure, only_strong_roots ? NULL : cld_closure, 1316 - code_closure); 1317 - 1318 -} 1319 +class AlwaysTrueClosure: public BoolObjectClosure { 1320 +public: 1321 + bool do_object_b(oop p) { return true; } 1322 +}; 1323 +static AlwaysTrueClosure always_true; 1324 1325 void GenCollectedHeap::gen_process_weak_roots(OopClosure* root_closure) { 1326 - SharedHeap::process_weak_roots(root_closure); 1327 - // "Local" "weak" refs 1328 + JNIHandles::weak_oops_do(&always_true, root_closure); 1329 for (int i = 0; i < _n_gens; i++) { 1330 _gens[i]->ref_processor()->weak_oops_do(root_closure); 1331 } 1332 1333 diff --git a/src/share/vm/memory/genCollectedHeap.hpp b/src/share/vm/memory/genCollectedHeap.hpp 1334 --- a/src/share/vm/memory/genCollectedHeap.hpp 1335 +++ b/src/share/vm/memory/genCollectedHeap.hpp 1336 @@ -85,8 +85,7 @@ 1337 1338 // Data structure for claiming the (potentially) parallel tasks in 1339 // (gen-specific) roots processing. 1340 - SubTasksDone* _gen_process_roots_tasks; 1341 - SubTasksDone* gen_process_roots_tasks() { return _gen_process_roots_tasks; } 1342 + SubTasksDone* _process_strong_tasks; 1343 1344 // Collects the given generation. 1345 void collect_generation(Generation* gen, bool full, size_t size, bool is_tlab, 1346 @@ -387,6 +386,7 @@ 1347 static GenCollectedHeap* heap(); 1348 1349 void set_par_threads(uint t); 1350 + void set_n_termination(uint t); 1351 1352 // Invoke the "do_oop" method of one of the closures "not_older_gens" 1353 // or "older_gens" on root locations for the generation at 1354 @@ -400,11 +400,25 @@ 1355 // The "so" argument determines which of the roots 1356 // the closure is applied to: 1357 // "SO_None" does none; 1358 + enum ScanningOption { 1359 + SO_None = 0x0, 1360 + SO_AllCodeCache = 0x8, 1361 + SO_ScavengeCodeCache = 0x10 1362 + }; 1363 + 1364 private: 1365 + void process_roots(bool activate_scope, 1366 + ScanningOption so, 1367 + OopClosure* strong_roots, 1368 + OopClosure* weak_roots, 1369 + CLDClosure* strong_cld_closure, 1370 + CLDClosure* weak_cld_closure, 1371 + CodeBlobClosure* code_roots); 1372 + 1373 void gen_process_roots(int level, 1374 bool younger_gens_as_roots, 1375 bool activate_scope, 1376 - SharedHeap::ScanningOption so, 1377 + ScanningOption so, 1378 OopsInGenClosure* not_older_gens, 1379 OopsInGenClosure* weak_roots, 1380 OopsInGenClosure* older_gens, 1381 @@ -419,7 +433,7 @@ 1382 void gen_process_roots(int level, 1383 bool younger_gens_as_roots, 1384 bool activate_scope, 1385 - SharedHeap::ScanningOption so, 1386 + ScanningOption so, 1387 bool only_strong_roots, 1388 OopsInGenClosure* not_older_gens, 1389 OopsInGenClosure* older_gens, 1390 diff --git a/src/share/vm/memory/genMarkSweep.cpp b/src/share/vm/memory/genMarkSweep.cpp 1391 --- a/src/share/vm/memory/genMarkSweep.cpp 1392 +++ b/src/share/vm/memory/genMarkSweep.cpp 1393 @@ -203,7 +203,7 @@ 1394 gch->gen_process_roots(level, 1395 false, // Younger gens are not roots. 1396 true, // activate StrongRootsScope 1397 - SharedHeap::SO_None, 1398 + GenCollectedHeap::SO_None, 1399 GenCollectedHeap::StrongRootsOnly, 1400 &follow_root_closure, 1401 &follow_root_closure, 1402 @@ -289,7 +289,7 @@ 1403 gch->gen_process_roots(level, 1404 false, // Younger gens are not roots. 1405 true, // activate StrongRootsScope 1406 - SharedHeap::SO_AllCodeCache, 1407 + GenCollectedHeap::SO_AllCodeCache, 1408 GenCollectedHeap::StrongAndWeakRoots, 1409 &adjust_pointer_closure, 1410 &adjust_pointer_closure, 1411 diff --git a/src/share/vm/memory/sharedHeap.cpp b/src/share/vm/memory/sharedHeap.cpp 1412 --- a/src/share/vm/memory/sharedHeap.cpp 1413 +++ b/src/share/vm/memory/sharedHeap.cpp 1414 @@ -32,7 +32,6 @@ 1415 #include "runtime/atomic.inline.hpp" 1416 #include "runtime/fprofiler.hpp" 1417 #include "runtime/java.hpp" 1418 -#include "services/management.hpp" 1419 #include "utilities/copy.hpp" 1420 #include "utilities/workgroup.hpp" 1421 1422 @@ -40,33 +39,13 @@ 1423 1424 SharedHeap* SharedHeap::_sh; 1425 1426 -// The set of potentially parallel tasks in root scanning. 1427 -enum SH_process_roots_tasks { 1428 - SH_PS_Universe_oops_do, 1429 - SH_PS_JNIHandles_oops_do, 1430 - SH_PS_ObjectSynchronizer_oops_do, 1431 - SH_PS_FlatProfiler_oops_do, 1432 - SH_PS_Management_oops_do, 1433 - SH_PS_SystemDictionary_oops_do, 1434 - SH_PS_ClassLoaderDataGraph_oops_do, 1435 - SH_PS_jvmti_oops_do, 1436 - SH_PS_CodeCache_oops_do, 1437 - // Leave this one last. 1438 - SH_PS_NumElements 1439 -}; 1440 - 1441 SharedHeap::SharedHeap(CollectorPolicy* policy_) : 1442 CollectedHeap(), 1443 _collector_policy(policy_), 1444 _rem_set(NULL), 1445 - _strong_roots_scope(NULL), 1446 _strong_roots_parity(0), 1447 - _process_strong_tasks(new SubTasksDone(SH_PS_NumElements)), 1448 _workers(NULL) 1449 { 1450 - if (_process_strong_tasks == NULL || !_process_strong_tasks->valid()) { 1451 - vm_exit_during_initialization("Failed necessary allocation."); 1452 - } 1453 _sh = this; // ch is static, should be set only once. 1454 if ((UseParNewGC || 1455 (UseConcMarkSweepGC && (CMSParallelInitialMarkEnabled || 1456 @@ -79,14 +58,6 @@ 1457 } 1458 } 1459 1460 -int SharedHeap::n_termination() { 1461 - return _process_strong_tasks->n_threads(); 1462 -} 1463 - 1464 -void SharedHeap::set_n_termination(int t) { 1465 - _process_strong_tasks->set_n_threads(t); 1466 -} 1467 - 1468 bool SharedHeap::heap_lock_held_for_gc() { 1469 Thread* t = Thread::current(); 1470 return Heap_lock->owned_by_self() 1471 @@ -97,31 +68,6 @@ 1472 void SharedHeap::set_par_threads(uint t) { 1473 assert(t == 0 || !UseSerialGC, "Cannot have parallel threads"); 1474 _n_par_threads = t; 1475 - _process_strong_tasks->set_n_threads(t); 1476 -} 1477 - 1478 -#ifdef ASSERT 1479 -class AssertNonScavengableClosure: public OopClosure { 1480 -public: 1481 - virtual void do_oop(oop* p) { 1482 - assert(!Universe::heap()->is_in_partial_collection(*p), 1483 - "Referent should not be scavengable."); } 1484 - virtual void do_oop(narrowOop* p) { ShouldNotReachHere(); } 1485 -}; 1486 -static AssertNonScavengableClosure assert_is_non_scavengable_closure; 1487 -#endif 1488 - 1489 -SharedHeap::StrongRootsScope* SharedHeap::active_strong_roots_scope() const { 1490 - return _strong_roots_scope; 1491 -} 1492 -void SharedHeap::register_strong_roots_scope(SharedHeap::StrongRootsScope* scope) { 1493 - assert(_strong_roots_scope == NULL, "Should only have one StrongRootsScope active"); 1494 - assert(scope != NULL, "Illegal argument"); 1495 - _strong_roots_scope = scope; 1496 -} 1497 -void SharedHeap::unregister_strong_roots_scope(SharedHeap::StrongRootsScope* scope) { 1498 - assert(_strong_roots_scope == scope, "Wrong scope unregistered"); 1499 - _strong_roots_scope = NULL; 1500 } 1501 1502 void SharedHeap::change_strong_roots_parity() { 1503 @@ -135,174 +81,15 @@ 1504 } 1505 1506 SharedHeap::StrongRootsScope::StrongRootsScope(SharedHeap* heap, bool activate) 1507 - : MarkScope(activate), _sh(heap), _n_workers_done_with_threads(0) 1508 + : MarkScope(activate), _sh(heap) 1509 { 1510 if (_active) { 1511 - _sh->register_strong_roots_scope(this); 1512 _sh->change_strong_roots_parity(); 1513 // Zero the claimed high water mark in the StringTable 1514 StringTable::clear_parallel_claimed_index(); 1515 } 1516 } 1517 1518 -SharedHeap::StrongRootsScope::~StrongRootsScope() { 1519 - if (_active) { 1520 - _sh->unregister_strong_roots_scope(this); 1521 - } 1522 -} 1523 - 1524 -Monitor* SharedHeap::StrongRootsScope::_lock = new Monitor(Mutex::leaf, "StrongRootsScope lock", false); 1525 - 1526 -void SharedHeap::StrongRootsScope::mark_worker_done_with_threads(uint n_workers) { 1527 - // The Thread work barrier is only needed by G1 Class Unloading. 1528 - // No need to use the barrier if this is single-threaded code. 1529 - if (UseG1GC && ClassUnloadingWithConcurrentMark && n_workers > 0) { 1530 - uint new_value = (uint)Atomic::add(1, &_n_workers_done_with_threads); 1531 - if (new_value == n_workers) { 1532 - // This thread is last. Notify the others. 1533 - MonitorLockerEx ml(_lock, Mutex::_no_safepoint_check_flag); 1534 - _lock->notify_all(); 1535 - } 1536 - } 1537 -} 1538 - 1539 -void SharedHeap::StrongRootsScope::wait_until_all_workers_done_with_threads(uint n_workers) { 1540 - assert(UseG1GC, "Currently only used by G1"); 1541 - assert(ClassUnloadingWithConcurrentMark, "Currently only needed when doing G1 Class Unloading"); 1542 - 1543 - // No need to use the barrier if this is single-threaded code. 1544 - if (n_workers > 0 && (uint)_n_workers_done_with_threads != n_workers) { 1545 - MonitorLockerEx ml(_lock, Mutex::_no_safepoint_check_flag); 1546 - while ((uint)_n_workers_done_with_threads != n_workers) { 1547 - _lock->wait(Mutex::_no_safepoint_check_flag, 0, false); 1548 - } 1549 - } 1550 -} 1551 - 1552 -void SharedHeap::process_roots(bool activate_scope, 1553 - ScanningOption so, 1554 - OopClosure* strong_roots, 1555 - OopClosure* weak_roots, 1556 - CLDClosure* strong_cld_closure, 1557 - CLDClosure* weak_cld_closure, 1558 - CodeBlobClosure* code_roots) { 1559 - StrongRootsScope srs(this, activate_scope); 1560 - 1561 - // General roots. 1562 - assert(_strong_roots_parity != 0, "must have called prologue code"); 1563 - assert(code_roots != NULL, "code root closure should always be set"); 1564 - // _n_termination for _process_strong_tasks should be set up stream 1565 - // in a method not running in a GC worker. Otherwise the GC worker 1566 - // could be trying to change the termination condition while the task 1567 - // is executing in another GC worker. 1568 - 1569 - // Iterating over the CLDG and the Threads are done early to allow G1 to 1570 - // first process the strong CLDs and nmethods and then, after a barrier, 1571 - // let the thread process the weak CLDs and nmethods. 1572 - 1573 - if (!_process_strong_tasks->is_task_claimed(SH_PS_ClassLoaderDataGraph_oops_do)) { 1574 - ClassLoaderDataGraph::roots_cld_do(strong_cld_closure, weak_cld_closure); 1575 - } 1576 - 1577 - // Some CLDs contained in the thread frames should be considered strong. 1578 - // Don't process them if they will be processed during the ClassLoaderDataGraph phase. 1579 - CLDClosure* roots_from_clds_p = (strong_cld_closure != weak_cld_closure) ? strong_cld_closure : NULL; 1580 - // Only process code roots from thread stacks if we aren't visiting the entire CodeCache anyway 1581 - CodeBlobClosure* roots_from_code_p = (so & SO_AllCodeCache) ? NULL : code_roots; 1582 - 1583 - Threads::possibly_parallel_oops_do(strong_roots, roots_from_clds_p, roots_from_code_p); 1584 - 1585 - // This is the point where this worker thread will not find more strong CLDs/nmethods. 1586 - // Report this so G1 can synchronize the strong and weak CLDs/nmethods processing. 1587 - active_strong_roots_scope()->mark_worker_done_with_threads(n_par_threads()); 1588 - 1589 - if (!_process_strong_tasks->is_task_claimed(SH_PS_Universe_oops_do)) { 1590 - Universe::oops_do(strong_roots); 1591 - } 1592 - // Global (strong) JNI handles 1593 - if (!_process_strong_tasks->is_task_claimed(SH_PS_JNIHandles_oops_do)) 1594 - JNIHandles::oops_do(strong_roots); 1595 - 1596 - if (!_process_strong_tasks-> is_task_claimed(SH_PS_ObjectSynchronizer_oops_do)) 1597 - ObjectSynchronizer::oops_do(strong_roots); 1598 - if (!_process_strong_tasks->is_task_claimed(SH_PS_FlatProfiler_oops_do)) 1599 - FlatProfiler::oops_do(strong_roots); 1600 - if (!_process_strong_tasks->is_task_claimed(SH_PS_Management_oops_do)) 1601 - Management::oops_do(strong_roots); 1602 - if (!_process_strong_tasks->is_task_claimed(SH_PS_jvmti_oops_do)) 1603 - JvmtiExport::oops_do(strong_roots); 1604 - 1605 - if (!_process_strong_tasks->is_task_claimed(SH_PS_SystemDictionary_oops_do)) { 1606 - SystemDictionary::roots_oops_do(strong_roots, weak_roots); 1607 - } 1608 - 1609 - // All threads execute the following. A specific chunk of buckets 1610 - // from the StringTable are the individual tasks. 1611 - if (weak_roots != NULL) { 1612 - if (CollectedHeap::use_parallel_gc_threads()) { 1613 - StringTable::possibly_parallel_oops_do(weak_roots); 1614 - } else { 1615 - StringTable::oops_do(weak_roots); 1616 - } 1617 - } 1618 - 1619 - if (!_process_strong_tasks->is_task_claimed(SH_PS_CodeCache_oops_do)) { 1620 - if (so & SO_ScavengeCodeCache) { 1621 - assert(code_roots != NULL, "must supply closure for code cache"); 1622 - 1623 - // We only visit parts of the CodeCache when scavenging. 1624 - CodeCache::scavenge_root_nmethods_do(code_roots); 1625 - } 1626 - if (so & SO_AllCodeCache) { 1627 - assert(code_roots != NULL, "must supply closure for code cache"); 1628 - 1629 - // CMSCollector uses this to do intermediate-strength collections. 1630 - // We scan the entire code cache, since CodeCache::do_unloading is not called. 1631 - CodeCache::blobs_do(code_roots); 1632 - } 1633 - // Verify that the code cache contents are not subject to 1634 - // movement by a scavenging collection. 1635 - DEBUG_ONLY(CodeBlobToOopClosure assert_code_is_non_scavengable(&assert_is_non_scavengable_closure, !CodeBlobToOopClosure::FixRelocations)); 1636 - DEBUG_ONLY(CodeCache::asserted_non_scavengable_nmethods_do(&assert_code_is_non_scavengable)); 1637 - } 1638 - 1639 - _process_strong_tasks->all_tasks_completed(); 1640 -} 1641 - 1642 -void SharedHeap::process_all_roots(bool activate_scope, 1643 - ScanningOption so, 1644 - OopClosure* roots, 1645 - CLDClosure* cld_closure, 1646 - CodeBlobClosure* code_closure) { 1647 - process_roots(activate_scope, so, 1648 - roots, roots, 1649 - cld_closure, cld_closure, 1650 - code_closure); 1651 -} 1652 - 1653 -void SharedHeap::process_strong_roots(bool activate_scope, 1654 - ScanningOption so, 1655 - OopClosure* roots, 1656 - CLDClosure* cld_closure, 1657 - CodeBlobClosure* code_closure) { 1658 - process_roots(activate_scope, so, 1659 - roots, NULL, 1660 - cld_closure, NULL, 1661 - code_closure); 1662 -} 1663 - 1664 - 1665 -class AlwaysTrueClosure: public BoolObjectClosure { 1666 -public: 1667 - bool do_object_b(oop p) { return true; } 1668 -}; 1669 -static AlwaysTrueClosure always_true; 1670 - 1671 -void SharedHeap::process_weak_roots(OopClosure* root_closure) { 1672 - // Global (weak) JNI handles 1673 - JNIHandles::weak_oops_do(&always_true, root_closure); 1674 -} 1675 - 1676 void SharedHeap::set_barrier_set(BarrierSet* bs) { 1677 _barrier_set = bs; 1678 // Cached barrier set for fast access in oops 1679 diff --git a/src/share/vm/memory/sharedHeap.hpp b/src/share/vm/memory/sharedHeap.hpp 1680 --- a/src/share/vm/memory/sharedHeap.hpp 1681 +++ b/src/share/vm/memory/sharedHeap.hpp 1682 @@ -61,18 +61,18 @@ 1683 // counts the number of tasks that have been done and then reset 1684 // the SubTasksDone so that it can be used again. When the number of 1685 // tasks is set to the number of GC workers, then _n_threads must 1686 -// be set to the number of active GC workers. G1CollectedHeap, 1687 -// HRInto_G1RemSet, GenCollectedHeap and SharedHeap have SubTasksDone. 1688 -// This seems too many. 1689 +// be set to the number of active GC workers. G1RootProcessor and 1690 +// GenCollectedHeap have SubTasksDone. 1691 // 3) SequentialSubTasksDone has an _n_threads that is used in 1692 // a way similar to SubTasksDone and has the same dependency on the 1693 // number of active GC workers. CompactibleFreeListSpace and Space 1694 // have SequentialSubTasksDone's. 1695 -// Example of using SubTasksDone and SequentialSubTasksDone 1696 -// G1CollectedHeap::g1_process_roots() 1697 -// to SharedHeap::process_roots() and uses 1698 -// SubTasksDone* _process_strong_tasks to claim tasks. 1699 -// process_roots() calls 1700 +// 1701 +// Examples of using SubTasksDone and SequentialSubTasksDone: 1702 +// G1RootProcessor and GenCollectedHeap::process_roots() use 1703 +// SubTasksDone* _process_strong_tasks to claim tasks for workers 1704 +// 1705 +// GenCollectedHeap::gen_process_roots() calls 1706 // rem_set()->younger_refs_iterate() 1707 // to scan the card table and which eventually calls down into 1708 // CardTableModRefBS::par_non_clean_card_iterate_work(). This method 1709 @@ -104,10 +104,6 @@ 1710 friend class VM_GC_Operation; 1711 friend class VM_CGC_Operation; 1712 1713 -private: 1714 - // For claiming strong_roots tasks. 1715 - SubTasksDone* _process_strong_tasks; 1716 - 1717 protected: 1718 // There should be only a single instance of "SharedHeap" in a program. 1719 // This is enforced with the protected constructor below, which will also 1720 @@ -140,7 +136,6 @@ 1721 static SharedHeap* heap() { return _sh; } 1722 1723 void set_barrier_set(BarrierSet* bs); 1724 - SubTasksDone* process_strong_tasks() { return _process_strong_tasks; } 1725 1726 // Does operations required after initialization has been done. 1727 virtual void post_initialize(); 1728 @@ -193,69 +188,19 @@ 1729 // strong_roots_prologue calls change_strong_roots_parity, if 1730 // parallel tasks are enabled. 1731 class StrongRootsScope : public MarkingCodeBlobClosure::MarkScope { 1732 - // Used to implement the Thread work barrier. 1733 - static Monitor* _lock; 1734 - 1735 SharedHeap* _sh; 1736 - volatile jint _n_workers_done_with_threads; 1737 1738 public: 1739 StrongRootsScope(SharedHeap* heap, bool activate = true); 1740 - ~StrongRootsScope(); 1741 - 1742 - // Mark that this thread is done with the Threads work. 1743 - void mark_worker_done_with_threads(uint n_workers); 1744 - // Wait until all n_workers are done with the Threads work. 1745 - void wait_until_all_workers_done_with_threads(uint n_workers); 1746 }; 1747 friend class StrongRootsScope; 1748 1749 - // The current active StrongRootScope 1750 - StrongRootsScope* _strong_roots_scope; 1751 - 1752 - StrongRootsScope* active_strong_roots_scope() const; 1753 - 1754 private: 1755 - void register_strong_roots_scope(StrongRootsScope* scope); 1756 - void unregister_strong_roots_scope(StrongRootsScope* scope); 1757 void change_strong_roots_parity(); 1758 1759 public: 1760 - enum ScanningOption { 1761 - SO_None = 0x0, 1762 - SO_AllCodeCache = 0x8, 1763 - SO_ScavengeCodeCache = 0x10 1764 - }; 1765 - 1766 FlexibleWorkGang* workers() const { return _workers; } 1767 1768 - // Invoke the "do_oop" method the closure "roots" on all root locations. 1769 - // The "so" argument determines which roots the closure is applied to: 1770 - // "SO_None" does none; 1771 - // "SO_AllCodeCache" applies the closure to all elements of the CodeCache. 1772 - // "SO_ScavengeCodeCache" applies the closure to elements on the scavenge root list in the CodeCache. 1773 - void process_roots(bool activate_scope, 1774 - ScanningOption so, 1775 - OopClosure* strong_roots, 1776 - OopClosure* weak_roots, 1777 - CLDClosure* strong_cld_closure, 1778 - CLDClosure* weak_cld_closure, 1779 - CodeBlobClosure* code_roots); 1780 - void process_all_roots(bool activate_scope, 1781 - ScanningOption so, 1782 - OopClosure* roots, 1783 - CLDClosure* cld_closure, 1784 - CodeBlobClosure* code_roots); 1785 - void process_strong_roots(bool activate_scope, 1786 - ScanningOption so, 1787 - OopClosure* roots, 1788 - CLDClosure* cld_closure, 1789 - CodeBlobClosure* code_roots); 1790 - 1791 - 1792 - // Apply "root_closure" to the JNI weak roots.. 1793 - void process_weak_roots(OopClosure* root_closure); 1794 - 1795 // The functions below are helper functions that a subclass of 1796 // "SharedHeap" can use in the implementation of its virtual 1797 // functions. 1798 @@ -270,9 +215,6 @@ 1799 // (such as process roots) subsequently. 1800 virtual void set_par_threads(uint t); 1801 1802 - int n_termination(); 1803 - void set_n_termination(int t); 1804 - 1805 // 1806 // New methods from CollectedHeap 1807 // 1808 @@ -284,8 +226,4 @@ 1809 size_t capacity); 1810 }; 1811 1812 -inline SharedHeap::ScanningOption operator|(SharedHeap::ScanningOption so0, SharedHeap::ScanningOption so1) { 1813 - return static_cast<SharedHeap::ScanningOption>(static_cast<int>(so0) | static_cast<int>(so1)); 1814 -} 1815 - 1816 #endif // SHARE_VM_MEMORY_SHAREDHEAP_HPP