diff src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp @ 4834:6a78aa6ac1ff

7132311: G1: assert((s == klass->oop_size(this)) || (Universe::heap()->is_gc_active() && ((is_typeArray()... Summary: Move the check for when to call collect() to before we do a humongous object allocation Reviewed-by: stefank, tonyp
author brutisso
date Mon, 23 Jan 2012 20:36:16 +0100
parents 57025542827f
children d30fa85f9994
line wrap: on
line diff
--- a/src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp	Fri Jan 20 18:01:32 2012 +0100
+++ b/src/share/vm/gc_implementation/g1/g1CollectedHeap.cpp	Mon Jan 23 20:36:16 2012 +0100
@@ -1029,6 +1029,15 @@
   assert(isHumongous(word_size), "attempt_allocation_humongous() "
          "should only be called for humongous allocations");
 
+  // Humongous objects can exhaust the heap quickly, so we should check if we
+  // need to start a marking cycle at each humongous object allocation. We do
+  // the check before we do the actual allocation. The reason for doing it
+  // before the allocation is that we avoid having to keep track of the newly
+  // allocated memory while we do a GC.
+  if (g1_policy()->need_to_start_conc_mark("concurrent humongous allocation", word_size)) {
+    collect(GCCause::_g1_humongous_allocation);
+  }
+
   // We will loop until a) we manage to successfully perform the
   // allocation or b) we successfully schedule a collection which
   // fails to perform the allocation. b) is the only case when we'll
@@ -1045,30 +1054,17 @@
       // regions, we'll first try to do the allocation without doing a
       // collection hoping that there's enough space in the heap.
       result = humongous_obj_allocate(word_size);
-
-      if (result == NULL) {
-        if (GC_locker::is_active_and_needs_gc()) {
-          should_try_gc = false;
-        } else {
-          // Read the GC count while still holding the Heap_lock.
-          gc_count_before = SharedHeap::heap()->total_collections();
-          should_try_gc = true;
-        }
+      if (result != NULL) {
+        return result;
       }
-    }
-
-    if (result != NULL) {
-      if (g1_policy()->need_to_start_conc_mark("concurrent humongous allocation")) {
-        // We need to release the Heap_lock before we try to call collect().
-        // The result will not be stored in any object before this method
-        // returns, so the GC might miss it. Thus, we create a handle to the result
-        // and fake an object at that place.
-        CollectedHeap::fill_with_object(result, word_size, false);
-        Handle h((oop)result);
-        collect(GCCause::_g1_humongous_allocation);
-        assert(result == (HeapWord*)h(), "Humongous objects should not be moved by collections");
+
+      if (GC_locker::is_active_and_needs_gc()) {
+        should_try_gc = false;
+      } else {
+        // Read the GC count while still holding the Heap_lock.
+        gc_count_before = SharedHeap::heap()->total_collections();
+        should_try_gc = true;
       }
-      return result;
     }
 
     if (should_try_gc) {