# HG changeset patch # User ctornqvi # Date 1450799622 0 # Node ID a92a6b278599f9cb9f09c25024056949b5b9c44b # Parent 7a6d0993a080f4d5c64d5d7dce3d7d1b6c63c9a7# Parent 3771329165d4d96a13950358359bf82b4d3f0634 Merge diff -r 7a6d0993a080 -r a92a6b278599 hotspot/src/share/vm/gc/g1/concurrentMark.cpp --- a/hotspot/src/share/vm/gc/g1/concurrentMark.cpp Tue Dec 22 05:26:55 2015 -0800 +++ b/hotspot/src/share/vm/gc/g1/concurrentMark.cpp Tue Dec 22 15:53:42 2015 +0000 @@ -32,10 +32,8 @@ #include "gc/g1/g1CollectorPolicy.hpp" #include "gc/g1/g1CollectorState.hpp" #include "gc/g1/g1OopClosures.inline.hpp" -#include "gc/g1/g1RemSet.hpp" #include "gc/g1/g1StringDedup.hpp" #include "gc/g1/heapRegion.inline.hpp" -#include "gc/g1/heapRegionManager.inline.hpp" #include "gc/g1/heapRegionRemSet.hpp" #include "gc/g1/heapRegionSet.inline.hpp" #include "gc/g1/suspendibleThreadSet.hpp" @@ -1595,24 +1593,6 @@ } }; -class G1ParScrubRemSetTask: public AbstractGangTask { -protected: - G1RemSet* _g1rs; - BitMap* _region_bm; - BitMap* _card_bm; - HeapRegionClaimer _hrclaimer; - -public: - G1ParScrubRemSetTask(G1CollectedHeap* g1h, BitMap* region_bm, BitMap* card_bm, uint n_workers) : - AbstractGangTask("G1 ScrubRS"), _g1rs(g1h->g1_rem_set()), _region_bm(region_bm), _card_bm(card_bm), _hrclaimer(n_workers) { - } - - void work(uint worker_id) { - _g1rs->scrub(_region_bm, _card_bm, worker_id, &_hrclaimer); - } - -}; - void ConcurrentMark::cleanup() { // world is stopped at this checkpoint assert(SafepointSynchronize::is_at_safepoint(), @@ -1700,12 +1680,8 @@ // regions. if (G1ScrubRemSets) { double rs_scrub_start = os::elapsedTime(); - G1ParScrubRemSetTask g1_par_scrub_rs_task(g1h, &_region_bm, &_card_bm, n_workers); - g1h->workers()->run_task(&g1_par_scrub_rs_task); - - double rs_scrub_end = os::elapsedTime(); - double this_rs_scrub_time = (rs_scrub_end - rs_scrub_start); - _total_rs_scrub_time += this_rs_scrub_time; + g1h->scrub_rem_set(&_region_bm, &_card_bm); + _total_rs_scrub_time += (os::elapsedTime() - rs_scrub_start); } // this will also free any regions totally full of garbage objects, diff -r 7a6d0993a080 -r a92a6b278599 hotspot/src/share/vm/gc/g1/g1CollectedHeap.cpp --- a/hotspot/src/share/vm/gc/g1/g1CollectedHeap.cpp Tue Dec 22 05:26:55 2015 -0800 +++ b/hotspot/src/share/vm/gc/g1/g1CollectedHeap.cpp Tue Dec 22 15:53:42 2015 +0000 @@ -1789,9 +1789,6 @@ uint n_queues = ParallelGCThreads; _task_queues = new RefToScanQueueSet(n_queues); - uint n_rem_sets = HeapRegionRemSet::num_par_rem_sets(); - assert(n_rem_sets > 0, "Invariant."); - _worker_cset_start_region = NEW_C_HEAP_ARRAY(HeapRegion*, n_queues, mtGC); _worker_cset_start_region_time_stamp = NEW_C_HEAP_ARRAY(uint, n_queues, mtGC); _evacuation_failed_info_array = NEW_C_HEAP_ARRAY(EvacuationFailedInfo, n_queues, mtGC); @@ -1891,7 +1888,6 @@ _g1_rem_set = new G1RemSet(this, g1_barrier_set()); // Carve out the G1 part of the heap. - ReservedSpace g1_rs = heap_rs.first_part(max_byte_size); size_t page_size = UseLargePages ? os::large_page_size() : os::vm_page_size(); G1RegionToSpaceMapper* heap_storage = @@ -1940,6 +1936,8 @@ const uint max_region_idx = (1U << (sizeof(RegionIdx_t)*BitsPerByte-1)) - 1; guarantee((max_regions() - 1) <= max_region_idx, "too many regions"); + G1RemSet::initialize(max_regions()); + size_t max_cards_per_region = ((size_t)1 << (sizeof(CardIdx_t)*BitsPerByte-1)) - 1; guarantee(HeapRegion::CardsPerRegion > 0, "make sure it's initialized"); guarantee(HeapRegion::CardsPerRegion < max_cards_per_region, @@ -1967,9 +1965,6 @@ } _cmThread = _cm->cmThread(); - // Initialize the from_card cache structure of HeapRegionRemSet. - HeapRegionRemSet::init_heap(max_regions()); - // Now expand into the initial heap size. if (!expand(init_byte_size)) { vm_shutdown_during_initialization("Failed to allocate initial heap."); @@ -5416,6 +5411,33 @@ } #endif // PRODUCT +class G1ParScrubRemSetTask: public AbstractGangTask { +protected: + G1RemSet* _g1rs; + BitMap* _region_bm; + BitMap* _card_bm; + HeapRegionClaimer _hrclaimer; + +public: + G1ParScrubRemSetTask(G1RemSet* g1_rs, BitMap* region_bm, BitMap* card_bm, uint num_workers) : + AbstractGangTask("G1 ScrubRS"), + _g1rs(g1_rs), + _region_bm(region_bm), + _card_bm(card_bm), + _hrclaimer(num_workers) { + } + + void work(uint worker_id) { + _g1rs->scrub(_region_bm, _card_bm, worker_id, &_hrclaimer); + } +}; + +void G1CollectedHeap::scrub_rem_set(BitMap* region_bm, BitMap* card_bm) { + uint num_workers = workers()->active_workers(); + G1ParScrubRemSetTask g1_par_scrub_rs_task(g1_rem_set(), region_bm, card_bm, num_workers); + workers()->run_task(&g1_par_scrub_rs_task); +} + void G1CollectedHeap::cleanUpCardTable() { G1SATBCardTableModRefBS* ct_bs = g1_barrier_set(); double start = os::elapsedTime(); diff -r 7a6d0993a080 -r a92a6b278599 hotspot/src/share/vm/gc/g1/g1CollectedHeap.hpp --- a/hotspot/src/share/vm/gc/g1/g1CollectedHeap.hpp Tue Dec 22 05:26:55 2015 -0800 +++ b/hotspot/src/share/vm/gc/g1/g1CollectedHeap.hpp Tue Dec 22 15:53:42 2015 +0000 @@ -984,6 +984,8 @@ // The rem set and barrier set. G1RemSet* g1_rem_set() const { return _g1_rem_set; } + void scrub_rem_set(BitMap* region_bm, BitMap* card_bm); + unsigned get_gc_time_stamp() { return _gc_time_stamp; } diff -r 7a6d0993a080 -r a92a6b278599 hotspot/src/share/vm/gc/g1/g1FromCardCache.cpp --- a/hotspot/src/share/vm/gc/g1/g1FromCardCache.cpp Tue Dec 22 05:26:55 2015 -0800 +++ b/hotspot/src/share/vm/gc/g1/g1FromCardCache.cpp Tue Dec 22 15:53:42 2015 +0000 @@ -24,7 +24,7 @@ #include "precompiled.hpp" #include "gc/g1/g1FromCardCache.hpp" -#include "gc/g1/heapRegionRemSet.hpp" +#include "gc/g1/g1RemSet.hpp" #include "memory/padded.inline.hpp" #include "utilities/debug.hpp" @@ -32,11 +32,12 @@ uint G1FromCardCache::_max_regions = 0; size_t G1FromCardCache::_static_mem_size = 0; -void G1FromCardCache::initialize(uint n_par_rs, uint max_num_regions) { +void G1FromCardCache::initialize(uint num_par_rem_sets, uint max_num_regions) { + guarantee(max_num_regions > 0, "Heap size must be valid"); guarantee(_cache == NULL, "Should not call this multiple times"); _max_regions = max_num_regions; - _cache = Padded2DArray::create_unfreeable(n_par_rs, + _cache = Padded2DArray::create_unfreeable(num_par_rem_sets, _max_regions, &_static_mem_size); @@ -47,9 +48,10 @@ guarantee((size_t)start_idx + new_num_regions <= max_uintx, "Trying to invalidate beyond maximum region, from %u size " SIZE_FORMAT, start_idx, new_num_regions); - for (uint i = 0; i < HeapRegionRemSet::num_par_rem_sets(); i++) { - uint end_idx = (start_idx + (uint)new_num_regions); - assert(end_idx <= _max_regions, "Must be within max."); + uint end_idx = (start_idx + (uint)new_num_regions); + assert(end_idx <= _max_regions, "Must be within max."); + + for (uint i = 0; i < G1RemSet::num_par_rem_sets(); i++) { for (uint j = start_idx; j < end_idx; j++) { set(i, j, InvalidCard); } @@ -58,7 +60,7 @@ #ifndef PRODUCT void G1FromCardCache::print(outputStream* out) { - for (uint i = 0; i < HeapRegionRemSet::num_par_rem_sets(); i++) { + for (uint i = 0; i < G1RemSet::num_par_rem_sets(); i++) { for (uint j = 0; j < _max_regions; j++) { out->print_cr("_from_card_cache[%u][%u] = %d.", i, j, at(i, j)); @@ -68,7 +70,7 @@ #endif void G1FromCardCache::clear(uint region_idx) { - uint num_par_remsets = HeapRegionRemSet::num_par_rem_sets(); + uint num_par_remsets = G1RemSet::num_par_rem_sets(); for (uint i = 0; i < num_par_remsets; i++) { set(i, region_idx, InvalidCard); } diff -r 7a6d0993a080 -r a92a6b278599 hotspot/src/share/vm/gc/g1/g1FromCardCache.hpp --- a/hotspot/src/share/vm/gc/g1/g1FromCardCache.hpp Tue Dec 22 05:26:55 2015 -0800 +++ b/hotspot/src/share/vm/gc/g1/g1FromCardCache.hpp Tue Dec 22 15:53:42 2015 +0000 @@ -65,7 +65,7 @@ _cache[worker_id][region_idx] = val; } - static void initialize(uint n_par_rs, uint max_num_regions); + static void initialize(uint num_par_rem_sets, uint max_num_regions); static void invalidate(uint start_idx, size_t num_regions); diff -r 7a6d0993a080 -r a92a6b278599 hotspot/src/share/vm/gc/g1/g1RemSet.cpp --- a/hotspot/src/share/vm/gc/g1/g1RemSet.cpp Tue Dec 22 05:26:55 2015 -0800 +++ b/hotspot/src/share/vm/gc/g1/g1RemSet.cpp Tue Dec 22 15:53:42 2015 +0000 @@ -25,9 +25,11 @@ #include "precompiled.hpp" #include "gc/g1/concurrentG1Refine.hpp" #include "gc/g1/concurrentG1RefineThread.hpp" +#include "gc/g1/dirtyCardQueue.hpp" #include "gc/g1/g1BlockOffsetTable.inline.hpp" #include "gc/g1/g1CollectedHeap.inline.hpp" #include "gc/g1/g1CollectorPolicy.hpp" +#include "gc/g1/g1FromCardCache.hpp" #include "gc/g1/g1GCPhaseTimes.hpp" #include "gc/g1/g1HotCardCache.hpp" #include "gc/g1/g1OopClosures.inline.hpp" @@ -76,6 +78,14 @@ FREE_C_HEAP_ARRAY(G1ParPushHeapRSClosure*, _cset_rs_update_cl); } +uint G1RemSet::num_par_rem_sets() { + return MAX2(DirtyCardQueueSet::num_par_ids() + ConcurrentG1Refine::thread_num(), ParallelGCThreads); +} + +void G1RemSet::initialize(uint max_regions) { + G1FromCardCache::initialize(num_par_rem_sets(), max_regions); +} + ScanRSClosure::ScanRSClosure(G1ParPushHeapRSClosure* oc, CodeBlobClosure* code_root_cl, uint worker_i) : diff -r 7a6d0993a080 -r a92a6b278599 hotspot/src/share/vm/gc/g1/g1RemSet.hpp --- a/hotspot/src/share/vm/gc/g1/g1RemSet.hpp Tue Dec 22 05:26:55 2015 -0800 +++ b/hotspot/src/share/vm/gc/g1/g1RemSet.hpp Tue Dec 22 15:53:42 2015 +0000 @@ -75,6 +75,16 @@ G1ParPushHeapRSClosure** _cset_rs_update_cl; public: + // Gives an approximation on how many threads can be expected to add records to + // a remembered set in parallel. This can be used for sizing data structures to + // decrease performance losses due to data structure sharing. + // Examples for quantities that influence this value are the maximum number of + // mutator threads, maximum number of concurrent refinement or GC threads. + static uint num_par_rem_sets(); + + // Initialize data that depends on the heap size being known. + static void initialize(uint max_regions); + // This is called to reset dual hash tables after the gc pause // is finished and the initial hash table is no longer being // scanned. diff -r 7a6d0993a080 -r a92a6b278599 hotspot/src/share/vm/gc/g1/heapRegion.cpp --- a/hotspot/src/share/vm/gc/g1/heapRegion.cpp Tue Dec 22 05:26:55 2015 -0800 +++ b/hotspot/src/share/vm/gc/g1/heapRegion.cpp Tue Dec 22 15:53:42 2015 +0000 @@ -258,7 +258,6 @@ _predicted_bytes_to_copy(0) { _rem_set = new HeapRegionRemSet(sharedOffsetArray, this); - assert(HeapRegionRemSet::num_par_rem_sets() > 0, "Invariant."); initialize(mr); } diff -r 7a6d0993a080 -r a92a6b278599 hotspot/src/share/vm/gc/g1/heapRegionRemSet.cpp --- a/hotspot/src/share/vm/gc/g1/heapRegionRemSet.cpp Tue Dec 22 05:26:55 2015 -0800 +++ b/hotspot/src/share/vm/gc/g1/heapRegionRemSet.cpp Tue Dec 22 15:53:42 2015 +0000 @@ -687,13 +687,6 @@ _sparse_table.do_cleanup_work(hrrs_cleanup_task); } -// Determines how many threads can add records to an rset in parallel. -// This can be done by either mutator threads together with the -// concurrent refinement threads or GC threads. -uint HeapRegionRemSet::num_par_rem_sets() { - return MAX2(DirtyCardQueueSet::num_par_ids() + ConcurrentG1Refine::thread_num(), ParallelGCThreads); -} - HeapRegionRemSet::HeapRegionRemSet(G1BlockOffsetSharedArray* bosa, HeapRegion* hr) : _bosa(bosa), diff -r 7a6d0993a080 -r a92a6b278599 hotspot/src/share/vm/gc/g1/heapRegionRemSet.hpp --- a/hotspot/src/share/vm/gc/g1/heapRegionRemSet.hpp Tue Dec 22 05:26:55 2015 -0800 +++ b/hotspot/src/share/vm/gc/g1/heapRegionRemSet.hpp Tue Dec 22 15:53:42 2015 +0000 @@ -191,7 +191,6 @@ public: HeapRegionRemSet(G1BlockOffsetSharedArray* bosa, HeapRegion* hr); - static uint num_par_rem_sets(); static void setup_remset_size(); bool is_empty() const { @@ -321,12 +320,6 @@ // Called during a stop-world phase to perform any deferred cleanups. static void cleanup(); - // Declare the heap size (in # of regions) to the HeapRegionRemSet(s). - // (Uses it to initialize from_card_cache). - static void init_heap(uint max_regions) { - G1FromCardCache::initialize(num_par_rem_sets(), max_regions); - } - static void invalidate_from_card_cache(uint start_idx, size_t num_regions) { G1FromCardCache::invalidate(start_idx, num_regions); }