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;
 }