src/share/vm/memory/metaspace.cpp
Print this page
rev 6878 : 8049599: MetaspaceGC::_capacity_until_GC can overflow
@@ -1413,11 +1413,33 @@
}
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 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());