< prev index next >

src/share/vm/gc/g1/g1CollectedHeap.cpp

Print this page

        

@@ -318,16 +318,12 @@
   // This will be the "starts humongous" region.
   HeapRegion* first_hr = region_at(first);
   // The header of the new object will be placed at the bottom of
   // the first region.
   HeapWord* new_obj = first_hr->bottom();
-  // This will be the new end of the first region in the series that
-  // should also match the end of the last region in the series.
-  HeapWord* new_end = new_obj + word_size_sum;
-  // This will be the new top of the first region that will reflect
-  // this allocation.
-  HeapWord* new_top = new_obj + word_size;
+  // This will be the new top of the new object.
+  HeapWord* obj_top = new_obj + word_size;
 
   // First, we need to zero the header of the space that we will be
   // allocating. When we update top further down, some refinement
   // threads might try to scan the region. By zeroing the header we
   // ensure that any thread that will try to scan the region will

@@ -344,23 +340,20 @@
 
   // 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(new_top, new_end);
+  first_hr->set_starts_humongous(obj_top);
   first_hr->set_allocation_context(context);
   // Then, if there are any, we will set up the "continues
   // humongous" regions.
   HeapRegion* hr = NULL;
   for (uint i = first + 1; i < last; ++i) {
     hr = region_at(i);
     hr->set_continues_humongous(first_hr);
     hr->set_allocation_context(context);
   }
-  // If we have "continues humongous" regions (hr != NULL), then the
-  // end of the last one should match new_end.
-  assert(hr == NULL || hr->end() == new_end, "sanity");
 
   // Up to this point no concurrent thread would have been able to
   // do any scanning on any region in this series. All the top
   // fields still point to bottom, so the intersection between
   // [bottom,top] and [card_start,card_end] will be empty. Before we

@@ -369,23 +362,13 @@
   // object header and the BOT initialization.
   OrderAccess::storestore();
 
   // Now that the BOT and the object header have been initialized,
   // we can update top of the "starts humongous" region.
-  assert(first_hr->bottom() < new_top && new_top <= first_hr->end(),
-         "new_top should be in this region");
-  first_hr->set_top(new_top);
+  first_hr->set_top(MIN2(first_hr->end(), obj_top));
   if (_hr_printer.is_active()) {
-    HeapWord* bottom = first_hr->bottom();
-    HeapWord* end = first_hr->orig_end();
-    if ((first + 1) == last) {
-      // the series has a single humongous region
-      _hr_printer.alloc(G1HRPrinter::SingleHumongous, first_hr, new_top);
-    } else {
-      // the series has more than one humongous regions
-      _hr_printer.alloc(G1HRPrinter::StartsHumongous, first_hr, end);
-    }
+    _hr_printer.alloc(G1HRPrinter::StartsHumongous, first_hr, first_hr->top());
   }
 
   // Now, we will update the top fields of the "continues humongous"
   // regions. The reason we need to do this is that, otherwise,
   // these regions would look empty and this will confuse parts of

@@ -400,31 +383,31 @@
   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() < new_top && new_top <= hr->end(),
+      assert(hr->bottom() < obj_top && obj_top <= hr->end(),
              "new_top should fall on this region");
-      hr->set_top(new_top);
-      _hr_printer.alloc(G1HRPrinter::ContinuesHumongous, hr, new_top);
+      hr->set_top(obj_top);
+      _hr_printer.alloc(G1HRPrinter::ContinuesHumongous, hr, obj_top);
     } else {
       // not last one
-      assert(new_top > hr->end(), "new_top should be above this region");
+      assert(obj_top > hr->end(), "obj_top should be above this region");
       hr->set_top(hr->end());
       _hr_printer.alloc(G1HRPrinter::ContinuesHumongous, hr, hr->end());
     }
   }
-  // If we have continues humongous regions (hr != NULL), then the
-  // end of the last one should match new_end and its top should
-  // match new_top.
-  assert(hr == NULL ||
-         (hr->end() == new_end && hr->top() == new_top), "sanity");
+  // If we have continues humongous regions (hr != NULL), its top should
+  // match obj_top.
+  assert(hr == NULL || (hr->top() == obj_top), "sanity");
   check_bitmaps("Humongous Region Allocation", first_hr);
 
-  assert(first_hr->used() == word_size * HeapWordSize, "invariant");
-  increase_used(first_hr->used());
-  _humongous_set.add(first_hr);
+  increase_used(word_size * HeapWordSize);
+
+  for (uint i = first; i < last; ++i) {
+    _humongous_set.add(region_at(i));
+  }
 
   return new_obj;
 }
 
 // If could fit into free regions w/o expansion, try.

