Tue, 07 Dec 2010 16:44:34 -0800
Merge
1.1 --- a/src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp Tue Dec 07 16:18:45 2010 -0800 1.2 +++ b/src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp Tue Dec 07 16:44:34 2010 -0800 1.3 @@ -619,15 +619,19 @@ 1.4 HeapWord* 1.5 G1CollectedHeap::replace_cur_alloc_region_and_allocate(size_t word_size, 1.6 bool at_safepoint, 1.7 - bool do_dirtying) { 1.8 + bool do_dirtying, 1.9 + bool can_expand) { 1.10 assert_heap_locked_or_at_safepoint(); 1.11 assert(_cur_alloc_region == NULL, 1.12 "replace_cur_alloc_region_and_allocate() should only be called " 1.13 "after retiring the previous current alloc region"); 1.14 assert(SafepointSynchronize::is_at_safepoint() == at_safepoint, 1.15 "at_safepoint and is_at_safepoint() should be a tautology"); 1.16 - 1.17 - if (!g1_policy()->is_young_list_full()) { 1.18 + assert(!can_expand || g1_policy()->can_expand_young_list(), 1.19 + "we should not call this method with can_expand == true if " 1.20 + "we are not allowed to expand the young gen"); 1.21 + 1.22 + if (can_expand || !g1_policy()->is_young_list_full()) { 1.23 if (!at_safepoint) { 1.24 // The cleanup operation might update _summary_bytes_used 1.25 // concurrently with this method. So, right now, if we don't 1.26 @@ -738,11 +742,26 @@ 1.27 } 1.28 1.29 if (GC_locker::is_active_and_needs_gc()) { 1.30 - // We are locked out of GC because of the GC locker. Right now, 1.31 - // we'll just stall until the GC locker-induced GC 1.32 - // completes. This will be fixed in the near future by extending 1.33 - // the eden while waiting for the GC locker to schedule the GC 1.34 - // (see CR 6994056). 1.35 + // We are locked out of GC because of the GC locker. We can 1.36 + // allocate a new region only if we can expand the young gen. 1.37 + 1.38 + if (g1_policy()->can_expand_young_list()) { 1.39 + // Yes, we are allowed to expand the young gen. Let's try to 1.40 + // allocate a new current alloc region. 1.41 + 1.42 + HeapWord* result = 1.43 + replace_cur_alloc_region_and_allocate(word_size, 1.44 + false, /* at_safepoint */ 1.45 + true, /* do_dirtying */ 1.46 + true /* can_expand */); 1.47 + if (result != NULL) { 1.48 + assert_heap_not_locked(); 1.49 + return result; 1.50 + } 1.51 + } 1.52 + // We could not expand the young gen further (or we could but we 1.53 + // failed to allocate a new region). We'll stall until the GC 1.54 + // locker forces a GC. 1.55 1.56 // If this thread is not in a jni critical section, we stall 1.57 // the requestor until the critical section has cleared and 1.58 @@ -950,7 +969,8 @@ 1.59 "at this point we should have no cur alloc region"); 1.60 return replace_cur_alloc_region_and_allocate(word_size, 1.61 true, /* at_safepoint */ 1.62 - false /* do_dirtying */); 1.63 + false /* do_dirtying */, 1.64 + false /* can_expand */); 1.65 } else { 1.66 return attempt_allocation_humongous(word_size, 1.67 true /* at_safepoint */);
2.1 --- a/src/share/vm/gc_implementation/g1/g1CollectedHeap.hpp Tue Dec 07 16:18:45 2010 -0800 2.2 +++ b/src/share/vm/gc_implementation/g1/g1CollectedHeap.hpp Tue Dec 07 16:44:34 2010 -0800 2.3 @@ -496,12 +496,15 @@ 2.4 inline HeapWord* attempt_allocation(size_t word_size); 2.5 2.6 // It assumes that the current alloc region has been retired and 2.7 - // tries to allocate a new one. If it's successful, it performs 2.8 - // the allocation out of the new current alloc region and updates 2.9 - // _cur_alloc_region. 2.10 + // tries to allocate a new one. If it's successful, it performs the 2.11 + // allocation out of the new current alloc region and updates 2.12 + // _cur_alloc_region. Normally, it would try to allocate a new 2.13 + // region if the young gen is not full, unless can_expand is true in 2.14 + // which case it would always try to allocate a new region. 2.15 HeapWord* replace_cur_alloc_region_and_allocate(size_t word_size, 2.16 bool at_safepoint, 2.17 - bool do_dirtying); 2.18 + bool do_dirtying, 2.19 + bool can_expand); 2.20 2.21 // The slow path when we are unable to allocate a new current alloc 2.22 // region to satisfy an allocation request (i.e., when
3.1 --- a/src/share/vm/gc_implementation/g1/g1CollectedHeap.inline.hpp Tue Dec 07 16:18:45 2010 -0800 3.2 +++ b/src/share/vm/gc_implementation/g1/g1CollectedHeap.inline.hpp Tue Dec 07 16:44:34 2010 -0800 3.3 @@ -119,8 +119,9 @@ 3.4 3.5 // Try to get a new region and allocate out of it 3.6 HeapWord* result = replace_cur_alloc_region_and_allocate(word_size, 3.7 - false, /* at safepoint */ 3.8 - true /* do_dirtying */); 3.9 + false, /* at_safepoint */ 3.10 + true, /* do_dirtying */ 3.11 + false /* can_expand */); 3.12 if (result != NULL) { 3.13 assert_heap_not_locked(); 3.14 return result;
4.1 --- a/src/share/vm/gc_implementation/g1/g1CollectorPolicy.cpp Tue Dec 07 16:18:45 2010 -0800 4.2 +++ b/src/share/vm/gc_implementation/g1/g1CollectorPolicy.cpp Tue Dec 07 16:44:34 2010 -0800 4.3 @@ -479,6 +479,7 @@ 4.4 // region before we need to do a collection again. 4.5 size_t min_length = _g1->young_list()->length() + 1; 4.6 _young_list_target_length = MAX2(_young_list_target_length, min_length); 4.7 + calculate_max_gc_locker_expansion(); 4.8 calculate_survivors_policy(); 4.9 } 4.10 4.11 @@ -2301,6 +2302,21 @@ 4.12 }; 4.13 } 4.14 4.15 +void G1CollectorPolicy::calculate_max_gc_locker_expansion() { 4.16 + size_t expansion_region_num = 0; 4.17 + if (GCLockerEdenExpansionPercent > 0) { 4.18 + double perc = (double) GCLockerEdenExpansionPercent / 100.0; 4.19 + double expansion_region_num_d = perc * (double) _young_list_target_length; 4.20 + // We use ceiling so that if expansion_region_num_d is > 0.0 (but 4.21 + // less than 1.0) we'll get 1. 4.22 + expansion_region_num = (size_t) ceil(expansion_region_num_d); 4.23 + } else { 4.24 + assert(expansion_region_num == 0, "sanity"); 4.25 + } 4.26 + _young_list_max_length = _young_list_target_length + expansion_region_num; 4.27 + assert(_young_list_target_length <= _young_list_max_length, "post-condition"); 4.28 +} 4.29 + 4.30 // Calculates survivor space parameters. 4.31 void G1CollectorPolicy::calculate_survivors_policy() 4.32 {
5.1 --- a/src/share/vm/gc_implementation/g1/g1CollectorPolicy.hpp Tue Dec 07 16:18:45 2010 -0800 5.2 +++ b/src/share/vm/gc_implementation/g1/g1CollectorPolicy.hpp Tue Dec 07 16:44:34 2010 -0800 5.3 @@ -196,6 +196,10 @@ 5.4 size_t _young_list_target_length; 5.5 size_t _young_list_fixed_length; 5.6 5.7 + // The max number of regions we can extend the eden by while the GC 5.8 + // locker is active. This should be >= _young_list_target_length; 5.9 + size_t _young_list_max_length; 5.10 + 5.11 size_t _young_cset_length; 5.12 bool _last_young_gc_full; 5.13 5.14 @@ -1113,13 +1117,22 @@ 5.15 5.16 bool is_young_list_full() { 5.17 size_t young_list_length = _g1->young_list()->length(); 5.18 - size_t young_list_max_length = _young_list_target_length; 5.19 + size_t young_list_target_length = _young_list_target_length; 5.20 + if (G1FixedEdenSize) { 5.21 + young_list_target_length -= _max_survivor_regions; 5.22 + } 5.23 + return young_list_length >= young_list_target_length; 5.24 + } 5.25 + 5.26 + bool can_expand_young_list() { 5.27 + size_t young_list_length = _g1->young_list()->length(); 5.28 + size_t young_list_max_length = _young_list_max_length; 5.29 if (G1FixedEdenSize) { 5.30 young_list_max_length -= _max_survivor_regions; 5.31 } 5.32 + return young_list_length < young_list_max_length; 5.33 + } 5.34 5.35 - return young_list_length >= young_list_max_length; 5.36 - } 5.37 void update_region_num(bool young); 5.38 5.39 bool in_young_gc_mode() { 5.40 @@ -1231,6 +1244,8 @@ 5.41 _survivors_age_table.merge_par(age_table); 5.42 } 5.43 5.44 + void calculate_max_gc_locker_expansion(); 5.45 + 5.46 // Calculates survivor space parameters. 5.47 void calculate_survivors_policy(); 5.48
6.1 --- a/src/share/vm/runtime/globals.hpp Tue Dec 07 16:18:45 2010 -0800 6.2 +++ b/src/share/vm/runtime/globals.hpp Tue Dec 07 16:44:34 2010 -0800 6.3 @@ -1403,6 +1403,10 @@ 6.4 "The exit of a JNI CS necessitating a scavenge also" \ 6.5 " kicks off a bkgrd concurrent collection") \ 6.6 \ 6.7 + product(uintx, GCLockerEdenExpansionPercent, 5, \ 6.8 + "How much the GC can expand the eden by while the GC locker " \ 6.9 + "is active (as a percentage)") \ 6.10 + \ 6.11 develop(bool, UseCMSAdaptiveFreeLists, true, \ 6.12 "Use Adaptive Free Lists in the CMS generation") \ 6.13 \