hotspot/src/share/vm/gc/serial/defNewGeneration.cpp
changeset 35458 71a08884be5f
parent 35061 be6025ebffea
child 35471 deb38c83d759
--- a/hotspot/src/share/vm/gc/serial/defNewGeneration.cpp	Wed Jan 06 14:54:24 2016 +0000
+++ b/hotspot/src/share/vm/gc/serial/defNewGeneration.cpp	Tue Jan 05 17:05:13 2016 -0800
@@ -364,6 +364,36 @@
   return success;
 }
 
+size_t DefNewGeneration::adjust_for_thread_increase(size_t new_size_candidate,
+                                                    size_t new_size_before,
+                                                    size_t alignment) const {
+  size_t desired_new_size = new_size_before;
+
+  if (NewSizeThreadIncrease > 0) {
+    int threads_count;
+    size_t thread_increase_size = 0;
+
+    // 1. Check an overflow at 'threads_count * NewSizeThreadIncrease'.
+    threads_count = Threads::number_of_non_daemon_threads();
+    if (NewSizeThreadIncrease <= max_uintx / threads_count) {
+      thread_increase_size = threads_count * NewSizeThreadIncrease;
+
+      // 2. Check an overflow at 'new_size_candidate + thread_increase_size'.
+      if (new_size_candidate <= max_uintx - thread_increase_size) {
+        new_size_candidate += thread_increase_size;
+
+        // 3. Check an overflow at 'align_size_up'.
+        size_t aligned_max = ((max_uintx - alignment) & ~(alignment-1));
+        if (new_size_candidate <= aligned_max) {
+          desired_new_size = align_size_up(new_size_candidate, alignment);
+        }
+      }
+    }
+  }
+
+  return desired_new_size;
+}
+
 void DefNewGeneration::compute_new_size() {
   // This is called after a GC that includes the old generation, so from-space
   // will normally be empty.
@@ -385,12 +415,13 @@
   // All space sizes must be multiples of Generation::GenGrain.
   size_t alignment = Generation::GenGrain;
 
-  // Compute desired new generation size based on NewRatio and
-  // NewSizeThreadIncrease
-  size_t desired_new_size = old_size/NewRatio;
-  int threads_count = Threads::number_of_non_daemon_threads();
-  size_t thread_increase_size = threads_count * NewSizeThreadIncrease;
-  desired_new_size = align_size_up(desired_new_size + thread_increase_size, alignment);
+  int threads_count = 0;
+  size_t thread_increase_size = 0;
+
+  size_t new_size_candidate = old_size / NewRatio;
+  // Compute desired new generation size based on NewRatio and NewSizeThreadIncrease
+  // and reverts to previous value if any overflow happens
+  size_t desired_new_size = adjust_for_thread_increase(new_size_candidate, new_size_before, alignment);
 
   // Adjust new generation size
   desired_new_size = MAX2(MIN2(desired_new_size, max_new_size), min_new_size);