--- old/src/hotspot/share/gc/parallel/psCompactionManager.cpp 2019-11-18 15:27:43.554136648 +0100 +++ new/src/hotspot/share/gc/parallel/psCompactionManager.cpp 2019-11-18 15:27:43.217126217 +0100 @@ -104,11 +104,8 @@ "Not initialized?"); _shadow_region_array = new (ResourceObj::C_HEAP, mtInternal) GrowableArray(10, true); - guarantee(_shadow_region_array != NULL, "Could not allocate shadow_region_array"); - _shadow_region_monitor = new Monitor(Mutex::barrier, "CompactionManager monitor", Mutex::_allow_vm_block_flag, Monitor::_safepoint_check_never); - guarantee(_shadow_region_monitor != NULL, "Could not allocate shadow_region_monitor"); } void ParCompactionManager::reset_all_bitmap_query_caches() { @@ -195,10 +192,10 @@ _shadow_region_array->append(shadow_region); } -void ParCompactionManager::enqueue_shadow_region(size_t shadow_region) { +void ParCompactionManager::add_shadow_region(size_t shadow_region) { _shadow_region_array->append(shadow_region); } -void ParCompactionManager::dequeue_shadow_region() { +void ParCompactionManager::remove_all_shadow_regions() { _shadow_region_array->clear(); } \ No newline at end of file --- old/src/hotspot/share/gc/parallel/psCompactionManager.hpp 2019-11-18 15:27:44.827176048 +0100 +++ new/src/hotspot/share/gc/parallel/psCompactionManager.hpp 2019-11-18 15:27:44.488165556 +0100 @@ -25,10 +25,10 @@ #ifndef SHARE_GC_PARALLEL_PSCOMPACTIONMANAGER_HPP #define SHARE_GC_PARALLEL_PSCOMPACTIONMANAGER_HPP +#include "gc/parallel/psParallelCompact.hpp" #include "gc/shared/taskqueue.hpp" #include "memory/allocation.hpp" #include "utilities/stack.hpp" -#include "psParallelCompact.hpp" class MutableSpace; class PSOldGen; @@ -119,13 +119,15 @@ // marking stack and overflow stack directly. public: - static size_t acquire_shadow_region(PSParallelCompact::RegionData* region_ptr); - static void release_shadow_region(size_t shadow_region); - static void enqueue_shadow_region(size_t shadow_region); - static void dequeue_shadow_region(); - inline size_t shadow_record() { return _shadow_record; } - inline void set_shadow_record(size_t record) { _shadow_record = record; } - inline size_t next_shadow_record(size_t workers) { _shadow_record += workers; return shadow_record(); } + static size_t acquire_shadow_region(PSParallelCompact::RegionData* region_ptr); + static void release_shadow_region(size_t shadow_region); + + static void add_shadow_region(size_t shadow_region); + static void remove_all_shadow_regions(); + + inline size_t shadow_record() { return _shadow_record; } + inline void set_shadow_record(size_t record) { _shadow_record = record; } + inline size_t next_shadow_record(size_t workers) { _shadow_record += workers; return shadow_record(); } void reset_bitmap_query_cache() { _last_query_beg = NULL; --- old/src/hotspot/share/gc/parallel/psParallelCompact.cpp 2019-11-18 15:27:46.133216470 +0100 +++ new/src/hotspot/share/gc/parallel/psParallelCompact.cpp 2019-11-18 15:27:45.784205668 +0100 @@ -125,11 +125,6 @@ const ParallelCompactData::RegionData::region_sz_t ParallelCompactData::RegionData::dc_completed = 0xcU << dc_shift; -const int ParallelCompactData::RegionData::UNUSED = 0; -const int ParallelCompactData::RegionData::SHADOW = 1; -const int ParallelCompactData::RegionData::FILLED = 2; -const int ParallelCompactData::RegionData::FINISH = 3; - SpaceInfo PSParallelCompact::_space_info[PSParallelCompact::last_space_id]; SpanSubjectToDiscoveryClosure PSParallelCompact::_span_based_discoverer; @@ -1028,7 +1023,7 @@ void PSParallelCompact::post_compact() { GCTraceTime(Info, gc, phases) tm("Post Compact", &_gc_timer); - ParCompactionManager::dequeue_shadow_region(); + ParCompactionManager::remove_all_shadow_regions(); for (unsigned int id = old_space_id; id < last_space_id; ++id) { // Clear the marking bitmap, summary data and split info. @@ -2423,10 +2418,10 @@ for (size_t cur = end_region - 1; cur + 1 > beg_region; --cur) { if (sd.region(cur)->claim_unsafe()) { ParCompactionManager* cm = ParCompactionManager::manager_array(worker_id); - if (sd.region(cur)->try_push()) { - cm->region_stack()->push(cur); - region_logger.handle(cur); - } + bool try_push = sd.region(cur)->try_push(); + assert(try_push, "Must succeed at this point."); + cm->region_stack()->push(cur); + region_logger.handle(cur); // Assign regions to tasks in round-robin fashion. if (++worker_id == parallel_gc_threads) { worker_id = 0; @@ -2669,7 +2664,7 @@ // // max push count is thus: last_space_id * (active_gc_threads * PAR_OLD_DENSE_PREFIX_OVER_PARTITIONING + 1) TaskQueue task_queue(last_space_id * (active_gc_threads * PAR_OLD_DENSE_PREFIX_OVER_PARTITIONING + 1)); - enqueue_shadow_region(); + initialize_shadow_regions(); prepare_region_draining_tasks(active_gc_threads); enqueue_dense_prefix_tasks(task_queue, active_gc_threads); @@ -3139,7 +3134,6 @@ // The last object did not fit. Note that interior oop updates were // deferred, then copy enough of the object to fill the region. region_ptr->set_deferred_obj_addr(closure.destination()); - status = closure.copy_until_full(); // copies from closure.source() decrement_destination_counts(cm, src_space_id, src_region_idx, @@ -3165,14 +3159,15 @@ } while (true); } -void PSParallelCompact::fill_and_update_region(ParCompactionManager* cm, size_t region_idx) { +void PSParallelCompact::fill_and_update_region(ParCompactionManager* cm, size_t region_idx) +{ MoveAndUpdateClosure cl(mark_bitmap(), cm, region_idx); fill_region(cm, cl, region_idx); } -void PSParallelCompact::fill_shadow_region(ParCompactionManager* cm, size_t region_idx) +void PSParallelCompact::fill_and_update_shadow_region(ParCompactionManager* cm, size_t region_idx) { - // Acquire a shadow region at first + // Acquire a shadow region first ParallelCompactData& sd = summary_data(); RegionData* const region_ptr = sd.region(region_idx); size_t shadow_region = cm->acquire_shadow_region(region_ptr); @@ -3184,16 +3179,18 @@ region_ptr->mark_normal(); return fill_region(cm, cl, region_idx); } else { - ShadowClosure cl(mark_bitmap(), cm, region_idx, shadow_region); + MoveAndUpdateShadowClosure cl(mark_bitmap(), cm, region_idx, shadow_region); return fill_region(cm, cl, region_idx); } } -void PSParallelCompact::copy_back(HeapWord *shadow_addr, HeapWord *region_addr) { +void PSParallelCompact::copy_back(HeapWord *shadow_addr, HeapWord *region_addr) +{ Copy::aligned_conjoint_words(shadow_addr, region_addr, _summary_data.RegionSize); } -bool PSParallelCompact::steal_shadow_region(ParCompactionManager* cm, size_t ®ion_idx) { +bool PSParallelCompact::steal_shadow_region(ParCompactionManager* cm, size_t ®ion_idx) +{ size_t record = cm->shadow_record(); ParallelCompactData& sd = _summary_data; size_t old_new_top = sd.addr_to_region_idx(_space_info[old_space_id].new_top()); @@ -3210,7 +3207,8 @@ return false; } -void PSParallelCompact::enqueue_shadow_region() { +void PSParallelCompact::initialize_shadow_regions() +{ const ParallelCompactData& sd = PSParallelCompact::summary_data(); for (unsigned int id = old_space_id; id < last_space_id; ++id) { @@ -3223,12 +3221,13 @@ sd.addr_to_region_idx(sd.region_align_down(space->end())); for (size_t cur = beg_region + 1; cur < end_region; ++cur) { - ParCompactionManager::enqueue_shadow_region(cur); + ParCompactionManager::add_shadow_region(cur); } } } -void PSParallelCompact::initialize_steal_record(uint which) { +void PSParallelCompact::initialize_steal_record(uint which) +{ ParCompactionManager* cm = ParCompactionManager::gc_thread_compaction_manager(which); size_t record = _summary_data.addr_to_region_idx(_space_info[old_space_id].dense_prefix()); @@ -3337,7 +3336,7 @@ void MoveAndUpdateClosure::complete_region(ParCompactionManager *cm, HeapWord *dest_addr, PSParallelCompact::RegionData *region_ptr) { - assert(region_ptr->shadow_state() == ParallelCompactData::RegionData::FINISH, "Region should be finished"); + assert(region_ptr->shadow_state() == ParallelCompactData::RegionData::FinishedShadow, "Region should be finished"); region_ptr->set_completed(); } @@ -3373,9 +3372,9 @@ return is_full() ? ParMarkBitMap::full : ParMarkBitMap::incomplete; } -void ShadowClosure::complete_region(ParCompactionManager *cm, HeapWord *dest_addr, +void MoveAndUpdateShadowClosure::complete_region(ParCompactionManager *cm, HeapWord *dest_addr, PSParallelCompact::RegionData *region_ptr) { - assert(region_ptr->shadow_state() == ParallelCompactData::RegionData::SHADOW, "Region should be shadow"); + assert(region_ptr->shadow_state() == ParallelCompactData::RegionData::Shadow, "Region should be shadow"); // Record the shadow region index region_ptr->set_shadow_region(_shadow); // Mark the shadow region filled --- old/src/hotspot/share/gc/parallel/psParallelCompact.hpp 2019-11-18 15:27:47.445257077 +0100 +++ new/src/hotspot/share/gc/parallel/psParallelCompact.hpp 2019-11-18 15:27:47.106246585 +0100 @@ -332,15 +332,15 @@ // Possible values of _shadow_state, and transition is as follows // Normal Path: - // UNUSED -> try_push() -> FINISHED + // UnusedShadow -> try_push() -> FinishedShadow // Steal Path: - // UNUSED -> try_steal() -> SHADOW -> mark_filled() -> FILLED -> try_copy() -> FINISHED - static const int UNUSED; // Original state - static const int SHADOW; // Stolen by an idle thread, and a shadow region is created for it - static const int FILLED; // Its shadow region has been filled and ready to be copied back - static const int FINISH; // Work has been done + // UnusedShadow -> try_steal() -> Shadow -> mark_filled() -> FilledShadow -> try_copy() -> FinishedShadow + static const int UnusedShadow = 0; // Original state + static const int Shadow = 1; // Stolen by an idle thread, and a shadow region is created for it + static const int FilledShadow = 2; // Its shadow region has been filled and ready to be copied back + static const int FinishedShadow = 3; // Work has been done - // Preempt the region to avoid double processes + // Reserve the region to avoid double processing inline bool try_push(); inline bool try_steal(); // Mark the region as filled and ready to be copied back @@ -626,25 +626,25 @@ } inline bool ParallelCompactData::RegionData::try_push() { - return Atomic::cmpxchg(FINISH, &_shadow_state, UNUSED) == UNUSED; + return Atomic::cmpxchg(FinishedShadow, &_shadow_state, UnusedShadow) == UnusedShadow; } inline bool ParallelCompactData::RegionData::try_steal() { - return Atomic::cmpxchg(SHADOW, &_shadow_state, UNUSED) == UNUSED; + return Atomic::cmpxchg(Shadow, &_shadow_state, UnusedShadow) == UnusedShadow; } inline void ParallelCompactData::RegionData::mark_filled() { - int old = Atomic::cmpxchg(FILLED, &_shadow_state, SHADOW); - assert(old == SHADOW, "Fail to mark the region as filled"); + int old = Atomic::cmpxchg(FilledShadow, &_shadow_state, Shadow); + assert(old == Shadow, "Fail to mark the region as filled"); } inline bool ParallelCompactData::RegionData::try_copy() { - return Atomic::cmpxchg(FINISH, &_shadow_state, FILLED) == FILLED; + return Atomic::cmpxchg(FinishedShadow, &_shadow_state, FilledShadow) == FilledShadow; } void ParallelCompactData::RegionData::mark_normal() { - int old = Atomic::cmpxchg(FINISH, &_shadow_state, SHADOW); - assert(old == SHADOW, "Fail to mark the region as finish"); + int old = Atomic::cmpxchg(FinishedShadow, &_shadow_state, Shadow); + assert(old == Shadow, "Fail to mark the region as finish"); } inline ParallelCompactData::RegionData* @@ -1234,16 +1234,13 @@ static void fill_and_update_region(ParCompactionManager* cm, size_t region); static bool steal_shadow_region(ParCompactionManager* cm, size_t& region_idx); - static void fill_shadow_region(ParCompactionManager* cm, size_t region_idx); - static void fill_and_update_shadow_region(ParCompactionManager* cm, size_t region) { - fill_shadow_region(cm, region); - } + static void fill_and_update_shadow_region(ParCompactionManager* cm, size_t region); // Copy the content of a shadow region back to its corresponding heap region static void copy_back(HeapWord* shadow_addr, HeapWord* region_addr); // Initialize the steal record of a GC thread static void initialize_steal_record(uint which); // Reuse the empty heap regions as shadow regions, like to-space regions - static void enqueue_shadow_region(); + static void initialize_shadow_regions(); // Fill in the block table for the specified region. static void fill_blocks(size_t region_idx); @@ -1353,10 +1350,10 @@ _destination += words; } -class ShadowClosure: public MoveAndUpdateClosure { +class MoveAndUpdateShadowClosure: public MoveAndUpdateClosure { inline size_t calculate_shadow_offset(size_t region_idx, size_t shadow_idx); public: - inline ShadowClosure(ParMarkBitMap* bitmap, ParCompactionManager* cm, + inline MoveAndUpdateShadowClosure(ParMarkBitMap* bitmap, ParCompactionManager* cm, size_t region, size_t shadow); virtual void complete_region(ParCompactionManager* cm, HeapWord* dest_addr, @@ -1366,7 +1363,7 @@ size_t _shadow; }; -inline size_t ShadowClosure::calculate_shadow_offset(size_t region_idx, size_t shadow_idx) { +inline size_t MoveAndUpdateShadowClosure::calculate_shadow_offset(size_t region_idx, size_t shadow_idx) { ParallelCompactData& sd = PSParallelCompact::summary_data(); HeapWord* dest_addr = sd.region_to_addr(region_idx); HeapWord* shadow_addr = sd.region_to_addr(shadow_idx); @@ -1374,7 +1371,7 @@ } inline -ShadowClosure::ShadowClosure(ParMarkBitMap *bitmap, +MoveAndUpdateShadowClosure::MoveAndUpdateShadowClosure(ParMarkBitMap *bitmap, ParCompactionManager *cm, size_t region, size_t shadow) :