diff --git a/src/hotspot/share/gc/serial/cardTableRS.cpp b/src/hotspot/share/gc/serial/cardTableRS.cpp index 18a890fde43..80cf36044b7 100644 --- a/src/hotspot/share/gc/serial/cardTableRS.cpp +++ b/src/hotspot/share/gc/serial/cardTableRS.cpp @@ -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; diff --git a/src/hotspot/share/gc/serial/cardTableRS.hpp b/src/hotspot/share/gc/serial/cardTableRS.hpp index 8ff4f1af862..21e972d06fa 100644 --- a/src/hotspot/share/gc/serial/cardTableRS.hpp +++ b/src/hotspot/share/gc/serial/cardTableRS.hpp @@ -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; diff --git a/src/hotspot/share/gc/serial/defNewGeneration.cpp b/src/hotspot/share/gc/serial/defNewGeneration.cpp index 5a4c37b1661..b85041c80a5 100644 --- a/src/hotspot/share/gc/serial/defNewGeneration.cpp +++ b/src/hotspot/share/gc/serial/defNewGeneration.cpp @@ -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 - 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::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 - 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 - 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 - 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 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". diff --git a/src/hotspot/share/gc/serial/serialHeap.cpp b/src/hotspot/share/gc/serial/serialHeap.cpp index 47ee5a089b9..6d5ce55a1c8 100644 --- a/src/hotspot/share/gc/serial/serialHeap.cpp +++ b/src/hotspot/share/gc/serial/serialHeap.cpp @@ -146,17 +146,6 @@ GrowableArray 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(); diff --git a/src/hotspot/share/gc/serial/serialHeap.hpp b/src/hotspot/share/gc/serial/serialHeap.hpp index 3376e166703..2b04d04eaea 100644 --- a/src/hotspot/share/gc/serial/serialHeap.hpp +++ b/src/hotspot/share/gc/serial/serialHeap.hpp @@ -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; diff --git a/src/hotspot/share/gc/serial/serialHeap.inline.hpp b/src/hotspot/share/gc/serial/serialHeap.inline.hpp index 6e06c7b6d57..27819f0d1c9 100644 --- a/src/hotspot/share/gc/serial/serialHeap.inline.hpp +++ b/src/hotspot/share/gc/serial/serialHeap.inline.hpp @@ -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 + 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::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 + 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 + 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 + 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 diff --git a/src/hotspot/share/gc/serial/tenuredGeneration.cpp b/src/hotspot/share/gc/serial/tenuredGeneration.cpp index 103eebc4a52..954b063336d 100644 --- a/src/hotspot/share/gc/serial/tenuredGeneration.cpp +++ b/src/hotspot/share/gc/serial/tenuredGeneration.cpp @@ -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, diff --git a/src/hotspot/share/gc/serial/tenuredGeneration.hpp b/src/hotspot/share/gc/serial/tenuredGeneration.hpp index 26f85b9ec8e..4e506343113 100644 --- a/src/hotspot/share/gc/serial/tenuredGeneration.hpp +++ b/src/hotspot/share/gc/serial/tenuredGeneration.hpp @@ -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;