8325259: Serial: Inline OldGenScanClosure during Young GC

Reviewed-by: stefank, tschatzl
This commit is contained in:
Albert Mingkun Yang 2024-02-08 16:20:09 +00:00
parent ab5e94777c
commit 0ea75b28d4
8 changed files with 109 additions and 123 deletions

View File

@ -26,19 +26,18 @@
#include "classfile/classLoaderDataGraph.hpp"
#include "gc/serial/cardTableRS.hpp"
#include "gc/serial/generation.hpp"
#include "gc/serial/serialHeap.hpp"
#include "gc/serial/tenuredGeneration.hpp"
#include "gc/serial/serialHeap.inline.hpp"
#include "gc/shared/space.inline.hpp"
#include "memory/iterator.inline.hpp"
#include "utilities/align.hpp"
void CardTableRS::younger_refs_in_space_iterate(TenuredSpace* sp,
OopIterateClosure* cl) {
void CardTableRS::scan_old_to_young_refs(TenuredSpace* sp) {
verify_used_region_at_save_marks(sp);
const MemRegion urasm = sp->used_region_at_save_marks();
if (!urasm.is_empty()) {
non_clean_card_iterate(sp, urasm, cl, this);
OldGenScanClosure cl(SerialHeap::heap()->young_gen());
non_clean_card_iterate(sp, urasm, &cl, this);
}
}
@ -225,7 +224,7 @@ static void prefetch_write(void *p) {
}
static void scan_obj_with_limit(oop obj,
OopIterateClosure* cl,
OldGenScanClosure* cl,
HeapWord* start,
HeapWord* end) {
if (!obj->is_typeArray()) {
@ -236,7 +235,7 @@ static void scan_obj_with_limit(oop obj,
void CardTableRS::non_clean_card_iterate(TenuredSpace* sp,
MemRegion mr,
OopIterateClosure* cl,
OldGenScanClosure* cl,
CardTableRS* ct) {
struct {
HeapWord* start_addr;
@ -267,7 +266,6 @@ void CardTableRS::non_clean_card_iterate(TenuredSpace* sp,
for (CardValue* current_card = start_card; current_card < end_card; /* empty */) {
CardValue* const dirty_l = find_first_dirty_card(current_card, end_card);
if (dirty_l == end_card) {
// No dirty cards to iterate.
return;

View File

@ -29,6 +29,7 @@
#include "memory/memRegion.hpp"
#include "oops/oop.hpp"
class OldGenScanClosure;
class Space;
class TenuredGeneration;
class TenuredSpace;
@ -61,7 +62,7 @@ class CardTableRS : public CardTable {
public:
CardTableRS(MemRegion whole_heap);
void younger_refs_in_space_iterate(TenuredSpace* sp, OopIterateClosure* cl);
void scan_old_to_young_refs(TenuredSpace* sp);
virtual void verify_used_region_at_save_marks(Space* sp) const NOT_DEBUG_RETURN;
@ -88,7 +89,7 @@ public:
// of mr. Clears the dirty cards as they are processed.
void non_clean_card_iterate(TenuredSpace* sp,
MemRegion mr,
OopIterateClosure* cl,
OldGenScanClosure* cl,
CardTableRS* ct);
bool is_in_young(const void* p) const override;

View File

@ -61,91 +61,6 @@
#include "utilities/globalDefinitions.hpp"
#include "utilities/stack.inline.hpp"
class ScavengeHelper {
DefNewGeneration* _young_gen;
HeapWord* _young_gen_end;
public:
ScavengeHelper(DefNewGeneration* young_gen) :
_young_gen(young_gen),
_young_gen_end(young_gen->reserved().end()) {}
bool is_in_young_gen(void* p) const {
return p < _young_gen_end;
}
template <typename T, typename Func>
void try_scavenge(T* p, Func&& f) {
T heap_oop = RawAccess<>::oop_load(p);
// Should we copy the obj?
if (!CompressedOops::is_null(heap_oop)) {
oop obj = CompressedOops::decode_not_null(heap_oop);
if (is_in_young_gen(obj)) {
assert(!_young_gen->to()->is_in_reserved(obj), "Scanning field twice?");
oop new_obj = obj->is_forwarded() ? obj->forwardee()
: _young_gen->copy_to_survivor_space(obj);
RawAccess<IS_NOT_NULL>::oop_store(p, new_obj);
// callback
f(new_obj);
}
}
}
};
class InHeapScanClosure : public BasicOopIterateClosure {
ScavengeHelper _helper;
protected:
bool is_in_young_gen(void* p) const {
return _helper.is_in_young_gen(p);
}
template <typename T, typename Func>
void try_scavenge(T* p, Func&& f) {
_helper.try_scavenge(p, f);
}
InHeapScanClosure(DefNewGeneration* young_gen) :
BasicOopIterateClosure(young_gen->ref_processor()),
_helper(young_gen) {}
};
class OffHeapScanClosure : public OopClosure {
ScavengeHelper _helper;
protected:
bool is_in_young_gen(void* p) const {
return _helper.is_in_young_gen(p);
}
template <typename T, typename Func>
void try_scavenge(T* p, Func&& f) {
_helper.try_scavenge(p, f);
}
OffHeapScanClosure(DefNewGeneration* young_gen) : _helper(young_gen) {}
};
class OldGenScanClosure : public InHeapScanClosure {
CardTableRS* _rs;
template <typename T>
void do_oop_work(T* p) {
assert(!is_in_young_gen(p), "precondition");
try_scavenge(p, [&] (oop new_obj) {
// If p points to a younger generation, mark the card.
if (is_in_young_gen(new_obj)) {
_rs->inline_write_ref_field_gc(p);
}
});
}
public:
OldGenScanClosure(DefNewGeneration* g) : InHeapScanClosure(g),
_rs(SerialHeap::heap()->rem_set()) {}
void do_oop(oop* p) { do_oop_work(p); }
void do_oop(narrowOop* p) { do_oop_work(p); }
};
class PromoteFailureClosure : public InHeapScanClosure {
template <typename T>
void do_oop_work(T* p) {
@ -785,11 +700,19 @@ void DefNewGeneration::collect(bool full,
{
StrongRootsScope srs(0);
RootScanClosure root_cl{this};
CLDScanClosure cld_scan_closure{this};
CLDScanClosure cld_cl{this};
heap->young_process_roots(&root_cl,
&old_gen_cl,
&cld_scan_closure);
MarkingCodeBlobClosure code_cl(&root_cl,
CodeBlobToOopClosure::FixRelocations,
false /* keepalive_nmethods */);
heap->process_roots(SerialHeap::SO_ScavengeCodeCache,
&root_cl,
&cld_cl,
&cld_cl,
&code_cl);
_old_gen->scan_old_to_young_refs();
}
// "evacuate followers".

View File

@ -146,17 +146,6 @@ GrowableArray<MemoryPool*> SerialHeap::memory_pools() {
return memory_pools;
}
void SerialHeap::young_process_roots(OopClosure* root_closure,
OopIterateClosure* old_gen_closure,
CLDClosure* cld_closure) {
MarkingCodeBlobClosure mark_code_closure(root_closure, CodeBlobToOopClosure::FixRelocations, false /* keepalive nmethods */);
process_roots(SO_ScavengeCodeCache, root_closure,
cld_closure, cld_closure, &mark_code_closure);
old_gen()->younger_refs_iterate(old_gen_closure);
}
void SerialHeap::safepoint_synchronize_begin() {
if (UseStringDeduplication) {
SuspendibleThreadSet::synchronize();

View File

@ -372,10 +372,6 @@ public:
void oop_since_save_marks_iterate(OopClosureType1* cur,
OopClosureType2* older);
void young_process_roots(OopClosure* root_closure,
OopIterateClosure* old_gen_closure,
CLDClosure* cld_closure);
void safepoint_synchronize_begin() override;
void safepoint_synchronize_end() override;

View File

@ -37,4 +37,89 @@ void SerialHeap::oop_since_save_marks_iterate(OopClosureType1* cur,
old_gen()->oop_since_save_marks_iterate(older);
}
class ScavengeHelper {
DefNewGeneration* _young_gen;
HeapWord* _young_gen_end;
public:
ScavengeHelper(DefNewGeneration* young_gen) :
_young_gen(young_gen),
_young_gen_end(young_gen->reserved().end()) {}
bool is_in_young_gen(void* p) const {
return p < _young_gen_end;
}
template <typename T, typename Func>
void try_scavenge(T* p, Func&& f) {
T heap_oop = RawAccess<>::oop_load(p);
// Should we copy the obj?
if (!CompressedOops::is_null(heap_oop)) {
oop obj = CompressedOops::decode_not_null(heap_oop);
if (is_in_young_gen(obj)) {
assert(!_young_gen->to()->is_in_reserved(obj), "Scanning field twice?");
oop new_obj = obj->is_forwarded() ? obj->forwardee()
: _young_gen->copy_to_survivor_space(obj);
RawAccess<IS_NOT_NULL>::oop_store(p, new_obj);
// callback
f(new_obj);
}
}
}
};
class InHeapScanClosure : public BasicOopIterateClosure {
ScavengeHelper _helper;
protected:
bool is_in_young_gen(void* p) const {
return _helper.is_in_young_gen(p);
}
template <typename T, typename Func>
void try_scavenge(T* p, Func&& f) {
_helper.try_scavenge(p, f);
}
InHeapScanClosure(DefNewGeneration* young_gen) :
BasicOopIterateClosure(young_gen->ref_processor()),
_helper(young_gen) {}
};
class OffHeapScanClosure : public OopClosure {
ScavengeHelper _helper;
protected:
bool is_in_young_gen(void* p) const {
return _helper.is_in_young_gen(p);
}
template <typename T, typename Func>
void try_scavenge(T* p, Func&& f) {
_helper.try_scavenge(p, f);
}
OffHeapScanClosure(DefNewGeneration* young_gen) : _helper(young_gen) {}
};
class OldGenScanClosure : public InHeapScanClosure {
CardTableRS* _rs;
template <typename T>
void do_oop_work(T* p) {
assert(!is_in_young_gen(p), "precondition");
try_scavenge(p, [&] (oop new_obj) {
// If p points to a younger generation, mark the card.
if (is_in_young_gen(new_obj)) {
_rs->inline_write_ref_field_gc(p);
}
});
}
public:
OldGenScanClosure(DefNewGeneration* g) : InHeapScanClosure(g),
_rs(SerialHeap::heap()->rem_set()) {}
void do_oop(oop* p) { do_oop_work(p); }
void do_oop(narrowOop* p) { do_oop_work(p); }
};
#endif // SHARE_GC_SERIAL_SERIALHEAP_INLINE_HPP

View File

@ -267,14 +267,8 @@ HeapWord* TenuredGeneration::block_start(const void* p) const {
return space()->block_start_const(p);
}
void TenuredGeneration::younger_refs_iterate(OopIterateClosure* blk) {
// Apply "cl->do_oop" to (the address of) (exactly) all the ref fields in
// "sp" that point into the young generation.
// The iteration is only over objects allocated at the start of the
// iterations; objects allocated as a result of applying the closure are
// not included.
_rs->younger_refs_in_space_iterate(space(), blk);
void TenuredGeneration::scan_old_to_young_refs() {
_rs->scan_old_to_young_refs(space());
}
TenuredGeneration::TenuredGeneration(ReservedSpace rs,

View File

@ -100,7 +100,7 @@ class TenuredGeneration: public Generation {
HeapWord* block_start(const void* p) const;
void younger_refs_iterate(OopIterateClosure* blk);
void scan_old_to_young_refs();
bool is_in(const void* p) const;