src/share/vm/memory/metaspace.cpp
Print this page
rev 6878 : 8049599: MetaspaceGC::_capacity_until_GC can overflow
*** 1413,1423 ****
}
size_t MetaspaceGC::inc_capacity_until_GC(size_t v) {
assert_is_size_aligned(v, Metaspace::commit_alignment());
! return (size_t)Atomic::add_ptr(v, &_capacity_until_GC);
}
size_t MetaspaceGC::dec_capacity_until_GC(size_t v) {
assert_is_size_aligned(v, Metaspace::commit_alignment());
--- 1413,1445 ----
}
size_t MetaspaceGC::inc_capacity_until_GC(size_t v) {
assert_is_size_aligned(v, Metaspace::commit_alignment());
! size_t capacity_until_GC = (size_t) _capacity_until_GC;
! size_t new_value = capacity_until_GC + v;
!
! if (new_value < capacity_until_GC) {
! // the addition wrapped around, set new_value to max value
! new_value = max_uintx;
! }
!
! bool cas_succeeded = false;
! size_t num_retries = 5; // just to limit the number of CAS attempts
! for (size_t i = 0; i < num_retries; i++) {
! intptr_t cmp = (intptr_t) capacity_until_GC;
! intptr_t swap = (intptr_t) new_value;
! intptr_t prev = Atomic::cmpxchg_ptr(swap, &_capacity_until_GC, cmp);
!
! if (prev == cmp) {
! cas_succeeded = true;
! break;
! }
! }
!
! // if the CAS did not succeed, just return the current value
! return cas_succeeded ? new_value : _capacity_until_GC;
}
size_t MetaspaceGC::dec_capacity_until_GC(size_t v) {
assert_is_size_aligned(v, Metaspace::commit_alignment());