Mon, 30 Aug 2010 13:00:51 -0400
Merge
1.1 --- a/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepGeneration.hpp Wed Aug 25 10:31:45 2010 -0700 1.2 +++ b/src/share/vm/gc_implementation/concurrentMarkSweep/concurrentMarkSweepGeneration.hpp Mon Aug 30 13:00:51 2010 -0400 1.3 @@ -252,12 +252,13 @@ 1.4 class ChunkArray: public CHeapObj { 1.5 size_t _index; 1.6 size_t _capacity; 1.7 + size_t _overflows; 1.8 HeapWord** _array; // storage for array 1.9 1.10 public: 1.11 - ChunkArray() : _index(0), _capacity(0), _array(NULL) {} 1.12 + ChunkArray() : _index(0), _capacity(0), _overflows(0), _array(NULL) {} 1.13 ChunkArray(HeapWord** a, size_t c): 1.14 - _index(0), _capacity(c), _array(a) {} 1.15 + _index(0), _capacity(c), _overflows(0), _array(a) {} 1.16 1.17 HeapWord** array() { return _array; } 1.18 void set_array(HeapWord** a) { _array = a; } 1.19 @@ -266,7 +267,9 @@ 1.20 void set_capacity(size_t c) { _capacity = c; } 1.21 1.22 size_t end() { 1.23 - assert(_index < capacity(), "_index out of bounds"); 1.24 + assert(_index <= capacity(), 1.25 + err_msg("_index (" SIZE_FORMAT ") > _capacity (" SIZE_FORMAT "): out of bounds", 1.26 + _index, _capacity)); 1.27 return _index; 1.28 } // exclusive 1.29 1.30 @@ -277,12 +280,23 @@ 1.31 1.32 void reset() { 1.33 _index = 0; 1.34 + if (_overflows > 0 && PrintCMSStatistics > 1) { 1.35 + warning("CMS: ChunkArray[" SIZE_FORMAT "] overflowed " SIZE_FORMAT " times", 1.36 + _capacity, _overflows); 1.37 + } 1.38 + _overflows = 0; 1.39 } 1.40 1.41 void record_sample(HeapWord* p, size_t sz) { 1.42 // For now we do not do anything with the size 1.43 if (_index < _capacity) { 1.44 _array[_index++] = p; 1.45 + } else { 1.46 + ++_overflows; 1.47 + assert(_index == _capacity, 1.48 + err_msg("_index (" SIZE_FORMAT ") > _capacity (" SIZE_FORMAT 1.49 + "): out of bounds at overflow#" SIZE_FORMAT, 1.50 + _index, _capacity, _overflows)); 1.51 } 1.52 } 1.53 };
2.1 --- a/src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp Wed Aug 25 10:31:45 2010 -0700 2.2 +++ b/src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp Mon Aug 30 13:00:51 2010 -0400 2.3 @@ -2753,7 +2753,7 @@ 2.4 print_taskqueue_stats_hdr(st); 2.5 2.6 TaskQueueStats totals; 2.7 - const int n = MAX2(workers()->total_workers(), 1); 2.8 + const int n = workers() != NULL ? workers()->total_workers() : 1; 2.9 for (int i = 0; i < n; ++i) { 2.10 st->print("%3d ", i); task_queue(i)->stats.print(st); st->cr(); 2.11 totals += task_queue(i)->stats; 2.12 @@ -2764,7 +2764,7 @@ 2.13 } 2.14 2.15 void G1CollectedHeap::reset_taskqueue_stats() { 2.16 - const int n = MAX2(workers()->total_workers(), 1); 2.17 + const int n = workers() != NULL ? workers()->total_workers() : 1; 2.18 for (int i = 0; i < n; ++i) { 2.19 task_queue(i)->stats.reset(); 2.20 }
3.1 --- a/src/share/vm/services/g1MemoryPool.cpp Wed Aug 25 10:31:45 2010 -0700 3.2 +++ b/src/share/vm/services/g1MemoryPool.cpp Mon Aug 30 13:00:51 2010 -0400 3.3 @@ -28,12 +28,11 @@ 3.4 G1MemoryPoolSuper::G1MemoryPoolSuper(G1CollectedHeap* g1h, 3.5 const char* name, 3.6 size_t init_size, 3.7 - size_t max_size, 3.8 bool support_usage_threshold) : 3.9 _g1h(g1h), CollectedMemoryPool(name, 3.10 MemoryPool::Heap, 3.11 init_size, 3.12 - max_size, 3.13 + undefined_max(), 3.14 support_usage_threshold) { 3.15 assert(UseG1GC, "sanity"); 3.16 } 3.17 @@ -53,13 +52,6 @@ 3.18 } 3.19 3.20 // See the comment at the top of g1MemoryPool.hpp 3.21 -size_t G1MemoryPoolSuper::eden_space_max(G1CollectedHeap* g1h) { 3.22 - // This should ensure that it returns a value no smaller than the 3.23 - // region size. Currently, eden_space_committed() guarantees that. 3.24 - return eden_space_committed(g1h); 3.25 -} 3.26 - 3.27 -// See the comment at the top of g1MemoryPool.hpp 3.28 size_t G1MemoryPoolSuper::survivor_space_committed(G1CollectedHeap* g1h) { 3.29 return MAX2(survivor_space_used(g1h), (size_t) HeapRegion::GrainBytes); 3.30 } 3.31 @@ -72,13 +64,6 @@ 3.32 } 3.33 3.34 // See the comment at the top of g1MemoryPool.hpp 3.35 -size_t G1MemoryPoolSuper::survivor_space_max(G1CollectedHeap* g1h) { 3.36 - // This should ensure that it returns a value no smaller than the 3.37 - // region size. Currently, survivor_space_committed() guarantees that. 3.38 - return survivor_space_committed(g1h); 3.39 -} 3.40 - 3.41 -// See the comment at the top of g1MemoryPool.hpp 3.42 size_t G1MemoryPoolSuper::old_space_committed(G1CollectedHeap* g1h) { 3.43 size_t committed = overall_committed(g1h); 3.44 size_t eden_committed = eden_space_committed(g1h); 3.45 @@ -99,24 +84,11 @@ 3.46 return used; 3.47 } 3.48 3.49 -// See the comment at the top of g1MemoryPool.hpp 3.50 -size_t G1MemoryPoolSuper::old_space_max(G1CollectedHeap* g1h) { 3.51 - size_t max = overall_max(g1h); 3.52 - size_t eden_max = eden_space_max(g1h); 3.53 - size_t survivor_max = survivor_space_max(g1h); 3.54 - max = subtract_up_to_zero(max, eden_max); 3.55 - max = subtract_up_to_zero(max, survivor_max); 3.56 - max = MAX2(max, (size_t) HeapRegion::GrainBytes); 3.57 - return max; 3.58 -} 3.59 - 3.60 G1EdenPool::G1EdenPool(G1CollectedHeap* g1h) : 3.61 G1MemoryPoolSuper(g1h, 3.62 "G1 Eden", 3.63 eden_space_committed(g1h), /* init_size */ 3.64 - eden_space_max(g1h), /* max_size */ 3.65 - false /* support_usage_threshold */) { 3.66 -} 3.67 + false /* support_usage_threshold */) { } 3.68 3.69 MemoryUsage G1EdenPool::get_memory_usage() { 3.70 size_t initial_sz = initial_size(); 3.71 @@ -131,9 +103,7 @@ 3.72 G1MemoryPoolSuper(g1h, 3.73 "G1 Survivor", 3.74 survivor_space_committed(g1h), /* init_size */ 3.75 - survivor_space_max(g1h), /* max_size */ 3.76 - false /* support_usage_threshold */) { 3.77 -} 3.78 + false /* support_usage_threshold */) { } 3.79 3.80 MemoryUsage G1SurvivorPool::get_memory_usage() { 3.81 size_t initial_sz = initial_size(); 3.82 @@ -148,9 +118,7 @@ 3.83 G1MemoryPoolSuper(g1h, 3.84 "G1 Old Gen", 3.85 old_space_committed(g1h), /* init_size */ 3.86 - old_space_max(g1h), /* max_size */ 3.87 - true /* support_usage_threshold */) { 3.88 -} 3.89 + true /* support_usage_threshold */) { } 3.90 3.91 MemoryUsage G1OldGenPool::get_memory_usage() { 3.92 size_t initial_sz = initial_size();
4.1 --- a/src/share/vm/services/g1MemoryPool.hpp Wed Aug 25 10:31:45 2010 -0700 4.2 +++ b/src/share/vm/services/g1MemoryPool.hpp Mon Aug 30 13:00:51 2010 -0400 4.3 @@ -74,14 +74,20 @@ 4.4 // in the future. 4.5 // 4.6 // 3) Another decision that is again not straightforward is what is 4.7 -// the max size that each memory pool can grow to. Right now, we set 4.8 -// that the committed size for the eden and the survivors and 4.9 -// calculate the old gen max as follows (basically, it's a similar 4.10 -// pattern to what we use for the committed space, as described 4.11 -// above): 4.12 +// the max size that each memory pool can grow to. One way to do this 4.13 +// would be to use the committed size for the max for the eden and 4.14 +// survivors and calculate the old gen max as follows (basically, it's 4.15 +// a similar pattern to what we use for the committed space, as 4.16 +// described above): 4.17 // 4.18 // old_gen_max = overall_max - eden_max - survivor_max 4.19 // 4.20 +// Unfortunately, the above makes the max of each pool fluctuate over 4.21 +// time and, even though this is allowed according to the spec, it 4.22 +// broke several assumptions in the M&M framework (there were cases 4.23 +// where used would reach a value greater than max). So, for max we 4.24 +// use -1, which means "undefined" according to the spec. 4.25 +// 4.26 // 4) Now, there is a very subtle issue with all the above. The 4.27 // framework will call get_memory_usage() on the three pools 4.28 // asynchronously. As a result, each call might get a different value 4.29 @@ -125,33 +131,30 @@ 4.30 G1MemoryPoolSuper(G1CollectedHeap* g1h, 4.31 const char* name, 4.32 size_t init_size, 4.33 - size_t max_size, 4.34 bool support_usage_threshold); 4.35 4.36 // The reason why all the code is in static methods is so that it 4.37 // can be safely called from the constructors of the subclasses. 4.38 4.39 + static size_t undefined_max() { 4.40 + return (size_t) -1; 4.41 + } 4.42 + 4.43 static size_t overall_committed(G1CollectedHeap* g1h) { 4.44 return g1h->capacity(); 4.45 } 4.46 static size_t overall_used(G1CollectedHeap* g1h) { 4.47 return g1h->used_unlocked(); 4.48 } 4.49 - static size_t overall_max(G1CollectedHeap* g1h) { 4.50 - return g1h->g1_reserved_obj_bytes(); 4.51 - } 4.52 4.53 static size_t eden_space_committed(G1CollectedHeap* g1h); 4.54 static size_t eden_space_used(G1CollectedHeap* g1h); 4.55 - static size_t eden_space_max(G1CollectedHeap* g1h); 4.56 4.57 static size_t survivor_space_committed(G1CollectedHeap* g1h); 4.58 static size_t survivor_space_used(G1CollectedHeap* g1h); 4.59 - static size_t survivor_space_max(G1CollectedHeap* g1h); 4.60 4.61 static size_t old_space_committed(G1CollectedHeap* g1h); 4.62 static size_t old_space_used(G1CollectedHeap* g1h); 4.63 - static size_t old_space_max(G1CollectedHeap* g1h); 4.64 }; 4.65 4.66 // Memory pool that represents the G1 eden. 4.67 @@ -163,7 +166,7 @@ 4.68 return eden_space_used(_g1h); 4.69 } 4.70 size_t max_size() const { 4.71 - return eden_space_max(_g1h); 4.72 + return undefined_max(); 4.73 } 4.74 MemoryUsage get_memory_usage(); 4.75 }; 4.76 @@ -177,7 +180,7 @@ 4.77 return survivor_space_used(_g1h); 4.78 } 4.79 size_t max_size() const { 4.80 - return survivor_space_max(_g1h); 4.81 + return undefined_max(); 4.82 } 4.83 MemoryUsage get_memory_usage(); 4.84 }; 4.85 @@ -191,7 +194,7 @@ 4.86 return old_space_used(_g1h); 4.87 } 4.88 size_t max_size() const { 4.89 - return old_space_max(_g1h); 4.90 + return undefined_max(); 4.91 } 4.92 MemoryUsage get_memory_usage(); 4.93 };
5.1 --- a/src/share/vm/services/management.cpp Wed Aug 25 10:31:45 2010 -0700 5.2 +++ b/src/share/vm/services/management.cpp Mon Aug 30 13:00:51 2010 -0400 5.3 @@ -785,10 +785,11 @@ 5.4 } 5.5 } 5.6 5.7 - // In our current implementation, all pools should have 5.8 - // defined init and max size 5.9 - assert(!has_undefined_init_size, "Undefined init size"); 5.10 - assert(!has_undefined_max_size, "Undefined max size"); 5.11 + // In our current implementation, we make sure that all non-heap 5.12 + // pools have defined init and max sizes. Heap pools do not matter, 5.13 + // as we never use total_init and total_max for them. 5.14 + assert(heap || !has_undefined_init_size, "Undefined init size"); 5.15 + assert(heap || !has_undefined_max_size, "Undefined max size"); 5.16 5.17 MemoryUsage usage((heap ? InitialHeapSize : total_init), 5.18 total_used,
6.1 --- a/test/gc/6581734/Test6581734.java Wed Aug 25 10:31:45 2010 -0700 6.2 +++ b/test/gc/6581734/Test6581734.java Mon Aug 30 13:00:51 2010 -0400 6.3 @@ -121,7 +121,7 @@ 6.4 } 6.5 6.6 if (collectorsWithTime<collectorsFound) { 6.7 - throw new RuntimeException("collectors found with zero time"; 6.8 + throw new RuntimeException("collectors found with zero time"); 6.9 } 6.10 System.out.println("Test passed."); 6.11 }