# HG changeset patch # User Haoyu Li # Date 1573008570 -28800 # Wed Nov 06 10:49:30 2019 +0800 # Node ID 28f672ff8e7b18687fd295a4b75a8d9629612c99 # Parent ae5a11e6bc13e5b62798ad286c71b8ab8341880c add _offset in MoveAndUpdateClosure to reuse more code, solve assertion violation in complete_region, and change mark_filled to void diff -r ae5a11e6bc13 -r 28f672ff8e7b src/hotspot/share/gc/parallel/psParallelCompact.cpp --- a/src/hotspot/share/gc/parallel/psParallelCompact.cpp Wed Nov 06 10:48:25 2019 +0800 +++ b/src/hotspot/share/gc/parallel/psParallelCompact.cpp Wed Nov 06 10:49:30 2019 +0800 @@ -3138,7 +3138,8 @@ if (status == ParMarkBitMap::would_overflow) { // The last object did not fit. Note that interior oop updates were // deferred, then copy enough of the object to fill the region. - closure.set_deferred_obj_addr_for(region_ptr); + 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, @@ -3180,6 +3181,7 @@ // ShadowClosure to fill the acquired shadow region. if (shadow_region == 0) { MoveAndUpdateClosure cl(mark_bitmap(), cm, region_idx); + region_ptr->mark_normal(); return fill_region(cm, cl, region_idx); } else { ShadowClosure cl(mark_bitmap(), cm, region_idx, shadow_region); @@ -3305,9 +3307,9 @@ ParMarkBitMap::IterationStatus MoveAndUpdateClosure::copy_until_full() { - if (source() != destination()) { + if (source() != copy_destination()) { DEBUG_ONLY(PSParallelCompact::check_new_location(source(), destination());) - Copy::aligned_conjoint_words(source(), destination(), words_remaining()); + Copy::aligned_conjoint_words(source(), copy_destination(), words_remaining()); } update_state(words_remaining()); assert(is_full(), "sanity"); @@ -3326,9 +3328,9 @@ // This test is necessary; if omitted, the pointer updates to a partial object // that crosses the dense prefix boundary could be overwritten. - if (source() != destination()) { + if (source() != copy_destination()) { DEBUG_ONLY(PSParallelCompact::check_new_location(source(), destination());) - Copy::aligned_conjoint_words(source(), destination(), words); + Copy::aligned_conjoint_words(source(), copy_destination(), words); } update_state(words); } @@ -3339,50 +3341,41 @@ region_ptr->set_completed(); } -void MoveAndUpdateClosure::allocate_block() { +ParMarkBitMapClosure::IterationStatus +MoveAndUpdateClosure::do_addr(HeapWord* addr, size_t words) { assert(destination() != NULL, "sanity"); + assert(bitmap()->obj_size(addr) == words, "bad size"); + + _source = addr; assert(PSParallelCompact::summary_data().calc_new_pointer(source(), compaction_manager()) == destination(), "wrong destination"); - // The start_array must be updated even if the object is not moving. - if (_start_array != NULL) { - _start_array->allocate_block(destination()); - } -} - -void MoveAndUpdateClosure::set_deferred_obj_addr_for(PSParallelCompact::RegionData *region_ptr) { - region_ptr->set_deferred_obj_addr(destination()); -} - -ParMarkBitMapClosure::IterationStatus -MoveAndUpdateClosure::do_addr(HeapWord* addr, size_t words) { - assert(bitmap()->obj_size(addr) == words, "bad size"); - - _source = addr; - if (words > words_remaining()) { return ParMarkBitMap::would_overflow; } - allocate_block(); - - if (destination() != source()) { + // The start_array must be updated even if the object is not moving. + if (_start_array != NULL) { + _start_array->allocate_block(destination()); + } + + if (copy_destination() != source()) { DEBUG_ONLY(PSParallelCompact::check_new_location(source(), destination());) - Copy::aligned_conjoint_words(source(), destination(), words); + Copy::aligned_conjoint_words(source(), copy_destination(), words); } - oop moved_oop = (oop) destination(); + oop moved_oop = (oop) copy_destination(); compaction_manager()->update_contents(moved_oop); assert(oopDesc::is_oop_or_null(moved_oop), "Expected an oop or NULL at " PTR_FORMAT, p2i(moved_oop)); update_state(words); - assert(destination() == (HeapWord*)moved_oop + moved_oop->size(), "sanity"); + assert(copy_destination() == (HeapWord*)moved_oop + moved_oop->size(), "sanity"); return is_full() ? ParMarkBitMap::full : ParMarkBitMap::incomplete; } void ShadowClosure::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::SHADOW, "Region should be shadow"); // Record the shadow region index region_ptr->set_shadow_region(_shadow); // Mark the shadow region filled @@ -3396,22 +3389,6 @@ } } -void ShadowClosure::allocate_block() { - HeapWord *real_dest = destination() - _offset; - assert(real_dest != NULL, "sanity"); - assert(PSParallelCompact::summary_data().calc_new_pointer(source(), compaction_manager()) == - real_dest, "wrong destination"); - - // The start_array must be updated even if the object is not moving. - if (_start_array != NULL) { - _start_array->allocate_block(real_dest); - } -} - -void ShadowClosure::set_deferred_obj_addr_for(PSParallelCompact::RegionData *region_ptr) { - region_ptr->set_deferred_obj_addr(destination() - _offset); -} - UpdateOnlyClosure::UpdateOnlyClosure(ParMarkBitMap* mbm, ParCompactionManager* cm, PSParallelCompact::SpaceId space_id) : diff -r ae5a11e6bc13 -r 28f672ff8e7b src/hotspot/share/gc/parallel/psParallelCompact.hpp --- a/src/hotspot/share/gc/parallel/psParallelCompact.hpp Wed Nov 06 10:48:25 2019 +0800 +++ b/src/hotspot/share/gc/parallel/psParallelCompact.hpp Wed Nov 06 10:49:30 2019 +0800 @@ -344,9 +344,13 @@ inline bool try_push(); inline bool try_steal(); // Mark the region as filled and ready to be copied back - inline bool mark_filled(); + inline void mark_filled(); // Preempt the region to copy the shadow region content back inline bool try_copy(); + // Special case: see the comment in PSParallelCompact::fill_shadow_region. + // Return to the normal path here + inline void mark_normal(); + int shadow_state() { return _shadow_state; } @@ -629,14 +633,19 @@ return Atomic::cmpxchg(SHADOW, &_shadow_state, UNUSED) == UNUSED; } -inline bool ParallelCompactData::RegionData::mark_filled() { - return Atomic::cmpxchg(FILLED, &_shadow_state, SHADOW) == SHADOW; +inline void ParallelCompactData::RegionData::mark_filled() { + int old = Atomic::cmpxchg(FILLED, &_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; } +void ParallelCompactData::RegionData::mark_normal() { + _shadow_state = FINISH; +} + inline ParallelCompactData::RegionData* ParallelCompactData::region(size_t region_idx) const { @@ -1287,6 +1296,7 @@ // Accessors. HeapWord* destination() const { return _destination; } + HeapWord* copy_destination() const { return _destination + _offset; } // If the object will fit (size <= words_remaining()), copy it to the current // destination, update the interior oops and the start array and return either @@ -1306,10 +1316,6 @@ virtual void complete_region(ParCompactionManager* cm, HeapWord* dest_addr, PSParallelCompact::RegionData* region_ptr); - virtual void allocate_block(); - - virtual void set_deferred_obj_addr_for(PSParallelCompact::RegionData* region_ptr); - protected: // Update variables to indicate that word_count words were processed. inline void update_state(size_t word_count); @@ -1317,6 +1323,7 @@ protected: HeapWord* _destination; // Next addr to be written. ObjectStartArray* const _start_array; + size_t _offset; }; inline size_t MoveAndUpdateClosure::calculate_words_remaining(size_t region) { @@ -1334,7 +1341,8 @@ size_t region_idx) : ParMarkBitMapClosure(bitmap, cm, calculate_words_remaining(region_idx)), _destination(PSParallelCompact::summary_data().region_to_addr(region_idx)), - _start_array(PSParallelCompact::start_array(PSParallelCompact::space_id(_destination))) { } + _start_array(PSParallelCompact::start_array(PSParallelCompact::space_id(_destination))), + _offset(0) { } inline void MoveAndUpdateClosure::update_state(size_t words) @@ -1353,13 +1361,8 @@ virtual void complete_region(ParCompactionManager* cm, HeapWord* dest_addr, PSParallelCompact::RegionData* region_ptr); - virtual void allocate_block(); - - virtual void set_deferred_obj_addr_for(PSParallelCompact::RegionData* region_ptr); - private: size_t _shadow; - size_t _offset; }; inline size_t ShadowClosure::calculate_shadow_offset(size_t region_idx, size_t shadow_idx) { @@ -1375,10 +1378,8 @@ size_t region, size_t shadow) : MoveAndUpdateClosure(bitmap, cm, region), - _shadow(shadow), - _offset(calculate_shadow_offset(region, shadow)) { - ParallelCompactData& sd = PSParallelCompact::summary_data(); - _destination = sd.region_to_addr(shadow); + _shadow(shadow) { + _offset = calculate_shadow_offset(region, shadow); } class UpdateOnlyClosure: public ParMarkBitMapClosure {