changeset 10864:1825208d432f

8166663: Simplify oops_on_card_seq_iterate_careful Summary: Remove unnecessary parameter, change return value. Reviewed-by: tschatzl, mgerdin, phh
author kbarrett
date Mon, 26 Sep 2016 14:38:35 -0400
parents be47c996965c
children 1a2714e736d0
files src/share/vm/gc_implementation/g1/g1RemSet.cpp src/share/vm/gc_implementation/g1/heapRegion.cpp src/share/vm/gc_implementation/g1/heapRegion.hpp
diffstat 3 files changed, 39 insertions(+), 49 deletions(-) [+]
line wrap: on
line diff
--- a/src/share/vm/gc_implementation/g1/g1RemSet.cpp	Fri Oct 21 22:26:51 2016 -0400
+++ b/src/share/vm/gc_implementation/g1/g1RemSet.cpp	Mon Sep 26 14:38:35 2016 -0400
@@ -568,20 +568,18 @@
   // fail arbitrarily). We tell the iteration code to perform this
   // filtering when it has been determined that there has been an actual
   // allocation in this region and making it safe to check the young type.
-  bool filter_young = true;
 
-  HeapWord* stop_point =
+  bool card_processed =
     r->oops_on_card_seq_iterate_careful(dirtyRegion,
                                         &filter_then_update_rs_oop_cl,
-                                        filter_young,
                                         card_ptr);
 
