8138681: Runtime.getFreeMemory() reports wrong value after humongous allocation.
authordavid
Fri, 20 Nov 2015 17:32:02 +0100
changeset 34249 a015a11067a2
parent 34245 8ab9cefd6373
child 34250 d5b35cbe05a6
8138681: Runtime.getFreeMemory() reports wrong value after humongous allocation. Reviewed-by: tschatzl, mgerdin
hotspot/src/share/vm/gc/g1/g1BlockOffsetTable.cpp
hotspot/src/share/vm/gc/g1/g1BlockOffsetTable.hpp
hotspot/src/share/vm/gc/g1/g1CollectedHeap.cpp
hotspot/src/share/vm/gc/g1/heapRegion.cpp
hotspot/src/share/vm/gc/g1/heapRegion.hpp
--- a/hotspot/src/share/vm/gc/g1/g1BlockOffsetTable.cpp	Fri Sep 11 15:18:43 2015 +0200
+++ b/hotspot/src/share/vm/gc/g1/g1BlockOffsetTable.cpp	Fri Nov 20 17:32:02 2015 +0100
@@ -499,11 +499,14 @@
   return _next_offset_threshold;
 }
 
-void G1BlockOffsetArrayContigSpace::set_for_starts_humongous(HeapWord* obj_top) {
+void G1BlockOffsetArrayContigSpace::set_for_starts_humongous(HeapWord* obj_top, size_t fill_size) {
   // The first BOT entry should have offset 0.
   reset_bot();
   alloc_block(_bottom, obj_top);
- }
+  if (fill_size > 0) {
+    alloc_block(obj_top, fill_size);
+  }
+}
 
 #ifndef PRODUCT
 void G1BlockOffsetArrayContigSpace::print_on(outputStream* out) {
--- a/hotspot/src/share/vm/gc/g1/g1BlockOffsetTable.hpp	Fri Sep 11 15:18:43 2015 +0200
+++ b/hotspot/src/share/vm/gc/g1/g1BlockOffsetTable.hpp	Fri Nov 20 17:32:02 2015 +0100
@@ -372,7 +372,7 @@
   HeapWord* block_start_unsafe(const void* addr);
   HeapWord* block_start_unsafe_const(const void* addr) const;
 
-  void set_for_starts_humongous(HeapWord* obj_top);
+  void set_for_starts_humongous(HeapWord* obj_top, size_t fill_size);
 
   virtual void print_on(outputStream* out) PRODUCT_RETURN;
 };
--- a/hotspot/src/share/vm/gc/g1/g1CollectedHeap.cpp	Fri Sep 11 15:18:43 2015 +0200
+++ b/hotspot/src/share/vm/gc/g1/g1CollectedHeap.cpp	Fri Nov 20 17:32:02 2015 +0100
@@ -339,11 +339,18 @@
   // thread to calculate the object size incorrectly.
   Copy::fill_to_words(new_obj, oopDesc::header_size(), 0);
 
+  size_t fill_size = word_size_sum - word_size;
+  if (fill_size >= min_fill_size()) {
+    fill_with_objects(obj_top, fill_size);
+  } else {
+    fill_size = 0;
+  }
+
   // We will set up the first region as "starts humongous". This
   // will also update the BOT covering all the regions to reflect
   // that there is a single object that starts at the bottom of the
   // first region.
-  first_hr->set_starts_humongous(obj_top);
+  first_hr->set_starts_humongous(obj_top, fill_size);
   first_hr->set_allocation_context(context);
   // Then, if there are any, we will set up the "continues
   // humongous" regions.
@@ -365,9 +372,9 @@
 
   // Now that the BOT and the object header have been initialized,
   // we can update top of the "starts humongous" region.
-  first_hr->set_top(MIN2(first_hr->end(), obj_top));
+  first_hr->set_top(first_hr->end());
   if (_hr_printer.is_active()) {
-    _hr_printer.alloc(G1HRPrinter::StartsHumongous, first_hr, first_hr->top());
+    _hr_printer.alloc(G1HRPrinter::StartsHumongous, first_hr, first_hr->end());
   }
 
   // Now, we will update the top fields of the "continues humongous"
