src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp

Print this page
rev 4735 : 8015237: Parallelize string table scanning during strong root processing
Summary: Parallelize the scanning of the intern string table by having each GC worker claim a given number of buckets.
Reviewed-by:


3296 
3297     assert(Thread::current()->is_VM_thread(),
3298            "Expected to be executed serially by the VM thread at this point");
3299 
3300     CodeBlobToOopClosure blobsCl(&rootsCl, /*do_marking=*/ false);
3301     VerifyKlassClosure klassCl(this, &rootsCl);
3302 
3303     // We apply the relevant closures to all the oops in the
3304     // system dictionary, the string table and the code cache.
3305     const int so = SO_AllClasses | SO_Strings | SO_CodeCache;
3306 
3307     // Need cleared claim bits for the strong roots processing
3308     ClassLoaderDataGraph::clear_claimed_marks();
3309 
3310     process_strong_roots(true,      // activate StrongRootsScope
3311                          false,     // we set "is scavenging" to false,
3312                                     // so we don't reset the dirty cards.
3313                          ScanningOption(so),  // roots scanning options
3314                          &rootsCl,
3315                          &blobsCl,
3316                          &klassCl
3317                          );
3318 
3319     bool failures = rootsCl.failures();
3320 
3321     if (vo != VerifyOption_G1UseMarkWord) {
3322       // If we're verifying during a full GC then the region sets
3323       // will have been torn down at the start of the GC. Therefore
3324       // verifying the region sets will fail. So we only verify
3325       // the region sets when not in a full GC.
3326       if (!silent) { gclog_or_tty->print("HeapRegionSets "); }
3327       verify_region_sets();
3328     }
3329 
3330     if (!silent) { gclog_or_tty->print("HeapRegions "); }
3331     if (GCParallelVerificationEnabled && ParallelGCThreads > 1) {
3332       assert(check_heap_region_claim_values(HeapRegion::InitialClaimValue),
3333              "sanity check");
3334 
3335       G1ParVerifyTask task(this, vo);
3336       assert(UseDynamicNumberOfGCThreads ||
3337         workers()->active_workers() == workers()->total_workers(),


4995         // 'mark' this nmethod.
4996         // Note: Revisit the following if CodeBlobToOopClosure::do_code_blob()
4997         // or MarkingCodeBlobClosure::do_code_blob() change.
4998         if (!nm->test_set_oops_do_mark()) {
4999           do_newly_marked_nmethod(nm);
5000         }
5001       }
5002     }
5003   }
5004 };
5005 
5006 // This method is run in a GC worker.
5007 
5008 void
5009 G1CollectedHeap::
5010 g1_process_strong_roots(bool is_scavenging,
5011                         ScanningOption so,
5012                         OopClosure* scan_non_heap_roots,
5013                         OopsInHeapRegionClosure* scan_rs,
5014                         G1KlassScanClosure* scan_klasses,
5015                         int worker_i) {
5016 
5017   // First scan the strong roots
5018   double ext_roots_start = os::elapsedTime();
5019   double closure_app_time_sec = 0.0;
5020 
5021   BufferingOopClosure buf_scan_non_heap_roots(scan_non_heap_roots);
5022 
5023   // Walk the code cache w/o buffering, because StarTask cannot handle
5024   // unaligned oop locations.
5025   G1FilteredCodeBlobToOopClosure eager_scan_code_roots(this, scan_non_heap_roots);
5026 
5027   process_strong_roots(false, // no scoping; this is parallel code
5028                        is_scavenging, so,

5029                        &buf_scan_non_heap_roots,
5030                        &eager_scan_code_roots,
5031                        scan_klasses
5032                        );
5033 
5034   // Now the CM ref_processor roots.
5035   if (!_process_strong_tasks->is_task_claimed(G1H_PS_refProcessor_oops_do)) {
5036     // We need to treat the discovered reference lists of the
5037     // concurrent mark ref processor as roots and keep entries
5038     // (which are added by the marking threads) on them live
5039     // until they can be processed at the end of marking.
5040     ref_processor_cm()->weak_oops_do(&buf_scan_non_heap_roots);
5041   }
5042 
5043   // Finish up any enqueued closure apps (attributed as object copy time).
5044   buf_scan_non_heap_roots.done();
5045 
5046   double obj_copy_time_sec = buf_scan_non_heap_roots.closure_app_seconds();
5047 
5048   g1_policy()->phase_times()->record_obj_copy_time(worker_i, obj_copy_time_sec * 1000.0);
5049 
5050   double ext_root_time_ms =
5051     ((os::elapsedTime() - ext_roots_start) - obj_copy_time_sec) * 1000.0;
5052 




3296 
3297     assert(Thread::current()->is_VM_thread(),
3298            "Expected to be executed serially by the VM thread at this point");
3299 
3300     CodeBlobToOopClosure blobsCl(&rootsCl, /*do_marking=*/ false);
3301     VerifyKlassClosure klassCl(this, &rootsCl);
3302 
3303     // We apply the relevant closures to all the oops in the
3304     // system dictionary, the string table and the code cache.
3305     const int so = SO_AllClasses | SO_Strings | SO_CodeCache;
3306 
3307     // Need cleared claim bits for the strong roots processing
3308     ClassLoaderDataGraph::clear_claimed_marks();
3309 
3310     process_strong_roots(true,               // activate StrongRootsScope
3311                          false,              // we set "is scavenging" to false,
3312                                              // so we don't reset the dirty cards.
3313                          ScanningOption(so), // roots scanning options
3314                          &rootsCl,
3315                          &blobsCl,
3316                          &klassCl);

3317 
3318     bool failures = rootsCl.failures();
3319 
3320     if (vo != VerifyOption_G1UseMarkWord) {
3321       // If we're verifying during a full GC then the region sets
3322       // will have been torn down at the start of the GC. Therefore
3323       // verifying the region sets will fail. So we only verify
3324       // the region sets when not in a full GC.
3325       if (!silent) { gclog_or_tty->print("HeapRegionSets "); }
3326       verify_region_sets();
3327     }
3328 
3329     if (!silent) { gclog_or_tty->print("HeapRegions "); }
3330     if (GCParallelVerificationEnabled && ParallelGCThreads > 1) {
3331       assert(check_heap_region_claim_values(HeapRegion::InitialClaimValue),
3332              "sanity check");
3333 
3334       G1ParVerifyTask task(this, vo);
3335       assert(UseDynamicNumberOfGCThreads ||
3336         workers()->active_workers() == workers()->total_workers(),


4994         // 'mark' this nmethod.
4995         // Note: Revisit the following if CodeBlobToOopClosure::do_code_blob()
4996         // or MarkingCodeBlobClosure::do_code_blob() change.
4997         if (!nm->test_set_oops_do_mark()) {
4998           do_newly_marked_nmethod(nm);
4999         }
5000       }
5001     }
5002   }
5003 };
5004 
5005 // This method is run in a GC worker.
5006 
5007 void
5008 G1CollectedHeap::
5009 g1_process_strong_roots(bool is_scavenging,
5010                         ScanningOption so,
5011                         OopClosure* scan_non_heap_roots,
5012                         OopsInHeapRegionClosure* scan_rs,
5013                         G1KlassScanClosure* scan_klasses,
5014                         uint worker_i) {
5015 
5016   // First scan the strong roots
5017   double ext_roots_start = os::elapsedTime();
5018   double closure_app_time_sec = 0.0;
5019 
5020   BufferingOopClosure buf_scan_non_heap_roots(scan_non_heap_roots);
5021 
5022   // Walk the code cache w/o buffering, because StarTask cannot handle
5023   // unaligned oop locations.
5024   G1FilteredCodeBlobToOopClosure eager_scan_code_roots(this, scan_non_heap_roots);
5025 
5026   process_strong_roots(false, // no scoping; this is parallel code
5027                        is_scavenging,
5028                        so,
5029                        &buf_scan_non_heap_roots,
5030                        &eager_scan_code_roots,
5031                        scan_klasses,
5032                        worker_i);
5033 
5034   // Now the CM ref_processor roots.
5035   if (!_process_strong_tasks->is_task_claimed(G1H_PS_refProcessor_oops_do)) {
5036     // We need to treat the discovered reference lists of the
5037     // concurrent mark ref processor as roots and keep entries
5038     // (which are added by the marking threads) on them live
5039     // until they can be processed at the end of marking.
5040     ref_processor_cm()->weak_oops_do(&buf_scan_non_heap_roots);
5041   }
5042 
5043   // Finish up any enqueued closure apps (attributed as object copy time).
5044   buf_scan_non_heap_roots.done();
5045 
5046   double obj_copy_time_sec = buf_scan_non_heap_roots.closure_app_seconds();
5047 
5048   g1_policy()->phase_times()->record_obj_copy_time(worker_i, obj_copy_time_sec * 1000.0);
5049 
5050   double ext_root_time_ms =
5051     ((os::elapsedTime() - ext_roots_start) - obj_copy_time_sec) * 1000.0;
5052