Skip to content

Commit 283e486

Browse files
committed
refactoring, fix loosing pin counts on thread exit
1 parent dc86044 commit 283e486

8 files changed

+131
-40
lines changed

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2473,7 +2473,7 @@ void G1CollectedHeap::retire_tlabs() {
24732473

24742474
void G1CollectedHeap::flush_region_pin_cache() {
24752475
for (JavaThreadIteratorWithHandle jtiwh; JavaThread *thread = jtiwh.next(); ) {
2476-
Pair<uint, size_t> stats = G1ThreadLocalData::get_and_reset_pinned_region_cache(thread);
2476+
Pair<uint, size_t> stats = G1ThreadLocalData::get_and_reset_pin_cache(thread);
24772477
if (stats.second != 0) {
24782478
region_at(stats.first)->add_pinned_object_count(stats.second);
24792479
}

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

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -775,8 +775,8 @@ class G1CollectedHeap : public CollectedHeap {
775775

776776
void retire_tlabs();
777777

778-
// Update all region's pin counts from the per-thread caches. Must be called
779-
// before any decision based on pin counts.
778+
// Update all region's pin counts from the per-thread caches and resets them.
779+
// Must be called before any decision based on pin counts.
780780
void flush_region_pin_cache();
781781

782782
void expand_heap_after_young_collection();

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

Lines changed: 17 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -266,36 +266,38 @@ inline void G1CollectedHeap::pin_object(JavaThread* thread, oop obj) {
266266
assert(obj != nullptr, "obj must not be null");
267267
assert(!is_gc_active(), "must not pin objects during a GC");
268268
assert(obj->is_typeArray(), "must be typeArray");
269-
270-
uint last_idx = G1ThreadLocalData::cached_pinned_region_idx(thread);
271269
HeapRegion* r = heap_region_containing(obj);
272-
if (last_idx == r->hrm_index()) {
273-
G1ThreadLocalData::inc_cached_pinned_region_count(thread);
270+
uint obj_region_idx = r->hrm_index();
271+
272+
uint cached_idx = G1ThreadLocalData::cached_pinned_region_idx(thread);
273+
if (cached_idx == obj_region_idx) {
274+
G1ThreadLocalData::inc_cached_pin_count(thread);
274275
} else {
275276
// Flush old.
276-
size_t pin_count = G1ThreadLocalData::cached_pinned_region_count(thread);
277-
if (pin_count != 0) {
278-
region_at(last_idx)->add_pinned_object_count(pin_count);
277+
size_t cached_pin_count = G1ThreadLocalData::cached_pin_count(thread);
278+
if (cached_pin_count != 0) {
279+
region_at(cached_idx)->add_pinned_object_count(cached_pin_count);
279280
}
280-
G1ThreadLocalData::get_and_set_pinned_region_cache(thread, r->hrm_index(), (size_t)1);
281+
G1ThreadLocalData::get_and_set_pin_cache(thread, obj_region_idx, (size_t)1);
281282
}
282283
}
283284

284285
inline void G1CollectedHeap::unpin_object(JavaThread* thread, oop obj) {
285286
assert(obj != nullptr, "obj must not be null");
286287
assert(!is_gc_active(), "must not unpin objects during a GC");
287288
HeapRegion* r = heap_region_containing(obj);
289+
uint obj_region_idx = r->hrm_index();
288290

289-
uint last_idx = G1ThreadLocalData::cached_pinned_region_idx(thread);
290-
if (last_idx == r->hrm_index()) {
291-
G1ThreadLocalData::dec_cached_pinned_region_count(thread);
291+
uint cached_idx = G1ThreadLocalData::cached_pinned_region_idx(thread);
292+
if (cached_idx == obj_region_idx) {
293+
G1ThreadLocalData::dec_cached_pin_count(thread);
292294
} else {
293295
// Flush old.
294-
size_t pin_count = G1ThreadLocalData::cached_pinned_region_count(thread);
295-
if (pin_count != 0) {
296-
region_at(last_idx)->add_pinned_object_count(pin_count);
296+
size_t cached_pin_count = G1ThreadLocalData::cached_pin_count(thread);
297+
if (cached_pin_count != 0) {
298+
region_at(cached_idx)->add_pinned_object_count(cached_pin_count);
297299
}
298-
G1ThreadLocalData::get_and_set_pinned_region_cache(thread, r->hrm_index(), ~(size_t)0);
300+
G1ThreadLocalData::get_and_set_pin_cache(thread, obj_region_idx, ~(size_t)0);
299301
}
300302
}
301303

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
/*
2+
* Copyright (c) 2024, Oracle and/or its affiliates. All rights reserved.
3+
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4+
*
5+
* This code is free software; you can redistribute it and/or modify it
6+
* under the terms of the GNU General Public License version 2 only, as
7+
* published by the Free Software Foundation.
8+
*
9+
* This code is distributed in the hope that it will be useful, but WITHOUT
10+
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11+
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12+
* version 2 for more details (a copy is included in the LICENSE file that
13+
* accompanied this code).
14+
*
15+
* You should have received a copy of the GNU General Public License version
16+
* 2 along with this work; if not, write to the Free Software Foundation,
17+
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18+
*
19+
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20+
* or visit www.oracle.com if you need additional information or have any
21+
* questions.
22+
*
23+
*/
24+
25+
#include "precompiled.hpp"
26+
27+
#include "gc/g1/g1RegionPinCache.hpp"
28+
#include "gc/g1/g1CollectedHeap.hpp"
29+
30+
G1RegionPinCache::~G1RegionPinCache() {
31+
if (_count != 0) {
32+
G1CollectedHeap::heap()->region_at(_region_idx)->add_pinned_object_count(_count);
33+
}
34+
get_and_reset();
35+
}
Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
/*
2+
* Copyright (c) 2024, Oracle and/or its affiliates. All rights reserved.
3+
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4+
*
5+
* This code is free software; you can redistribute it and/or modify it
6+
* under the terms of the GNU General Public License version 2 only, as
7+
* published by the Free Software Foundation.
8+
*
9+
* This code is distributed in the hope that it will be useful, but WITHOUT
10+
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11+
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12+
* version 2 for more details (a copy is included in the LICENSE file that
13+
* accompanied this code).
14+
*
15+
* You should have received a copy of the GNU General Public License version
16+
* 2 along with this work; if not, write to the Free Software Foundation,
17+
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18+
*
19+
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20+
* or visit www.oracle.com if you need additional information or have any
21+
* questions.
22+
*
23+
*/
24+
25+
#ifndef SHARE_GC_G1_G1REGIONPINCACHE_HPP
26+
#define SHARE_GC_G1_G1REGIONPINCACHE_HPP
27+
28+
#include "memory/allocation.hpp"
29+
#include "utilities/pair.hpp"
30+
#include "utilities/globalDefinitions.hpp"
31+
32+
class G1RegionPinCache : public StackObj {
33+
uint _region_idx;
34+
size_t _count;
35+
36+
public:
37+
G1RegionPinCache() : _region_idx(0), _count(0) { }
38+
~G1RegionPinCache();
39+
40+
uint region_idx() const { return _region_idx; }
41+
size_t count() const { return _count; }
42+
43+
void inc_count() { ++_count; }
44+
void dec_count() { --_count; }
45+
46+
size_t get_and_set(uint new_region_idx, size_t new_count) {
47+
size_t result = _count;
48+
_region_idx = new_region_idx;
49+
_count = new_count;
50+
return result;
51+
}
52+
53+
Pair<uint, size_t> get_and_reset() {
54+
Pair<uint, size_t> result(_region_idx, get_and_set(0, 0));
55+
return result;
56+
}
57+
};
58+
59+
#endif /* SHARE_GC_G1_G1REGIONPINCACHE_HPP */

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

Lines changed: 14 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626

2727
#include "gc/g1/g1BarrierSet.hpp"
2828
#include "gc/g1/g1DirtyCardQueue.hpp"
29+
#include "gc/g1/g1RegionPinCache.hpp"
2930
#include "gc/shared/gc_globals.hpp"
3031
#include "gc/shared/satbMarkQueue.hpp"
3132
#include "runtime/javaThread.hpp"
@@ -37,14 +38,12 @@ class G1ThreadLocalData {
3738
SATBMarkQueue _satb_mark_queue;
3839
G1DirtyCardQueue _dirty_card_queue;
3940

40-
uint _cached_pinned_region_idx;
41-
size_t _cached_pinned_region_count;
41+
G1RegionPinCache _pin_cache;
4242

4343
G1ThreadLocalData() :
4444
_satb_mark_queue(&G1BarrierSet::satb_mark_queue_set()),
4545
_dirty_card_queue(&G1BarrierSet::dirty_card_queue_set()),
46-
_cached_pinned_region_idx(0),
47-
_cached_pinned_region_count(0) {}
46+
_pin_cache() {}
4847

4948
static G1ThreadLocalData* data(Thread* thread) {
5049
assert(UseG1GC, "Sanity");
@@ -97,32 +96,27 @@ class G1ThreadLocalData {
9796
}
9897

9998
static uint cached_pinned_region_idx(Thread* thread) {
100-
return data(thread)->_cached_pinned_region_idx;
99+
return data(thread)->_pin_cache.region_idx();
101100
}
102101

103-
static size_t cached_pinned_region_count(Thread* thread) {
104-
return data(thread)->_cached_pinned_region_count;
102+
static size_t cached_pin_count(Thread* thread) {
103+
return data(thread)->_pin_cache.count();
105104
}
106105

107-
static void inc_cached_pinned_region_count(Thread* thread) {
108-
++data(thread)->_cached_pinned_region_count;
106+
static void inc_cached_pin_count(Thread* thread) {
107+
data(thread)->_pin_cache.inc_count();
109108
}
110109

111-
static void dec_cached_pinned_region_count(Thread* thread) {
112-
--data(thread)->_cached_pinned_region_count;
110+
static void dec_cached_pin_count(Thread* thread) {
111+
data(thread)->_pin_cache.dec_count();
113112
}
114113

115-
static size_t get_and_set_pinned_region_cache(Thread* thread, uint region_idx, size_t new_count) {
116-
G1ThreadLocalData* d = data(thread);
117-
size_t result = d->_cached_pinned_region_count;
118-
d->_cached_pinned_region_idx = region_idx;
119-
d->_cached_pinned_region_count = new_count;
120-
return result;
114+
static size_t get_and_set_pin_cache(Thread* thread, uint region_idx, size_t new_count) {
115+
return data(thread)->_pin_cache.get_and_set(region_idx, new_count);
121116
}
122117

123-
static Pair<uint, size_t> get_and_reset_pinned_region_cache(Thread* thread) {
124-
Pair<uint, size_t> result { data(thread)->cached_pinned_region_idx(thread), get_and_set_pinned_region_cache(thread, 0, 0) };
125-
return result;
118+
static Pair<uint, size_t> get_and_reset_pin_cache(Thread* thread) {
119+
return data(thread)->_pin_cache.get_and_reset();
126120
}
127121
};
128122

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

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,7 @@ class G1PreEvacuateCollectionSetBatchTask::JavaThreadRetireTLABAndFlushLogs : pu
6666
G1DirtyCardQueueSet& qset = G1BarrierSet::dirty_card_queue_set();
6767
_refinement_stats += qset.concatenate_log_and_stats(thread);
6868
// Flush region pincount cache.
69-
Pair<uint, size_t> region_pin_cache = G1ThreadLocalData::get_and_reset_pinned_region_cache(thread);
69+
Pair<uint, size_t> region_pin_cache = G1ThreadLocalData::get_and_reset_pin_cache(thread);
7070
if (region_pin_cache.second != 0) {
7171
G1CollectedHeap::heap()->region_at(region_pin_cache.first)->add_pinned_object_count(region_pin_cache.second);
7272
}
@@ -140,7 +140,7 @@ class G1PreEvacuateCollectionSetBatchTask::NonJavaThreadFlushLogs : public G1Abs
140140
G1DirtyCardQueueSet& qset = G1BarrierSet::dirty_card_queue_set();
141141
_refinement_stats += qset.concatenate_log_and_stats(thread);
142142

143-
assert(G1ThreadLocalData::cached_pinned_region_count(thread) == 0, "NonJava thread pinned Java objects");
143+
assert(G1ThreadLocalData::cached_pin_count(thread) == 0, "NonJava thread pinned Java objects");
144144
}
145145
} _tc;
146146

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -554,6 +554,7 @@ inline void HeapRegion::record_surv_words_in_group(size_t words_survived) {
554554
}
555555

556556
inline void HeapRegion::add_pinned_object_count(size_t value) {
557+
assert(value != 0, "wasted effort");
557558
assert(!is_free(), "trying to pin free region %u, adding %zu", hrm_index(), value);
558559
Atomic::add(&_pinned_object_count, value, memory_order_relaxed);
559560
if (UseNewCode) {

0 commit comments

Comments
 (0)