Merge
authortonyp
Mon, 30 Aug 2010 13:00:51 -0400
changeset 6429 e4f809183a8c
parent 6419 6b7a06ace8ab (current diff)
parent 6428 a774c26f5fc3 (diff)
child 6430 f933692e6fb3
Merge
--- a/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepGeneration.hpp	Wed Aug 25 10:31:45 2010 -0700
+++ b/hotspot/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepGeneration.hpp	Mon Aug 30 13:00:51 2010 -0400
@@ -252,12 +252,13 @@
 class ChunkArray: public CHeapObj {
   size_t _index;
   size_t _capacity;
+  size_t _overflows;
   HeapWord** _array;   // storage for array
 
  public:
-  ChunkArray() : _index(0), _capacity(0), _array(NULL) {}
+  ChunkArray() : _index(0), _capacity(0), _overflows(0), _array(NULL) {}
   ChunkArray(HeapWord** a, size_t c):
-    _index(0), _capacity(c), _array(a) {}
+    _index(0), _capacity(c), _overflows(0), _array(a) {}
 
   HeapWord** array() { return _array; }
   void set_array(HeapWord** a) { _array = a; }
@@ -266,7 +267,9 @@
   void set_capacity(size_t c) { _capacity = c; }
 
   size_t end() {
-    assert(_index < capacity(), "_index out of bounds");
+    assert(_index <= capacity(),
+           err_msg("_index (" SIZE_FORMAT ") > _capacity (" SIZE_FORMAT "): out of bounds",
+                   _index, _capacity));
     return _index;
   }  // exclusive
 
@@ -277,12 +280,23 @@
 
   void reset() {
     _index = 0;
+    if (_overflows > 0 && PrintCMSStatistics > 1) {
+      warning("CMS: ChunkArray[" SIZE_FORMAT "] overflowed " SIZE_FORMAT " times",
+              _capacity, _overflows);
+    }
+    _overflows = 0;
   }
 
   void record_sample(HeapWord* p, size_t sz) {
     // For now we do not do anything with the size
     if (_index < _capacity) {
       _array[_index++] = p;
+    } else {
+      ++_overflows;
+      assert(_index == _capacity,
+             err_msg("_index (" SIZE_FORMAT ") > _capacity (" SIZE_FORMAT
+                     "): out of bounds at overflow#" SIZE_FORMAT,
+                     _index, _capacity, _overflows));
     }
   }
 };
--- a/hotspot/src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp	Wed Aug 25 10:31:45 2010 -0700
+++ b/hotspot/src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp	Mon Aug 30 13:00:51 2010 -0400
@@ -2753,7 +2753,7 @@
   print_taskqueue_stats_hdr(st);
 
   TaskQueueStats totals;
-  const int n = MAX2(workers()->total_workers(), 1);
+  const int n = workers() != NULL ? workers()->total_workers() : 1;
   for (int i = 0; i < n; ++i) {
     st->print("%3d ", i); task_queue(i)->stats.print(st); st->cr();
     totals += task_queue(i)->stats;
@@ -2764,7 +2764,7 @@
 }
 
 void G1CollectedHeap::reset_taskqueue_stats() {
-  const int n = MAX2(workers()->total_workers(), 1);
+  const int n = workers() != NULL ? workers()->total_workers() : 1;
   for (int i = 0; i < n; ++i) {
     task_queue(i)->stats.reset();
   }
--- a/hotspot/src/share/vm/services/g1MemoryPool.cpp	Wed Aug 25 10:31:45 2010 -0700
+++ b/hotspot/src/share/vm/services/g1MemoryPool.cpp	Mon Aug 30 13:00:51 2010 -0400
@@ -28,12 +28,11 @@
 G1MemoryPoolSuper::G1MemoryPoolSuper(G1CollectedHeap* g1h,
                                      const char* name,
                                      size_t init_size,
-                                     size_t max_size,
                                      bool support_usage_threshold) :
   _g1h(g1h), CollectedMemoryPool(name,
                                  MemoryPool::Heap,
                                  init_size,
-                                 max_size,
+                                 undefined_max(),
                                  support_usage_threshold) {
   assert(UseG1GC, "sanity");
 }
@@ -53,13 +52,6 @@
 }
 
 // See the comment at the top of g1MemoryPool.hpp
