src/share/vm/memory/metaspace.cpp
Print this page
rev 7145 : 8049599: MetaspaceGC::_capacity_until_GC can overflow (02)
@@ -1420,16 +1420,16 @@
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 aligned max value
+ // The addition wrapped around, set new_value to aligned max value.
new_value = align_size_down(max_uintx, Metaspace::commit_alignment());
}
intptr_t expected = (intptr_t) capacity_until_GC;
- intptr_t actual = Atomic::cmpxchg((intptr_t) new_value, &_capacity_until_GC, expected);
+ intptr_t actual = Atomic::cmpxchg_ptr((intptr_t) new_value, &_capacity_until_GC, expected);
if (expected != actual) {
return false;
}
@@ -3343,28 +3343,29 @@
MetaWord* Metaspace::expand_and_allocate(size_t word_size, MetadataType mdtype) {
size_t delta_bytes = MetaspaceGC::delta_capacity_until_GC(word_size * BytesPerWord);
assert(delta_bytes > 0, "Must be");
- size_t before_inc = 0;
- size_t after_inc = 0;
- MetaWord* res = NULL;
- bool inc_succeeded = false;
-
- while (!inc_succeeded && res == NULL) {
- inc_succeeded = MetaspaceGC::inc_capacity_until_GC(delta_bytes,
- &after_inc,
- &before_inc);
+ size_t before = 0;
+ size_t after = 0;
+ MetaWord* res;
+ bool incremented;
+
+ // Each thread increments the HWM at most once. Even if the thread fails to increment
+ // the HWM, an allocation is still attempted. This is because another thread must then
+ // have incremented the HWM and therefore the allocation might still succeed.
+ do {
+ incremented = MetaspaceGC::inc_capacity_until_GC(delta_bytes, &after, &before);
res = allocate(word_size, mdtype);
- }
+ } while (!incremented && res == NULL);
- if (inc_succeeded) {
- tracer()->report_gc_threshold(before_inc, after_inc,
+ if (incremented) {
+ tracer()->report_gc_threshold(before, after,
MetaspaceGCThresholdUpdater::ExpandAndAllocate);
if (PrintGCDetails && Verbose) {
gclog_or_tty->print_cr("Increase capacity to GC from " SIZE_FORMAT
- " to " SIZE_FORMAT, before_inc, after_inc);
+ " to " SIZE_FORMAT, before, after);
}
}
return res;
}