@@ -375,25 +382,18 @@
   hr = NULL;
   for (uint i = first + 1; i < last; ++i) {
     hr = region_at(i);
-    if ((i + 1) == last) {
-      // last continues humongous region
-      assert(hr->bottom() < obj_top && obj_top <= hr->end(),
-             "new_top should fall on this region");
-      hr->set_top(obj_top);
-      _hr_printer.alloc(G1HRPrinter::ContinuesHumongous, hr, obj_top);
-    } else {
-      // not last one
-      assert(obj_top > hr->end(), "obj_top should be above this region");
-      hr->set_top(hr->end());
+    hr->set_top(hr->end());
+    if (_hr_printer.is_active()) {
       _hr_printer.alloc(G1HRPrinter::ContinuesHumongous, hr, hr->end());
     }
   }
-  // If we have continues humongous regions (hr != NULL), its top should
-  // match obj_top.
-  assert(hr == NULL || (hr->top() == obj_top), "sanity");
+
+  assert(hr == NULL || (hr->bottom() < obj_top && obj_top <= hr->end()),
+         "obj_top should be in last region");
+
   check_bitmaps("Humongous Region Allocation", first_hr);
 
-  increase_used(word_size * HeapWordSize);
+  increase_used(word_size_sum * HeapWordSize);
 
   for (uint i = first; i < last; ++i) {
     _humongous_set.add(region_at(i));
--- a/hotspot/src/share/vm/gc/g1/heapRegion.cpp	Fri Sep 11 15:18:43 2015 +0200
+++ b/hotspot/src/share/vm/gc/g1/heapRegion.cpp	Fri Nov 20 17:32:02 2015 +0100
@@ -211,14 +211,14 @@
   _gc_efficiency = (double) reclaimable_bytes() / region_elapsed_time_ms;
 }
 
-void HeapRegion::set_starts_humongous(HeapWord* obj_top) {
+void HeapRegion::set_starts_humongous(HeapWord* obj_top, size_t fill_size) {
   assert(!is_humongous(), "sanity / pre-condition");
   assert(top() == bottom(), "should be empty");
 
   _type.set_starts_humongous();
   _humongous_start_region = this;
 
-  _offsets.set_for_starts_humongous(obj_top);
+  _offsets.set_for_starts_humongous(obj_top, fill_size);
 }
 
 void HeapRegion::set_continues_humongous(HeapRegion* first_hr) {
@@ -756,16 +756,6 @@
     size_t obj_size = block_size(p);
     object_num += 1;
 
-    if (is_region_humongous != g1->is_humongous(obj_size) &&
-        !g1->is_obj_dead(obj, this)) { // Dead objects may have bigger block_size since they span several objects.
-      gclog_or_tty->print_cr("obj " PTR_FORMAT " is of %shumongous size ("
-                             SIZE_FORMAT " words) in a %shumongous region",
-                             p2i(p), g1->is_humongous(obj_size) ? "" : "non-",
-                             obj_size, is_region_humongous ? "" : "non-");
-       *failures = true;
-       return;
-    }
-
     if (!g1->is_obj_dead_cond(obj, this, vo)) {
       if (obj->is_oop()) {
         Klass* klass = obj->klass();
@@ -876,14 +866,6 @@
     }
   }
 
-  if (is_region_humongous && object_num > 1) {
-    gclog_or_tty->print_cr("region [" PTR_FORMAT "," PTR_FORMAT "] is humongous "
-                           "but has " SIZE_FORMAT ", objects",
-                           p2i(bottom()), p2i(end()), object_num);
-    *failures = true;
-    return;
-  }
-
   verify_strong_code_roots(vo, failures);
 }
 
--- a/hotspot/src/share/vm/gc/g1/heapRegion.hpp	Fri Sep 11 15:18:43 2015 +0200
+++ b/hotspot/src/share/vm/gc/g1/heapRegion.hpp	Fri Nov 20 17:32:02 2015 +0100
@@ -455,9 +455,9 @@
   // the first region in a series of one or more contiguous regions
   // that will contain a single "humongous" object.
   //
-  // obj_top : points to the end of the humongous object that's being
-  // allocated.
-  void set_starts_humongous(HeapWord* obj_top);
+  // obj_top : points to the top of the humongous object.
+  // fill_size : size of the filler object at the end of the region series.
+  void set_starts_humongous(HeapWord* obj_top, size_t fill_size);
 
   // Makes the current region be a "continues humongous'
   // region. first_hr is the "start humongous" region of the series