-size_t G1MemoryPoolSuper::eden_space_max(G1CollectedHeap* g1h) {
-  // This should ensure that it returns a value no smaller than the
-  // region size. Currently, eden_space_committed() guarantees that.
-  return eden_space_committed(g1h);
-}
-
-// See the comment at the top of g1MemoryPool.hpp
 size_t G1MemoryPoolSuper::survivor_space_committed(G1CollectedHeap* g1h) {
   return MAX2(survivor_space_used(g1h), (size_t) HeapRegion::GrainBytes);
 }
@@ -72,13 +64,6 @@
 }
 
 // See the comment at the top of g1MemoryPool.hpp
-size_t G1MemoryPoolSuper::survivor_space_max(G1CollectedHeap* g1h) {
-  // This should ensure that it returns a value no smaller than the
-  // region size. Currently, survivor_space_committed() guarantees that.
-  return survivor_space_committed(g1h);
-}
-
-// See the comment at the top of g1MemoryPool.hpp
 size_t G1MemoryPoolSuper::old_space_committed(G1CollectedHeap* g1h) {
   size_t committed = overall_committed(g1h);
   size_t eden_committed = eden_space_committed(g1h);
@@ -99,24 +84,11 @@
   return used;
 }
 
-// See the comment at the top of g1MemoryPool.hpp
-size_t G1MemoryPoolSuper::old_space_max(G1CollectedHeap* g1h) {
-  size_t max = overall_max(g1h);
-  size_t eden_max = eden_space_max(g1h);
-  size_t survivor_max = survivor_space_max(g1h);
-  max = subtract_up_to_zero(max, eden_max);
-  max = subtract_up_to_zero(max, survivor_max);
-  max = MAX2(max, (size_t) HeapRegion::GrainBytes);
-  return max;
-}
-
 G1EdenPool::G1EdenPool(G1CollectedHeap* g1h) :
   G1MemoryPoolSuper(g1h,
                     "G1 Eden",
                     eden_space_committed(g1h), /* init_size */
-                    eden_space_max(g1h), /* max_size */
-                    false /* support_usage_threshold */) {
-}
+                    false /* support_usage_threshold */) { }
 
 MemoryUsage G1EdenPool::get_memory_usage() {
   size_t initial_sz = initial_size();
@@ -131,9 +103,7 @@
   G1MemoryPoolSuper(g1h,
                     "G1 Survivor",
                     survivor_space_committed(g1h), /* init_size */
-                    survivor_space_max(g1h), /* max_size */
-                    false /* support_usage_threshold */) {
-}
+                    false /* support_usage_threshold */) { }
 
 MemoryUsage G1SurvivorPool::get_memory_usage() {
   size_t initial_sz = initial_size();
@@ -148,9 +118,7 @@
   G1MemoryPoolSuper(g1h,
                     "G1 Old Gen",
                     old_space_committed(g1h), /* init_size */
-                    old_space_max(g1h), /* max_size */
-                    true /* support_usage_threshold */) {
-}
+                    true /* support_usage_threshold */) { }
 
 MemoryUsage G1OldGenPool::get_memory_usage() {
   size_t initial_sz = initial_size();
--- a/hotspot/src/share/vm/services/g1MemoryPool.hpp	Wed Aug 25 10:31:45 2010 -0700
+++ b/hotspot/src/share/vm/services/g1MemoryPool.hpp	Mon Aug 30 13:00:51 2010 -0400
@@ -74,14 +74,20 @@
 // in the future.
 //
 // 3) Another decision that is again not straightforward is what is
-// the max size that each memory pool can grow to. Right now, we set
-// that the committed size for the eden and the survivors and
-// calculate the old gen max as follows (basically, it's a similar
-// pattern to what we use for the committed space, as described
-// above):
+// the max size that each memory pool can grow to. One way to do this
+// would be to use the committed size for the max for the eden and
+// survivors and calculate the old gen max as follows (basically, it's
+// a similar pattern to what we use for the committed space, as
+// described above):
 //
 //  old_gen_max = overall_max - eden_max - survivor_max
 //
+// Unfortunately, the above makes the max of each pool fluctuate over
+// time and, even though this is allowed according to the spec, it
+// broke several assumptions in the M&M framework (there were cases
+// where used would reach a value greater than max). So, for max we
+// use -1, which means "undefined" according to the spec.
+//
 // 4) Now, there is a very subtle issue with all the above. The
 // framework will call get_memory_usage() on the three pools
 // asynchronously. As a result, each call might get a different value
@@ -125,33 +131,30 @@
   G1MemoryPoolSuper(G1CollectedHeap* g1h,
                     const char* name,
                     size_t init_size,
-                    size_t max_size,
                     bool support_usage_threshold);
 
   // The reason why all the code is in static methods is so that it
   // can be safely called from the constructors of the subclasses.
 
+  static size_t undefined_max() {
+    return (size_t) -1;
+  }
+
   static size_t overall_committed(G1CollectedHeap* g1h) {
     return g1h->capacity();
   }
   static size_t overall_used(G1CollectedHeap* g1h) {
     return g1h->used_unlocked();
   }
-  static size_t overall_max(G1CollectedHeap* g1h) {
-    return g1h->g1_reserved_obj_bytes();
-  }
 
   static size_t eden_space_committed(G1CollectedHeap* g1h);
   static size_t eden_space_used(G1CollectedHeap* g1h);
-  static size_t eden_space_max(G1CollectedHeap* g1h);
 
   static size_t survivor_space_committed(G1CollectedHeap* g1h);
   static size_t survivor_space_used(G1CollectedHeap* g1h);
-  static size_t survivor_space_max(G1CollectedHeap* g1h);
 
   static size_t old_space_committed(G1CollectedHeap* g1h);
   static size_t old_space_used(G1CollectedHeap* g1h);
-  static size_t old_space_max(G1CollectedHeap* g1h);
 };
 
 // Memory pool that represents the G1 eden.
