-
Type:
Enhancement
-
Resolution: Fixed
-
Priority:
P4
-
Affects Version/s: 25, 26, 27
-
Component/s: hotspot
Convert ShenandoahOldGeneration to use Atomic<T>, this also fix the code issue below(missing volatile may not causing any issue as long as AtomicAccess is always used to access the fields)
>>> orignal description
Came across the source code of ShenandoahOldGeneration, and noticed that we use AtomicAccess to read/write to fileds `_promoted_expended`, `_promotion_failure_count`, `_promotion_failure_words` but non of them is declared with volatile modifier.
It supposed to be a small fix by just adding the missing `volatile` modifier, but instead of adding `volatile` modifier, I think we cloud use Atomic<T> instead of static APIs from AtomicAccess.
```
// Bytes of old-gen memory expended on promotions. This may be modified concurrently
// by mutators and gc workers when promotion LABs are retired during evacuation. It
// is therefore always accessed through atomic operations. This is increased when a
// PLAB is allocated for promotions. The value is decreased by the amount of memory
// remaining in a PLAB when it is retired.
size_t _promoted_expended;
...
// Keep track of the number and size of promotions that failed. Perhaps we should use this to increase
// the size of the old generation for the next collection cycle.
size_t _promotion_failure_count;
size_t _promotion_failure_words;
```
```
void ShenandoahOldGeneration::reset_promoted_expended() {
shenandoah_assert_heaplocked_or_safepoint();
AtomicAccess::store(&_promoted_expended, static_cast<size_t>(0));
AtomicAccess::store(&_promotion_failure_count, static_cast<size_t>(0));
AtomicAccess::store(&_promotion_failure_words, static_cast<size_t>(0));
}
...
void ShenandoahOldGeneration::handle_failed_promotion(Thread* thread, size_t size) {
AtomicAccess::inc(&_promotion_failure_count);
AtomicAccess::add(&_promotion_failure_words, size);
LogTarget(Debug, gc, plab) lt;
LogStream ls(lt);
if (lt.is_enabled()) {
log_failed_promotion(ls, thread, size);
}
}
```
>>> orignal description
Came across the source code of ShenandoahOldGeneration, and noticed that we use AtomicAccess to read/write to fileds `_promoted_expended`, `_promotion_failure_count`, `_promotion_failure_words` but non of them is declared with volatile modifier.
It supposed to be a small fix by just adding the missing `volatile` modifier, but instead of adding `volatile` modifier, I think we cloud use Atomic<T> instead of static APIs from AtomicAccess.
```
// Bytes of old-gen memory expended on promotions. This may be modified concurrently
// by mutators and gc workers when promotion LABs are retired during evacuation. It
// is therefore always accessed through atomic operations. This is increased when a
// PLAB is allocated for promotions. The value is decreased by the amount of memory
// remaining in a PLAB when it is retired.
size_t _promoted_expended;
...
// Keep track of the number and size of promotions that failed. Perhaps we should use this to increase
// the size of the old generation for the next collection cycle.
size_t _promotion_failure_count;
size_t _promotion_failure_words;
```
```
void ShenandoahOldGeneration::reset_promoted_expended() {
shenandoah_assert_heaplocked_or_safepoint();
AtomicAccess::store(&_promoted_expended, static_cast<size_t>(0));
AtomicAccess::store(&_promotion_failure_count, static_cast<size_t>(0));
AtomicAccess::store(&_promotion_failure_words, static_cast<size_t>(0));
}
...
void ShenandoahOldGeneration::handle_failed_promotion(Thread* thread, size_t size) {
AtomicAccess::inc(&_promotion_failure_count);
AtomicAccess::add(&_promotion_failure_words, size);
LogTarget(Debug, gc, plab) lt;
LogStream ls(lt);
if (lt.is_enabled()) {
log_failed_promotion(ls, thread, size);
}
}
```
- links to
-
Commit(master)
openjdk/jdk/09ed8e66
-
Review(master)
openjdk/jdk/29456