diff src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp @ 1991:016a3628c885

6994056: G1: when GC locker is active, extend the Eden instead of allocating into the old gen Summary: Allow the eden to the expanded up to a point when the GC locker is active. Reviewed-by: jwilhelm, johnc, ysr, jcoomes
author tonyp
date Tue, 07 Dec 2010 16:47:42 -0500
parents d9310331a29c
children 8df09fb45352
line wrap: on
line diff
--- a/src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp	Thu Dec 02 13:20:39 2010 -0500
+++ b/src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp	Tue Dec 07 16:47:42 2010 -0500
@@ -619,15 +619,19 @@
 HeapWord*
 G1CollectedHeap::replace_cur_alloc_region_and_allocate(size_t word_size,
                                                        bool at_safepoint,
-                                                       bool do_dirtying) {
+                                                       bool do_dirtying,
+                                                       bool can_expand) {
   assert_heap_locked_or_at_safepoint();
   assert(_cur_alloc_region == NULL,
          "replace_cur_alloc_region_and_allocate() should only be called "
          "after retiring the previous current alloc region");
   assert(SafepointSynchronize::is_at_safepoint() == at_safepoint,
          "at_safepoint and is_at_safepoint() should be a tautology");
-
-  if (!g1_policy()->is_young_list_full()) {
+  assert(!can_expand || g1_policy()->can_expand_young_list(),
+         "we should not call this method with can_expand == true if "
+         "we are not allowed to expand the young gen");
+
+  if (can_expand || !g1_policy()->is_young_list_full()) {
     if (!at_safepoint) {
       // The cleanup operation might update _summary_bytes_used
       // concurrently with this method. So, right now, if we don't
@@ -738,11 +742,26 @@
     }
 
     if (GC_locker::is_active_and_needs_gc()) {
-      // We are locked out of GC because of the GC locker. Right now,
-      // we'll just stall until the GC locker-induced GC
-      // completes. This will be fixed in the near future by extending
-      // the eden while waiting for the GC locker to schedule the GC
-      // (see CR 6994056).
+      // We are locked out of GC because of the GC locker. We can
+      // allocate a new region only if we can expand the young gen.
+
+      if (g1_policy()->can_expand_young_list()) {
+        // Yes, we are allowed to expand the young gen. Let's try to
+        // allocate a new current alloc region.
+
+        HeapWord* result =
+          replace_cur_alloc_region_and_allocate(word_size,
+                                                false, /* at_safepoint */
+                                                true,  /* do_dirtying */
+                                                true   /* can_expand */);
+        if (result != NULL) {
+          assert_heap_not_locked();
+          return result;
+        }
+      }
+      // We could not expand the young gen further (or we could but we
+      // failed to allocate a new region). We'll stall until the GC
+      // locker forces a GC.
 
       // If this thread is not in a jni critical section, we stall
       // the requestor until the critical section has cleared and
@@ -950,7 +969,8 @@
            "at this point we should have no cur alloc region");
     return replace_cur_alloc_region_and_allocate(word_size,
                                                  true, /* at_safepoint */
-                                                 false /* do_dirtying */);
+                                                 false /* do_dirtying */,
+                                                 false /* can_expand */);
   } else {
     return attempt_allocation_humongous(word_size,
                                         true /* at_safepoint */);