Skip to content

Commit 8c8d1b3

Browse files
Hamlin Limashoubing
Hamlin Li
andcommitted
8263495: Gather liveness info in the mark phase of G1 full gc
Co-authored-by: Shoubing Ma <mashoubing1@huawei.com> Reviewed-by: tschatzl, sjohanss, ayang
1 parent a85dc55 commit 8c8d1b3

10 files changed

+57
-18
lines changed

src/hotspot/share/gc/g1/g1ConcurrentMark.cpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -2840,7 +2840,7 @@ G1CMTask::G1CMTask(uint worker_id,
28402840
_cm(cm),
28412841
_next_mark_bitmap(NULL),
28422842
_task_queue(task_queue),
2843-
_mark_stats_cache(mark_stats, RegionMarkStatsCacheSize),
2843+
_mark_stats_cache(mark_stats, G1RegionMarkStatsCache::RegionMarkStatsCacheSize),
28442844
_calls(0),
28452845
_time_target_ms(0.0),
28462846
_start_time_ms(0.0),

src/hotspot/share/gc/g1/g1ConcurrentMark.hpp

-4
Original file line numberDiff line numberDiff line change
@@ -611,10 +611,6 @@ class G1CMTask : public TerminatorTerminator {
611611
init_hash_seed = 17
612612
};
613613

614-
// Number of entries in the per-task stats entry. This seems enough to have a very
615-
// low cache miss rate.
616-
static const uint RegionMarkStatsCacheSize = 1024;
617-
618614
G1CMObjArrayProcessor _objArray_processor;
619615

620616
uint _worker_id;

src/hotspot/share/gc/g1/g1FullCollector.cpp

+9-1
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@
3636
#include "gc/g1/g1FullGCScope.hpp"
3737
#include "gc/g1/g1OopClosures.hpp"
3838
#include "gc/g1/g1Policy.hpp"
39+
#include "gc/g1/g1RegionMarkStatsCache.inline.hpp"
3940
#include "gc/g1/g1StringDedup.hpp"
4041
#include "gc/shared/gcTraceTime.inline.hpp"
4142
#include "gc/shared/preservedMarks.hpp"
@@ -122,8 +123,14 @@ G1FullCollector::G1FullCollector(G1CollectedHeap* heap, bool explicit_gc, bool c
122123
_preserved_marks_set.init(_num_workers);
123124
_markers = NEW_C_HEAP_ARRAY(G1FullGCMarker*, _num_workers, mtGC);
124125
_compaction_points = NEW_C_HEAP_ARRAY(G1FullGCCompactionPoint*, _num_workers, mtGC);
126+
127+
_live_stats = NEW_C_HEAP_ARRAY(G1RegionMarkStats, _heap->max_regions(), mtGC);
128+
for (uint j = 0; j < heap->max_regions(); j++) {
129+
_live_stats[j].clear();
130+
}
131+
125132
for (uint i = 0; i < _num_workers; i++) {
126-
_markers[i] = new G1FullGCMarker(this, i, _preserved_marks_set.get(i));
133+
_markers[i] = new G1FullGCMarker(this, i, _preserved_marks_set.get(i), _live_stats);
127134
_compaction_points[i] = new G1FullGCCompactionPoint();
128135
_oop_queue_set.register_queue(i, marker(i)->oop_stack());
129136
_array_queue_set.register_queue(i, marker(i)->objarray_stack());
@@ -138,6 +145,7 @@ G1FullCollector::~G1FullCollector() {
138145
}
139146
FREE_C_HEAP_ARRAY(G1FullGCMarker*, _markers);
140147
FREE_C_HEAP_ARRAY(G1FullGCCompactionPoint*, _compaction_points);
148+
FREE_C_HEAP_ARRAY(G1RegionMarkStats, _live_stats);
141149
}
142150

143151
class PrepareRegionsClosure : public HeapRegionClosure {

src/hotspot/share/gc/g1/g1FullCollector.hpp

+2
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@
3030
#include "gc/g1/g1FullGCMarker.hpp"
3131
#include "gc/g1/g1FullGCOopClosures.hpp"
3232
#include "gc/g1/g1FullGCScope.hpp"
33+
#include "gc/g1/g1RegionMarkStatsCache.hpp"
3334
#include "gc/shared/preservedMarks.hpp"
3435
#include "gc/shared/referenceProcessor.hpp"
3536
#include "gc/shared/taskqueue.hpp"
@@ -67,6 +68,7 @@ class G1FullCollector : StackObj {
6768
G1FullGCCompactionPoint _serial_compaction_point;
6869
G1IsAliveClosure _is_alive;
6970
ReferenceProcessorIsAliveMutator _is_alive_mutator;
71+
G1RegionMarkStats* _live_stats;
7072

7173
static uint calc_active_workers();
7274

src/hotspot/share/gc/g1/g1FullGCMarkTask.cpp

+1
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,7 @@ void G1FullGCMarkTask::work(uint worker_id) {
6060

6161
// Mark stack is populated, now process and drain it.
6262
marker->complete_marking(collector()->oop_queue_set(), collector()->array_queue_set(), &_terminator);
63+
marker->flush_mark_stats_cache();
6364

6465
// This is the point where the entire marking should have completed.
6566
assert(marker->oop_stack()->is_empty(), "Marking should have completed");

src/hotspot/share/gc/g1/g1FullGCMarker.cpp

+9-2
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,8 @@
3232

3333
G1FullGCMarker::G1FullGCMarker(G1FullCollector* collector,
3434
uint worker_id,
35-
PreservedMarks* preserved_stack) :
35+
PreservedMarks* preserved_stack,
36+
G1RegionMarkStats* mark_stats) :
3637
_collector(collector),
3738
_worker_id(worker_id),
3839
_bitmap(collector->mark_bitmap()),
@@ -42,7 +43,9 @@ G1FullGCMarker::G1FullGCMarker(G1FullCollector* collector,
4243
_mark_closure(worker_id, this, G1CollectedHeap::heap()->ref_processor_stw()),
4344
_verify_closure(VerifyOption_G1UseFullMarking),
4445
_stack_closure(this),
45-
_cld_closure(mark_closure(), ClassLoaderData::_claim_strong) {
46+
_cld_closure(mark_closure(), ClassLoaderData::_claim_strong),
47+
_mark_stats_cache(mark_stats, G1RegionMarkStatsCache::RegionMarkStatsCacheSize) {
48+
_mark_stats_cache.reset();
4649
_oop_stack.initialize();
4750
_objarray_stack.initialize();
4851
}
@@ -67,3 +70,7 @@ void G1FullGCMarker::complete_marking(OopQueueSet* oop_stacks,
6770
}
6871
} while (!is_empty() || !terminator->offer_termination());
6972
}
73+
74+
void G1FullGCMarker::flush_mark_stats_cache() {
75+
_mark_stats_cache.evict_all();
76+
}

src/hotspot/share/gc/g1/g1FullGCMarker.hpp

+11-1
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626
#define SHARE_GC_G1_G1FULLGCMARKER_HPP
2727

2828
#include "gc/g1/g1FullGCOopClosures.hpp"
29+
#include "gc/g1/g1RegionMarkStatsCache.hpp"
2930
#include "gc/shared/preservedMarks.hpp"
3031
#include "gc/shared/taskqueue.hpp"
3132
#include "memory/iterator.hpp"
@@ -63,6 +64,9 @@ class G1FullGCMarker : public CHeapObj<mtGC> {
6364
G1FollowStackClosure _stack_closure;
6465
CLDToOopClosure _cld_closure;
6566

67+
68+
G1RegionMarkStatsCache _mark_stats_cache;
69+
6670
inline bool is_empty();
6771
inline bool pop_object(oop& obj);
6872
inline bool pop_objarray(ObjArrayTask& array);
@@ -74,7 +78,10 @@ class G1FullGCMarker : public CHeapObj<mtGC> {
7478
inline void follow_array(objArrayOop array);
7579
inline void follow_array_chunk(objArrayOop array, int index);
7680
public:
77-
G1FullGCMarker(G1FullCollector* collector, uint worker_id, PreservedMarks* preserved_stack);
81+
G1FullGCMarker(G1FullCollector* collector,
82+
uint worker_id,
83+
PreservedMarks* preserved_stack,
84+
G1RegionMarkStats* mark_stats);
7885
~G1FullGCMarker();
7986

8087
// Stack getters
@@ -96,6 +103,9 @@ class G1FullGCMarker : public CHeapObj<mtGC> {
96103
CLDToOopClosure* cld_closure() { return &_cld_closure; }
97104
G1MarkAndPushClosure* mark_closure() { return &_mark_closure; }
98105
G1FollowStackClosure* stack_closure() { return &_stack_closure; }
106+
107+
// Flush live bytes to regions
108+
void flush_mark_stats_cache();
99109
};
100110

101111
#endif // SHARE_GC_G1_G1FULLGCMARKER_HPP

src/hotspot/share/gc/g1/g1FullGCMarker.inline.hpp

+5
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@
3232
#include "gc/g1/g1FullCollector.inline.hpp"
3333
#include "gc/g1/g1FullGCMarker.hpp"
3434
#include "gc/g1/g1FullGCOopClosures.inline.hpp"
35+
#include "gc/g1/g1RegionMarkStatsCache.hpp"
3536
#include "gc/g1/g1StringDedup.hpp"
3637
#include "gc/g1/g1StringDedupQueue.hpp"
3738
#include "gc/shared/preservedMarks.inline.hpp"
@@ -65,6 +66,10 @@ inline bool G1FullGCMarker::mark_object(oop obj) {
6566
java_lang_String::is_instance_inlined(obj)) {
6667
G1StringDedup::enqueue_from_mark(obj, _worker_id);
6768
}
69+
70+
// Collect live words.
71+
_mark_stats_cache.add_live_words(obj);
72+
6873
return true;
6974
}
7075

src/hotspot/share/gc/g1/g1RegionMarkStatsCache.cpp

+9-2
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
*/
2424

2525
#include "precompiled.hpp"
26+
#include "gc/g1/g1CollectedHeap.inline.hpp"
2627
#include "gc/g1/g1RegionMarkStatsCache.inline.hpp"
2728
#include "memory/allocation.inline.hpp"
2829
#include "utilities/powerOfTwo.hpp"
@@ -44,6 +45,11 @@ G1RegionMarkStatsCache::~G1RegionMarkStatsCache() {
4445
FREE_C_HEAP_ARRAY(G1RegionMarkStatsCacheEntry, _cache);
4546
}
4647

48+
void G1RegionMarkStatsCache::add_live_words(oop obj) {
49+
uint hr_index = G1CollectedHeap::heap()->addr_to_region(cast_from_oop<HeapWord*>(obj));
50+
add_live_words(hr_index, (size_t) obj->size());
51+
}
52+
4753
// Evict all remaining statistics, returning cache hits and misses.
4854
Pair<size_t, size_t> G1RegionMarkStatsCache::evict_all() {
4955
for (uint i = 0; i < _num_cache_entries; i++) {
@@ -52,12 +58,13 @@ Pair<size_t, size_t> G1RegionMarkStatsCache::evict_all() {
5258
return Pair<size_t,size_t>(_cache_hits, _cache_misses);
5359
}
5460

55-
// Reset all cache entries to their default values.
5661
void G1RegionMarkStatsCache::reset() {
5762
_cache_hits = 0;
5863
_cache_misses = 0;
5964

6065
for (uint i = 0; i < _num_cache_entries; i++) {
61-
_cache[i].clear();
66+
// Avoid the initial cache miss and eviction by setting the i'th's cache
67+
// region_idx to the region_idx due to how the hash is calculated.
68+
_cache[i].clear(i);
6269
}
6370
}

src/hotspot/share/gc/g1/g1RegionMarkStatsCache.hpp

+10-7
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626
#define SHARE_GC_G1_G1REGIONMARKSTATSCACHE_HPP
2727

2828
#include "memory/allocation.hpp"
29+
#include "oops/oop.hpp"
2930
#include "utilities/debug.hpp"
3031
#include "utilities/globalDefinitions.hpp"
3132
#include "utilities/pair.hpp"
@@ -69,14 +70,10 @@ class G1RegionMarkStatsCache {
6970
uint _region_idx;
7071
G1RegionMarkStats _stats;
7172

72-
void clear() {
73-
_region_idx = 0;
73+
void clear(uint idx = 0) {
74+
_region_idx = idx;
7475
_stats.clear();
7576
}
76-
77-
bool is_clear() const {
78-
return _region_idx == 0 && _stats.is_clear();
79-
}
8077
};
8178

8279
// The actual cache and its number of entries.
@@ -98,10 +95,15 @@ class G1RegionMarkStatsCache {
9895

9996
G1RegionMarkStatsCacheEntry* find_for_add(uint region_idx);
10097
public:
98+
// Number of entries in the per-task stats entry. This value seems enough
99+
// to have a very low cache miss rate.
100+
static const uint RegionMarkStatsCacheSize = 1024;
101+
101102
G1RegionMarkStatsCache(G1RegionMarkStats* target, uint num_cache_entries);
102103

103104
~G1RegionMarkStatsCache();
104105

106+
void add_live_words(oop obj);
105107
void add_live_words(uint region_idx, size_t live_words) {
106108
G1RegionMarkStatsCacheEntry* const cur = find_for_add(region_idx);
107109
cur->_stats._live_words += live_words;
@@ -118,7 +120,8 @@ class G1RegionMarkStatsCache {
118120
// Evict all remaining statistics, returning cache hits and misses.
119121
Pair<size_t, size_t> evict_all();
120122

121-
// Reset all cache entries to their default values.
123+
// Reset liveness of all cache entries to their default values,
124+
// initialize _region_idx to avoid initial cache miss.
122125
void reset();
123126

124127
size_t hits() const { return _cache_hits; }

0 commit comments

Comments
 (0)