From c7fcd62302a4b70214e4aea7052e661a2aa9b03b Mon Sep 17 00:00:00 2001 From: Guoxiong Li Date: Fri, 12 Apr 2024 07:29:41 +0000 Subject: [PATCH] 8330006: Serial: Extract out ContiguousSpace::block_start_const Reviewed-by: ayang, tschatzl --- src/hotspot/share/gc/serial/cardTableRS.cpp | 12 +++---- src/hotspot/share/gc/serial/cardTableRS.hpp | 4 +-- .../share/gc/serial/defNewGeneration.cpp | 29 +++++++++++++-- .../share/gc/serial/tenuredGeneration.cpp | 18 ++++++++-- .../share/gc/serial/tenuredGeneration.hpp | 2 +- src/hotspot/share/gc/shared/space.cpp | 35 ------------------- src/hotspot/share/gc/shared/space.hpp | 8 ----- 7 files changed, 50 insertions(+), 58 deletions(-) diff --git a/src/hotspot/share/gc/serial/cardTableRS.cpp b/src/hotspot/share/gc/serial/cardTableRS.cpp index 789b5f21cffa1..71492a8468dee 100644 --- a/src/hotspot/share/gc/serial/cardTableRS.cpp +++ b/src/hotspot/share/gc/serial/cardTableRS.cpp @@ -31,9 +31,9 @@ #include "memory/iterator.inline.hpp" #include "utilities/align.hpp" -void CardTableRS::scan_old_to_young_refs(TenuredSpace* sp, HeapWord* saved_mark_word) { - const MemRegion ur = sp->used_region(); - const MemRegion urasm = MemRegion(sp->bottom(), saved_mark_word); +void CardTableRS::scan_old_to_young_refs(TenuredGeneration* tg, HeapWord* saved_mark_word) { + const MemRegion ur = tg->used_region(); + const MemRegion urasm = MemRegion(tg->space()->bottom(), saved_mark_word); assert(ur.contains(urasm), "Did you forget to call save_marks()? " @@ -43,7 +43,7 @@ void CardTableRS::scan_old_to_young_refs(TenuredSpace* sp, HeapWord* saved_mark_ if (!urasm.is_empty()) { OldGenScanClosure cl(SerialHeap::heap()->young_gen()); - non_clean_card_iterate(sp, urasm, &cl); + non_clean_card_iterate(tg, urasm, &cl); } } @@ -225,7 +225,7 @@ static void scan_obj_with_limit(oop obj, } } -void CardTableRS::non_clean_card_iterate(TenuredSpace* sp, +void CardTableRS::non_clean_card_iterate(TenuredGeneration* tg, MemRegion mr, OldGenScanClosure* cl) { struct { @@ -238,7 +238,7 @@ void CardTableRS::non_clean_card_iterate(TenuredSpace* sp, assert(cached_obj.start_addr != nullptr, "inv"); return cached_obj.start_addr; } - HeapWord* result = sp->block_start_const(addr); + HeapWord* result = tg->block_start(addr); cached_obj.start_addr = result; cached_obj.end_addr = result + cast_to_oop(result)->size(); diff --git a/src/hotspot/share/gc/serial/cardTableRS.hpp b/src/hotspot/share/gc/serial/cardTableRS.hpp index 9be2c720dcb6f..c12cd906482bd 100644 --- a/src/hotspot/share/gc/serial/cardTableRS.hpp +++ b/src/hotspot/share/gc/serial/cardTableRS.hpp @@ -60,7 +60,7 @@ class CardTableRS : public CardTable { public: CardTableRS(MemRegion whole_heap); - void scan_old_to_young_refs(TenuredSpace* sp, HeapWord* saved_mark_word); + void scan_old_to_young_refs(TenuredGeneration* tg, HeapWord* saved_mark_word); void inline_write_ref_field_gc(void* field) { CardValue* byte = byte_for(field); @@ -83,7 +83,7 @@ class CardTableRS : public CardTable { // Iterate over the portion of the card-table which covers the given // region mr in the given space and apply cl to any dirty sub-regions // of mr. Clears the dirty cards as they are processed. - void non_clean_card_iterate(TenuredSpace* sp, + void non_clean_card_iterate(TenuredGeneration* tg, MemRegion mr, OldGenScanClosure* cl); diff --git a/src/hotspot/share/gc/serial/defNewGeneration.cpp b/src/hotspot/share/gc/serial/defNewGeneration.cpp index 7ac0d9b554ad2..9817bb7620c05 100644 --- a/src/hotspot/share/gc/serial/defNewGeneration.cpp +++ b/src/hotspot/share/gc/serial/defNewGeneration.cpp @@ -571,15 +571,38 @@ void DefNewGeneration::object_iterate(ObjectClosure* blk) { from()->object_iterate(blk); } +// If "p" is in the space, returns the address of the start of the +// "block" that contains "p". We say "block" instead of "object" since +// some heaps may not pack objects densely; a chunk may either be an +// object or a non-object. If "p" is not in the space, return null. +// Very general, slow implementation. +static HeapWord* block_start_const(const ContiguousSpace* cs, const void* p) { + assert(MemRegion(cs->bottom(), cs->end()).contains(p), + "p (" PTR_FORMAT ") not in space [" PTR_FORMAT ", " PTR_FORMAT ")", + p2i(p), p2i(cs->bottom()), p2i(cs->end())); + if (p >= cs->top()) { + return cs->top(); + } else { + HeapWord* last = cs->bottom(); + HeapWord* cur = last; + while (cur <= p) { + last = cur; + cur += cast_to_oop(cur)->size(); + } + assert(oopDesc::is_oop(cast_to_oop(last)), PTR_FORMAT " should be an object start", p2i(last)); + return last; + } +} + HeapWord* DefNewGeneration::block_start(const void* p) const { if (eden()->is_in_reserved(p)) { - return eden()->block_start_const(p); + return block_start_const(eden(), p); } if (from()->is_in_reserved(p)) { - return from()->block_start_const(p); + return block_start_const(from(), p); } assert(to()->is_in_reserved(p), "inv"); - return to()->block_start_const(p); + return block_start_const(to(), p); } // The last collection bailed out, we are running out of heap space, diff --git a/src/hotspot/share/gc/serial/tenuredGeneration.cpp b/src/hotspot/share/gc/serial/tenuredGeneration.cpp index d6a1a4a69105a..ddbb7b8403be8 100644 --- a/src/hotspot/share/gc/serial/tenuredGeneration.cpp +++ b/src/hotspot/share/gc/serial/tenuredGeneration.cpp @@ -264,12 +264,24 @@ void TenuredGeneration::compute_new_size_inner() { } } -HeapWord* TenuredGeneration::block_start(const void* p) const { - return space()->block_start_const(p); +HeapWord* TenuredGeneration::block_start(const void* addr) const { + HeapWord* cur_block = _bts->block_start_reaching_into_card(addr); + + while (true) { + HeapWord* next_block = cur_block + cast_to_oop(cur_block)->size(); + if (next_block > addr) { + assert(cur_block <= addr, "postcondition"); + return cur_block; + } + cur_block = next_block; + // Because the BOT is precise, we should never step into the next card + // (i.e. crossing the card boundary). + assert(!SerialBlockOffsetTable::is_crossing_card_boundary(cur_block, (HeapWord*)addr), "must be"); + } } void TenuredGeneration::scan_old_to_young_refs() { - _rs->scan_old_to_young_refs(space(), saved_mark_word()); + _rs->scan_old_to_young_refs(this, saved_mark_word()); } TenuredGeneration::TenuredGeneration(ReservedSpace rs, diff --git a/src/hotspot/share/gc/serial/tenuredGeneration.hpp b/src/hotspot/share/gc/serial/tenuredGeneration.hpp index 9983790b82eb2..04d5d61207432 100644 --- a/src/hotspot/share/gc/serial/tenuredGeneration.hpp +++ b/src/hotspot/share/gc/serial/tenuredGeneration.hpp @@ -112,7 +112,7 @@ class TenuredGeneration: public Generation { return _virtual_space.uncommitted_size() == 0; } - HeapWord* block_start(const void* p) const; + HeapWord* block_start(const void* addr) const; void scan_old_to_young_refs(); diff --git a/src/hotspot/share/gc/shared/space.cpp b/src/hotspot/share/gc/shared/space.cpp index f5622cd64dea0..a7e22856a569d 100644 --- a/src/hotspot/share/gc/shared/space.cpp +++ b/src/hotspot/share/gc/shared/space.cpp @@ -125,25 +125,6 @@ void ContiguousSpace::object_iterate(ObjectClosure* blk) { } } -// Very general, slow implementation. -HeapWord* ContiguousSpace::block_start_const(const void* p) const { - assert(MemRegion(bottom(), end()).contains(p), - "p (" PTR_FORMAT ") not in space [" PTR_FORMAT ", " PTR_FORMAT ")", - p2i(p), p2i(bottom()), p2i(end())); - if (p >= top()) { - return top(); - } else { - HeapWord* last = bottom(); - HeapWord* cur = last; - while (cur <= p) { - last = cur; - cur += cast_to_oop(cur)->size(); - } - assert(oopDesc::is_oop(cast_to_oop(last)), PTR_FORMAT " should be an object start", p2i(last)); - return last; - } -} - // This version requires locking. inline HeapWord* ContiguousSpace::allocate_impl(size_t size) { assert(Heap_lock->owned_by_self() || @@ -191,22 +172,6 @@ HeapWord* ContiguousSpace::par_allocate(size_t size) { } #if INCLUDE_SERIALGC -HeapWord* TenuredSpace::block_start_const(const void* addr) const { - HeapWord* cur_block = _offsets->block_start_reaching_into_card(addr); - - while (true) { - HeapWord* next_block = cur_block + cast_to_oop(cur_block)->size(); - if (next_block > addr) { - assert(cur_block <= addr, "postcondition"); - return cur_block; - } - cur_block = next_block; - // Because the BOT is precise, we should never step into the next card - // (i.e. crossing the card boundary). - assert(!SerialBlockOffsetTable::is_crossing_card_boundary(cur_block, (HeapWord*)addr), "must be"); - } -} - TenuredSpace::TenuredSpace(SerialBlockOffsetTable* offsets, MemRegion mr) : _offsets(offsets) diff --git a/src/hotspot/share/gc/shared/space.hpp b/src/hotspot/share/gc/shared/space.hpp index a4679b3adad2b..44f10cbd1ceb6 100644 --- a/src/hotspot/share/gc/shared/space.hpp +++ b/src/hotspot/share/gc/shared/space.hpp @@ -169,12 +169,6 @@ class ContiguousSpace: public CHeapObj { // Iteration void object_iterate(ObjectClosure* blk); - // If "p" is in the space, returns the address of the start of the - // "block" that contains "p". We say "block" instead of "object" since - // some heaps may not pack objects densely; a chunk may either be an - // object or a non-object. If "p" is not in the space, return null. - virtual HeapWord* block_start_const(const void* p) const; - // Addresses for inlined allocation HeapWord** top_addr() { return &_top; } @@ -197,8 +191,6 @@ class TenuredSpace: public ContiguousSpace { TenuredSpace(SerialBlockOffsetTable* offsets, MemRegion mr); - HeapWord* block_start_const(const void* addr) const override; - // Add offset table update. inline HeapWord* allocate(size_t word_size) override; inline HeapWord* par_allocate(size_t word_size) override;