Skip to content

Commit

Permalink
JDK-8263495: Gather liveness info in the mark phase of G1 full gc
Browse files Browse the repository at this point in the history
  • Loading branch information
Hamlin-Li committed Mar 12, 2021
1 parent 35c9da7 commit c47c30d
Show file tree
Hide file tree
Showing 10 changed files with 59 additions and 4 deletions.
17 changes: 16 additions & 1 deletion src/hotspot/share/gc/g1/g1FullCollector.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@
#include "gc/g1/g1FullGCScope.hpp"
#include "gc/g1/g1OopClosures.hpp"
#include "gc/g1/g1Policy.hpp"
#include "gc/g1/g1RegionMarkStatsCache.inline.hpp"
#include "gc/g1/g1StringDedup.hpp"
#include "gc/shared/gcTraceTime.inline.hpp"
#include "gc/shared/preservedMarks.hpp"
Expand Down Expand Up @@ -121,8 +122,14 @@ G1FullCollector::G1FullCollector(G1CollectedHeap* heap, bool explicit_gc, bool c
_preserved_marks_set.init(_num_workers);
_markers = NEW_C_HEAP_ARRAY(G1FullGCMarker*, _num_workers, mtGC);
_compaction_points = NEW_C_HEAP_ARRAY(G1FullGCCompactionPoint*, _num_workers, mtGC);

_live_stats = NEW_C_HEAP_ARRAY(G1RegionMarkStats, _heap->max_regions(), mtGC);
for (uint j = 0; j < heap->max_regions(); j++) {
_live_stats[j].clear();
}

for (uint i = 0; i < _num_workers; i++) {
_markers[i] = new G1FullGCMarker(this, i, _preserved_marks_set.get(i));
_markers[i] = new G1FullGCMarker(this, i, _preserved_marks_set.get(i), _live_stats);
_compaction_points[i] = new G1FullGCCompactionPoint();
_oop_queue_set.register_queue(i, marker(i)->oop_stack());
_array_queue_set.register_queue(i, marker(i)->objarray_stack());
Expand All @@ -137,6 +144,7 @@ G1FullCollector::~G1FullCollector() {
}
FREE_C_HEAP_ARRAY(G1FullGCMarker*, _markers);
FREE_C_HEAP_ARRAY(G1FullGCCompactionPoint*, _compaction_points);
FREE_C_HEAP_ARRAY(G1RegionMarkStats, _live_stats);
}

class PrepareRegionsClosure : public HeapRegionClosure {
Expand Down Expand Up @@ -237,6 +245,13 @@ void G1FullCollector::phase1_mark_live_objects() {
// Do the actual marking.
G1FullGCMarkTask marking_task(this);
run_task(&marking_task);

// collect live bytes.
uint sum = 0;
for (uint j = 0; j < _heap->max_regions(); j++) {
sum += _live_stats[j]._live_words;
}
_heap->set_used(sum * HeapWordSize);
}

{
Expand Down
1 change: 1 addition & 0 deletions src/hotspot/share/gc/g1/g1FullCollector.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,7 @@ class G1FullCollector : StackObj {
G1FullGCCompactionPoint _serial_compaction_point;
G1IsAliveClosure _is_alive;
ReferenceProcessorIsAliveMutator _is_alive_mutator;
G1RegionMarkStats* _live_stats;

static uint calc_active_workers();

Expand Down
3 changes: 3 additions & 0 deletions src/hotspot/share/gc/g1/g1FullGCMarkTask.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@
#include "gc/g1/g1FullGCMarkTask.hpp"
#include "gc/g1/g1FullGCOopClosures.inline.hpp"
#include "gc/g1/g1FullGCReferenceProcessorExecutor.hpp"
#include "gc/g1/g1RegionMarkStatsCache.inline.hpp"
#include "gc/shared/gcTraceTime.inline.hpp"
#include "gc/shared/referenceProcessor.hpp"
#include "memory/iterator.inline.hpp"
Expand Down Expand Up @@ -60,6 +61,8 @@ void G1FullGCMarkTask::work(uint worker_id) {

// Mark stack is populated, now process and drain it.
marker->complete_marking(collector()->oop_queue_set(), collector()->array_queue_set(), &_terminator);
// flush live bytes to regions
marker->flush_mark_region_cache();

// This is the point where the entire marking should have completed.
assert(marker->oop_stack()->is_empty(), "Marking should have completed");
Expand Down
8 changes: 6 additions & 2 deletions src/hotspot/share/gc/g1/g1FullGCMarker.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -25,14 +25,16 @@
#include "precompiled.hpp"
#include "classfile/classLoaderData.hpp"
#include "gc/g1/g1FullGCMarker.inline.hpp"
#include "gc/g1/g1RegionMarkStatsCache.inline.hpp"
#include "gc/shared/referenceProcessor.hpp"
#include "gc/shared/taskTerminator.hpp"
#include "gc/shared/verifyOption.hpp"
#include "memory/iterator.inline.hpp"

G1FullGCMarker::G1FullGCMarker(G1FullCollector* collector,
uint worker_id,
PreservedMarks* preserved_stack) :
PreservedMarks* preserved_stack,
G1RegionMarkStats* mark_stats) :
_collector(collector),
_worker_id(worker_id),
_bitmap(collector->mark_bitmap()),
Expand All @@ -42,7 +44,9 @@ G1FullGCMarker::G1FullGCMarker(G1FullCollector* collector,
_mark_closure(worker_id, this, G1CollectedHeap::heap()->ref_processor_stw()),
_verify_closure(VerifyOption_G1UseFullMarking),
_stack_closure(this),
_cld_closure(mark_closure(), ClassLoaderData::_claim_strong) {
_cld_closure(mark_closure(), ClassLoaderData::_claim_strong),
_mark_region_cache(mark_stats, RegionMarkStatsCacheSize) {
_mark_region_cache.initialize();
_oop_stack.initialize();
_objarray_stack.initialize();
}
Expand Down
13 changes: 12 additions & 1 deletion src/hotspot/share/gc/g1/g1FullGCMarker.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,12 @@ class G1FullGCMarker : public CHeapObj<mtGC> {
G1FollowStackClosure _stack_closure;
CLDToOopClosure _cld_closure;


G1RegionMarkStatsCache _mark_region_cache;
// Number of entries in the per-task stats entry. This seems enough to have a very
// low cache miss rate.
static const uint RegionMarkStatsCacheSize = 1024;

inline bool is_empty();
inline bool pop_object(oop& obj);
inline bool pop_objarray(ObjArrayTask& array);
Expand All @@ -74,7 +80,8 @@ class G1FullGCMarker : public CHeapObj<mtGC> {
inline void follow_array(objArrayOop array);
inline void follow_array_chunk(objArrayOop array, int index);
public:
G1FullGCMarker(G1FullCollector* collector, uint worker_id, PreservedMarks* preserved_stack);
G1FullGCMarker(G1FullCollector* collector, uint worker_id,
PreservedMarks* preserved_stack, G1RegionMarkStats* mark_stats);
~G1FullGCMarker();

// Stack getters
Expand All @@ -96,6 +103,10 @@ class G1FullGCMarker : public CHeapObj<mtGC> {
CLDToOopClosure* cld_closure() { return &_cld_closure; }
G1MarkAndPushClosure* mark_closure() { return &_mark_closure; }
G1FollowStackClosure* stack_closure() { return &_stack_closure; }

void flush_mark_region_cache() {
_mark_region_cache.evict_all();
}
};

#endif // SHARE_GC_G1_G1FULLGCMARKER_HPP
5 changes: 5 additions & 0 deletions src/hotspot/share/gc/g1/g1FullGCMarker.inline.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,11 @@ inline bool G1FullGCMarker::mark_object(oop obj) {
java_lang_String::is_instance_inlined(obj)) {
G1StringDedup::enqueue_from_mark(obj, _worker_id);
}

// Collect live words.
uint hr_index = G1CollectedHeap::heap()->addr_to_region(cast_from_oop<HeapWord*>(obj));
_mark_region_cache.add_live_words(hr_index, (size_t)obj->size());

return true;
}

Expand Down
1 change: 1 addition & 0 deletions src/hotspot/share/gc/g1/g1FullGCOopClosures.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
#include "gc/g1/g1FullCollector.hpp"
#include "gc/g1/g1FullGCMarker.inline.hpp"
#include "gc/g1/g1FullGCOopClosures.inline.hpp"
#include "gc/g1/g1RegionMarkStatsCache.inline.hpp"
#include "logging/logStream.hpp"
#include "memory/iterator.inline.hpp"
#include "oops/access.inline.hpp"
Expand Down
12 changes: 12 additions & 0 deletions src/hotspot/share/gc/g1/g1RegionMarkStatsCache.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
*/

#include "precompiled.hpp"
#include "gc/g1/g1CollectedHeap.hpp"
#include "gc/g1/g1RegionMarkStatsCache.inline.hpp"
#include "memory/allocation.inline.hpp"
#include "utilities/powerOfTwo.hpp"
Expand All @@ -44,6 +45,17 @@ G1RegionMarkStatsCache::~G1RegionMarkStatsCache() {
FREE_C_HEAP_ARRAY(G1RegionMarkStatsCacheEntry, _cache);
}

// cache size is equal to or bigger than region size to intialize region_index
void G1RegionMarkStatsCache::initialize() {
_cache_hits = 0;
_cache_misses = 0;

for (uint i = 0; i < _num_cache_entries; i++) {
_cache[i].clear();
_cache[i]._region_idx = i;
}
}

// Evict all remaining statistics, returning cache hits and misses.
Pair<size_t, size_t> G1RegionMarkStatsCache::evict_all() {
for (uint i = 0; i < _num_cache_entries; i++) {
Expand Down
2 changes: 2 additions & 0 deletions src/hotspot/share/gc/g1/g1RegionMarkStatsCache.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,8 @@ class G1RegionMarkStatsCache {

~G1RegionMarkStatsCache();

void initialize();

void add_live_words(uint region_idx, size_t live_words) {
G1RegionMarkStatsCacheEntry* const cur = find_for_add(region_idx);
cur->_stats._live_words += live_words;
Expand Down
1 change: 1 addition & 0 deletions src/hotspot/share/gc/g1/heapRegion.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@

#include "gc/g1/g1BlockOffsetTable.hpp"
#include "gc/g1/g1HeapRegionTraceType.hpp"
#include "gc/g1/g1RegionMarkStatsCache.hpp"
#include "gc/g1/g1SurvRateGroup.hpp"
#include "gc/g1/heapRegionTracer.hpp"
#include "gc/g1/heapRegionType.hpp"
Expand Down

0 comments on commit c47c30d

Please sign in to comment.