@@ -1137,19 +1120,19 @@
     _g1h(g1h), _mr_bs(mr_bs) {}
 
   bool doHeapRegion(HeapRegion* r) {
     HeapRegionRemSet* hrrs = r->rem_set();
 
+    _g1h->reset_gc_time_stamps(r);
+
     if (r->is_continues_humongous()) {
       // We'll assert that the strong code root list and RSet is empty
       assert(hrrs->strong_code_roots_list_length() == 0, "sanity");
       assert(hrrs->occupied() == 0, "RSet should be empty");
-      return false;
-    }
-
-    _g1h->reset_gc_time_stamps(r);
+    } else {
     hrrs->clear();
+    }
     // You might think here that we could clear just the cards
     // corresponding to the used region.  But no: if we leave a dirty card
     // in a region we might allocate into, then it would prevent that card
     // from being enqueued, and cause it to be missed.
     // Re: the performance cost: we shouldn't be doing full GC anyway!

@@ -1203,16 +1186,11 @@
   bool doHeapRegion(HeapRegion* hr) {
     assert(!hr->is_young(), "not expecting to find young regions");
     if (hr->is_free()) {
       // We only generate output for non-empty regions.
     } else if (hr->is_starts_humongous()) {
-      if (hr->region_num() == 1) {
-        // single humongous region
-        _hr_printer->post_compaction(hr, G1HRPrinter::SingleHumongous);
-      } else {
         _hr_printer->post_compaction(hr, G1HRPrinter::StartsHumongous);
-      }
     } else if (hr->is_continues_humongous()) {
       _hr_printer->post_compaction(hr, G1HRPrinter::ContinuesHumongous);
     } else if (hr->is_archive()) {
       _hr_printer->post_compaction(hr, G1HRPrinter::Archive);
     } else if (hr->is_old()) {

@@ -2220,21 +2198,11 @@
 size_t G1CollectedHeap::capacity() const {
   return _hrm.length() * HeapRegion::GrainBytes;
 }
 
 void G1CollectedHeap::reset_gc_time_stamps(HeapRegion* hr) {
-  assert(!hr->is_continues_humongous(), "pre-condition");
   hr->reset_gc_time_stamp();
-  if (hr->is_starts_humongous()) {
-    uint first_index = hr->hrm_index() + 1;
-    uint last_index = hr->last_hc_index();
-    for (uint i = first_index; i < last_index; i += 1) {
-      HeapRegion* chr = region_at(i);
-      assert(chr->is_continues_humongous(), "sanity");
-      chr->reset_gc_time_stamp();
-    }
-  }
 }
 
 #ifndef PRODUCT
 
 class CheckGCTimeStampsHRClosure : public HeapRegionClosure {

@@ -2298,13 +2266,11 @@
 class SumUsedClosure: public HeapRegionClosure {
   size_t _used;
 public:
   SumUsedClosure() : _used(0) {}
   bool doHeapRegion(HeapRegion* r) {
-    if (!r->is_continues_humongous()) {
       _used += r->used();
-    }
     return false;
   }
   size_t result() { return _used; }
 };
 

@@ -2521,13 +2487,13 @@
 }
 
 bool G1CollectedHeap::is_in(const void* p) const {
   if (_hrm.reserved().contains(p)) {
     // Given that we know that p is in the reserved space,
-    // heap_region_containing_raw() should successfully
+    // heap_region_containing() should successfully
     // return the containing region.
-    HeapRegion* hr = heap_region_containing_raw(p);
+    HeapRegion* hr = heap_region_containing(p);
     return hr->is_in(p);
   } else {
     return false;
   }
 }

@@ -3060,11 +3026,11 @@
     if (!r->is_continues_humongous()) {
       bool failures = false;
       r->verify(_vo, &failures);
       if (failures) {
         _failures = true;
-      } else {
+      } else if (!r->is_starts_humongous()) {
         VerifyObjsInRegionClosure not_dead_yet_cl(r, _vo);
         r->object_iterate(&not_dead_yet_cl);
         if (_vo != VerifyOption_G1UseNextMarking) {
           if (r->max_live_bytes() < not_dead_yet_cl.live_bytes()) {
             gclog_or_tty->print_cr("[" PTR_FORMAT "," PTR_FORMAT "] "

@@ -5314,28 +5280,14 @@
 }
 
 void G1CollectedHeap::free_humongous_region(HeapRegion* hr,
                                      FreeRegionList* free_list,
                                      bool par) {
-  assert(hr->is_starts_humongous(), "this is only for starts humongous regions");
+  assert(hr->is_humongous(), "this is only for humongous regions");
   assert(free_list != NULL, "pre-condition");
-
-  size_t hr_capacity = hr->capacity();
-  // We need to read this before we make the region non-humongous,
-  // otherwise the information will be gone.
-  uint last_index = hr->last_hc_index();
   hr->clear_humongous();
   free_region(hr, free_list, par);
-
-  uint i = hr->hrm_index() + 1;
-  while (i < last_index) {
-    HeapRegion* curr_hr = region_at(i);
-    assert(curr_hr->is_continues_humongous(), "invariant");
-    curr_hr->clear_humongous();
-    free_region(curr_hr, free_list, par);
-    i += 1;
-  }
 }
 
 void G1CollectedHeap::remove_from_old_sets(const HeapRegionSetCount& old_regions_removed,
                                        const HeapRegionSetCount& humongous_regions_removed) {
   if (old_regions_removed.length() > 0 || humongous_regions_removed.length() > 0) {

@@ -5495,12 +5447,10 @@
     _caller(caller), _g1h(g1h), _failures(false) { }
 
   bool failures() { return _failures; }
 
   virtual bool doHeapRegion(HeapRegion* hr) {
-    if (hr->is_continues_humongous()) return false;
-
     bool result = _g1h->verify_bitmaps(_caller, hr);
     if (!result) {
       _failures = true;
     }
     return false;

@@ -5770,15 +5720,14 @@
     uint region_idx = r->hrm_index();
     if (!g1h->is_humongous_reclaim_candidate(region_idx) ||
         !r->rem_set()->is_empty()) {
 
       if (G1TraceEagerReclaimHumongousObjects) {
-        gclog_or_tty->print_cr("Live humongous region %u size " SIZE_FORMAT " start " PTR_FORMAT " length %u with remset " SIZE_FORMAT " code roots " SIZE_FORMAT " is marked %d reclaim candidate %d type array %d",
+        gclog_or_tty->print_cr("Live humongous region %u object size " SIZE_FORMAT " start " PTR_FORMAT "  with remset " SIZE_FORMAT " code roots " SIZE_FORMAT " is marked %d reclaim candidate %d type array %d",
                                region_idx,
                                (size_t)obj->size() * HeapWordSize,
                                p2i(r->bottom()),
-                               r->region_num(),
                                r->rem_set()->occupied(),
                                r->rem_set()->strong_code_roots_list_length(),
                                next_bitmap->isMarked(r->bottom()),
                                g1h->is_humongous_reclaim_candidate(region_idx),
                                obj->is_typeArray()

@@ -5791,15 +5740,14 @@
     guarantee(obj->is_typeArray(),
               "Only eagerly reclaiming type arrays is supported, but the object "
               PTR_FORMAT " is not.", p2i(r->bottom()));
 
     if (G1TraceEagerReclaimHumongousObjects) {
-      gclog_or_tty->print_cr("Dead humongous region %u size " SIZE_FORMAT " start " PTR_FORMAT " length %u with remset " SIZE_FORMAT " code roots " SIZE_FORMAT " is marked %d reclaim candidate %d type array %d",
+      gclog_or_tty->print_cr("Dead humongous region %u object size " SIZE_FORMAT " start " PTR_FORMAT " with remset " SIZE_FORMAT " code roots " SIZE_FORMAT " is marked %d reclaim candidate %d type array %d",
                              region_idx,
                              (size_t)obj->size() * HeapWordSize,
                              p2i(r->bottom()),
-                             r->region_num(),
                              r->rem_set()->occupied(),
                              r->rem_set()->strong_code_roots_list_length(),
                              next_bitmap->isMarked(r->bottom()),
                              g1h->is_humongous_reclaim_candidate(region_idx),
                              obj->is_typeArray()

@@ -5807,14 +5755,18 @@
     }
     // Need to clear mark bit of the humongous object if already set.
     if (next_bitmap->isMarked(r->bottom())) {
       next_bitmap->clear(r->bottom());
     }
+    do {
+      HeapRegion* next = g1h->next_region_in_humongous(r);
     _freed_bytes += r->used();
     r->set_containing_set(NULL);
     _humongous_regions_removed.increment(1u, r->capacity());
     g1h->free_humongous_region(r, _free_region_list, false);
+      r = next;
+    } while (r != NULL);
 
     return false;
   }
 
   HeapRegionSetCount& humongous_free_count() {

@@ -6045,14 +5997,10 @@
       assert(_old_set->is_empty(), "pre-condition");
     }
   }
 
   bool doHeapRegion(HeapRegion* r) {
-    if (r->is_continues_humongous()) {
-      return false;
-    }
-
     if (r->is_empty()) {
       // Add free regions to the free list
       r->set_free();
       r->set_allocation_context(AllocationContext::system());
       _hrm->insert_into_free_list(r);

@@ -6236,18 +6184,14 @@
                            HeapRegionManager* hrm) :
     _old_set(old_set), _humongous_set(humongous_set), _hrm(hrm),
     _old_count(), _humongous_count(), _free_count(){ }
 
   bool doHeapRegion(HeapRegion* hr) {
-    if (hr->is_continues_humongous()) {
-      return false;
-    }
-
     if (hr->is_young()) {
       // TODO
-    } else if (hr->is_starts_humongous()) {
-      assert(hr->containing_set() == _humongous_set, "Heap region %u is starts humongous but not in humongous set.", hr->hrm_index());
+    } else if (hr->is_humongous()) {
+      assert(hr->containing_set() == _humongous_set, "Heap region %u is humongous but not in humongous set.", hr->hrm_index());
       _humongous_count.increment(1u, hr->capacity());
     } else if (hr->is_empty()) {
       assert(_hrm->is_free(hr), "Heap region %u is empty but not on the free list.", hr->hrm_index());
       _free_count.increment(1u, hr->capacity());
     } else if (hr->is_old()) {
< prev index next >