Mercurial > hg > graal-compiler
comparison src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp @ 796:29e7d79232b9
6819065: G1: eliminate high serial card table clearing time
Reviewed-by: iveresov, tonyp
author | apetrusenko |
---|---|
date | Tue, 19 May 2009 04:05:31 -0700 |
parents | 315a5d70b295 |
children | d44bdab1c03d |
comparison
equal
deleted
inserted
replaced
795:215f81b4d9b3 | 796:29e7d79232b9 |
---|---|
442 curr = curr->get_next_young_region(); | 442 curr = curr->get_next_young_region(); |
443 } | 443 } |
444 } | 444 } |
445 | 445 |
446 gclog_or_tty->print_cr(""); | 446 gclog_or_tty->print_cr(""); |
447 } | |
448 | |
449 void G1CollectedHeap::push_dirty_cards_region(HeapRegion* hr) | |
450 { | |
451 // Claim the right to put the region on the dirty cards region list | |
452 // by installing a self pointer. | |
453 HeapRegion* next = hr->get_next_dirty_cards_region(); | |
454 if (next == NULL) { | |
455 HeapRegion* res = (HeapRegion*) | |
456 Atomic::cmpxchg_ptr(hr, hr->next_dirty_cards_region_addr(), | |
457 NULL); | |
458 if (res == NULL) { | |
459 HeapRegion* head; | |
460 do { | |
461 // Put the region to the dirty cards region list. | |
462 head = _dirty_cards_region_list; | |
463 next = (HeapRegion*) | |
464 Atomic::cmpxchg_ptr(hr, &_dirty_cards_region_list, head); | |
465 if (next == head) { | |
466 assert(hr->get_next_dirty_cards_region() == hr, | |
467 "hr->get_next_dirty_cards_region() != hr"); | |
468 if (next == NULL) { | |
469 // The last region in the list points to itself. | |
470 hr->set_next_dirty_cards_region(hr); | |
471 } else { | |
472 hr->set_next_dirty_cards_region(next); | |
473 } | |
474 } | |
475 } while (next != head); | |
476 } | |
477 } | |
478 } | |
479 | |
480 HeapRegion* G1CollectedHeap::pop_dirty_cards_region() | |
481 { | |
482 HeapRegion* head; | |
483 HeapRegion* hr; | |
484 do { | |
485 head = _dirty_cards_region_list; | |
486 if (head == NULL) { | |
487 return NULL; | |
488 } | |
489 HeapRegion* new_head = head->get_next_dirty_cards_region(); | |
490 if (head == new_head) { | |
491 // The last region. | |
492 new_head = NULL; | |
493 } | |
494 hr = (HeapRegion*)Atomic::cmpxchg_ptr(new_head, &_dirty_cards_region_list, | |
495 head); | |
496 } while (hr != head); | |
497 assert(hr != NULL, "invariant"); | |
498 hr->set_next_dirty_cards_region(NULL); | |
499 return hr; | |
447 } | 500 } |
448 | 501 |
449 void G1CollectedHeap::stop_conc_gc_threads() { | 502 void G1CollectedHeap::stop_conc_gc_threads() { |
450 _cg1r->stop(); | 503 _cg1r->stop(); |
451 _czft->stop(); | 504 _czft->stop(); |
1327 _unclean_regions_coming(false), | 1380 _unclean_regions_coming(false), |
1328 _young_list(new YoungList(this)), | 1381 _young_list(new YoungList(this)), |
1329 _gc_time_stamp(0), | 1382 _gc_time_stamp(0), |
1330 _surviving_young_words(NULL), | 1383 _surviving_young_words(NULL), |
1331 _in_cset_fast_test(NULL), | 1384 _in_cset_fast_test(NULL), |
1332 _in_cset_fast_test_base(NULL) { | 1385 _in_cset_fast_test_base(NULL), |
1386 _dirty_cards_region_list(NULL) { | |
1333 _g1h = this; // To catch bugs. | 1387 _g1h = this; // To catch bugs. |
1334 if (_process_strong_tasks == NULL || !_process_strong_tasks->valid()) { | 1388 if (_process_strong_tasks == NULL || !_process_strong_tasks->valid()) { |
1335 vm_exit_during_initialization("Failed necessary allocation."); | 1389 vm_exit_during_initialization("Failed necessary allocation."); |
1336 } | 1390 } |
1337 int n_queues = MAX2((int)ParallelGCThreads, 1); | 1391 int n_queues = MAX2((int)ParallelGCThreads, 1); |
4689 | 4743 |
4690 list = list->get_next_young_region(); | 4744 list = list->get_next_young_region(); |
4691 } | 4745 } |
4692 } | 4746 } |
4693 | 4747 |
4748 | |
4749 class G1ParCleanupCTTask : public AbstractGangTask { | |
4750 CardTableModRefBS* _ct_bs; | |
4751 G1CollectedHeap* _g1h; | |
4752 public: | |
4753 G1ParCleanupCTTask(CardTableModRefBS* ct_bs, | |
4754 G1CollectedHeap* g1h) : | |
4755 AbstractGangTask("G1 Par Cleanup CT Task"), | |
4756 _ct_bs(ct_bs), | |
4757 _g1h(g1h) | |
4758 { } | |
4759 | |
4760 void work(int i) { | |
4761 HeapRegion* r; | |
4762 while (r = _g1h->pop_dirty_cards_region()) { | |
4763 clear_cards(r); | |
4764 } | |
4765 } | |
4766 void clear_cards(HeapRegion* r) { | |
4767 // Cards for Survivor and Scan-Only regions will be dirtied later. | |
4768 if (!r->is_scan_only() && !r->is_survivor()) { | |
4769 _ct_bs->clear(MemRegion(r->bottom(), r->end())); | |
4770 } | |
4771 } | |
4772 }; | |
4773 | |
4774 | |
4694 void G1CollectedHeap::cleanUpCardTable() { | 4775 void G1CollectedHeap::cleanUpCardTable() { |
4695 CardTableModRefBS* ct_bs = (CardTableModRefBS*) (barrier_set()); | 4776 CardTableModRefBS* ct_bs = (CardTableModRefBS*) (barrier_set()); |
4696 double start = os::elapsedTime(); | 4777 double start = os::elapsedTime(); |
4697 | 4778 |
4698 ct_bs->clear(_g1_committed); | 4779 // Iterate over the dirty cards region list. |
4699 | 4780 G1ParCleanupCTTask cleanup_task(ct_bs, this); |
4781 if (ParallelGCThreads > 0) { | |
4782 set_par_threads(workers()->total_workers()); | |
4783 workers()->run_task(&cleanup_task); | |
4784 set_par_threads(0); | |
4785 } else { | |
4786 while (_dirty_cards_region_list) { | |
4787 HeapRegion* r = _dirty_cards_region_list; | |
4788 cleanup_task.clear_cards(r); | |
4789 _dirty_cards_region_list = r->get_next_dirty_cards_region(); | |
4790 if (_dirty_cards_region_list == r) { | |
4791 // The last region. | |
4792 _dirty_cards_region_list = NULL; | |
4793 } | |
4794 r->set_next_dirty_cards_region(NULL); | |
4795 } | |
4796 } | |
4700 // now, redirty the cards of the scan-only and survivor regions | 4797 // now, redirty the cards of the scan-only and survivor regions |
4701 // (it seemed faster to do it this way, instead of iterating over | 4798 // (it seemed faster to do it this way, instead of iterating over |
4702 // all regions and then clearing / dirtying as approprite) | 4799 // all regions and then clearing / dirtying as appropriate) |
4703 dirtyCardsForYoungRegions(ct_bs, _young_list->first_scan_only_region()); | 4800 dirtyCardsForYoungRegions(ct_bs, _young_list->first_scan_only_region()); |
4704 dirtyCardsForYoungRegions(ct_bs, _young_list->first_survivor_region()); | 4801 dirtyCardsForYoungRegions(ct_bs, _young_list->first_survivor_region()); |
4705 | 4802 |
4706 double elapsed = os::elapsedTime() - start; | 4803 double elapsed = os::elapsedTime() - start; |
4707 g1_policy()->record_clear_ct_time( elapsed * 1000.0); | 4804 g1_policy()->record_clear_ct_time( elapsed * 1000.0); |