comparison src/share/vm/gc_implementation/g1/heapRegionRemSet.cpp @ 1261:0414c1049f15

6923991: G1: improve scalability of RSet scanning Summary: Implemented block-based work stealing. Moved copying during the rset scanning phase to the main copying phase. Made the size of rset table depend on the region size. Reviewed-by: apetrusenko, tonyp
author iveresov
date Thu, 11 Feb 2010 15:52:19 -0800
parents 9eee977dd1a9
children f9ec1e4bbb44
comparison
equal deleted inserted replaced
1260:8859772195c6 1261:0414c1049f15
503 _sparse_table(hr) 503 _sparse_table(hr)
504 { 504 {
505 typedef PosParPRT* PosParPRTPtr; 505 typedef PosParPRT* PosParPRTPtr;
506 if (_max_fine_entries == 0) { 506 if (_max_fine_entries == 0) {
507 assert(_mod_max_fine_entries_mask == 0, "Both or none."); 507 assert(_mod_max_fine_entries_mask == 0, "Both or none.");
508 _max_fine_entries = (size_t)(1 << G1LogRSRegionEntries); 508 size_t max_entries_log = (size_t)log2_long((jlong)G1RSetRegionEntries);
509 _max_fine_entries = (size_t)(1 << max_entries_log);
509 _mod_max_fine_entries_mask = _max_fine_entries - 1; 510 _mod_max_fine_entries_mask = _max_fine_entries - 1;
510 #if SAMPLE_FOR_EVICTION 511 #if SAMPLE_FOR_EVICTION
511 assert(_fine_eviction_sample_size == 0 512 assert(_fine_eviction_sample_size == 0
512 && _fine_eviction_stride == 0, "All init at same time."); 513 && _fine_eviction_stride == 0, "All init at same time.");
513 _fine_eviction_sample_size = MAX2((size_t)4, (size_t)G1LogRSRegionEntries); 514 _fine_eviction_sample_size = MAX2((size_t)4, max_entries_log);
514 _fine_eviction_stride = _max_fine_entries / _fine_eviction_sample_size; 515 _fine_eviction_stride = _max_fine_entries / _fine_eviction_sample_size;
515 #endif 516 #endif
516 } 517 }
517 _fine_grain_regions = new PosParPRTPtr[_max_fine_entries]; 518 _fine_grain_regions = new PosParPRTPtr[_max_fine_entries];
518 if (_fine_grain_regions == NULL) 519 if (_fine_grain_regions == NULL)
653 "overflow(f: %d, t: %d)", 654 "overflow(f: %d, t: %d)",
654 tid, from_hrs_ind, cur_hrs_ind); 655 tid, from_hrs_ind, cur_hrs_ind);
655 #endif 656 #endif
656 } 657 }
657 658
658 // Otherwise, transfer from sparse to fine-grain.
659 CardIdx_t cards[SparsePRTEntry::CardsPerEntry];
660 if (G1HRRSUseSparseTable) {
661 bool res = _sparse_table.get_cards(from_hrs_ind, &cards[0]);
662 assert(res, "There should have been an entry");
663 }
664
665 if (_n_fine_entries == _max_fine_entries) { 659 if (_n_fine_entries == _max_fine_entries) {
666 prt = delete_region_table(); 660 prt = delete_region_table();
667 } else { 661 } else {
668 prt = PosParPRT::alloc(from_hr); 662 prt = PosParPRT::alloc(from_hr);
669 } 663 }
674 PosParPRT* first_prt = _fine_grain_regions[ind]; 668 PosParPRT* first_prt = _fine_grain_regions[ind];
675 prt->set_next(first_prt); // XXX Maybe move to init? 669 prt->set_next(first_prt); // XXX Maybe move to init?
676 _fine_grain_regions[ind] = prt; 670 _fine_grain_regions[ind] = prt;
677 _n_fine_entries++; 671 _n_fine_entries++;
678 672
679 // Add in the cards from the sparse table.
680 if (G1HRRSUseSparseTable) { 673 if (G1HRRSUseSparseTable) {
681 for (int i = 0; i < SparsePRTEntry::CardsPerEntry; i++) { 674 // Transfer from sparse to fine-grain.
682 CardIdx_t c = cards[i]; 675 SparsePRTEntry *sprt_entry = _sparse_table.get_entry(from_hrs_ind);
676 assert(sprt_entry != NULL, "There should have been an entry");
677 for (int i = 0; i < SparsePRTEntry::cards_num(); i++) {
678 CardIdx_t c = sprt_entry->card(i);
683 if (c != SparsePRTEntry::NullEntry) { 679 if (c != SparsePRTEntry::NullEntry) {
684 prt->add_card(c); 680 prt->add_card(c);
685 } 681 }
686 } 682 }
687 // Now we can delete the sparse entry. 683 // Now we can delete the sparse entry.
1082 false /* in-resource-area */), 1078 false /* in-resource-area */),
1083 _iter_state(Unclaimed) 1079 _iter_state(Unclaimed)
1084 {} 1080 {}
1085 1081
1086 1082
1083 void HeapRegionRemSet::setup_remset_size() {
1084 // Setup sparse and fine-grain tables sizes.
1085 // table_size = base * (log(region_size / 1M) + 1)
1086 int region_size_log_mb = MAX2((int)HeapRegion::LogOfHRGrainBytes - (int)LOG_M, 0);
1087 if (FLAG_IS_DEFAULT(G1RSetSparseRegionEntries)) {
1088 G1RSetSparseRegionEntries = G1RSetSparseRegionEntriesBase * (region_size_log_mb + 1);
1089 }
1090 if (FLAG_IS_DEFAULT(G1RSetRegionEntries)) {
1091 G1RSetRegionEntries = G1RSetRegionEntriesBase * (region_size_log_mb + 1);
1092 }
1093 guarantee(G1RSetSparseRegionEntries > 0 && G1RSetRegionEntries > 0 , "Sanity");
1094 }
1095
1087 void HeapRegionRemSet::init_for_par_iteration() { 1096 void HeapRegionRemSet::init_for_par_iteration() {
1088 _iter_state = Unclaimed; 1097 _iter_state = Unclaimed;
1089 } 1098 }
1090 1099
1091 bool HeapRegionRemSet::claim_iter() { 1100 bool HeapRegionRemSet::claim_iter() {
1397 #ifndef PRODUCT 1406 #ifndef PRODUCT
1398 void HeapRegionRemSet::test() { 1407 void HeapRegionRemSet::test() {
1399 os::sleep(Thread::current(), (jlong)5000, false); 1408 os::sleep(Thread::current(), (jlong)5000, false);
1400 G1CollectedHeap* g1h = G1CollectedHeap::heap(); 1409 G1CollectedHeap* g1h = G1CollectedHeap::heap();
1401 1410
1402 // Run with "-XX:G1LogRSRegionEntries=2", so that 1 and 5 end up in same 1411 // Run with "-XX:G1LogRSetRegionEntries=2", so that 1 and 5 end up in same
1403 // hash bucket. 1412 // hash bucket.
1404 HeapRegion* hr0 = g1h->region_at(0); 1413 HeapRegion* hr0 = g1h->region_at(0);
1405 HeapRegion* hr1 = g1h->region_at(1); 1414 HeapRegion* hr1 = g1h->region_at(1);
1406 HeapRegion* hr2 = g1h->region_at(5); 1415 HeapRegion* hr2 = g1h->region_at(5);
1407 HeapRegion* hr3 = g1h->region_at(6); 1416 HeapRegion* hr3 = g1h->region_at(6);