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() for parallelism. 127 -// The number of GC workers is passed to heap_region_par_iterate(). 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 - G1ParPushHeapRSClosure* 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 - G1ParPushHeapRSClosure* 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,7 +79,6 @@ 607 _cards_scanned(NULL), _total_cards_scanned(0), 608 _prev_period_summary() 609 { 610 - _seq_task = new SubTasksDone(NumSeqTasks); 611 _cset_rs_update_cl = NEW_C_HEAP_ARRAY(G1ParPushHeapRSClosure*, n_workers(), mtGC); 612 for (uint i = 0; i < n_workers(); i++) { 613 _cset_rs_update_cl[i] = NULL; 614 @@ -90,7 +89,6 @@ 615 } 616 617 G1RemSet::~G1RemSet() { 618 - delete _seq_task; 619 for (uint i = 0; i < n_workers(); i++) { 620 assert(_cset_rs_update_cl[i] == NULL, "it should be"); 621 } 622 diff --git a/src/share/vm/gc_implementation/g1/g1RemSet.hpp b/src/share/vm/gc_implementation/g1/g1RemSet.hpp 623 --- a/src/share/vm/gc_implementation/g1/g1RemSet.hpp 624 +++ b/src/share/vm/gc_implementation/g1/g1RemSet.hpp 625 @@ -58,7 +58,6 @@ 626 }; 627 628 CardTableModRefBS* _ct_bs; 629 - SubTasksDone* _seq_task; 630 G1CollectorPolicy* _g1p; 631 632 ConcurrentG1Refine* _cg1r; 633 diff --git a/src/share/vm/gc_implementation/g1/g1RootProcessor.cpp b/src/share/vm/gc_implementation/g1/g1RootProcessor.cpp 634 new file mode 100644 635 --- /dev/null 636 +++ b/src/share/vm/gc_implementation/g1/g1RootProcessor.cpp 637 @@ -0,0 +1,290 @@ 638 +/* 639 + * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved. 640 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 641 + * 642 + * This code is free software; you can redistribute it and/or modify it 643 + * under the terms of the GNU General Public License version 2 only, as 644 + * published by the Free Software Foundation. 645 + * 646 + * This code is distributed in the hope that it will be useful, but WITHOUT 647 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 648 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 649 + * version 2 for more details (a copy is included in the LICENSE file that 650 + * accompanied this code). 651 + * 652 + * You should have received a copy of the GNU General Public License version 653 + * 2 along with this work; if not, write to the Free Software Foundation, 654 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 655 + * 656 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 657 + * or visit www.oracle.com if you need additional information or have any 658 + * questions. 659 + * 660 + */ 661 + 662 +#include "precompiled.hpp" 663 + 664 +#include "classfile/stringTable.hpp" 665 +#include "classfile/systemDictionary.hpp" 666 +#include "code/codeCache.hpp" 667 +#include "gc_implementation/g1/bufferingOopClosure.hpp" 668 +#include "gc_implementation/g1/g1CollectedHeap.inline.hpp" 669 +#include "gc_implementation/g1/g1CollectorPolicy.hpp" 670 +#include "gc_implementation/g1/g1GCPhaseTimes.hpp" 671 +#include "gc_implementation/g1/g1RemSet.inline.hpp" 672 +#include "gc_implementation/g1/g1RootProcessor.hpp" 673 +#include "memory/allocation.inline.hpp" 674 +#include "runtime/fprofiler.hpp" 675 +#include "runtime/mutex.hpp" 676 +#include "services/management.hpp" 677 + 678 +class G1CodeBlobClosure : public CodeBlobClosure { 679 + class HeapRegionGatheringOopClosure : public OopClosure { 680 + G1CollectedHeap* _g1h; 681 + OopClosure* _work; 682 + nmethod* _nm; 683 + 684 + template <typename T> 685 + void do_oop_work(T* p) { 686 + _work->do_oop(p); 687 + T oop_or_narrowoop = oopDesc::load_heap_oop(p); 688 + if (!oopDesc::is_null(oop_or_narrowoop)) { 689 + oop o = oopDesc::decode_heap_oop_not_null(oop_or_narrowoop); 690 + HeapRegion* hr = _g1h->heap_region_containing_raw(o); 691 + 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"); 692 + hr->add_strong_code_root(_nm); 693 + } 694 + } 695 + 696 + public: 697 + HeapRegionGatheringOopClosure(OopClosure* oc) : _g1h(G1CollectedHeap::heap()), _work(oc), _nm(NULL) {} 698 + 699 + void do_oop(oop* o) { 700 + do_oop_work(o); 701 + } 702 + 703 + void do_oop(narrowOop* o) { 704 + do_oop_work(o); 705 + } 706 + 707 + void set_nm(nmethod* nm) { 708 + _nm = nm; 709 + } 710 + }; 711 + 712 + HeapRegionGatheringOopClosure _oc; 713 +public: 714 + G1CodeBlobClosure(OopClosure* oc) : _oc(oc) {} 715 + 716 + void do_code_blob(CodeBlob* cb) { 717 + nmethod* nm = cb->as_nmethod_or_null(); 718 + if (nm != NULL) { 719 + if (!nm->test_set_oops_do_mark()) { 720 + _oc.set_nm(nm); 721 + nm->oops_do(&_oc); 722 + nm->fix_oop_relocations(); 723 + } 724 + } 725 + } 726 +}; 727 + 728 + 729 +void G1RootProcessor::worker_has_discovered_all_strong_classes() { 730 + uint n_workers = _g1h->n_par_threads(); 731 + assert(ClassUnloadingWithConcurrentMark, "Currently only needed when doing G1 Class Unloading"); 732 + 733 + uint new_value = (uint)Atomic::add(1, &_n_workers_discovered_strong_classes); 734 + if (new_value == n_workers) { 735 + // This thread is last. Notify the others. 736 + MonitorLockerEx ml(&_lock, Mutex::_no_safepoint_check_flag); 737 + _lock.notify_all(); 738 + } 739 +} 740 + 741 +void G1RootProcessor::wait_until_all_strong_classes_discovered() { 742 + uint n_workers = _g1h->n_par_threads(); 743 + assert(ClassUnloadingWithConcurrentMark, "Currently only needed when doing G1 Class Unloading"); 744 + 745 + if ((uint)_n_workers_discovered_strong_classes != n_workers) { 746 + MonitorLockerEx ml(&_lock, Mutex::_no_safepoint_check_flag); 747 + while ((uint)_n_workers_discovered_strong_classes != n_workers) { 748 + _lock.wait(Mutex::_no_safepoint_check_flag, 0, false); 749 + } 750 + } 751 +} 752 + 753 +G1RootProcessor::G1RootProcessor(G1CollectedHeap* g1h) : 754 + _g1h(g1h), 755 + _process_strong_tasks(new SubTasksDone(G1RP_PS_NumElements)), 756 + _srs(g1h), 757 + _lock(Mutex::leaf, "G1 Root Scanning barrier lock", false, Monitor::_safepoint_check_never), 758 + _n_workers_discovered_strong_classes(0) {} 759 + 760 +void G1RootProcessor::evacuate_roots(OopClosure* scan_non_heap_roots, 761 + OopClosure* scan_non_heap_weak_roots, 762 + CLDClosure* scan_strong_clds, 763 + CLDClosure* scan_weak_clds, 764 + bool trace_metadata, 765 + uint worker_i) { 766 + // First scan the shared roots. 767 + double ext_roots_start = os::elapsedTime(); 768 + 769 + BufferingOopClosure buf_scan_non_heap_roots(scan_non_heap_roots); 770 + BufferingOopClosure buf_scan_non_heap_weak_roots(scan_non_heap_weak_roots); 771 + 772 + OopClosure* const weak_roots = &buf_scan_non_heap_weak_roots; 773 + OopClosure* const strong_roots = &buf_scan_non_heap_roots; 774 + 775 + // CodeBlobClosures are not interoperable with BufferingOopClosures 776 + G1CodeBlobClosure root_code_blobs(scan_non_heap_roots); 777 + 778 + process_java_roots(strong_roots, 779 + trace_metadata ? scan_strong_clds : NULL, 780 + scan_strong_clds, 781 + trace_metadata ? NULL : scan_weak_clds, 782 + &root_code_blobs); 783 + 784 + // This is the point where this worker thread will not find more strong CLDs/nmethods. 785 + // Report this so G1 can synchronize the strong and weak CLDs/nmethods processing. 786 + if (trace_metadata) { 787 + worker_has_discovered_all_strong_classes(); 788 + } 789 + 790 + process_vm_roots(strong_roots, weak_roots); 791 + 792 + // Now the CM ref_processor roots. 793 + if (!_process_strong_tasks->is_task_claimed(G1RP_PS_refProcessor_oops_do)) { 794 + // We need to treat the discovered reference lists of the 795 + // concurrent mark ref processor as roots and keep entries 796 + // (which are added by the marking threads) on them live 797 + // until they can be processed at the end of marking. 798 + _g1h->ref_processor_cm()->weak_oops_do(&buf_scan_non_heap_roots); 799 + } 800 + 801 + if (trace_metadata) { 802 + // Barrier to make sure all workers passed 803 + // the strong CLD and strong nmethods phases. 804 + wait_until_all_strong_classes_discovered(); 805 + 806 + // Now take the complement of the strong CLDs. 807 + ClassLoaderDataGraph::roots_cld_do(NULL, scan_weak_clds); 808 + } 809 + 810 + // Finish up any enqueued closure apps (attributed as object copy time). 811 + buf_scan_non_heap_roots.done(); 812 + buf_scan_non_heap_weak_roots.done(); 813 + 814 + double obj_copy_time_sec = buf_scan_non_heap_roots.closure_app_seconds() 815 + + buf_scan_non_heap_weak_roots.closure_app_seconds(); 816 + 817 + G1GCPhaseTimes* phase_times = _g1h->g1_policy()->phase_times(); 818 + phase_times->record_time_secs(G1GCPhaseTimes::ObjCopy, worker_i, obj_copy_time_sec); 819 + 820 + double ext_root_time_sec = os::elapsedTime() - ext_roots_start - obj_copy_time_sec; 821 + 822 + phase_times->record_time_secs(G1GCPhaseTimes::ExtRootScan, worker_i, ext_root_time_sec); 823 + 824 + // During conc marking we have to filter the per-thread SATB buffers 825 + // to make sure we remove any oops into the CSet (which will show up 826 + // as implicitly live). 827 + { 828 + G1GCParPhaseTimesTracker x(phase_times, G1GCPhaseTimes::SATBFiltering, worker_i); 829 + if (!_process_strong_tasks->is_task_claimed(G1RP_PS_filter_satb_buffers) && _g1h->mark_in_progress()) { 830 + JavaThread::satb_mark_queue_set().filter_thread_buffers(); 831 + } 832 + } 833 + 834 + _process_strong_tasks->all_tasks_completed(); 835 +} 836 + 837 +void G1RootProcessor::process_strong_roots(OopClosure* oops, 838 + CLDClosure* clds, 839 + CodeBlobClosure* blobs) { 840 + 841 + process_java_roots(oops, clds, clds, NULL, blobs); 842 + process_vm_roots(oops, NULL); 843 + 844 + _process_strong_tasks->all_tasks_completed(); 845 +} 846 + 847 +void G1RootProcessor::process_all_roots(OopClosure* oops, 848 + CLDClosure* clds, 849 + CodeBlobClosure* blobs) { 850 + 851 + process_java_roots(oops, NULL, clds, clds, NULL); 852 + process_vm_roots(oops, oops); 853 + 854 + if (!_process_strong_tasks->is_task_claimed(G1RP_PS_CodeCache_oops_do)) { 855 + CodeCache::blobs_do(blobs); 856 + } 857 + 858 + _process_strong_tasks->all_tasks_completed(); 859 +} 860 + 861 +void G1RootProcessor::process_java_roots(OopClosure* strong_roots, 862 + CLDClosure* thread_stack_clds, 863 + CLDClosure* strong_clds, 864 + CLDClosure* weak_clds, 865 + CodeBlobClosure* strong_code) { 866 + assert(thread_stack_clds == NULL || weak_clds == NULL, "There is overlap between those, only one may be set"); 867 + // Iterating over the CLDG and the Threads are done early to allow us to 868 + // first process the strong CLDs and nmethods and then, after a barrier, 869 + // let the thread process the weak CLDs and nmethods. 870 + 871 + if (!_process_strong_tasks->is_task_claimed(G1RP_PS_ClassLoaderDataGraph_oops_do)) { 872 + ClassLoaderDataGraph::roots_cld_do(strong_clds, weak_clds); 873 + } 874 + 875 + Threads::possibly_parallel_oops_do(strong_roots, thread_stack_clds, strong_code); 876 +} 877 + 878 +void G1RootProcessor::process_vm_roots(OopClosure* strong_roots, 879 + OopClosure* weak_roots) { 880 + 881 + if (!_process_strong_tasks->is_task_claimed(G1RP_PS_Universe_oops_do)) { 882 + Universe::oops_do(strong_roots); 883 + } 884 + 885 + if (!_process_strong_tasks->is_task_claimed(G1RP_PS_JNIHandles_oops_do)) { 886 + JNIHandles::oops_do(strong_roots); 887 + } 888 + 889 + if (!_process_strong_tasks-> is_task_claimed(G1RP_PS_ObjectSynchronizer_oops_do)) { 890 + ObjectSynchronizer::oops_do(strong_roots); 891 + } 892 + 893 + if (!_process_strong_tasks->is_task_claimed(G1RP_PS_FlatProfiler_oops_do)) { 894 + FlatProfiler::oops_do(strong_roots); 895 + } 896 + 897 + if (!_process_strong_tasks->is_task_claimed(G1RP_PS_Management_oops_do)) { 898 + Management::oops_do(strong_roots); 899 + } 900 + 901 + if (!_process_strong_tasks->is_task_claimed(G1RP_PS_jvmti_oops_do)) { 902 + JvmtiExport::oops_do(strong_roots); 903 + } 904 + 905 + if (!_process_strong_tasks->is_task_claimed(G1RP_PS_SystemDictionary_oops_do)) { 906 + SystemDictionary::roots_oops_do(strong_roots, weak_roots); 907 + } 908 + 909 + // All threads execute the following. A specific chunk of buckets 910 + // from the StringTable are the individual tasks. 911 + if (weak_roots != NULL) { 912 + StringTable::possibly_parallel_oops_do(weak_roots); 913 + } 914 +} 915 + 916 +void G1RootProcessor::scan_remembered_sets(G1ParPushHeapRSClosure* scan_rs, 917 + OopClosure* scan_non_heap_weak_roots, 918 + uint worker_i) { 919 + // Now scan the complement of the collection set. 920 + G1CodeBlobClosure scavenge_cs_nmethods(scan_non_heap_weak_roots); 921 + 922 + _g1h->g1_rem_set()->oops_into_collection_set_do(scan_rs, &scavenge_cs_nmethods, worker_i); 923 +} 924 + 925 +void G1RootProcessor::set_num_workers(int active_workers) { 926 + _process_strong_tasks->set_n_threads(active_workers); 927 +} 928 diff --git a/src/share/vm/gc_implementation/g1/g1RootProcessor.hpp b/src/share/vm/gc_implementation/g1/g1RootProcessor.hpp 929 new file mode 100644 930 --- /dev/null 931 +++ b/src/share/vm/gc_implementation/g1/g1RootProcessor.hpp 932 @@ -0,0 +1,116 @@ 933 +/* 934 + * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved. 935 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 936 + * 937 + * This code is free software; you can redistribute it and/or modify it 938 + * under the terms of the GNU General Public License version 2 only, as 939 + * published by the Free Software Foundation. 940 + * 941 + * This code is distributed in the hope that it will be useful, but WITHOUT 942 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 943 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 944 + * version 2 for more details (a copy is included in the LICENSE file that 945 + * accompanied this code). 946 + * 947 + * You should have received a copy of the GNU General Public License version 948 + * 2 along with this work; if not, write to the Free Software Foundation, 949 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 950 + * 951 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 952 + * or visit www.oracle.com if you need additional information or have any 953 + * questions. 954 + * 955 + */ 956 + 957 +#ifndef SHARE_VM_GC_IMPLEMENTATION_G1_ROOTPROCESSOR_HPP 958 +#define SHARE_VM_GC_IMPLEMENTATION_G1_ROOTPROCESSOR_HPP 959 + 960 +#include "memory/allocation.hpp" 961 +#include "memory/sharedHeap.hpp" 962 +#include "runtime/mutex.hpp" 963 + 964 +class CLDClosure; 965 +class CodeBlobClosure; 966 +class G1CollectedHeap; 967 +class G1ParPushHeapRSClosure; 968 +class Monitor; 969 +class OopClosure; 970 +class SubTasksDone; 971 + 972 +// Scoped object to assist in applying oop, CLD and code blob closures to 973 +// root locations. Handles claiming of different root scanning tasks 974 +// and takes care of global state for root scanning via a StrongRootsScope. 975 +// In the parallel case there is a shared G1RootProcessor object where all 976 +// worker thread call the process_roots methods. 977 +class G1RootProcessor : public StackObj { 978 + G1CollectedHeap* _g1h; 979 + SubTasksDone* _process_strong_tasks; 980 + SharedHeap::StrongRootsScope _srs; 981 + 982 + // Used to implement the Thread work barrier. 983 + Monitor _lock; 984 + volatile jint _n_workers_discovered_strong_classes; 985 + 986 + enum G1H_process_roots_tasks { 987 + G1RP_PS_Universe_oops_do, 988 + G1RP_PS_JNIHandles_oops_do, 989 + G1RP_PS_ObjectSynchronizer_oops_do, 990 + G1RP_PS_FlatProfiler_oops_do, 991 + G1RP_PS_Management_oops_do, 992 + G1RP_PS_SystemDictionary_oops_do, 993 + G1RP_PS_ClassLoaderDataGraph_oops_do, 994 + G1RP_PS_jvmti_oops_do, 995 + G1RP_PS_CodeCache_oops_do, 996 + G1RP_PS_filter_satb_buffers, 997 + G1RP_PS_refProcessor_oops_do, 998 + // Leave this one last. 999 + G1RP_PS_NumElements 1000 + }; 1001 + 1002 + void worker_has_discovered_all_strong_classes(); 1003 + void wait_until_all_strong_classes_discovered(); 1004 + 1005 + void process_java_roots(OopClosure* scan_non_heap_roots, 1006 + CLDClosure* thread_stack_clds, 1007 + CLDClosure* scan_strong_clds, 1008 + CLDClosure* scan_weak_clds, 1009 + CodeBlobClosure* scan_strong_code); 1010 + 1011 + void process_vm_roots(OopClosure* scan_non_heap_roots, 1012 + OopClosure* scan_non_heap_weak_roots); 1013 + 1014 +public: 1015 + G1RootProcessor(G1CollectedHeap* g1h); 1016 + 1017 + // Apply closures to the strongly and weakly reachable roots in the system 1018 + // in a single pass. 1019 + // Record and report timing measurements for sub phases using the worker_i 1020 + void evacuate_roots(OopClosure* scan_non_heap_roots, 1021 + OopClosure* scan_non_heap_weak_roots, 1022 + CLDClosure* scan_strong_clds, 1023 + CLDClosure* scan_weak_clds, 1024 + bool trace_metadata, 1025 + uint worker_i); 1026 + 1027 + // Apply oops, clds and blobs to all strongly reachable roots in the system 1028 + void process_strong_roots(OopClosure* oops, 1029 + CLDClosure* clds, 1030 + CodeBlobClosure* blobs); 1031 + 1032 + // Apply oops, clds and blobs to strongly and weakly reachable roots in the system 1033 + void process_all_roots(OopClosure* oops, 1034 + CLDClosure* clds, 1035 + CodeBlobClosure* blobs); 1036 + 1037 + // Apply scan_rs to all locations in the union of the remembered sets for all 1038 + // regions in the collection set 1039 + // (having done "set_region" to indicate the region in which the root resides), 1040 + void scan_remembered_sets(G1ParPushHeapRSClosure* scan_rs, 1041 + OopClosure* scan_non_heap_weak_roots, 1042 + uint worker_i); 1043 + 1044 + // Inform the root processor about the number of worker threads 1045 + void set_num_workers(int active_workers); 1046 +}; 1047 + 1048 +#endif // SHARE_VM_GC_IMPLEMENTATION_G1_ROOTPROCESSOR_HPP 1049 diff --git a/src/share/vm/gc_implementation/parNew/parNewGeneration.cpp b/src/share/vm/gc_implementation/parNew/parNewGeneration.cpp 1050 --- a/src/share/vm/gc_implementation/parNew/parNewGeneration.cpp 1051 +++ b/src/share/vm/gc_implementation/parNew/parNewGeneration.cpp 1052 @@ -618,7 +618,7 @@ 1053 true, // Process younger gens, if any, 1054 // as strong roots. 1055 false, // no scope; this is parallel code 1056 - SharedHeap::SO_ScavengeCodeCache, 1057 + GenCollectedHeap::SO_ScavengeCodeCache, 1058 GenCollectedHeap::StrongAndWeakRoots, 1059 &par_scan_state.to_space_root_closure(), 1060 &par_scan_state.older_gen_closure(), 1061 diff --git a/src/share/vm/memory/defNewGeneration.cpp b/src/share/vm/memory/defNewGeneration.cpp 1062 --- a/src/share/vm/memory/defNewGeneration.cpp 1063 +++ b/src/share/vm/memory/defNewGeneration.cpp 1064 @@ -626,7 +626,7 @@ 1065 true, // Process younger gens, if any, 1066 // as strong roots. 1067 true, // activate StrongRootsScope 1068 - SharedHeap::SO_ScavengeCodeCache, 1069 + GenCollectedHeap::SO_ScavengeCodeCache, 1070 GenCollectedHeap::StrongAndWeakRoots, 1071 &fsc_with_no_gc_barrier, 1072 &fsc_with_gc_barrier, 1073 diff --git a/src/share/vm/memory/genCollectedHeap.cpp b/src/share/vm/memory/genCollectedHeap.cpp 1074 --- a/src/share/vm/memory/genCollectedHeap.cpp 1075 +++ b/src/share/vm/memory/genCollectedHeap.cpp 1076 @@ -26,6 +26,7 @@ 1077 #include "classfile/symbolTable.hpp" 1078 #include "classfile/systemDictionary.hpp" 1079 #include "classfile/vmSymbols.hpp" 1080 +#include "code/codeCache.hpp" 1081 #include "code/icBuffer.hpp" 1082 #include "gc_implementation/shared/collectorCounters.hpp" 1083 #include "gc_implementation/shared/gcTrace.hpp" 1084 @@ -47,6 +48,7 @@ 1085 #include "runtime/handles.inline.hpp" 1086 #include "runtime/java.hpp" 1087 #include "runtime/vmThread.hpp" 1088 +#include "services/management.hpp" 1089 #include "services/memoryService.hpp" 1090 #include "utilities/vmError.hpp" 1091 #include "utilities/workgroup.hpp" 1092 @@ -61,7 +63,15 @@ 1093 1094 // The set of potentially parallel tasks in root scanning. 1095 enum GCH_strong_roots_tasks { 1096 - // We probably want to parallelize both of these internally, but for now... 1097 + GCH_PS_Universe_oops_do, 1098 + GCH_PS_JNIHandles_oops_do, 1099 + GCH_PS_ObjectSynchronizer_oops_do, 1100 + GCH_PS_FlatProfiler_oops_do, 1101 + GCH_PS_Management_oops_do, 1102 + GCH_PS_SystemDictionary_oops_do, 1103 + GCH_PS_ClassLoaderDataGraph_oops_do, 1104 + GCH_PS_jvmti_oops_do, 1105 + GCH_PS_CodeCache_oops_do, 1106 GCH_PS_younger_gens, 1107 // Leave this one last. 1108 GCH_PS_NumElements 1109 @@ -71,13 +81,9 @@ 1110 SharedHeap(policy), 1111 _rem_set(NULL), 1112 _gen_policy(policy), 1113 - _gen_process_roots_tasks(new SubTasksDone(GCH_PS_NumElements)), 1114 + _process_strong_tasks(new SubTasksDone(GCH_PS_NumElements)), 1115 _full_collections_completed(0) 1116 { 1117 - if (_gen_process_roots_tasks == NULL || 1118 - !_gen_process_roots_tasks->valid()) { 1119 - vm_exit_during_initialization("Failed necessary allocation."); 1120 - } 1121 assert(policy != NULL, "Sanity check"); 1122 } 1123 1124 @@ -569,29 +575,137 @@ 1125 1126 void GenCollectedHeap::set_par_threads(uint t) { 1127 SharedHeap::set_par_threads(t); 1128 - _gen_process_roots_tasks->set_n_threads(t); 1129 + set_n_termination(t); 1130 } 1131 1132 -void GenCollectedHeap:: 1133 -gen_process_roots(int level, 1134 - bool younger_gens_as_roots, 1135 - bool activate_scope, 1136 - SharedHeap::ScanningOption so, 1137 - OopsInGenClosure* not_older_gens, 1138 - OopsInGenClosure* weak_roots, 1139 - OopsInGenClosure* older_gens, 1140 - CLDClosure* cld_closure, 1141 - CLDClosure* weak_cld_closure, 1142 - CodeBlobClosure* code_closure) { 1143 +void GenCollectedHeap::set_n_termination(uint t) { 1144 + _process_strong_tasks->set_n_threads(t); 1145 +} 1146 + 1147 +#ifdef ASSERT 1148 +class AssertNonScavengableClosure: public OopClosure { 1149 +public: 1150 + virtual void do_oop(oop* p) { 1151 + assert(!Universe::heap()->is_in_partial_collection(*p), 1152 + "Referent should not be scavengable."); } 1153 + virtual void do_oop(narrowOop* p) { ShouldNotReachHere(); } 1154 +}; 1155 +static AssertNonScavengableClosure assert_is_non_scavengable_closure; 1156 +#endif 1157 + 1158 +void GenCollectedHeap::process_roots(bool activate_scope, 1159 + ScanningOption so, 1160 + OopClosure* strong_roots, 1161 + OopClosure* weak_roots, 1162 + CLDClosure* strong_cld_closure, 1163 + CLDClosure* weak_cld_closure, 1164 + CodeBlobClosure* code_roots) { 1165 + StrongRootsScope srs(this, activate_scope); 1166 1167 // General roots. 1168 - SharedHeap::process_roots(activate_scope, so, 1169 - not_older_gens, weak_roots, 1170 - cld_closure, weak_cld_closure, 1171 - code_closure); 1172 + assert(_strong_roots_parity != 0, "must have called prologue code"); 1173 + assert(code_roots != NULL, "code root closure should always be set"); 1174 + // _n_termination for _process_strong_tasks should be set up stream 1175 + // in a method not running in a GC worker. Otherwise the GC worker 1176 + // could be trying to change the termination condition while the task 1177 + // is executing in another GC worker. 1178 + 1179 + if (!_process_strong_tasks->is_task_claimed(GCH_PS_ClassLoaderDataGraph_oops_do)) { 1180 + ClassLoaderDataGraph::roots_cld_do(strong_cld_closure, weak_cld_closure); 1181 + } 1182 + 1183 + // Some CLDs contained in the thread frames should be considered strong. 1184 + // Don't process them if they will be processed during the ClassLoaderDataGraph phase. 1185 + CLDClosure* roots_from_clds_p = (strong_cld_closure != weak_cld_closure) ? strong_cld_closure : NULL; 1186 + // Only process code roots from thread stacks if we aren't visiting the entire CodeCache anyway 1187 + CodeBlobClosure* roots_from_code_p = (so & SO_AllCodeCache) ? NULL : code_roots; 1188 + 1189 + Threads::possibly_parallel_oops_do(strong_roots, roots_from_clds_p, roots_from_code_p); 1190 + 1191 + if (!_process_strong_tasks->is_task_claimed(GCH_PS_Universe_oops_do)) { 1192 + Universe::oops_do(strong_roots); 1193 + } 1194 + // Global (strong) JNI handles 1195 + if (!_process_strong_tasks->is_task_claimed(GCH_PS_JNIHandles_oops_do)) { 1196 + JNIHandles::oops_do(strong_roots); 1197 + } 1198 + 1199 + if (!_process_strong_tasks->is_task_claimed(GCH_PS_ObjectSynchronizer_oops_do)) { 1200 + ObjectSynchronizer::oops_do(strong_roots); 1201 + } 1202 + if (!_process_strong_tasks->is_task_claimed(GCH_PS_FlatProfiler_oops_do)) { 1203 + FlatProfiler::oops_do(strong_roots); 1204 + } 1205 + if (!_process_strong_tasks->is_task_claimed(GCH_PS_Management_oops_do)) { 1206 + Management::oops_do(strong_roots); 1207 + } 1208 + if (!_process_strong_tasks->is_task_claimed(GCH_PS_jvmti_oops_do)) { 1209 + JvmtiExport::oops_do(strong_roots); 1210 + } 1211 + 1212 + if (!_process_strong_tasks->is_task_claimed(GCH_PS_SystemDictionary_oops_do)) { 1213 + SystemDictionary::roots_oops_do(strong_roots, weak_roots); 1214 + } 1215 + 1216 + // All threads execute the following. A specific chunk of buckets 1217 + // from the StringTable are the individual tasks. 1218 + if (weak_roots != NULL) { 1219 + if (CollectedHeap::use_parallel_gc_threads()) { 1220 + StringTable::possibly_parallel_oops_do(weak_roots); 1221 + } else { 1222 + StringTable::oops_do(weak_roots); 1223 + } 1224 + } 1225 + 1226 + if (!_process_strong_tasks->is_task_claimed(GCH_PS_CodeCache_oops_do)) { 1227 + if (so & SO_ScavengeCodeCache) { 1228 + assert(code_roots != NULL, "must supply closure for code cache"); 1229 + 1230 + // We only visit parts of the CodeCache when scavenging. 1231 + CodeCache::scavenge_root_nmethods_do(code_roots); 1232 + } 1233 + if (so & SO_AllCodeCache) { 1234 + assert(code_roots != NULL, "must supply closure for code cache"); 1235 + 1236 + // CMSCollector uses this to do intermediate-strength collections. 1237 + // We scan the entire code cache, since CodeCache::do_unloading is not called. 1238 + CodeCache::blobs_do(code_roots); 1239 + } 1240 + // Verify that the code cache contents are not subject to 1241 + // movement by a scavenging collection. 1242 + DEBUG_ONLY(CodeBlobToOopClosure assert_code_is_non_scavengable(&assert_is_non_scavengable_closure, !CodeBlobToOopClosure::FixRelocations)); 1243 + DEBUG_ONLY(CodeCache::asserted_non_scavengable_nmethods_do(&assert_code_is_non_scavengable)); 1244 + } 1245 + 1246 +} 1247 + 1248 +void GenCollectedHeap::gen_process_roots(int level, 1249 + bool younger_gens_as_roots, 1250 + bool activate_scope, 1251 + ScanningOption so, 1252 + bool only_strong_roots, 1253 + OopsInGenClosure* not_older_gens, 1254 + OopsInGenClosure* older_gens, 1255 + CLDClosure* cld_closure) { 1256 + const bool is_adjust_phase = !only_strong_roots && !younger_gens_as_roots; 1257 + 1258 + bool is_moving_collection = false; 1259 + if (level == 0 || is_adjust_phase) { 1260 + // young collections are always moving 1261 + is_moving_collection = true; 1262 + } 1263 + 1264 + MarkingCodeBlobClosure mark_code_closure(not_older_gens, is_moving_collection); 1265 + OopsInGenClosure* weak_roots = only_strong_roots ? NULL : not_older_gens; 1266 + CLDClosure* weak_cld_closure = only_strong_roots ? NULL : cld_closure; 1267 + 1268 + process_roots(activate_scope, so, 1269 + not_older_gens, weak_roots, 1270 + cld_closure, weak_cld_closure, 1271 + &mark_code_closure); 1272 1273 if (younger_gens_as_roots) { 1274 - if (!_gen_process_roots_tasks->is_task_claimed(GCH_PS_younger_gens)) { 1275 + if (!_process_strong_tasks->is_task_claimed(GCH_PS_younger_gens)) { 1276 if (level == 1) { 1277 not_older_gens->set_generation(_young_gen); 1278 _young_gen->oop_iterate(not_older_gens); 1279 @@ -607,43 +721,18 @@ 1280 older_gens->reset_generation(); 1281 } 1282 1283 - _gen_process_roots_tasks->all_tasks_completed(); 1284 + _process_strong_tasks->all_tasks_completed(); 1285 } 1286 1287 -void GenCollectedHeap:: 1288 -gen_process_roots(int level, 1289 - bool younger_gens_as_roots, 1290 - bool activate_scope, 1291 - SharedHeap::ScanningOption so, 1292 - bool only_strong_roots, 1293 - OopsInGenClosure* not_older_gens, 1294 - OopsInGenClosure* older_gens, 1295 - CLDClosure* cld_closure) { 1296 1297 - const bool is_adjust_phase = !only_strong_roots && !younger_gens_as_roots; 1298 - 1299 - bool is_moving_collection = false; 1300 - if (level == 0 || is_adjust_phase) { 1301 - // young collections are always moving 1302 - is_moving_collection = true; 1303 - } 1304 - 1305 - MarkingCodeBlobClosure mark_code_closure(not_older_gens, is_moving_collection); 1306 - CodeBlobClosure* code_closure = &mark_code_closure; 1307 - 1308 - gen_process_roots(level, 1309 - younger_gens_as_roots, 1310 - activate_scope, so, 1311 - not_older_gens, only_strong_roots ? NULL : not_older_gens, 1312 - older_gens, 1313 - cld_closure, only_strong_roots ? NULL : cld_closure, 1314 - code_closure); 1315 - 1316 -} 1317 +class AlwaysTrueClosure: public BoolObjectClosure { 1318 +public: 1319 + bool do_object_b(oop p) { return true; } 1320 +}; 1321 +static AlwaysTrueClosure always_true; 1322 1323 void GenCollectedHeap::gen_process_weak_roots(OopClosure* root_closure) { 1324 - SharedHeap::process_weak_roots(root_closure); 1325 - // "Local" "weak" refs 1326 + JNIHandles::weak_oops_do(&always_true, root_closure); 1327 _young_gen->ref_processor()->weak_oops_do(root_closure); 1328 _old_gen->ref_processor()->weak_oops_do(root_closure); 1329 } 1330 diff --git a/src/share/vm/memory/genCollectedHeap.hpp b/src/share/vm/memory/genCollectedHeap.hpp 1331 --- a/src/share/vm/memory/genCollectedHeap.hpp 1332 +++ b/src/share/vm/memory/genCollectedHeap.hpp 1333 @@ -85,8 +85,7 @@ 1334 1335 // Data structure for claiming the (potentially) parallel tasks in 1336 // (gen-specific) roots processing. 1337 - SubTasksDone* _gen_process_roots_tasks; 1338 - SubTasksDone* gen_process_roots_tasks() { return _gen_process_roots_tasks; } 1339 + SubTasksDone* _process_strong_tasks; 1340 1341 // Collects the given generation. 1342 void collect_generation(Generation* gen, bool full, size_t size, bool is_tlab, 1343 @@ -387,6 +386,7 @@ 1344 static GenCollectedHeap* heap(); 1345 1346 void set_par_threads(uint t); 1347 + void set_n_termination(uint t); 1348 1349 // Invoke the "do_oop" method of one of the closures "not_older_gens" 1350 // or "older_gens" on root locations for the generation at 1351 @@ -400,11 +400,25 @@ 1352 // The "so" argument determines which of the roots 1353 // the closure is applied to: 1354 // "SO_None" does none; 1355 + enum ScanningOption { 1356 + SO_None = 0x0, 1357 + SO_AllCodeCache = 0x8, 1358 + SO_ScavengeCodeCache = 0x10 1359 + }; 1360 + 1361 private: 1362 + void process_roots(bool activate_scope, 1363 + ScanningOption so, 1364 + OopClosure* strong_roots, 1365 + OopClosure* weak_roots, 1366 + CLDClosure* strong_cld_closure, 1367 + CLDClosure* weak_cld_closure, 1368 + CodeBlobClosure* code_roots); 1369 + 1370 void gen_process_roots(int level, 1371 bool younger_gens_as_roots, 1372 bool activate_scope, 1373 - SharedHeap::ScanningOption so, 1374 + ScanningOption so, 1375 OopsInGenClosure* not_older_gens, 1376 OopsInGenClosure* weak_roots, 1377 OopsInGenClosure* older_gens, 1378 @@ -419,7 +433,7 @@ 1379 void gen_process_roots(int level, 1380 bool younger_gens_as_roots, 1381 bool activate_scope, 1382 - SharedHeap::ScanningOption so, 1383 + ScanningOption so, 1384 bool only_strong_roots, 1385 OopsInGenClosure* not_older_gens, 1386 OopsInGenClosure* older_gens, 1387 diff --git a/src/share/vm/memory/genMarkSweep.cpp b/src/share/vm/memory/genMarkSweep.cpp 1388 --- a/src/share/vm/memory/genMarkSweep.cpp 1389 +++ b/src/share/vm/memory/genMarkSweep.cpp 1390 @@ -203,7 +203,7 @@ 1391 gch->gen_process_roots(level, 1392 false, // Younger gens are not roots. 1393 true, // activate StrongRootsScope 1394 - SharedHeap::SO_None, 1395 + GenCollectedHeap::SO_None, 1396 GenCollectedHeap::StrongRootsOnly, 1397 &follow_root_closure, 1398 &follow_root_closure, 1399 @@ -289,7 +289,7 @@ 1400 gch->gen_process_roots(level, 1401 false, // Younger gens are not roots. 1402 true, // activate StrongRootsScope 1403 - SharedHeap::SO_AllCodeCache, 1404 + GenCollectedHeap::SO_AllCodeCache, 1405 GenCollectedHeap::StrongAndWeakRoots, 1406 &adjust_pointer_closure, 1407 &adjust_pointer_closure, 1408 diff --git a/src/share/vm/memory/sharedHeap.cpp b/src/share/vm/memory/sharedHeap.cpp 1409 --- a/src/share/vm/memory/sharedHeap.cpp 1410 +++ b/src/share/vm/memory/sharedHeap.cpp 1411 @@ -32,7 +32,6 @@ 1412 #include "runtime/atomic.inline.hpp" 1413 #include "runtime/fprofiler.hpp" 1414 #include "runtime/java.hpp" 1415 -#include "services/management.hpp" 1416 #include "utilities/copy.hpp" 1417 #include "utilities/workgroup.hpp" 1418 1419 @@ -40,32 +39,12 @@ 1420 1421 SharedHeap* SharedHeap::_sh; 1422 1423 -// The set of potentially parallel tasks in root scanning. 1424 -enum SH_process_roots_tasks { 1425 - SH_PS_Universe_oops_do, 1426 - SH_PS_JNIHandles_oops_do, 1427 - SH_PS_ObjectSynchronizer_oops_do, 1428 - SH_PS_FlatProfiler_oops_do, 1429 - SH_PS_Management_oops_do, 1430 - SH_PS_SystemDictionary_oops_do, 1431 - SH_PS_ClassLoaderDataGraph_oops_do, 1432 - SH_PS_jvmti_oops_do, 1433 - SH_PS_CodeCache_oops_do, 1434 - // Leave this one last. 1435 - SH_PS_NumElements 1436 -}; 1437 - 1438 SharedHeap::SharedHeap(CollectorPolicy* policy_) : 1439 CollectedHeap(), 1440 _collector_policy(policy_), 1441 - _strong_roots_scope(NULL), 1442 _strong_roots_parity(0), 1443 - _process_strong_tasks(new SubTasksDone(SH_PS_NumElements)), 1444 _workers(NULL) 1445 { 1446 - if (_process_strong_tasks == NULL || !_process_strong_tasks->valid()) { 1447 - vm_exit_during_initialization("Failed necessary allocation."); 1448 - } 1449 _sh = this; // ch is static, should be set only once. 1450 if (UseConcMarkSweepGC || UseG1GC) { 1451 _workers = new FlexibleWorkGang("GC Thread", ParallelGCThreads, 1452 @@ -79,14 +58,6 @@ 1453 } 1454 } 1455 1456 -int SharedHeap::n_termination() { 1457 - return _process_strong_tasks->n_threads(); 1458 -} 1459 - 1460 -void SharedHeap::set_n_termination(int t) { 1461 - _process_strong_tasks->set_n_threads(t); 1462 -} 1463 - 1464 bool SharedHeap::heap_lock_held_for_gc() { 1465 Thread* t = Thread::current(); 1466 return Heap_lock->owned_by_self() 1467 @@ -97,31 +68,6 @@ 1468 void SharedHeap::set_par_threads(uint t) { 1469 assert(t == 0 || !UseSerialGC, "Cannot have parallel threads"); 1470 _n_par_threads = t; 1471 - _process_strong_tasks->set_n_threads(t); 1472 -} 1473 - 1474 -#ifdef ASSERT 1475 -class AssertNonScavengableClosure: public OopClosure { 1476 -public: 1477 - virtual void do_oop(oop* p) { 1478 - assert(!Universe::heap()->is_in_partial_collection(*p), 1479 - "Referent should not be scavengable."); } 1480 - virtual void do_oop(narrowOop* p) { ShouldNotReachHere(); } 1481 -}; 1482 -static AssertNonScavengableClosure assert_is_non_scavengable_closure; 1483 -#endif 1484 - 1485 -SharedHeap::StrongRootsScope* SharedHeap::active_strong_roots_scope() const { 1486 - return _strong_roots_scope; 1487 -} 1488 -void SharedHeap::register_strong_roots_scope(SharedHeap::StrongRootsScope* scope) { 1489 - assert(_strong_roots_scope == NULL, "Should only have one StrongRootsScope active"); 1490 - assert(scope != NULL, "Illegal argument"); 1491 - _strong_roots_scope = scope; 1492 -} 1493 -void SharedHeap::unregister_strong_roots_scope(SharedHeap::StrongRootsScope* scope) { 1494 - assert(_strong_roots_scope == scope, "Wrong scope unregistered"); 1495 - _strong_roots_scope = NULL; 1496 } 1497 1498 void SharedHeap::change_strong_roots_parity() { 1499 @@ -135,174 +81,15 @@ 1500 } 1501 1502 SharedHeap::StrongRootsScope::StrongRootsScope(SharedHeap* heap, bool activate) 1503 - : MarkScope(activate), _sh(heap), _n_workers_done_with_threads(0) 1504 + : MarkScope(activate), _sh(heap) 1505 { 1506 if (_active) { 1507 - _sh->register_strong_roots_scope(this); 1508 _sh->change_strong_roots_parity(); 1509 // Zero the claimed high water mark in the StringTable 1510 StringTable::clear_parallel_claimed_index(); 1511 } 1512 } 1513 1514 -SharedHeap::StrongRootsScope::~StrongRootsScope() { 1515 - if (_active) { 1516 - _sh->unregister_strong_roots_scope(this); 1517 - } 1518 -} 1519 - 1520 -Monitor* SharedHeap::StrongRootsScope::_lock = new Monitor(Mutex::leaf, "StrongRootsScope lock", false, Monitor::_safepoint_check_never); 1521 - 1522 -void SharedHeap::StrongRootsScope::mark_worker_done_with_threads(uint n_workers) { 1523 - // The Thread work barrier is only needed by G1 Class Unloading. 1524 - // No need to use the barrier if this is single-threaded code. 1525 - if (UseG1GC && ClassUnloadingWithConcurrentMark && n_workers > 0) { 1526 - uint new_value = (uint)Atomic::add(1, &_n_workers_done_with_threads); 1527 - if (new_value == n_workers) { 1528 - // This thread is last. Notify the others. 1529 - MonitorLockerEx ml(_lock, Mutex::_no_safepoint_check_flag); 1530 - _lock->notify_all(); 1531 - } 1532 - } 1533 -} 1534 - 1535 -void SharedHeap::StrongRootsScope::wait_until_all_workers_done_with_threads(uint n_workers) { 1536 - assert(UseG1GC, "Currently only used by G1"); 1537 - assert(ClassUnloadingWithConcurrentMark, "Currently only needed when doing G1 Class Unloading"); 1538 - 1539 - // No need to use the barrier if this is single-threaded code. 1540 - if (n_workers > 0 && (uint)_n_workers_done_with_threads != n_workers) { 1541 - MonitorLockerEx ml(_lock, Mutex::_no_safepoint_check_flag); 1542 - while ((uint)_n_workers_done_with_threads != n_workers) { 1543 - _lock->wait(Mutex::_no_safepoint_check_flag, 0, false); 1544 - } 1545 - } 1546 -} 1547 - 1548 -void SharedHeap::process_roots(bool activate_scope, 1549 - ScanningOption so, 1550 - OopClosure* strong_roots, 1551 - OopClosure* weak_roots, 1552 - CLDClosure* strong_cld_closure, 1553 - CLDClosure* weak_cld_closure, 1554 - CodeBlobClosure* code_roots) { 1555 - StrongRootsScope srs(this, activate_scope); 1556 - 1557 - // General roots. 1558 - assert(_strong_roots_parity != 0, "must have called prologue code"); 1559 - assert(code_roots != NULL, "code root closure should always be set"); 1560 - // _n_termination for _process_strong_tasks should be set up stream 1561 - // in a method not running in a GC worker. Otherwise the GC worker 1562 - // could be trying to change the termination condition while the task 1563 - // is executing in another GC worker. 1564 - 1565 - // Iterating over the CLDG and the Threads are done early to allow G1 to 1566 - // first process the strong CLDs and nmethods and then, after a barrier, 1567 - // let the thread process the weak CLDs and nmethods. 1568 - 1569 - if (!_process_strong_tasks->is_task_claimed(SH_PS_ClassLoaderDataGraph_oops_do)) { 1570 - ClassLoaderDataGraph::roots_cld_do(strong_cld_closure, weak_cld_closure); 1571 - } 1572 - 1573 - // Some CLDs contained in the thread frames should be considered strong. 1574 - // Don't process them if they will be processed during the ClassLoaderDataGraph phase. 1575 - CLDClosure* roots_from_clds_p = (strong_cld_closure != weak_cld_closure) ? strong_cld_closure : NULL; 1576 - // Only process code roots from thread stacks if we aren't visiting the entire CodeCache anyway 1577 - CodeBlobClosure* roots_from_code_p = (so & SO_AllCodeCache) ? NULL : code_roots; 1578 - 1579 - Threads::possibly_parallel_oops_do(strong_roots, roots_from_clds_p, roots_from_code_p); 1580 - 1581 - // This is the point where this worker thread will not find more strong CLDs/nmethods. 1582 - // Report this so G1 can synchronize the strong and weak CLDs/nmethods processing. 1583 - active_strong_roots_scope()->mark_worker_done_with_threads(n_par_threads()); 1584 - 1585 - if (!_process_strong_tasks->is_task_claimed(SH_PS_Universe_oops_do)) { 1586 - Universe::oops_do(strong_roots); 1587 - } 1588 - // Global (strong) JNI handles 1589 - if (!_process_strong_tasks->is_task_claimed(SH_PS_JNIHandles_oops_do)) 1590 - JNIHandles::oops_do(strong_roots); 1591 - 1592 - if (!_process_strong_tasks-> is_task_claimed(SH_PS_ObjectSynchronizer_oops_do)) 1593 - ObjectSynchronizer::oops_do(strong_roots); 1594 - if (!_process_strong_tasks->is_task_claimed(SH_PS_FlatProfiler_oops_do)) 1595 - FlatProfiler::oops_do(strong_roots); 1596 - if (!_process_strong_tasks->is_task_claimed(SH_PS_Management_oops_do)) 1597 - Management::oops_do(strong_roots); 1598 - if (!_process_strong_tasks->is_task_claimed(SH_PS_jvmti_oops_do)) 1599 - JvmtiExport::oops_do(strong_roots); 1600 - 1601 - if (!_process_strong_tasks->is_task_claimed(SH_PS_SystemDictionary_oops_do)) { 1602 - SystemDictionary::roots_oops_do(strong_roots, weak_roots); 1603 - } 1604 - 1605 - // All threads execute the following. A specific chunk of buckets 1606 - // from the StringTable are the individual tasks. 1607 - if (weak_roots != NULL) { 1608 - if (CollectedHeap::use_parallel_gc_threads()) { 1609 - StringTable::possibly_parallel_oops_do(weak_roots); 1610 - } else { 1611 - StringTable::oops_do(weak_roots); 1612 - } 1613 - } 1614 - 1615 - if (!_process_strong_tasks->is_task_claimed(SH_PS_CodeCache_oops_do)) { 1616 - if (so & SO_ScavengeCodeCache) { 1617 - assert(code_roots != NULL, "must supply closure for code cache"); 1618 - 1619 - // We only visit parts of the CodeCache when scavenging. 1620 - CodeCache::scavenge_root_nmethods_do(code_roots); 1621 - } 1622 - if (so & SO_AllCodeCache) { 1623 - assert(code_roots != NULL, "must supply closure for code cache"); 1624 - 1625 - // CMSCollector uses this to do intermediate-strength collections. 1626 - // We scan the entire code cache, since CodeCache::do_unloading is not called. 1627 - CodeCache::blobs_do(code_roots); 1628 - } 1629 - // Verify that the code cache contents are not subject to 1630 - // movement by a scavenging collection. 1631 - DEBUG_ONLY(CodeBlobToOopClosure assert_code_is_non_scavengable(&assert_is_non_scavengable_closure, !CodeBlobToOopClosure::FixRelocations)); 1632 - DEBUG_ONLY(CodeCache::asserted_non_scavengable_nmethods_do(&assert_code_is_non_scavengable)); 1633 - } 1634 - 1635 - _process_strong_tasks->all_tasks_completed(); 1636 -} 1637 - 1638 -void SharedHeap::process_all_roots(bool activate_scope, 1639 - ScanningOption so, 1640 - OopClosure* roots, 1641 - CLDClosure* cld_closure, 1642 - CodeBlobClosure* code_closure) { 1643 - process_roots(activate_scope, so, 1644 - roots, roots, 1645 - cld_closure, cld_closure, 1646 - code_closure); 1647 -} 1648 - 1649 -void SharedHeap::process_strong_roots(bool activate_scope, 1650 - ScanningOption so, 1651 - OopClosure* roots, 1652 - CLDClosure* cld_closure, 1653 - CodeBlobClosure* code_closure) { 1654 - process_roots(activate_scope, so, 1655 - roots, NULL, 1656 - cld_closure, NULL, 1657 - code_closure); 1658 -} 1659 - 1660 - 1661 -class AlwaysTrueClosure: public BoolObjectClosure { 1662 -public: 1663 - bool do_object_b(oop p) { return true; } 1664 -}; 1665 -static AlwaysTrueClosure always_true; 1666 - 1667 -void SharedHeap::process_weak_roots(OopClosure* root_closure) { 1668 - // Global (weak) JNI handles 1669 - JNIHandles::weak_oops_do(&always_true, root_closure); 1670 -} 1671 - 1672 void SharedHeap::set_barrier_set(BarrierSet* bs) { 1673 _barrier_set = bs; 1674 // Cached barrier set for fast access in oops 1675 diff --git a/src/share/vm/memory/sharedHeap.hpp b/src/share/vm/memory/sharedHeap.hpp 1676 --- a/src/share/vm/memory/sharedHeap.hpp 1677 +++ b/src/share/vm/memory/sharedHeap.hpp 1678 @@ -61,18 +61,18 @@ 1679 // counts the number of tasks that have been done and then reset 1680 // the SubTasksDone so that it can be used again. When the number of 1681 // tasks is set to the number of GC workers, then _n_threads must 1682 -// be set to the number of active GC workers. G1CollectedHeap, 1683 -// HRInto_G1RemSet, GenCollectedHeap and SharedHeap have SubTasksDone. 1684 -// This seems too many. 1685 +// be set to the number of active GC workers. G1RootProcessor and 1686 +// GenCollectedHeap have SubTasksDone. 1687 // 3) SequentialSubTasksDone has an _n_threads that is used in 1688 // a way similar to SubTasksDone and has the same dependency on the 1689 // number of active GC workers. CompactibleFreeListSpace and Space 1690 // have SequentialSubTasksDone's. 1691 -// Example of using SubTasksDone and SequentialSubTasksDone 1692 -// G1CollectedHeap::g1_process_roots() 1693 -// to SharedHeap::process_roots() and uses 1694 -// SubTasksDone* _process_strong_tasks to claim tasks. 1695 -// process_roots() calls 1696 +// 1697 +// Examples of using SubTasksDone and SequentialSubTasksDone: 1698 +// G1RootProcessor and GenCollectedHeap::process_roots() use 1699 +// SubTasksDone* _process_strong_tasks to claim tasks for workers 1700 +// 1701 +// GenCollectedHeap::gen_process_roots() calls 1702 // rem_set()->younger_refs_iterate() 1703 // to scan the card table and which eventually calls down into 1704 // CardTableModRefBS::par_non_clean_card_iterate_work(). This method 1705 @@ -104,10 +104,6 @@ 1706 friend class VM_GC_Operation; 1707 friend class VM_CGC_Operation; 1708 1709 -private: 1710 - // For claiming strong_roots tasks. 1711 - SubTasksDone* _process_strong_tasks; 1712 - 1713 protected: 1714 // There should be only a single instance of "SharedHeap" in a program. 1715 // This is enforced with the protected constructor below, which will also 1716 @@ -140,7 +136,6 @@ 1717 static SharedHeap* heap() { return _sh; } 1718 1719 void set_barrier_set(BarrierSet* bs); 1720 - SubTasksDone* process_strong_tasks() { return _process_strong_tasks; } 1721 1722 // Does operations required after initialization has been done. 1723 virtual void post_initialize(); 1724 @@ -193,69 +188,19 @@ 1725 // strong_roots_prologue calls change_strong_roots_parity, if 1726 // parallel tasks are enabled. 1727 class StrongRootsScope : public MarkingCodeBlobClosure::MarkScope { 1728 - // Used to implement the Thread work barrier. 1729 - static Monitor* _lock; 1730 - 1731 SharedHeap* _sh; 1732 - volatile jint _n_workers_done_with_threads; 1733 1734 public: 1735 StrongRootsScope(SharedHeap* heap, bool activate = true); 1736 - ~StrongRootsScope(); 1737 - 1738 - // Mark that this thread is done with the Threads work. 1739 - void mark_worker_done_with_threads(uint n_workers); 1740 - // Wait until all n_workers are done with the Threads work. 1741 - void wait_until_all_workers_done_with_threads(uint n_workers); 1742 }; 1743 friend class StrongRootsScope; 1744 1745 - // The current active StrongRootScope 1746 - StrongRootsScope* _strong_roots_scope; 1747 - 1748 - StrongRootsScope* active_strong_roots_scope() const; 1749 - 1750 private: 1751 - void register_strong_roots_scope(StrongRootsScope* scope); 1752 - void unregister_strong_roots_scope(StrongRootsScope* scope); 1753 void change_strong_roots_parity(); 1754 1755 public: 1756 - enum ScanningOption { 1757 - SO_None = 0x0, 1758 - SO_AllCodeCache = 0x8, 1759 - SO_ScavengeCodeCache = 0x10 1760 - }; 1761 - 1762 FlexibleWorkGang* workers() const { return _workers; } 1763 1764 - // Invoke the "do_oop" method the closure "roots" on all root locations. 1765 - // The "so" argument determines which roots the closure is applied to: 1766 - // "SO_None" does none; 1767 - // "SO_AllCodeCache" applies the closure to all elements of the CodeCache. 1768 - // "SO_ScavengeCodeCache" applies the closure to elements on the scavenge root list in the CodeCache. 1769 - void process_roots(bool activate_scope, 1770 - ScanningOption so, 1771 - OopClosure* strong_roots, 1772 - OopClosure* weak_roots, 1773 - CLDClosure* strong_cld_closure, 1774 - CLDClosure* weak_cld_closure, 1775 - CodeBlobClosure* code_roots); 1776 - void process_all_roots(bool activate_scope, 1777 - ScanningOption so, 1778 - OopClosure* roots, 1779 - CLDClosure* cld_closure, 1780 - CodeBlobClosure* code_roots); 1781 - void process_strong_roots(bool activate_scope, 1782 - ScanningOption so, 1783 - OopClosure* roots, 1784 - CLDClosure* cld_closure, 1785 - CodeBlobClosure* code_roots); 1786 - 1787 - 1788 - // Apply "root_closure" to the JNI weak roots.. 1789 - void process_weak_roots(OopClosure* root_closure); 1790 - 1791 // The functions below are helper functions that a subclass of 1792 // "SharedHeap" can use in the implementation of its virtual 1793 // functions. 1794 @@ -270,9 +215,6 @@ 1795 // (such as process roots) subsequently. 1796 virtual void set_par_threads(uint t); 1797 1798 - int n_termination(); 1799 - void set_n_termination(int t); 1800 - 1801 // 1802 // New methods from CollectedHeap 1803 // 1804 @@ -284,8 +226,4 @@ 1805 size_t capacity); 1806 }; 1807 1808 -inline SharedHeap::ScanningOption operator|(SharedHeap::ScanningOption so0, SharedHeap::ScanningOption so1) { 1809 - return static_cast<SharedHeap::ScanningOption>(static_cast<int>(so0) | static_cast<int>(so1)); 1810 -} 1811 - 1812 #endif // SHARE_VM_MEMORY_SHAREDHEAP_HPP