-  // If stop_point is non-null, then we encountered an unallocated region
-  // (perhaps the unfilled portion of a TLAB.)  For now, we'll dirty the
-  // card and re-enqueue: if we put off the card until a GC pause, then the
-  // unallocated portion will be filled in.  Alternatively, we might try
-  // the full complexity of the technique used in "regular" precleaning.
-  if (stop_point != NULL) {
+  // If unable to process the card then we encountered an unparsable
+  // part of the heap (e.g. a partially allocated object).  Redirty
+  // and re-enqueue: if we put off the card until a GC pause, then the
+  // allocation will have completed.
+  if (!card_processed) {
+    assert(!_g1->is_gc_active(), "Unparsable heap during GC");
     // The card might have gotten re-dirtied and re-enqueued while we
     // worked.  (In fact, it's pretty likely.)
     if (*card_ptr != CardTableModRefBS::dirty_card_val()) {
--- a/src/share/vm/gc_implementation/g1/heapRegion.cpp	Fri Oct 21 22:26:51 2016 -0400
+++ b/src/share/vm/gc_implementation/g1/heapRegion.cpp	Mon Sep 26 14:38:35 2016 -0400
@@ -407,19 +407,10 @@
   return NULL;
 }
 
-HeapWord*
-HeapRegion::
-oops_on_card_seq_iterate_careful(MemRegion mr,
-                                 FilterOutOfRegionClosure* cl,
-                                 bool filter_young,
-                                 jbyte* card_ptr) {
-  // Currently, we should only have to clean the card if filter_young
-  // is true and vice versa.
-  if (filter_young) {
-    assert(card_ptr != NULL, "pre-condition");
-  } else {
-    assert(card_ptr == NULL, "pre-condition");
-  }
+bool HeapRegion::oops_on_card_seq_iterate_careful(MemRegion mr,
+                                                  FilterOutOfRegionClosure* cl,
+                                                  jbyte* card_ptr) {
+  assert(card_ptr != NULL, "pre-condition");
   G1CollectedHeap* g1h = G1CollectedHeap::heap();
 
   // If we're within a stop-world GC, then we might look at a card in a
@@ -430,7 +421,9 @@
   } else {
     mr = mr.intersection(used_region());
   }
-  if (mr.is_empty()) return NULL;
+  if (mr.is_empty()) {
+    return true;
+  }
   // Otherwise, find the obj that extends onto mr.start().
 
   // The intersection of the incoming mr (for the card) and the
@@ -439,27 +432,21 @@
   // G1CollectedHeap.cpp that allocates a new region sets the
   // is_young tag on the region before allocating. Thus we
   // safely know if this region is young.
-  if (is_young() && filter_young) {
-    return NULL;
+  if (is_young()) {
+    return true;
   }
 
-  assert(!is_young(), "check value of filter_young");
-
   // We can only clean the card here, after we make the decision that
-  // the card is not young. And we only clean the card if we have been
-  // asked to (i.e., card_ptr != NULL).
-  if (card_ptr != NULL) {
-    *card_ptr = CardTableModRefBS::clean_card_val();
-    // We must complete this write before we do any of the reads below.
-    OrderAccess::storeload();
-  }
+  // the card is not young.
+  *card_ptr = CardTableModRefBS::clean_card_val();
+  // We must complete this write before we do any of the reads below.
+  OrderAccess::storeload();
 
   // Cache the boundaries of the memory region in some const locals
   HeapWord* const start = mr.start();
   HeapWord* const end = mr.end();
 
-  // We used to use "block_start_careful" here.  But we're actually happy
-  // to update the BOT while we do this...
+  // Update BOT as needed while finding start of (potential) object.
   HeapWord* cur = block_start(start);
   assert(cur <= start, "Postcondition");
 
@@ -471,7 +458,9 @@
     obj = oop(cur);
     if (obj->klass_or_null() == NULL) {
       // Ran into an unparseable point.
-      return cur;
+      assert(!g1h->is_gc_active(),
+             err_msg("Unparsable heap during GC at " PTR_FORMAT, p2i(cur)));
+      return false;
     }
     // Otherwise...
     next = cur + block_size(cur);
@@ -488,7 +477,9 @@
     assert((cur + block_size(cur)) > (HeapWord*)obj, "Loop invariant");
     if (obj->klass_or_null() == NULL) {
       // Ran into an unparseable point.
-      return cur;
+      assert(!g1h->is_gc_active(),
+             err_msg("Unparsable heap during GC at " PTR_FORMAT, p2i(cur)));
+      return false;
     }
 
     // Advance the current pointer. "obj" still points to the object to iterate.
@@ -507,7 +498,7 @@
     }
   } while (cur < end);
 
-  return NULL;
+  return true;
 }
 
 // Code roots support
--- a/src/share/vm/gc_implementation/g1/heapRegion.hpp	Fri Oct 21 22:26:51 2016 -0400
+++ b/src/share/vm/gc_implementation/g1/heapRegion.hpp	Mon Sep 26 14:38:35 2016 -0400
@@ -718,16 +718,17 @@
   HeapWord*
   object_iterate_mem_careful(MemRegion mr, ObjectClosure* cl);
 
-  // filter_young: if true and the region is a young region then we
-  // skip the iteration.
-  // card_ptr: if not NULL, and we decide that the card is not young
-  // and we iterate over it, we'll clean the card before we start the
-  // iteration.
-  HeapWord*
-  oops_on_card_seq_iterate_careful(MemRegion mr,
-                                   FilterOutOfRegionClosure* cl,
-                                   bool filter_young,
-                                   jbyte* card_ptr);
+  // Iterate over the card in the card designated by card_ptr,
+  // applying cl to all references in the region.
+  // mr: the memory region covered by the card.
+  // card_ptr: if we decide that the card is not young and we iterate
+  // over it, we'll clean the card before we start the iteration.
+  // Returns true if card was successfully processed, false if an
+  // unparsable part of the heap was encountered, which should only
+  // happen when invoked concurrently with the mutator.
+  bool oops_on_card_seq_iterate_careful(MemRegion mr,
+                                        FilterOutOfRegionClosure* cl,
+                                        jbyte* card_ptr);
 
   size_t recorded_rs_length() const        { return _recorded_rs_length; }
   double predicted_elapsed_time_ms() const { return _predicted_elapsed_time_ms; }