@@ -163,7 +166,7 @@
     return eden_space_used(_g1h);
   }
   size_t max_size() const {
-    return eden_space_max(_g1h);
+    return undefined_max();
   }
   MemoryUsage get_memory_usage();
 };
@@ -177,7 +180,7 @@
     return survivor_space_used(_g1h);
   }
   size_t max_size() const {
-    return survivor_space_max(_g1h);
+    return undefined_max();
   }
   MemoryUsage get_memory_usage();
 };
@@ -191,7 +194,7 @@
     return old_space_used(_g1h);
   }
   size_t max_size() const {
-    return old_space_max(_g1h);
+    return undefined_max();
   }
   MemoryUsage get_memory_usage();
 };
--- a/hotspot/src/share/vm/services/management.cpp	Wed Aug 25 10:31:45 2010 -0700
+++ b/hotspot/src/share/vm/services/management.cpp	Mon Aug 30 13:00:51 2010 -0400
@@ -785,10 +785,11 @@
     }
   }
 
-  // In our current implementation, all pools should have
-  // defined init and max size
-  assert(!has_undefined_init_size, "Undefined init size");
-  assert(!has_undefined_max_size, "Undefined max size");
+  // In our current implementation, we make sure that all non-heap
+  // pools have defined init and max sizes. Heap pools do not matter,
+  // as we never use total_init and total_max for them.
+  assert(heap || !has_undefined_init_size, "Undefined init size");
+  assert(heap || !has_undefined_max_size,  "Undefined max size");
 
   MemoryUsage usage((heap ? InitialHeapSize : total_init),
                     total_used,
--- a/hotspot/test/gc/6581734/Test6581734.java	Wed Aug 25 10:31:45 2010 -0700
+++ b/hotspot/test/gc/6581734/Test6581734.java	Mon Aug 30 13:00:51 2010 -0400
@@ -121,7 +121,7 @@
         }
 
         if (collectorsWithTime<collectorsFound) {
-            throw new RuntimeException("collectors found with zero time";
+            throw new RuntimeException("collectors found with zero time");
         }
         System.out.println("Test passed.");
     }