Mercurial > hg > truffle
comparison src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepGeneration.cpp @ 11973:7b06ae405d7b
6990419: CMS Remaining work for 6572569: consistently skewed work distribution in (long) re-mark pauses
Reviewed-by: rasbold, tschatzl, jmasa
Contributed-by: yamauchi@google.com
author | jmasa |
---|---|
date | Tue, 23 Jul 2013 09:49:11 -0700 |
parents | 71180a6e5080 |
children | ca9dedeebdec |
comparison
equal
deleted
inserted
replaced
11135:2285b4a0a4e6 | 11973:7b06ae405d7b |
---|---|
567 // Construct the is_alive_closure with _span & markBitMap | 567 // Construct the is_alive_closure with _span & markBitMap |
568 _is_alive_closure(_span, &_markBitMap), | 568 _is_alive_closure(_span, &_markBitMap), |
569 _restart_addr(NULL), | 569 _restart_addr(NULL), |
570 _overflow_list(NULL), | 570 _overflow_list(NULL), |
571 _stats(cmsGen), | 571 _stats(cmsGen), |
572 _eden_chunk_lock(new Mutex(Mutex::leaf + 1, "CMS_eden_chunk_lock", true)), | |
572 _eden_chunk_array(NULL), // may be set in ctor body | 573 _eden_chunk_array(NULL), // may be set in ctor body |
573 _eden_chunk_capacity(0), // -- ditto -- | 574 _eden_chunk_capacity(0), // -- ditto -- |
574 _eden_chunk_index(0), // -- ditto -- | 575 _eden_chunk_index(0), // -- ditto -- |
575 _survivor_plab_array(NULL), // -- ditto -- | 576 _survivor_plab_array(NULL), // -- ditto -- |
576 _survivor_chunk_array(NULL), // -- ditto -- | 577 _survivor_chunk_array(NULL), // -- ditto -- |
2135 // For a mark-sweep, compute_new_size() will be called | 2136 // For a mark-sweep, compute_new_size() will be called |
2136 // in the heap's do_collection() method. | 2137 // in the heap's do_collection() method. |
2137 } | 2138 } |
2138 | 2139 |
2139 | 2140 |
2141 void CMSCollector::print_eden_and_survivor_chunk_arrays() { | |
2142 DefNewGeneration* dng = _young_gen->as_DefNewGeneration(); | |
2143 EdenSpace* eden_space = dng->eden(); | |
2144 ContiguousSpace* from_space = dng->from(); | |
2145 ContiguousSpace* to_space = dng->to(); | |
2146 // Eden | |
2147 if (_eden_chunk_array != NULL) { | |
2148 gclog_or_tty->print_cr("eden " PTR_FORMAT "-" PTR_FORMAT "-" PTR_FORMAT "(" SIZE_FORMAT ")", | |
2149 eden_space->bottom(), eden_space->top(), | |
2150 eden_space->end(), eden_space->capacity()); | |
2151 gclog_or_tty->print_cr("_eden_chunk_index=" SIZE_FORMAT ", " | |
2152 "_eden_chunk_capacity=" SIZE_FORMAT, | |
2153 _eden_chunk_index, _eden_chunk_capacity); | |
2154 for (size_t i = 0; i < _eden_chunk_index; i++) { | |
2155 gclog_or_tty->print_cr("_eden_chunk_array[" SIZE_FORMAT "]=" PTR_FORMAT, | |
2156 i, _eden_chunk_array[i]); | |
2157 } | |
2158 } | |
2159 // Survivor | |
2160 if (_survivor_chunk_array != NULL) { | |
2161 gclog_or_tty->print_cr("survivor " PTR_FORMAT "-" PTR_FORMAT "-" PTR_FORMAT "(" SIZE_FORMAT ")", | |
2162 from_space->bottom(), from_space->top(), | |
2163 from_space->end(), from_space->capacity()); | |
2164 gclog_or_tty->print_cr("_survivor_chunk_index=" SIZE_FORMAT ", " | |
2165 "_survivor_chunk_capacity=" SIZE_FORMAT, | |
2166 _survivor_chunk_index, _survivor_chunk_capacity); | |
2167 for (size_t i = 0; i < _survivor_chunk_index; i++) { | |
2168 gclog_or_tty->print_cr("_survivor_chunk_array[" SIZE_FORMAT "]=" PTR_FORMAT, | |
2169 i, _survivor_chunk_array[i]); | |
2170 } | |
2171 } | |
2172 } | |
2173 | |
2140 void CMSCollector::getFreelistLocks() const { | 2174 void CMSCollector::getFreelistLocks() const { |
2141 // Get locks for all free lists in all generations that this | 2175 // Get locks for all free lists in all generations that this |
2142 // collector is responsible for | 2176 // collector is responsible for |
2143 _cmsGen->freelistLock()->lock_without_safepoint_check(); | 2177 _cmsGen->freelistLock()->lock_without_safepoint_check(); |
2144 } | 2178 } |
3643 ClassLoaderDataGraph::remember_new_clds(true); | 3677 ClassLoaderDataGraph::remember_new_clds(true); |
3644 | 3678 |
3645 // Whenever a CLD is found, it will be claimed before proceeding to mark | 3679 // Whenever a CLD is found, it will be claimed before proceeding to mark |
3646 // the klasses. The claimed marks need to be cleared before marking starts. | 3680 // the klasses. The claimed marks need to be cleared before marking starts. |
3647 ClassLoaderDataGraph::clear_claimed_marks(); | 3681 ClassLoaderDataGraph::clear_claimed_marks(); |
3682 | |
3683 if (CMSPrintEdenSurvivorChunks) { | |
3684 print_eden_and_survivor_chunk_arrays(); | |
3685 } | |
3648 | 3686 |
3649 CMKlassClosure klass_closure(¬Older); | 3687 CMKlassClosure klass_closure(¬Older); |
3650 { | 3688 { |
3651 COMPILER2_PRESENT(DerivedPointerTableDeactivate dpt_deact;) | 3689 COMPILER2_PRESENT(DerivedPointerTableDeactivate dpt_deact;) |
3652 gch->rem_set()->prepare_for_younger_refs_iterate(false); // Not parallel. | 3690 gch->rem_set()->prepare_for_younger_refs_iterate(false); // Not parallel. |
4415 assert(Thread::current()->is_ConcurrentGC_thread(), "Wrong thread"); | 4453 assert(Thread::current()->is_ConcurrentGC_thread(), "Wrong thread"); |
4416 verify_work_stacks_empty(); | 4454 verify_work_stacks_empty(); |
4417 verify_overflow_empty(); | 4455 verify_overflow_empty(); |
4418 _abort_preclean = false; | 4456 _abort_preclean = false; |
4419 if (CMSPrecleaningEnabled) { | 4457 if (CMSPrecleaningEnabled) { |
4420 _eden_chunk_index = 0; | 4458 if (!CMSEdenChunksRecordAlways) { |
4459 _eden_chunk_index = 0; | |
4460 } | |
4421 size_t used = get_eden_used(); | 4461 size_t used = get_eden_used(); |
4422 size_t capacity = get_eden_capacity(); | 4462 size_t capacity = get_eden_capacity(); |
4423 // Don't start sampling unless we will get sufficiently | 4463 // Don't start sampling unless we will get sufficiently |
4424 // many samples. | 4464 // many samples. |
4425 if (used < (capacity/(CMSScheduleRemarkSamplingRatio * 100) | 4465 if (used < (capacity/(CMSScheduleRemarkSamplingRatio * 100) |
4524 assert(ConcurrentMarkSweepThread::cms_thread_has_cms_token(), | 4564 assert(ConcurrentMarkSweepThread::cms_thread_has_cms_token(), |
4525 "Should collect samples while holding CMS token"); | 4565 "Should collect samples while holding CMS token"); |
4526 if (!_start_sampling) { | 4566 if (!_start_sampling) { |
4527 return; | 4567 return; |
4528 } | 4568 } |
4529 if (_eden_chunk_array) { | 4569 // When CMSEdenChunksRecordAlways is true, the eden chunk array |
4570 // is populated by the young generation. | |
4571 if (_eden_chunk_array != NULL && !CMSEdenChunksRecordAlways) { | |
4530 if (_eden_chunk_index < _eden_chunk_capacity) { | 4572 if (_eden_chunk_index < _eden_chunk_capacity) { |
4531 _eden_chunk_array[_eden_chunk_index] = *_top_addr; // take sample | 4573 _eden_chunk_array[_eden_chunk_index] = *_top_addr; // take sample |
4532 assert(_eden_chunk_array[_eden_chunk_index] <= *_end_addr, | 4574 assert(_eden_chunk_array[_eden_chunk_index] <= *_end_addr, |
4533 "Unexpected state of Eden"); | 4575 "Unexpected state of Eden"); |
4534 // We'd like to check that what we just sampled is an oop-start address; | 4576 // We'd like to check that what we just sampled is an oop-start address; |
5008 // so here just in case a scavenge did not happen. | 5050 // so here just in case a scavenge did not happen. |
5009 gch->ensure_parsability(false); // fill TLAB's, but no need to retire them | 5051 gch->ensure_parsability(false); // fill TLAB's, but no need to retire them |
5010 // Update the saved marks which may affect the root scans. | 5052 // Update the saved marks which may affect the root scans. |
5011 gch->save_marks(); | 5053 gch->save_marks(); |
5012 | 5054 |
5055 if (CMSPrintEdenSurvivorChunks) { | |
5056 print_eden_and_survivor_chunk_arrays(); | |
5057 } | |
5058 | |
5013 { | 5059 { |
5014 COMPILER2_PRESENT(DerivedPointerTableDeactivate dpt_deact;) | 5060 COMPILER2_PRESENT(DerivedPointerTableDeactivate dpt_deact;) |
5015 | 5061 |
5016 // Note on the role of the mod union table: | 5062 // Note on the role of the mod union table: |
5017 // Since the marker in "markFromRoots" marks concurrently with | 5063 // Since the marker in "markFromRoots" marks concurrently with |
5526 gclog_or_tty->print("\n\t(%d: stole %d oops)", i, num_steals); | 5572 gclog_or_tty->print("\n\t(%d: stole %d oops)", i, num_steals); |
5527 } | 5573 } |
5528 ) | 5574 ) |
5529 assert(work_q->size() == 0 && _collector->overflow_list_is_empty(), | 5575 assert(work_q->size() == 0 && _collector->overflow_list_is_empty(), |
5530 "Else our work is not yet done"); | 5576 "Else our work is not yet done"); |
5577 } | |
5578 | |
5579 // Record object boundaries in _eden_chunk_array by sampling the eden | |
5580 // top in the slow-path eden object allocation code path and record | |
5581 // the boundaries, if CMSEdenChunksRecordAlways is true. If | |
5582 // CMSEdenChunksRecordAlways is false, we use the other asynchronous | |
5583 // sampling in sample_eden() that activates during the part of the | |
5584 // preclean phase. | |
5585 void CMSCollector::sample_eden_chunk() { | |
5586 if (CMSEdenChunksRecordAlways && _eden_chunk_array != NULL) { | |
5587 if (_eden_chunk_lock->try_lock()) { | |
5588 // Record a sample. This is the critical section. The contents | |
5589 // of the _eden_chunk_array have to be non-decreasing in the | |
5590 // address order. | |
5591 _eden_chunk_array[_eden_chunk_index] = *_top_addr; | |
5592 assert(_eden_chunk_array[_eden_chunk_index] <= *_end_addr, | |
5593 "Unexpected state of Eden"); | |
5594 if (_eden_chunk_index == 0 || | |
5595 ((_eden_chunk_array[_eden_chunk_index] > _eden_chunk_array[_eden_chunk_index-1]) && | |
5596 (pointer_delta(_eden_chunk_array[_eden_chunk_index], | |
5597 _eden_chunk_array[_eden_chunk_index-1]) >= CMSSamplingGrain))) { | |
5598 _eden_chunk_index++; // commit sample | |
5599 } | |
5600 _eden_chunk_lock->unlock(); | |
5601 } | |
5602 } | |
5531 } | 5603 } |
5532 | 5604 |
5533 // Return a thread-local PLAB recording array, as appropriate. | 5605 // Return a thread-local PLAB recording array, as appropriate. |
5534 void* CMSCollector::get_data_recorder(int thr_num) { | 5606 void* CMSCollector::get_data_recorder(int thr_num) { |
5535 if (_survivor_plab_array != NULL && | 5607 if (_survivor_plab_array != NULL && |
9375 | 9447 |
9376 default: | 9448 default: |
9377 ShouldNotReachHere(); | 9449 ShouldNotReachHere(); |
9378 } | 9450 } |
9379 } | 9451 } |
9380 |