mirror of
https://github.com/openjdk/jdk.git
synced 2026-08-04 15:15:23 +00:00
Add new fields to ShenandoahThreadLocalData for pin cache and delete ShenandoahRegionPinCache class
This commit is contained in:
parent
2dc045bf3f
commit
3435c8dd09
@ -178,7 +178,7 @@ void ShenandoahBarrierSet::on_thread_detach(Thread *thread) {
|
||||
StackWatermarkSet::finish_processing(JavaThread::cast(thread), &oops, StackWatermarkKind::gc);
|
||||
}
|
||||
|
||||
ShenandoahThreadLocalData::pin_count_cache(thread).flush();
|
||||
_heap->flush_region_pin_cache(JavaThread::cast(thread));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -2436,16 +2436,55 @@ void ShenandoahHeap::unregister_nmethod(nmethod* nm) {
|
||||
}
|
||||
|
||||
void ShenandoahHeap::pin_object(JavaThread* thr, oop o) {
|
||||
size_t region_idx = heap_region_index_containing(o);
|
||||
ShenandoahThreadLocalData::pin_count_cache(thr).inc_count(region_idx);
|
||||
assert(thr == JavaThread::current(), "Sanity");
|
||||
size_t reg_idx_pin = heap_region_index_containing(o);
|
||||
size_t reg_idx_cached = ShenandoahThreadLocalData::pin_cache_region(thr);
|
||||
size_t count = ShenandoahThreadLocalData::pin_cache_count(thr);
|
||||
if (reg_idx_pin == reg_idx_cached) {
|
||||
ShenandoahThreadLocalData::pin_cache_set_count(thr, count + 1);
|
||||
} else {
|
||||
if (count != 0) {
|
||||
get_region(reg_idx_cached)->inc_pin_count(count);
|
||||
}
|
||||
ShenandoahThreadLocalData::pin_cache_set_region(thr, reg_idx_pin);
|
||||
ShenandoahThreadLocalData::pin_cache_set_count(thr, 1);
|
||||
}
|
||||
}
|
||||
|
||||
void ShenandoahHeap::unpin_object(JavaThread* thr, oop o) {
|
||||
size_t region_idx = heap_region_index_containing(o);
|
||||
ShenandoahThreadLocalData::pin_count_cache(thr).dec_count(region_idx);
|
||||
assert(thr == JavaThread::current(), "Sanity");
|
||||
size_t reg_idx_pin = heap_region_index_containing(o);
|
||||
size_t reg_idx_cached = ShenandoahThreadLocalData::pin_cache_region(thr);
|
||||
size_t count = ShenandoahThreadLocalData::pin_cache_count(thr);
|
||||
if (reg_idx_pin == reg_idx_cached) {
|
||||
ShenandoahThreadLocalData::pin_cache_set_count(thr, count - 1);
|
||||
} else {
|
||||
if (count != 0) {
|
||||
get_region(reg_idx_cached)->inc_pin_count(count);
|
||||
}
|
||||
ShenandoahThreadLocalData::pin_cache_set_region(thr, reg_idx_pin);
|
||||
ShenandoahThreadLocalData::pin_cache_set_count(thr, ~(size_t)0);
|
||||
}
|
||||
}
|
||||
|
||||
void ShenandoahHeap::flush_region_pin_cache(JavaThread* thr) {
|
||||
size_t count = ShenandoahThreadLocalData::pin_cache_count(thr);
|
||||
if (count != 0) {
|
||||
get_region(ShenandoahThreadLocalData::pin_cache_region(thr))->inc_pin_count(count);
|
||||
}
|
||||
ShenandoahThreadLocalData::pin_cache_set_region(thr, SIZE_MAX);
|
||||
ShenandoahThreadLocalData::pin_cache_set_count(thr, 0);
|
||||
}
|
||||
|
||||
void ShenandoahHeap::flush_region_pin_cache() {
|
||||
assert(SafepointSynchronize::is_at_safepoint(), "Must be at a safepoint.");
|
||||
for (JavaThreadIteratorWithHandle jtiwh; JavaThread *thread = jtiwh.next(); ) {
|
||||
flush_region_pin_cache(thread);
|
||||
}
|
||||
}
|
||||
|
||||
void ShenandoahHeap::sync_pinned_region_status() {
|
||||
flush_region_pin_cache();
|
||||
ShenandoahHeapLocker locker(lock());
|
||||
|
||||
for (size_t i = 0; i < num_regions(); i++) {
|
||||
|
||||
@ -686,8 +686,9 @@ public:
|
||||
void pin_object(JavaThread* thread, oop obj) override;
|
||||
void unpin_object(JavaThread* thread, oop obj) override;
|
||||
|
||||
// Update all regions pin counts from the per-thread caches and resets them.
|
||||
// Updates each region's pin counts from the per-thread caches and resets them.
|
||||
// Must be called before any decision based on pin counts.
|
||||
void flush_region_pin_cache(JavaThread* thread);
|
||||
void flush_region_pin_cache();
|
||||
|
||||
void sync_pinned_region_status();
|
||||
|
||||
@ -227,7 +227,7 @@ public:
|
||||
void record_pin();
|
||||
void record_unpin();
|
||||
size_t pin_count() const;
|
||||
inline void add_pinned_object_count(size_t value);
|
||||
inline void inc_pin_count(size_t value);
|
||||
|
||||
private:
|
||||
static size_t RegionCount;
|
||||
|
||||
@ -197,7 +197,7 @@ inline void ShenandoahHeapRegion::restore_top_before_promote() {
|
||||
_top_before_promoted = nullptr;
|
||||
}
|
||||
|
||||
inline void ShenandoahHeapRegion::add_pinned_object_count(size_t value) {
|
||||
inline void ShenandoahHeapRegion::inc_pin_count(size_t value) {
|
||||
_critical_pins.add_then_fetch(value, memory_order_relaxed);
|
||||
}
|
||||
|
||||
|
||||
@ -1,53 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2024, 2026, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright Amazon.com Inc. or its affiliates. All Rights Reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef SHARE_GC_SHENANDOAH_SHENANDOAHREGIONPINCACHE_HPP
|
||||
#define SHARE_GC_SHENANDOAH_SHENANDOAHREGIONPINCACHE_HPP
|
||||
|
||||
#include "memory/allocation.hpp"
|
||||
#include "utilities/globalDefinitions.hpp"
|
||||
|
||||
// Holds (caches) the pending pinned object count adjustment for the region
|
||||
// _region_idx on a per thread basis.
|
||||
// Keeping such a cache avoids expensive atomic operations when updating the
|
||||
// pin count for the very common case that a single thread pins and unpins
|
||||
// the same object without any interleaving by garbage collection or by
|
||||
// pinning/unpinning of objects in other regions.
|
||||
class ShenandoahRegionPinCache : public StackObj {
|
||||
size_t _region_idx;
|
||||
size_t _count;
|
||||
|
||||
void flush_and_set(size_t new_region_idx, size_t new_count);
|
||||
|
||||
public:
|
||||
ShenandoahRegionPinCache() : _region_idx(SIZE_MAX), _count(0) { }
|
||||
|
||||
void inc_count(size_t region_idx);
|
||||
void dec_count(size_t region_idx);
|
||||
|
||||
void flush();
|
||||
};
|
||||
|
||||
#endif /* SHARE_GC_SHENANDOAH_SHENANDOAHREGIONPINCACHE_HPP */
|
||||
@ -1,63 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2024, 2026, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright Amazon.com Inc. or its affiliates. All Rights Reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef SHARE_GC_SHENANDOAH_SHENANDOAHREGIONPINCACHE_INLINE_HPP
|
||||
#define SHARE_GC_SHENANDOAH_SHENANDOAHREGIONPINCACHE_INLINE_HPP
|
||||
|
||||
#include "gc/shenandoah/shenandoahRegionPinCache.hpp"
|
||||
|
||||
#include "gc/shenandoah/shenandoahHeap.inline.hpp"
|
||||
|
||||
inline void ShenandoahRegionPinCache::inc_count(size_t region_idx) {
|
||||
if (region_idx == _region_idx) {
|
||||
++_count;
|
||||
} else {
|
||||
flush_and_set(region_idx, (size_t)1);
|
||||
}
|
||||
}
|
||||
|
||||
inline void ShenandoahRegionPinCache::dec_count(size_t region_idx) {
|
||||
if (region_idx == _region_idx) {
|
||||
--_count;
|
||||
} else {
|
||||
flush_and_set(region_idx, ~(size_t)0);
|
||||
}
|
||||
}
|
||||
|
||||
inline void ShenandoahRegionPinCache::flush_and_set(size_t new_region_idx, size_t new_count) {
|
||||
if (_count != 0) {
|
||||
ShenandoahHeapRegion* r = ShenandoahHeap::heap()->get_region(_region_idx);
|
||||
assert(r != nullptr, "Region %zu must exist", _region_idx);
|
||||
r->add_pinned_object_count(_count);
|
||||
}
|
||||
_region_idx = new_region_idx;
|
||||
_count = new_count;
|
||||
}
|
||||
|
||||
inline void ShenandoahRegionPinCache::flush() {
|
||||
flush_and_set(SIZE_MAX, 0);
|
||||
}
|
||||
|
||||
#endif /* SHARE_GC_SHENANDOAH_SHENANDOAHREGIONPINCACHE_INLINE_HPP */
|
||||
@ -39,7 +39,9 @@ ShenandoahThreadLocalData::ShenandoahThreadLocalData() :
|
||||
_shenandoah_plab(nullptr),
|
||||
_evacuation_stats(new ShenandoahEvacuationStats()),
|
||||
_invisible_root(nullptr),
|
||||
_invisible_root_word_size(0) {
|
||||
_invisible_root_word_size(0),
|
||||
_pin_region_idx(SIZE_MAX),
|
||||
_pin_count(0) {
|
||||
}
|
||||
|
||||
ShenandoahThreadLocalData::~ShenandoahThreadLocalData() {
|
||||
|
||||
@ -97,7 +97,8 @@ private:
|
||||
// Thread-local pin cache used to increment/decrement the pin count for
|
||||
// a region and flush the accumulated count to the shared pin counter.
|
||||
// This avoids contended atomic updates of the shared pin counter.
|
||||
ShenandoahRegionPinCache _pin_cache;
|
||||
size_t _pin_region_idx;
|
||||
size_t _pin_count;
|
||||
|
||||
ShenandoahThreadLocalData();
|
||||
~ShenandoahThreadLocalData();
|
||||
@ -249,8 +250,20 @@ public:
|
||||
return data(thread)->_invisible_root_word_size.load_relaxed();
|
||||
}
|
||||
|
||||
static ShenandoahRegionPinCache& pin_count_cache(Thread* thread) {
|
||||
return data(thread)->_pin_cache;
|
||||
static size_t pin_cache_region(Thread* thread) {
|
||||
return data(thread)->_pin_region_idx;
|
||||
}
|
||||
|
||||
static size_t pin_cache_count(Thread* thread) {
|
||||
return data(thread)->_pin_count;
|
||||
}
|
||||
|
||||
static void pin_cache_set_region(Thread* thread, size_t reg_idx_pin) {
|
||||
data(thread)->_pin_region_idx = reg_idx_pin;
|
||||
}
|
||||
|
||||
static void pin_cache_set_count(Thread* thread, size_t new_count) {
|
||||
data(thread)->_pin_count = new_count;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user